PageSourceSearch

https://www.xplova.com/en/products/x2

html xplova.com collected 2026-09-26 01:49:14 UTC 319,629 bytes, 5,874 lines download raw bytes

1<!DOCTYPE html>
2<html lang="en" style="height:100%;">
3  <head>
4      
4<script>
5        window.dataLayer = window.dataLayer || [];
6      </script>
6
7    
8      <!-- CYBERBIZ Google Tag Manager -->
9      
9<script>
vendor: 345 bytes, lines 9-13
9(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
10      new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
11      j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
12      'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
13      })(window,document,'script','cyb','
13GTM-TXD9LVJ
vendor: 3 bytes, line 13
13');
13</script>
13
14      <!-- End CYBERBIZ Google Tag Manager -->
15    
16      
16<script>
17        function getUserFromCookie(){
18          if(localStorage.customer && localStorage.customer != '{"notLogin":true}'){
19            return JSON.parse(localStorage.customer).id;
20          }else{
21            return "";
22          }
23        }
24        cyb = [{
25          'shop': "33373-Xplova",
26          'shop_plan': "enterprise",
27          'userId': getUserFromCookie()
28        }];
29      </script>
29
30    
31      <!-- CYBERBIZ Google Tag Manager -->
32      
32<script>
vendor: 345 bytes, lines 32-36
32(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
33      new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
34      j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
35      'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
36      })(window,document,'script','cyb','
36GTM-P7528MQ
vendor: 3 bytes, line 36
36');
36</script>
36
37      <!-- End CYBERBIZ Google Tag Manager -->
38    
39      <meta http-equiv="Content-Security-Policy" content="object-src 'none'; base-uri 'self'">
40
41    <meta charset="utf-8">
42<meta http-equiv="X-UA-Compatible" content="IE=edge">
43<meta name="viewport" content="width=device-width, initial-scale=1">
44<link rel="icon" href="https://cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxMzU1NDQ5X2Zhdmljb24ucG5nLnBuZyJdXQ.png?convert=false&sha=7828c38c7cd539c5">
45<link rel="apple-touch-icon" href="https://cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxMzU1NDQ5X2Zhdmljb24ucG5nLnBuZyJdXQ.png?convert=false&sha=7828c38c7cd539c5">
46
47<meta property="og:site_name" content="Xplova" />
48
49<!-- og tag -->
50
51
52<!-- og image -->
53
54  <meta property="og:image" content="https://cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL3Byb2R1Y3RzLzU4MDIxMzk1LzE3NTM5NTA3NzNfMGY5MDQ5MzhjYzU5YjNlNWE2ZTYucG5nIl0sWyJwIiwidGh1bWIiLCI0ODB4NDgwIl1d.png?sha=699e868f5d1b8407" />
55
56
57<title>
58  
59    Xplova | X2 - Smart Cycling Computer Xplova
60  
61</title>
62
63
64
65<script src='//cdn-general.cybassets.com/frontend/shop/useSettingsData-3a2e378145f8a165.js' type='text/javascript'></script>
65
66
67
68
69  
69<script>
70    window.setSettingsData({"draggable_sections":{"404":[],"index":["1752478878849_7","1751433913963_1","1751441121043_1","1751439706808_8","1751433767750_7","1751512152179_8","1751502858632_5","1751435274143_6","1751512699907_1","1751521270877_6","1751512337232_5","1751445071383_8","1751446031984_7"],"product":["product_info","product_description","board_comments","related_products"],"collection":[],"category":[],"blog":[],"article":[],"cart":[],"contact":[],"express_delivery":[],"search":[],"combo_product":["combo_product_info","combo_product_desc","board_comments"]},"sections":{"navbar":{"type":"navbar","visible":true,"settings":{"navbar_image_logo_url":"//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxNDM1MDAxX3hwbG92YV9sb2dvXzEwMC5wbmcucG5nIl1d.png?sha=2390923483f0eb3f","navbar_image_logo_tablet_url":"","navbar_image_logo_mobile_url":"","main_nav":"main-menu","slider_primary_linklist":"main-menu","slider_primary_linklist_set_open":true,"nav_show_three_dimension":true,"search_enabled":false,"display_only_index":false,"dict_header_banner_image_url":"","dict_header_banner_image_tablet_url":"","dict_header_banner_image_mobile_url":"","dict_header_banner_link":"/blogs/announcement","display_count_down":false,"link_menu_enabled":false,"link_menu":"undefined","navbar_display_style":"rowNav","menu_display_style":"three_dimension_menu","display_banner_type":"textBanner","header_banner_simple_text_size":"12","header_banner_simple_text_color":"#000000","header_banner_simple_bg":"#B6B8BA","header_banner_start":"","header_banner_end":"","timer_text_color":"#c39d6f","timer_bg_color":"#2b2b6e","header_logo_image_alt":"xplova","header_banner_image_alt":"","header_banner_simple_text":"Important Notice about Xplova Website Service Change","link_open_in_new_tab":true,"logo_height":""},"custom_name":"導覽列"},"footer":{"type":"footer","visible":true,"settings":{"footer_link":"footer","display_facebook":true,"shop_facebook":"https://www.facebook.com/acergadget.xplova/","display_instagram":true,"shop_instagram":"https://www.instagram.com/xplova.global/","display_line":false,"shop_line":"https://line.me/zh-hant/","display_youtube":true,"shop_youtube":"https://www.youtube.com/c/XplovaPoweredbyAcer","footer_link_arrangement":"display_x"},"block_order":["default_link_list","default_contact_info"],"blocks":{"default_link_list":{"type":"link_list_setting","thumbnail":"list","draggable":true,"visible":true,"settings":{"dict_link_list_block_title":"About Xplova","footer_link":"footer-menu-en"},"custom_name":"選單"},"default_contact_info":{"type":"contact_info_setting","thumbnail":"contactInfo","draggable":true,"visible":false,"settings":{"dict_contact_info_block_title":"Contact Info","display_phone":false,"dict_phone_number":"+886-2-2790-3878","display_fax_number":false,"dict_shop_fax_number":"","display_shop_email":true,"dict_shop_email":"[email protected]","display_shop_address":false,"dict_shop_address":"","display_office_time":false,"dict_shop_office_time":"10:00-17:00","display_tax_id":true,"dict_tax_id":"22089345"},"custom_name":"聯絡資訊"}},"custom_name":"頁腳"},"_main_slider_custom":{"type":"_main_slider_custom","visible":true,"blocks":{"display_main_slider_item_1":{"type":"image","visible":true,"settings":{"dict_link":"","dict_image_url":"/theme_src/i18n_shoestore/default_img/new_main_slider_item_1_lg.jpg","dict_tablet_image_url":"","dict_mobile_image_url":"","slide_contents_display":"left","dict_slide_btn_link":"","slide_title_color":"#000000","slide_content_color":"#000000","slide_btn_bg_color":"#000000","slide_btn_text_color":"#ffffff"},"custom_name":"素材"},"display_main_slider_item_2":{"type":"image","visible":true,"settings":{"dict_link":"","dict_image_url":"/theme_src/i18n_shoestore/default_img/new_main_slider_item_2_lg.jpg","dict_tablet_image_url":"","dict_mobile_image_url":"","slide_contents_display":"left","dict_slide_btn_link":"","slide_title_color":"#000000","slide_content_color":"#000000","slide_btn_bg_color":"#000000","slide_btn_text_color":"#ffffff"},"custom_name":"素材"},"display_main_slider_item_3":{"type":"image","visible":true,"settings":{"dict_link":"","dict_image_url":"/theme_src/i18n_shoestore/default_img/new_main_slider_item_3_lg.jpg","dict_tablet_image_url":"","dict_mobile_image_url":"","slide_contents_display":"left","dict_slide_btn_link":"","slide_title_color":"#000000","slide_content_color":"#000000","slide_btn_bg_color":"#000000","slide_btn_text_color":"#ffffff"},"custom_name":"素材"},"display_main_slider_item_4":{"type":"image","visible":false,"settings":{"dict_link":"","dict_image_url":"","dict_tablet_image_url":"","dict_mobile_image_url":"","slide_contents_display":"left","dict_slide_btn_link":"","slide_title_color":"#000000","slide_content_color":"#000000","slide_btn_bg_color":"#000000","slide_btn_text_color":"#ffffff"},"custom_name":"素材"},"display_main_slider_item_5":{"type":"image","visible":false,"settings":{"dict_link":"","dict_image_url":"","dict_tablet_image_url":"","dict_mobile_image_url":"","slide_contents_display":"left","dict_slide_btn_link":"","slide_title_color":"#000000","slide_content_color":"#000000","slide_btn_bg_color":"#000000","slide_btn_text_color":"#ffffff"},"custom_name":"素材"}},"block_order":["display_main_slider_item_1","display_main_slider_item_2","display_main_slider_item_3","display_main_slider_item_4","display_main_slider_item_5"],"settings":{"swiper_delay":"3","margin_x":"0","margin_bottom":"50","image_number":"1","image_space":"12","mobile_margin_x":"0","mobile_margin_bottom":"50","mobile_image_number":"1","mobile_image_space":"8"},"custom_name":"輪播素材"},"_index_product_banner":{"type":"_index_product_banner","visible":true,"settings":{"dict_link":"","dict_image_url":"/theme_src/i18n_shoestore/default_img/new_index_product_banner_1_lg.jpg","dict_tablet_image_url":"","dict_mobile_image_url":"","cta_btn_display_style":"topPosition","cta_btn_bg_color":"#000000","cta_btn_text_color":"#ffffff","margin_x":"0","margin_bottom":"50","mobile_margin_x":"0","mobile_margin_bottom":"24"},"custom_name":"橫幅廣告"},"_index_8_blocks":{"type":"_index_8_blocks","visible":true,"settings":{"dict_title":"New Arrivals","collection_handle":"frontpage","limit":"12","product_arrangement":"1","product_column_for_pc":"4","product_alignment":"leftPosition","product_text_align":"center","margin_x":"0","margin_bottom":"50","mobile_margin_x":"0","mobile_margin_bottom":"24","product_display":"displayDefault"},"custom_name":"商品分類"},"_index_4_blogs":{"type":"_index_4_blogs","visible":true,"blocks":{"index_4_blogs_1":{"type":"blog","visible":true,"settings":{"blog_handle":"news"},"custom_name":"部落格"},"index_4_blogs_2":{"type":"blog","visible":true,"settings":{"blog_handle":"news"},"custom_name":"部落格"},"index_4_blogs_3":{"type":"blog","visible":true,"settings":{"blog_handle":"news"},"custom_name":"部落格"},"index_4_blogs_4":{"type":"blog","visible":true,"settings":{"blog_handle":"news"},"custom_name":"部落格"}},"block_order":["index_4_blogs_1","index_4_blogs_2","index_4_blogs_3","index_4_blogs_4"],"settings":{"dict_title":"More Information","margin_x":"0","margin_bottom":"50","mobile_margin_x":"0","mobile_margin_bottom":"50"},"custom_name":"分頁頁籤"},"_index_4_blocks":{"type":"_index_4_blocks","visible":true,"blocks":{"display_index_4_block_1":{"type":"image","visible":true,"settings":{"title":"","dict_link":"","dict_image_url":"/theme_src/i18n_shoestore/default_img/new_index_4_blocks_1.jpg","dict_tablet_image_url":"","dict_mobile_image_url":""},"custom_name":"圖片"}},"block_order":["display_index_4_block_1"],"custom_name":"自訂排版設計","settings":{"margin_x":"0","margin_bottom":"50","margin_block":"10","mobile_margin_x":"0","mobile_margin_bottom":"50","mobile_columns":1,"mobile_margin_block":"10"}},"express_delivery_index_4_blocks":{"type":"_index_4_blocks","visible":false,"blocks":{"express_delivery_display_index_4_block_1":{"type":"image","visible":true,"settings":{"title":"","dict_link":"","dict_image_url":"/theme_src/i18n_shoestore/default_img/new_index_4_blocks_1.jpg","dict_tablet_image_url":"","dict_mobile_image_url":""}}},"block_order":["express_delivery_display_index_4_block_1"]},"custom_text":{"type":"custom_text","visible":true,"settings":{}},"blog":{"type":"blog","visible":true,"settings":{"article_limit_in_blog_page":"6"},"custom_name":"部落格設定"},"article":{"type":"article","visible":true,"settings":{"display_blog_menu":false,"dict_blog_tags_title":"Categories","blog_latest_post_limit":"2"},"custom_name":"部落格文章設定"},"category":{"type":"category","visible":true,"settings":{"category_sidebar_set_open":false,"category_product_block_limit":"4","category_product_swiper_item_limit":"
706","category_product_item_limit":"18"}},"shop_setting":{"type":"shop_setting","visible":true,"settings":{"favicon_image_url":"//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxMzU1NDQ5X2Zhdmljb24ucG5nLnBuZyJdXQ.png?sha=7828c38c7cd539c5","og_image_url":"//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxNDI4NTQ1X3hwbG92YV9sb2dvXzMwMC5wbmcucG5nIl1d.png?sha=3d8d077b3985cd46","shop_title":"Official Website","shop_description":"「全球運籌、在地經營」,Xplova將繼續專注於騎乘 與運動相關的IoT產品、服務與平台,並在全球各地結 盟銷售通路、建構服務體系, 期待和您在每一條騎乘的路上相遇。","shop_keywords":"xplova"},"custom_name":"全站設定"},"color_settings":{"type":"color_settings","visible":true,"settings":{"button_color":"#F15A22","button_text_color":"#FFFFFF","accent_color":"#F15A22","heading_color":"#565656","text_color":"#9A9EA2","price_color":"#F15A22","discount_price_color":"#C39D6F","theme_bg_color":"#FFFFFF","product_border_color":"#E2E2E2","tips_text_color":"#0C5460","nav_logo_bg_color":"#FFFFFF","nav_menu_bg_color":"#FFFFFF","nav_menu_text_color":"#5F6062","nav_menu_icon_color":"#5F6062","footer_bg_color":"#000000","footer_text_color":"#FFFFFF","checkout_button_color":"#000000","checkout_accent_color":"#F15A22"},"custom_name":"顏色設定"},"popup":{"type":"popup","visible":true,"blocks":{"popup_block_1":{"type":"image","visible":false,"settings":{"dict_image_url":"/theme_src/i18n_shoestore/default_img/popup_default.jpg","icon_size":"small"},"custom_name":"圖片"}},"block_order":["popup_block_1"],"settings":{},"custom_name":"彈窗廣告"},"product_info":{"type":"product_info","visible":true,"settings":{"display_product_sku":true,"dict_vip_custom_price_text":"","dict_vip_custom_price_href":""},"custom_name":"基本設定"},"product_description":{"type":"product_description","visible":true,"custom_name":"商品介紹"},"board_comments":{"type":"board_comments","visible":true,"settings":{},"thumbnail":"list","draggable":false},"related_products":{"type":"related_products","visible":true,"settings":{"display_related_cols":false,"use_custom_related_cols":false,"dict_group_related_cols_related_product":"Related Products","related_products_limit":"4"},"custom_name":"相關商品"},"combo_product_info":{"type":"combo_product_info","visible":true,"settings":{}},"combo_product_desc":{"type":"combo_product_desc","visible":true,"settings":{}},"contact":{"type":"contact","visible":true,"settings":{"show_google_map":true,"show_google_map_iframe":"\u003ciframe src=\"https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3613.6479170127777!2d121.56760821400371!3d25.07991984260527!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x3442ac6fbd841bbd%3A0x64e16bcf25e3da31!2zMTE05Y-w5YyX5biC5YWn5rmW5Y2A55Ge5YWJ6LevNTEz5be3MzDomZ8!5e0!3m2!1szh-TW!2stw!4v1485156761267\" width=\"600\" height=\"450\" frameborder=\"0\" style=\"border:0\" allowfullscreen\u003e\u003c/iframe\u003e"}},"collection":{"type":"collection","visible":true,"settings":{"collection_sidebar":"","collection_sidebar_set_open":false,"collection_pagination_limit":"24","is_infinite_scroll":false},"custom_name":"商品分類設定"},"404":{"type":"404","visible":true,"settings":{"image_url":"//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxOTM5MjAyX3hwbG92YV80MDRfMi5wbmcucG5nIl1d.png?sha=b2014796197d7fc0","dict_404_image_url":"//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxOTM5MjAyX3hwbG92YV80MDRfMi5wbmcucG5nIl1d.png?sha=b2014796197d7fc0","dict_title_text":"Sorry, this page does not exist or has been removed","dict_btn_text":"Back to Home"},"custom_name":"404頁"},"blogs_all":{"type":"blogs_all","visible":true,"settings":{}},"bundle_discounts":{"type":"bundle_discounts","visible":true,"settings":{}},"cart":{"type":"cart","visible":true,"settings":{}},"cart_empty":{"type":"cart_empty","visible":true,"settings":{}},"page":{"type":"page","visible":true,"settings":{}},"search":{"type":"search","visible":true,"settings":{"search_link_list":"main-menu"}},"customers/account":{"type":"customers/account","visible":true,"settings":{}},"customers/account_edit":{"type":"customers/account_edit","visible":true,"settings":{}},"customers/activate_account":{"type":"customers/activate_account","visible":true,"settings":{}},"customers/addresses":{"type":"customers/addresses","visible":true,"settings":{}},"customers/bonus_points":{"type":"customers/bonus_points","visible":true,"settings":{}},"customers/cancel":{"type":"customers/cancel","visible":true,"settings":{}},"customers/coupons":{"type":"customers/coupons","visible":true,"settings":{}},"customers/forgot_password":{"type":"customers/forgot_password","visible":true,"settings":{}},"customers/login":{"type":"customers/login","visible":true,"settings":{}},"customers/message":{"type":"customers/message","visible":true,"settings":{}},"customers/messages":{"type":"customers/messages","visible":true,"settings":{}},"customers/modify_password":{"type":"customers/modify_password","visible":true,"settings":{}},"customers/order":{"type":"customers/order","visible":true,"settings":{}},"customers/orders":{"type":"customers/orders","visible":true,"settings":{}},"customers/periodic_order":{"type":"customers/periodic_order","visible":true,"settings":{}},"customers/periodic_orders":{"type":"customers/periodic_orders","visible":true,"settings":{}},"customers/other_valid_orders":{"type":"customers/other_valid_orders","visible":true,"settings":{}},"customers/register":{"type":"customers/register","visible":true,"settings":{}},"customers/reset_password":{"type":"customers/reset_password","visible":true,"settings":{}},"customers/return":{"type":"customers/return","visible":true,"settings":{}},"customers/tracking_items":{"type":"customers/tracking_items","visible":true,"settings":{}},"express_delivery-navbar":{"type":"express_delivery-navbar","visible":true,"settings":{}},"express_delivery-content":{"type":"express_delivery-content","visible":true,"settings":{}},"1751433913963_1":{"type":"_index_product_banner","custom_name":"Banner AD 1","visible":false,"settings":{"dict_image_url":"//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxNDM0NDgzX3hwbG92YV9iYW5uZXJBRF9kZXNrdG9wLmpwZy5qcGVnIl1d.jpeg?sha=8ca1a66696d4e3df","dict_tablet_image_url":"//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxNDM0NTAwX3hwbG92YV9iYW5uZXJBRF9tb2JpbGUuanBnLmpwZWciXV0.jpeg?sha=ecf4bc2f60907416","dict_mobile_image_url":"//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxNDM0NTAwX3hwbG92YV9iYW5uZXJBRF9tb2JpbGUuanBnLmpwZWciXV0.jpeg?sha=ecf4bc2f60907416","dict_link":"/pages/about-us","display_cta_btn":true,"cta_btn_display_style":"bottomPosition","dict_cta_btn_text":"Learn More","cta_btn_bg_color":"#F24F0E","cta_btn_text_color":"#ffffff","margin_x":"0","margin_bottom":"50","mobile_margin_x":"0","mobile_margin_bottom":"24","product_banner_image_alt":"Learn More"},"blocks":{},"block_order":[]},"1751433767750_7":{"type":"_custom_html","custom_name":"Video","visible":true,"settings":{"margin_x":"0","margin_bottom":"0","mobile_margin_x":"0","mobile_margin_bottom":"0","dict_body_html":"\u003csection class=\"section\" style=\"max-height: 400px; background-color: black; margin: 0 auto;\"\u003e\n  \u003cdiv class=\"container\"\u003e\n    \u003cvideo auto
70play loop muted playsinline style=\"width: 100%; max-height: 300px; object-fit: cover; pointer-events: none;\"\u003e\n      \u003csource src=\"https://xplova-officialwebsite-2024-dev.s3.us-east-1.amazonaws.com/assets/videoplayback.mp4\" type=\"video/mp4\" /\u003e\n      Your browser does not support the HTML5 video element.\n    \u003c/video\u003e\n  \u003c/div\u003e\n\u003c/section\u003e\n"},"blocks":{},"block_order":[]},"1751435609718_4":{"type":"_index_4_blogs","custom_name":"Xplova Eco-System","visible":true,"settings":{"dict_title":"Xplova Eco-System","margin_x":"0","margin_bottom":"50","mobile_margin_x":"0","mobile_margin_bottom":"50"},"blocks":{},"block_order":[]},"1751435115661_5":{"type":"_index_4_blocks","custom_name":"自訂排版設計","visible":true,"settings":{"margin_x":"0","margin_bottom":"50","margin_block":"10","mobile_margin_x":"0","mobile_margin_bottom":"50","mobile_columns":1,"mobile_margin_block":"10"},"blocks":{"1751435115663_0":{"type":"image","custom_name":"圖片","visible":true,"settings":{"dict_image_url":"//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxNDM1MTY4X3hwbG92YV9hcHBzdG9yZS5wbmcucG5nIl1d.png?sha=b8f2f9abfaceea58","dict_tablet_image_url":"","dict_mobile_image_url":"","dict_link":"","block_propotion":"49"}},"1751435229233_3":{"type":"html","custom_name":"自訂HTML","visible":true,"settings":{"dict_body_html":"\u003cspan class=\"ckeditor\" style=\"margin: 40px;\"\u003e\n\n\u003cp\u003e\u003cspan style=\"color:#89898b;\"\u003eXplova’s series of apps are designed to for passionate cyclists to pair with Xplova’s indoor bike trainers, bike computers, heart rate monitors, speed and cadence sensors. The simplified but structural workout plan, real-time data display or way-back videos with data overlay, Xplova has an app to cultivate your endurance and strength toward cycling, training and fitness. \u003c/span\u003e\u003c/p\u003e\n\n\u003cp\u003e\u003cspan style=\"color:#89898b;\"\u003eDownload this app for free from the App Store or Google Play.\u003c/span\u003e\u003c/p\u003e\n\n\n\n\n                    \u003ca href=\"https://apps.apple.com/us/developer/xplova-inc/id889716512\" class=\"item expertises-item\" target=\"_blank\"\u003e\n                        \u003cimg src=\"assets/imgs/Download_on_the_App_Store_Badge_US-UK_RGB_blk_092917.svg\"alt=\"Download free bootstrap 4 landing page, free boootstrap 4 templates, Download free bootstrap 4.1 landing page, free boootstrap 4.1.1 templates, ollie Landing page\" class=\"box-shadow\" style=\"height: 36px;\"\u003e\n                    \u003c/a\u003e \n                    \u003ca href=\"https://play.google.com/store/apps/developer?id=Acer+Gadget+Inc.\" class=\"item expertises-item\" target=\"_blank\"\u003e\n                        \u003cimg src=\"assets/imgs/GetItOnGooglePlay_Badge_Web_color_English.png\"alt=\"Download free bootstrap 4 landing page, free boootstrap 4 templates, Download free bootstrap 4.1 landing page, free boootstrap 4.1.1 templates, ollie Landing page\" class=\"box-shadow\" style=\"height: 36px;\"\u003e\n                    \u003c/a\u003e \n\u003c/span\u003e"}},"1751445455200_2":{"type":"carousel","custom_name":"排程跑馬燈","visible":true,"settings":{"dict_carousel":"Mobile App","block_propotion":"20"}}},"block_order":["1751435115663_0","1751435229233_3","1751445455200_2"]},"1751435274143_6":{"type":"_graphic_introduction","custom_name":"Follow us","visible":true,"settings":{"text_display":"leftPosition","graphic_text":"#5F6062","graphic_bg":"#F4EEE2","margin_x":"0","margin_bottom":"0","mobile_margin_x":"0","mobile_margin_bottom":"0","dict_image_url":"","dict_tablet_image_url":"","dict_mobile_image_url":"","btn_display":"leftSide","block_propotion":"50"},"blocks":{"1751435274144_0":{"type":"title","custom_name":"標題","visible":true,"settings":{"dict_rich_text_title":"Follow us for updates or message us directly for support","dict_size":"18"}},"1751435274145_1":{"type":"text","custom_name":"內文","visible":true,"settings":{"dict_rich_text_content":"\u003cp\u003eTag us\u003cbr\u003e  \u003cem\u003e#Xplova    #TheWayXplova    #PoweredbyAcer\u003c/em\u003e\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n","dict_size":"12"}}
70},"block_order":["1751435274144_0","1751435274145_1"]},"1751439706808_8":{"type":"_text_editor_section","custom_name":"Brand - text","visible":true,"settings":{"margin_x":"0","margin_bottom":"0","mobile_margin_x":"6","mobile_margin_bottom":"0","dict_advanced_rich_text_content":"\u003cp style=\"text-align:center;\"\u003e\u003cspan style=\"color: rgb(95,96,98);font-size: 14px;\"\u003eThe word Xplova is a combination of \" \u003cstrong\u003e\u003cem\u003eeXplore\u003c/em\u003e\u003c/strong\u003e\u003c/span\u003e \u003cspan style=\"color: rgb(95,96,98);font-size: 14px;\"\u003e\" in English and \"\u003c/span\u003e \u003cspan style=\"color: rgb(95,96,98);font-size: 14px;\"\u003e\u003cstrong\u003e\u003cem\u003eva \u003c/em\u003e\u003c/strong\u003e\" in Spanish,\u003c/span\u003e\u003cbr\u003e\u003cspan style=\"color: rgb(95,96,98);font-size: 14px;\"\u003e meaning \"\u003cstrong\u003e to explore and to move forward \u003c/strong\u003e\".\u003c/span\u003e\u003c/p\u003e\n\u003cp style=\"text-align:center;\"\u003e\u003c/p\u003e\n\u003cp style=\"text-align:center;\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n"},"blocks":{},"block_order":[]},"1751441121043_1":{"type":"_index_product_banner","custom_name":"Brand - image","visible":true,"settings":{"dict_image_url":"//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxNDQxMjg4X3hwbG92YV9icmFuZF9pbnRyb3VkdWN0aW9uX2Rlc2t0b3AucG5nLnBuZyJdXQ.png?sha=421e6075bfe7a6da","dict_tablet_image_url":"//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxNDQyOTY1X3hwbG92YV9icmFuZF9pbnRyb3VkdWN0aW9uX3RhYmxldC5wbmcucG5nIl1d.png?sha=6b4d631a9e777155","dict_mobile_image_url":"//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxNDQyODM4X3hwbG92YV9icmFuZF9pbnRyb3VkdWN0aW9uX21vYmlsZS5wbmcucG5nIl1d.png?sha=6e65e9acf294b1dc","dict_link":"","cta_btn_display_style":"topPosition","cta_btn_bg_color":"#000000","cta_btn_text_color":"#ffffff","margin_x":"0","margin_bottom":"10","mobile_margin_x":"0","mobile_margin_bottom":"12"},"blocks":{},"block_order":[]},"1751445071383_8":{"type":"_text_editor_section","custom_name":"EcoSystem - text","visible":true,"settings":{"margin_x":"120","margin_bottom":"0","mobile_margin_x":"20","mobile_margin_bottom":"0","dict_advanced_rich_text_content":"\u003cp style=\"text-align:center;\"\u003e\u003c/p\u003e\n\u003cp style=\"text-align:center;\"\u003e\u003c/p\u003e\n\u003cp style=\"text-align:center;\"\u003e\u003c/p\u003e\n\u003cp style=\"text-align:center;\"\u003e\u003c/p\u003e\n\u003cp style=\"text-align:center;\"\u003e\u003c/p\u003e\n\u003cp style=\"text-align:center;\"\u003e\u003cspan style=\"font-size: 24px;\"\u003e\u003cstrong\u003eXplova Eco System\u003c/strong\u003e\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp style=\"text-align:center;\"\u003e\u003cspan style=\"color: #5f6062;font-size: 14px;\"\u003eXplova's series of apps are designed to for passionate cyclists to pair with Xplova's indoor bike trainers, bike computers, heart rate monitors, speed and cadence sensors. The simplified but structural workout plan, real-time data display or way-back videos with data overlay, Xplova has an app to cultivate your endurance and strength toward cycling, training and fitness.\u003c/span\u003e\u003c/p\u003e\n\u003cp style=\"text-align:center;\"\u003e\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp style=\"text-align:center;\"\u003e\u003cspan style=\"color: #5f6062;font-size: 14px;\"\u003eDownload Xplova app for free from the App Store or Google Play.\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n"},"blocks":{},"block_order":[]},"1751446031984_7":{"type":"_custom_html","custom_name":"Download App","visible":true,"settings":{"margin_x":"0","margin_bottom":"0","mobile_margin_x":"0","mobile_margin_bottom":"0","dict_body_html":"\u003cdiv style=\"text-align: center;\"\u003e\n    \u003ca href=\"https://apps.apple.com/us/developer/xplova-inc/id889716512\" class=\"item expertises-item\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\n        \u003cimg src=\"https://cdn-general.cybassets.com/s/files/33373/theme/121378/assets/1751445944_4f6bf42e_download_iOS.png?1751445945\" \n             alt=\"Download on iOS\" class=\"box-shadow\" style=\"height: 36px; margin: 0 8px;\"\u003e\n    \u003c/a\u003e \n    \u003ca href=\"https://play.google.com/store/apps/developer?id=Acer+Gadget+Inc.\" class=\"item expertises-item\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\n        \u003cimg src=\"https://cdn-general.cybassets.com/s/files/33373/theme/121378/assets/1751445747_2092ef84_download_Android.png?1751445747\" \n             alt=\"Download on Android\" class=\"box-shadow\" style=\"height: 36px; margin: 0 8px;\"\u003e\n    \u003c/a\u003e \n\u003c/div\u003e\n\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e"},"blocks":{},"block_order":[]},"1751502858632_5":{"type":"_index_4_blocks","custom_name":"Avatar 1","visible":true,"settings":{"margin_x":"0","margin_bottom":"50","margin_block":"100","mobile_margin_x":"0","mobile_margin_bottom":"50","mobile_columns":1,"mobile_margin_block":"0"},"blocks":{"1751502858635_0":{"type":"image","custom_name":"圖片","visible":true,"settings":{"dict_image_url":"//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxNTIxNTU4X3hwbG92YV9hdmF0YXJfMV9kZXNrdG9wLTIucG5nLnBuZyJdXQ.png?sha=110f5a46524fa3ec","dict_tablet_image_url":"//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxNTA0OTU1X3hwbG92YV9hdmF0YXJfMV90YWJsZXQucG5nLnBuZyJdXQ.png?sha=17d5065b14a7e162","dict_mobile_image_url":"//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxNTA0OTY5X3hwbG92YV9hdmF0YXJfMV9tb2JpbGUucG5nLnBuZyJdXQ.png?sha=87289f683ecc0676","dict_link":"","block_propotion":"30","custom_block_image_alt":"avatar","dict_image_description":""}},"1751502889752_3":{"type":"html","custom_name":"自訂HTML","visible":true,"settings":{"dict_body_html":"\u003cdiv class=\"d-flex align-items-center\" style=\"height: 240px;\"\u003e\n  \u003cdiv class=\"des my-5 text-start\" style=\"margin-left: 60px; margin-right: 60px;\"\u003e\n    \u003cp\u003e\n      \u003cstrong\u003e\u003cem style=\"color: #F15A22; font-size: 32px;\"\u003e\u0026ldquo;\u003c/em\u003e\u003c/strong\u003e\n      \u003cbr\u003e\n      \u003cspan style=\"color: #5F6062; font-size: 14px;\"\u003e\n        \u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;Truly knowledgeable and sensible folks! I really appreciated everything about fixing my bike up, and am enjoying the power assist!\n      \u003c/span\u003e\n    \u003c/p\u003e\n\n    \u003cp style=\"text-align: right; width: 100%; display: block; margin: 0;\"\u003e\n      \u003cstrong\u003e\u003cem style=\"color: #F15A22; font-size: 32px;\"\u003e\u0026rdquo;\u003c/em\u003e\u003c/strong\u003e\n    \u003c/p\u003e\n\n    \u003chr class=\"my-4\"\u003e\n\n\u003cp style=\"font-weight: 2000; font-size: 14px; color: #000000;\"\u003e\u003cstrong\u003e\u003cem\u003e\u0026#8212;\u0026#8212;\u0026#8212;  Seulzzing1021\u003c/em\u003e\u003c/strong\u003e\u003c/p\u003e\n\n    \u003cp\u003e\u003cspan style=\"color: #5F6062;font-size: 12px;\"\u003eKOREA\u003c/span\u003e\u003c/p\u003e\n  \u003c/div\u003e\n\u003c/div\u003e"}}},"block_order":["1751502858635_0","1751502889752_3"]},"1751512152179_8":{"type":"_text_editor_section","custom_name":"Share your progress","visible":true,"settings":{"margin_x":"0","margin_bottom":"0","mobile_margin_x":"0","mobile_margin_bottom":"0","dict_advanced_rich_text_content":"\u003ch3 style=\"text-align:center;\"\u003e\u003c/h3\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003ch3 style=\"text-align:center;\"\u003e\u003cspan style=\"font-size: 24px;\"\u003e\u003cstrong\u003eShare your progress with Xplova\u003c/strong\u003e\u003c/span\u003e\u003c/h3\u003e\n\u003cp\u003e\u003c/p\u003e\n"},"blocks":{},"block_order":[]},"1751512337232_5":{"type":"_index_4_blocks","custom_name":"Avatar 2","visible":false,"settings":{"margin_x":"0","margin_bottom":"50","margin_block":"10","mobile_margin_x":"0","mobile_margin_bottom":"50","mobile_columns":1,"mobile_margin_block":"10"},"blocks":{"1751512337234_0":{"type":"image","custom_name":"圖片","visible":true,"settings":{"dict_image_url":"//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxNTEyNjE3X3hwbG92YV9hdmF0YXJfMl9kZXNrdG9wLnBuZy5wbmciXV0.png?sha=81453adc754a40c0","dict_tablet_image_url":"//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxNTEyNjI1X3hwbG92YV9hdmF0YXJfMl90YWJsZXQucG5nLnBuZyJdXQ.png?sha=42165140c6d4eee7","dict_mobile_image_url":"//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxNTEyNjMzX3hwbG92YV9hdmF0YXJfMl9tb2JpbGUucG5nLnBuZyJdXQ.png?sha=437cf25ca64ffec2","dict_link":"","custom_block_image_alt":"avatar","block_propotion":"30","dict_image_description":""}},"1751512405891_3":{"type":"html","custom_name":"自訂HTML","visible":true,"settings":{"dict_body_html":"\u003cdiv class=\"d-flex align-items-center\" style=\"height: 240px;\"\u003e\n    \u003cdiv class=\"des my-5 text-start\" style=\"margin-left: 60px; margin-right: 60px;\"\u003e\n        \u003cp\u003e\n          \u003cstrong\u003e\u003cem style=\"color: #F15A22; font-size: 24px;\"\u003e\u0026ldquo;\u0026nbsp;\u0026nbsp;\u003c/em\u003e\u003c/strong\u003e\n          \u003cspan style=\"color: #89898b; font-size: 14px;\"\u003e\n            Outstanding! If you want professional, friendly, and expert service, it doesn't get better than this. Many thanks to Jason and his highly skilled team, where the price is just the right. \n          \u003c/span\u003e\n          \u003cstrong\u003e\u003cem style=\"color: #F15A22; font-size: 24px;\"\u003e\u0026nbsp;\u0026nbsp;\u0026rdquo;\u003c/em\u003e\u003c/strong\u003e\n        \u003c/p\u003e\n\n        \u003cbr\u003e\n\n        \u003cp\u003e\u003cem\u003e\u003cspan style=\"color: #aeb0b2;font-size: 12px;\"\u003e------------------------------------------------------------\u003c/span\u003e\u003c/em\u003e\u003c/p\u003e\n        \u003cp\u003e\u003cem\u003e\u003cstrong\u003e\u003cspan style=\"color: #000000;font-size: 14px;\"\u003eTeam Strassacker\u003c/span\u003e\u003c/strong\u003e\u003c/em\u003e\u003c/p\u003e\n        \u003cp\u003e\u003cspan style=\"color: #89898b;font-size: 12px;\"\u003eGermany\u003c/span\u003e\u003c/p\u003e\n    \u003c/div\u003e\n\u003c/div\u003e"}}},"block_order":["1751512337234_0","1751512405891_3"]},"1751512699907_1":{"type":"_index_product_banner","custom_name":"Banner AD 2","visible":true,"settings":{"dict_image_url":"//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxNTEyOTMyX3hwbG92YV9iYW5uZXJBRF8yX2Rlc2t0b3AuanBnLmpwZWciXV0.jpeg?sha=3453e989845300d9","dict_tablet_image_url":"","dict_mobile_image_url":"//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxNTEyOTQyX3hwbG92YV9iYW5uZXJBRF8yX21vYmlsZS5qcGcuanBlZyJdXQ.jpeg?sha=fadbfec15a28d183","dict_link":"","cta_btn_display_style":"topPosition","cta_btn_bg_color":"#000000","cta_btn_text_color":"#ffffff","margin_x":"0","margin_bottom":"0","mobile_margin_x":"0","mobile_margin_bottom":"0"},"blocks":{},"block_order":[]},"1751521270877_6":{"type":"_graphic_introduction","custom_name":"Follow us bottom","visible":true,"settings":{"text_display":"leftPosition","graphic_text":"#373420","graphic_bg"
70:"#F4EEE2","margin_x":"0","margin_bottom":"0","mobile_margin_x":"0","mobile_margin_bottom":"0","dict_image_url":"","dict_tablet_image_url":"","dict_mobile_image_url":"","btn_display":"leftSide","block_propotion":"50"},"blocks":{"1751521270880_1":{"type":"text","custom_name":"內文","visible":true,"settings":{"dict_rich_text_content":"\u003cp\u003e\u0026nbsp;\u0026nbsp;\u003c/p\u003e\n","dict_size":"14"}}},"block_order":["1751521270880_1"]},"1752478878849_7":{"type":"_custom_html","custom_name":"自訂HTML","visible":true,"settings":{"margin_x":"0","margin_bottom":"0","mobile_margin_x":"0","mobile_margin_bottom":"0","dict_body_html":"\u003cstyle\u003e\n  .hero-section {\n    height: 100vh;\n    background-image: url('https://cdn-general.cybassets.com/s/files/33373/theme/121378/assets/1752480023_bceefeb6_xplova_home_bg.jpg?1752480023');\n    background-size: cover;\n    background-position: center;\n    background-repeat: no-repeat;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    text-align: center;\n    color: white;\n    position: relative;\n    padding: 20px;\n  }\n\n  .hero-content {\n    max-width: 800px;\n    opacity: 0;\n    transform: translateY(20px);\n    animation: fadeInUp 1s ease-out forwards;\n    animation-delay: 0.3s;\n  }\n\n  @keyframes fadeInUp {\n    to {\n      opacity: 1;\n      transform: translateY(0);\n    }\n  }\n\n  .hero-content h1 {\n    font-size: 42px;\n    color: white;\n    margin-bottom: 1rem;\n    text-shadow: 0px 4px 6px rgba(0, 0, 0, 0.5);\n  }\n\n  .hero-content p {\n    font-size: 14px;\n    color: white;\n    margin-bottom: 2rem;\n    text-shadow: 0px 4px 6px rgba(0, 0, 0, 0.5);\n  }\n\n  .hero-button {\n    display: inline-block;\n    padding: 0 40px;\n    background-color: #F15A22;\n    color: white;\n    text-decoration: none;\n    font-size: 14px;\n    border: none;\n    border-radius: 4px;\n    height: 40px;\n    line-height: 40px;\n    transition: background-color 0.3s ease;\n  }\n\n  .hero-button:hover {\n    background-color: #d64e1d;\n    color: white;\n  }\n\n  @media (max-width: 576px) {\n    .hero-content h1 {\n      font-size: 32px;\n    }\n\n    .hero-content p {\n      font-size: 12px;\n    }\n  }\n\u003c/style\u003e\n\n\u003cdiv class=\"hero-section\"\u003e\n  \u003cdiv class=\"hero-content\"\u003e\n    \u003ch1\u003eA Real Cycling Experience \u003cbr\u003e Anytime, Anywhere\u003c/h1\u003e\n    \u003cp\u003eXplova joined Acer Group in 2015.\u003cbr\u003eA sub-brand of Acer subsidary Acer Gadget Inc.\u003c/p\u003e\n    \u003ca href=\"/pages/about-us\" class=\"hero-button\"\u003eLearn More\u003c/a\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n"},"blocks":{},"block_order":[]},"announcement_bar":{"type":"announcement_bar","visible":true,"blocks":{"announcement_bar_block_1":{"type":"text","visible":true,"settings":{"display_only_index":false,"display_period":"always","dict_link":"/blogs/announcement","link_open_in_new_tab":true,"dict_image_url":"","dict_image_tablet_url":"","dict_image_mobile_url":"","image_alt":"","dict_content":"Important Notice about Xplova Website Service Change","text_size":"12","text_color":"#000000","bg_color":"#B6B8BA","timer_text_color":"#c39d6f","timer_bg_color":"#2b2b6e","migrated_from_navbar":true}}},"block_order":["announcement_bar_block_1"],"settings":{"display_mode":"vertical","carousel_interval":"3"}}},"navbar_image_logo":true,"show_default_all_products":true,"one_dimension_limit":"6","two_dimension_limit":"10","header_banner_display":true,"header_banner_link":"/","display_main_slider":true,"display_phone":true,"phone_number":"0912345678","display_fax_number":true,"shop_fax_number":"0222345678","display_shop_email":true,"shop_email":"[email protected]","display_shop_address":true,"shop_address":"測試地址","display_office_time":true,"shop_office_time":"10:00-17:00","index_event_slider_display":true,"index_event_slider_item_1_display":true,"dict_index_event_slider_item_1_link":"#","index_event_slider_item_2_display":true,"dict_index_event_slider_item_2_title":"Autumn Shoes are now in store","dict_index_event_slider_item_2_link":"#","index_event_slider_item_3_display":true,"dict_index_event_slider_item_3_title":"Purchase any 3 items and get 20% off!","dict_index_event_slider_item_3_link":"#","index_event_slider_item_4_display":true,"dict_index_event_slider_item_4_title":"FINAL SALE/Summer shoes are now on clearance sale!","dict_index_event_slider_item_4_link":"#","index_event_slider_item_5_display":true,"dict_index_event_slider_item_5_title":"Sale ends soon","dict_index_event_slider_item_5_link":"#","index_event_slider_item_6_display":true,"dict_index_event_slider_item_6_title":"Register now and get $50 off","dict_index_event_slider_item_6_link":"#","index_event_slider_item_7_display":false,"dict_index_event_slider_item_7_title":"","dict_index_event_slider_item_7_link":"","
70index_event_slider_item_8_display":false,"dict_index_event_slider_item_8_title":"","dict_index_event_slider_item_8_link":"#","index_event_slider_item_9_display":false,"dict_index_event_slider_item_9_title":"","dict_index_event_slider_item_9_link":"#","index_event_slider_item_10_display":false,"dict_index_event_slider_item_10_title":"","dict_index_event_slider_item_10_link":"#","index_4_slider_display":true,"dict_index_4_slider_title":"Instagram","index_4_slider_item_1_display":true,"dict_index_4_slider_item_1_link":"#","index_4_slider_item_2_display":true,"dict_index_4_slider_item_2_link":"#","index_4_slider_item_3_display":true,"dict_index_4_slider_item_3_link":"#","index_4_slider_item_4_display":true,"dict_index_4_slider_item_4_link":"#","index_4_slider_item_5_display":true,"dict_index_4_slider_item_5_link":"#","index_4_slider_item_6_display":false,"dict_index_4_slider_item_6_link":"#","index_4_slider_item_7_display":false,"dict_index_4_slider_item_7_link":"#","index_4_slider_item_8_display":false,"dict_index_4_slider_item_8_link":"#","index_video_blocks_display":true,"dict_index_video_blocks_title":"Youtube","dict_index_video_blocks_video_link":"https://www.youtube.com/watch?v=3bI4IUIVjCk","collection_sidebar":"main-menu","collection_sidebar_set_open":false,"collection_pagination_limit":"24","product_slogan_display":false,"display_product_total_sold":false,"display_periodic_order_label":false,"cart_quantity_limit":"0","is_empty_clickable":true,"is_first_selected":false,"display_product_images_color":false,"discount_product_images_color_expand":false,"display_product_discounts_list":false,"display_discount_price_name":false,"discount_price_slogan_url":"/theme_src/beta_theme/default_img/onsale_icon.png","dict_discount_price_name":"","display_discount_price_suggestion_name":false,"dict_discount_price_suggestion_name":"","display_product_section_description":true,"dict_product_section_description":"Description","description_section_spec_setting":true,"dict_product_description_section_spec":"Specifications","description_section_shipping_setting":false,"dict_product_description_section_shipping":"Shipping Method","vip_custom_price_visible":false,"display_global_event_1":false,"dict_show_global_event_1_link":"#","display_global_event_2":false,"dict_show_global_event_2_link":"#","display_global_event_3":false,"dict_show_global_event_3_link":"#","display_contact_address":true,"dict_contact_address":"Shop Address","show_google_map":true,"show_google_map_iframe":"\u003ciframe src=\"https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3613.6479170127777!2d121.56760821400371!3d25.07991984260527!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x3442ac6fbd841bbd%3A0x64e16bcf25e3da31!2zMTE05Y-w5YyX5biC5YWn5rmW5Y2A55Ge5YWJ6LevNTEz5be3MzDomZ8!5e0!3m2!1szh-TW!2stw!4v1485156761267\" width=\"600\" height=\"450\" frameborder=\"0\" style=\"border:0\" allowfullscreen\u003e\u003c/iframe\u003e","display_selected_blog":false,"selected_blog":"news","display_inventory_policy":false,"display_product_vendor":false,"nav_icon_style":"icon_type_rounded","google_font":"{'ja':{'value':'Noto Sans JP'},'zh-TW':{'value':'Noto Sans TC'},'en':{'value':'Noto Sans TC'},'zh-CN':{'value':'Noto Sans TC'}}","product_text_align":"start","styled_shop_menu":"buttonType","product_video_display_location":"before","product_scale":"default_scale","product_labels":{"items":[{"id":"sale_label","kind":"system","title":"特價標籤","display":true,"type":"image","dict_text":{},"image":"/theme_src/beta_theme/default_img/onsale_icon.png","image_size":"large"},{"id":"out_of_stock_label","kind":"system","title":"缺貨標籤","display":false,"type":"text","dict_text":{},"image":"","image_size":"small"},{"id":"periodic_event_label","kind":"system","title":"定期定額標籤","display":false,"type":"text","dict_text":{},"image":"","image_size":"small"},{"id":"48c3b326-3102-4e3c-99ca-67585a705c76","kind":"custom","title":"自定義標籤 1","tag":"","display":false,"type":"text","dict_text":{},"image":"","image_size":"small"},{"id":"ed266c9a-5c16-4386-9615-63fa07c1db94","kind":"custom","title":"自定義標籤 2","tag":"","display":false,"type":"text","dict_text":{},"image":"","image_size":"small"},{"id":"cc116bf9-6498-44fb-91cd-947988d9431c","kind":"custom","title":"自定義標籤 3","tag":"","display":false,"type":"text","dict_text":{},"image":"","image_size":"small"},{"id":"596e2ed0-c50f-4986-8f83-e191334cced1","kind":"custom","title":"自定義標籤 4","tag":"","display":false,"type":"text","dict_text":{},"image":"","image_size":"small"},{"id":"86d1ad4c-1b76-4af6-98dc-2e03f7783aa1","kind":"custom","title":"自定義標籤 5","tag":"","display":false,"type":"text","dict_text":{},"image":"","image_size":"small"}]}});
71  </script>
71
72
73
74
75
76
77
78
79
80
81
82    <!-- for vendor -->
83    <!-- cyb_snippet _bootstrap start -->
84
85<!-- cyb_snippet _bootstrap end -->
86    <link href='//cdn-general.cybassets.com/frontend/shop/beta_theme/css/vendor-3a2e378145f8a165.css' rel='stylesheet' type='text/css' media='all' />
87
88    <!-- common css rulesets -->
89    <link href='//cdn-general.cybassets.com/frontend/shop/beta_theme/css/common-3a2e378145f8a165.css' rel='stylesheet' type='text/css' media='all' />
90
91    <!-- for navbar -->
92    <link href='//cdn-general.cybassets.com/frontend/shop/beta_theme/css/navbar-3a2e378145f8a165.css' rel='stylesheet' type='text/css' media='all' />
93
94    <!-- for footer -->
95    <link href='//cdn-general.cybassets.com/frontend/shop/beta_theme/css/footer-3a2e378145f8a165.css' rel='stylesheet' type='text/css' media='all' />
96
97    <!-- theme assets -->
98    <link href='//cdn-general.cybassets.com/frontend/shop/beta_theme/css/main-3a2e378145f8a165.css' rel='stylesheet' type='text/css' media='all' />
99
100    <!-- for vendor -->
101    
101<script src='//cdn-general.cybassets.com/frontend/shop/beta_theme/js/vendor-3a2e378145f8a165.js' type='text/javascript'></script>
101
102
103            
103<script>
104          window.sci = "eyJzaG9wX2lkIjozMzM3Mywic2hvcF9wbGFuIjoiZW50ZXJwcmlzZSIsImRp\nbV9hZmZpbGlhdGUiOm51bGwsImN1c3RvbWVyX2lkIjpudWxsLCJjdXN0b21l\ncl9uYW1lIjpudWxsLCJzaG9wX25hbWUiOiJYcGxvdmEiLCJzaGFyZV9hdHRy\naWJ1dGlvbl9lbmFibGVkIjpmYWxzZX0=\n";
105        </script>
105
106
107
108<meta name="csrf-param" content="authenticity_token" />
109<meta name="csrf-token" content="sxlytquXpvwV_B82jBgcUcAwIBLLe4jpYTrYo8JRgw8nz_mPPRKwLw5lOpeaog2WqEuDmVnwEBU-KU5kZ4NN4g" />
110<script>(function () {
111  window.gaConfigurations = {"useProductIdInProductEvents":false};
112})();
113</script>
vendor: 1 bytes, line 113
113
114<script>(function () {
115  window.CYBERBIZ_PageContext = {"page_type":"product"};
116})();
117</script>
117
118<link href="//cdn-general.cybassets.com/frontend/shop/quark-3a2e378145f8a165.css" rel="stylesheet" type="text/css" media="all" />
119        
119<script>
120          window.shopScriptHelper = {
121            i18nLocale: "en",
122            i18nLocaleDefault: "zh-TW",
123            availableCurrencies: ["TWD"],
124            defaultCurrency: "TWD",
125            currenciesInfo: [{"code":"TWD","money_format":"%u%n","decimal_precision":0,"email":"NT${{amount_no_decimals}}","unit":"","symbol":"NT$","email_unit":"NT${{amount_no_decimals}}","html_unit":"NT${{amount_no_decimals}}","format":"NT${{amount_no_decimals}}","html":"NT${{amount_no_decimals}}","trailing_zeros":false,"name":"新台幣 (TWD)"}],
126            vueOverrideTranslations: {"en":{"vue":{"bonus_mall":{"add_to_cart":"Add to Cart","already_added_to_cart":"Added to Cart","available_bonus_and_used":"Current bonus points: {customerRemainPoints} points, using {usedBonusPoints} points.","bonus_points":"{points} points","bonus_points_verbose":"{points} bonus points","bonus_price":"Bonus Price","bonus_price_asc":"Sort by Low to High Points","bonus_price_desc":"Sort by High to Low Points","bonus_redemption_price":"{price} Bonus Redemption points","countdown":"Sale starts in","days":"days","default_sort":"Recommended","exceed_buy_limit":"Quantity exceeds purchase limit.","exceed_stock_quantity":"Quantity exceeds available stock.","hours":"hours","insufficient_points":"Insufficient Points","loading_error":"Error loading shopping cart data.","minutes":"minutes","need_to_buy_something":"Quantity must be at least 1.","not_on_sale_yet":"Coming soon","points":"Points","proceed_to_checkout":"Proceed to Checkout","product_count":"A Total Of {totalCount} Items","quantity":"Quantity","recent_days_sold_asc":"Sort by Low to High Sales Volume","recent_days_sold_desc":"Bestselling","seconds":"seconds","select_itmes_count":"You have selected {quantity} bonus items.","sell_from_asc":"Listing date, old to new","sell_from_desc":"Listing date, new to old","sold_out":"Out of Stock","subtotal":"Subtotal","upcoming_product":"Sale starts on","wrong_quantity":"Invalid quantity input."},"common":{"add_to_cart":"Add to Cart","buy_at_least_one":"Purchase Quantity Must Be at Least 1","buy_now":"BUY NOW","cancel":"Cancel","confirm_submit":"Submit","contact_merchant":"Contact Shop","corona":{"confirm_no":"Cancel","confirm_yes":"Confirm","default_sort":"Store Recommendations","price_asc":"Price Low To High","price_desc":"Price High To Low","price_filter":"Price","recent_days_sold_desc":"Best Seller","select_page":"Select Page","select_sort_by":"Sort By","sell_from_asc":"Listing date, old to new","sell_from_desc":"Listing date, new to old","suggested_range":"Suggested Range"},"default_sort":"Store Recommendations","exceed_stock_quantity":"Exceeds Stock Quantity","exceed_upper_limit":"Exceeds Purchase Limit","failed_to_update_cart":"Failed to Update Shopping Cart","onsale":"On Sale","periodic_order_label":"Subscription","pre_order":"Pre-order","price_asc":"Price Low To High","price_desc":"Price High To Low","price_label":"Price","product_sold":"Sold {productSold} products","recent_days_sold_desc":"Best Seller","return":"Return","see_more":"See More","sell_from_asc":"Listing date, old to new","sell_from_desc":"Listing date, new to old","sold_out":"Out of Stock","subtotal":"Subtotal","system_busy_try_again":"System busy; please try again later.","theme":{"choose_specification":"Please Select Specifications","wrong_date":"Wrong Date"},"video_not_supported":"Your browser does not support HTML 5 video.","wrong_quantity":"Quantity Input Error"},"eticket_orders":{"category_all":"All Tickets","category_available":"Available","category_pending":"Unpaid","category_used":"Used up","eticket_orders_branch_stores_address":"Store Address","eticket_orders_branch_stores_name":"Store Name","eticket_orders_branch_stores_phone":"Store Phone","eticket_orders_branch_stores_show":"Show Redeemable Branch Stores","eticket_orders_cancel_order":"Cancel Order","eticket_orders_cancel_order_announcement":"I agree that the invalidation of the invoice or the \"businessman''s sales return, purchase, withdrawal or discount certificate\" will be fully handled by CYBERBIZ Corp. to facilitate the expediting of the refund process. If there is a return/discount, a discount order will be issued directly and uploaded to the Ministry of Finance''s electronic invoice integration service platform for storage. ","eticket_orders_cancel_order_cancel":"Cancel operation","eticket_orders_cancel_order_title":"Are you sure you want to cancel this order?","eticket_orders_canceled":"Canceled","eticket_orders_discounted_price":"Discounted Price","eticket_orders_eticket_notice":"E-ticket Notice","eticket_orders_go_to_payments":"Go to Payments","eticket_orders_invoice_infos":"Invoice Information","eticket_orders_invoice_number":"Invoice Number","eticket_orders_invoice_status":"Invoice Status","eticket_orders_order_date":"Order Date","eticket_orders_order_details":"Order Details","eticket_orders_order_established":"Order Established","eticket_orders_order_no_query_records":"No query records for this order at the moment","eticket_orders_order_notes":"Order Notes","eticket_orders_order_number":"Order Number","eticket_orders_order_query_records":"Query Records","eticket_orders_payment_infos":"Payment Information","eticket_orders_payment_method":"Payment Method","eticket_orders_payment_status":"Payment Status","eticket_orders_qrcode_download":"Download","eticket_orders_qrcode_not_used":"Not Used","eticket_orders_qrcode_quantity":"Quantity: {quantity}","eticket_orders_qrcode_share":"Share","eticket_orders_qrcode_share_text":"This is your e-ticket. Please keep it safe:\n{ title }-{ variantTitle }\nTicket number: { ticketNumber }","eticket_orders_qrcode_ticket_number":"ticket number: {ticket_number}","eticket_orders_qrcode_used":"Used","eticket_orders_qrcode_used_status":"Already used: {used} / Not yet used: {not_used}","eticket_orders_quantity":"Quantity: {quantity}","eticket_orders_send_etickets":"Send E-tickets","eticket_orders_send_message_to_shop":"Send Message to Shop","eticket_orders_separate_etickets":"Separate Etickets","eticket_orders_separate_etickets_cancel":"Cancel operation","eticket_orders_separate_etickets_confirm":"Confirm separate tickets","eticket_orders_separate_etickets_description":"Please note that you are about to go through the ticket splitting process. After splitting, each ticket will have an independent verification code QR Code (the original verification code QR Code will not be used). You can share screenshots of different verification codes with multiple people Use, this operation cannot be restored.","eticket_orders_submit":"Submit","eticket_orders_subtotal":"Subtotal","eticket_orders_title":"Eticket Order Inquiry","eticket_orders_total_price":"Total Price","eticket_orders_unused":"Unused: {quantity}","eticket_orders_usage_status":"Usage Status","eticket_orders_used":"Used: {quantity}","eticket_orders_view_order_details":"View Order Details","eticket_term_of_service":"CYBERBIZ E-Ticket Terms of Service","failed_to_send_message":"Message Sending Failed","order_empty_note":"No Information Available","payment_status_failed":"Payment Failed, Please Contact Customer Service","payment_status_pending":"Authorization Pending","payment_status_success":"Payment Successful","show_eticket_button_qr_code":"Display Ticket QR Code","show_eticket_button_used":"Ticket Already Used","usage_status_partial_used":"Partially Used","usage_status_used":"Fully Used"},"express_delivery":{"add_to_cart":"Add to Cart","add_to_cart_error":"Failed to Add to Cart.","address_incomplete":"Incomplete address entered.","address_incomplete_hint":"Your address is incomplete. Please input the correct address before adding to cart.","back_to_product_list":"Back to Product List","business_hours":"Business Hours","cancel":"Cancel","change":"Change","change_address":"Change Address","choose_store":"Select Delivery Store","cyberbiz_now":"CYBERBIZ NOW","default_sort":"Recommended","delivery_address":"Delivery Address","delivery_address_detail":"Floor or Unit Number","delivery_address_detail_hint":"Enter Floor or Unit Number","delivery_address_hint":"Enter Delivery Address","delivery_address_separate_tips":"Please enter floor or room number information separately","empty_collection":"This category currently has no products.","exit":"Confirm","exit_prompt":"Are you sure you want to exit Express Delivery?","express_delivery":"CYBERBIZ NOW","get_position_error_internal":"Error: Please enable browser access to location permissions.","get_position_error_no_permission":"Error: Please enable your web browser's location service.","get_position_error_require_https":"Error: HTTPS required.","get_position_error_timeout":"Error: Request timeout.","more_info":"More Information","not_search_stores_yet":"Please Click 'Search'","phone":"Contact Phone Number","please_select_specifications":"Please select specifications.","pre_order":"Pre-order","price_asc":"Price Low To High","price_desc":"Price High To Low","product_count":"A Total Of {totalCount}
126 Items","recent_days_sold_desc":"Bestselling","sales_start_info":"Sales Start on {time}","sales_start_info_verbose":"Sales Start on {day} {time}","search_failed":"Store search unsuccessful.","search_product_count":"You have searched for {selectedStoreName}'s products, totaling {count} items.","search_stores":"Search","sell_from_asc":"Listing date, old to new","sell_from_desc":"Listing date, new to old","service_description":"CYBERBIZ NOW Express Delivery Service Details:","service_description_detail":"This shopping service is provided by the CYBERBIZ system. We collaborate with third-party partners to offer delivery services, ensuring a faster shopping experience for you.","service_hours":"Available Time: {day} {time}","service_is_available":"The address you entered supports \"CYBERBIZ NOW Express Delivery\".","service_not_available_in_the_region":"We're sorry, the \"CYBERBIZ NOW Express Delivery\" service is currently not available in your area.","sold_out":"Out of Stock","store_address":"Store Address","store_address_info":"Address: {address}","store_is_closed":"Currently not accepting service","view_products":"View Products"},"express_delivery_with_regularly_used_address":{"address":"Delivery Address","address_incomplete_hint":"Please enter a complete delivery address","address_invalid_content":"Delivery address is required","address_placeholder":"Please enter a delivery address","button_create":"Add Address","button_save":"Save","button_save_as_regular":"Save as frequently used","cancel":"Cancel","create_address":"Add New Address","delete":"Delete","delete_failed":"Deletion failed","delete_hint":"Once the address is removed, it cannot be recovered.","delete_message":"Are you sure you want to delete this address?","delete_success":"Successfully deleted","edit":"Edit","empty_lists":"No frequently used delivery address","empty_lists_hint":"There are no addresses saved; please click [Add New Address] to create and set a default address.","limit_hint":"You can save up to 5 frequently used addresses. The system will automatically remove the earliest saved address.","name":"Name","name_invalid_content":"Name is required","name_placeholder":"Please enter a name","return":"Keep","save_as_regular":"Save as frequently used","save_success":"Success saved","search_failed":"No delivery stores available for this address. Please use a different delivery address.","select_address":"Select a frequently used delivery address","site":"Address","site_invalid_content":"Address is required","site_placeholder":"Please enter an address","title_address_lists":"Frequently used address saved","title_delete_address":"Are you sure you want to delete this address?","title_edit_address":"Edit delivery address","title_save_as_regular":"Save as frequently used"},"i18n_setting":{"currency":"Currency","language":"Language","language_currency_setting":"Language / Currency Settings"},"line_group_buy":{"add_to_cart":"Add to Cart","go_checkout":"Proceed to Checkout","product_description":"Description","product_shipping":"Shipping Method","product_spec":"Product Specifications"},"menu":{"fourDimensionMenu":{"account":"My Account","cart":"My Cart","help":"Help \u0026 Contact","locator":"Store Locator","wishlist":"My Wishlist"}},"omniauth_mobile":{"check_account":"Please fill in your mobile number for identity verification.","confirm_account_information":"Is the account information below belongs to you?","confirm_submit":" Submit","enter_mobile_number":"Please enter your mobile number.","merge":"Yes, please merge my account.","mobile_number":"Mobile number","phone_validation":"Phone verification","reconfirm":"No, I want to verify again.","registered":"Already have an account ?","resend":" Resend","resend_with_timer":"({ timer } second) Resend","retry_later_error":"Reached system operation limit, please refresh and try again.","return_login":"Back to log in page","send_confirmation_token":"The verification code has been sent to your phone.","send_message":"Send Verification Code","submit_btn":"Sign up","verification_code":"4-digit verification code"},"repurchase":{"alcohol_all_cannot_repurchase":"Products cannot be inquired again.","all_cannot_repurchase":"Products cannot be bought again.","comma":",","lense_all_cannot_repurchase":"Products cannot be delivered again.","partial_cannot_repurchase":"{ reasonList }please refer to your shopping cart.","quote_product_name":"{ productName }","reason_combo_product_changed":"changes for combo product(s)","reason_exceed_the_stock":"Out of stock item(s)","reason_product_is_discontinued":"unpublished item(s)","reason_product_not_found":"deleted item(s)","separator":","},"theme_pages":{"branch_store":{"get_store_empty":"No stores available","get_store_error":"An error occurred while loading store information","options_all_cities":"All Cities","search_stores":"Search","store_address":"Address: { address }","store_open_time":"Business Hours: { openingHours }
126","store_phone":"Phone: { phone }"},"collection":{"all_filters":"All Filters","filter_button":"Filter","filter_no_result":"Sorry, no results","not_on_sale_yet":"Coming soon","please_reselect":"Try removing some filters to see more items","product_sold_out":"Sold Out","products_total":"Total of {totalProductCounts} Products","reset_all_filters":"Reset All Filters","reset_filter_button":"Reset Filter","suggested_range":"Suggested Range","upcoming_product":"Sale starts on","view_product":"View Product"},"combo_product":{"add_cart_error_try_again":"Network error, please try again.","arrive_soon":"Arriving Soon","contact_shop":"Contact Shop","discount_bonus":"Redeemable credit(s) per item","has_stock":"In Stock","insufficient_selected_quantity":"Insufficient quantity, {count} more pieces required","inventory_status":"Inventory Status","less_than_count":"Quantity selected must be greater than {count}","limit_reached":"limit reached","no_stock":"Out of Stock","notification_enabled":"Notification Enabled","notify_me_when_stock_arrives":"Sold out! Notify me when the product is available.","over_cart_limit":"Quantity exceeds shopping cart limit; please remove some items and place the order again.","over_stock_quantity":"The quantity entered exceeds the stock quantity. Please decrease your order.","point_equal":"equivalent to","points":"credit(s)","pre_order":"Pre-order Goods","quantity_over_combo_product_limit":"Quantity exceeded required pieces","related_item_name":"Item Name","related_item_quantity":"Quantity","select_optional_combo_product_items":"Select Items","selectable_count":"{count} pieces required, ","selected_count":"{count} selected"},"contact":{"contact_form":"Contact Form","email":"Email Address","email_placeholder":"'Enter your email, e.g.: [email protected]'","fail_operation":"Something went wrong; please try again later!","invalid_email":"Invalid Email","invalid_name":"Name required","invalid_phone_number":"Phone Number Required","invalid_question_content":"Please enter your message","name":"Name","name_placeholder":"Enter your name","phone_number":"Phone Number","phone_number_placeholder":"Enter your phone number","question_content":"Message","question_content_placeholder":"Please enter your message","question_submit_fail":"Something went wrong; please try again later!","question_submit_success":"The question has been sent successfully. We will contact you as soon as possible!","question_type":"Question Type","success_operation":"Message Sent!"},"customer_coupon":{"customer_coupons_product_name":"Gift","customers_coupons_available_used":"Redeemable / Redeemed: ","customers_coupons_available_used_already_used":"{availableUsed} Coupon(s) / {alreadyUsed} Coupon(s)","customers_coupons_coupon":"Discount Coupon","customers_coupons_days":"Days","customers_coupons_discount":"% Off","customers_coupons_end_date":"End Date: ","customers_coupons_end_date_msg_1":"No expiration starting from {start_date}","customers_coupons_end_date_msg_2":"From Today to End Date {end_date}","customers_coupons_end_date_msg_3":"Available once order {name} is completed","customers_coupons_end_date_msg_4":"No Expiration","customers_coupons_expired":"Expired","customers_coupons_free_shipping":"FREE Shipping","customers_coupons_gift_coupon":"Gift Coupon","customers_coupons_left":"Left","customers_coupons_list_div":", ","customers_coupons_lookup_suit_product":"View products","customers_coupons_method":"Applicable Orders: ","customers_coupons_no_coupons_msg":"Sorry, no coupons available for your account!","customers_coupons_no_end_date":"No Expiration","customers_coupons_no_start_use":"Not Enabled","customers_coupons_not_suit":"Not combined with","customers_coupons_product_deleted":"The free gift product has been deleted.","customers_coupons_serial_number":"Code","customers_coupons_still_available":"{timesLeft} Coupon(s)","customers_coupons_suit_any_discount":"All promotions","customers_coupons_suit_any_product":"All products","customers_coupons_suit_discount":"Applicable Promotions: ","customers_coupons_suit_product":"Applicable Products: ","customers_coupons_unlimited":"Unlimited coupons","customers_coupons_unlimited_already_used":"Unlimited coupons / {alreadyUsed} Coupon(s)","threshold_hint":"Orders exceeding { price }"},"order_return":{"account_name":"Bank Account Name","address1":"Return Address","all_return":"Return all","apply_fail":"Application Failed","apply_return":"Return Application","apply_return_success":"Refund Request Sent","apply_success":"Successful Application","bank_account":"Bank Account","bank_branch_name":"Name of Branch","bonus_redemption":"Exchange Credit Point(s)","check_account_length":"Please check the length of the bank account number","check_order":"My Order(s)","choose_branch_bank":"Select Bank Branch","choose_return_reason":"Select Return Reason","city":"City","confirm_return":"Apply Refund","country_placeholder":"Select country","coupon_free_shipping":"Free Shipping Coupon","deliver_error":"Delivery Error","discount_detail":"Discount Details","enter_account_name":"Enter bank account name","enter_return_reason":"Please specify the return reason","estimated_refund_amount":"Estimated refund amount","free":"Free","gift_price":"Add-on Price","gift_purchase":"Gift with purchase","include_discount_and_shipping_fee":"Including discount and shipping fee","keep_shopping":"Keep Shopping","keyin_address1":"Please enter the address we should collect the returning goods","keyin_city":"Please enter city name","keyin_zip":"Please enter postal code","line_item_quantity":"Quantity: {lineItemQuantity}","literal_points":"point(s)","new_product_defect":"Defect on New Product","order_date":"Order Date","order_number":"Order Number","order_retrun_confirm":"Are you sure you want to request a refund?","others":"Others","please_choose_bank":"Select Bank","please_select_country":"Select Bank Country","price_includes_tax":"(includes consumption tax of {tax})","product_content_defect":"Wrong Product or Incomplete Product","product_defect":"Defective Product","refund":"Refund Amount","refund_account":"Refund Account","refund_info":"Refund Information","refund_instruction":"Excluding discounts and shipping fees, the actual refund will be as per the system amount.","refund_invoice_check":"I agree to the cancellation of the invoice or the \"Tax Payment Certificate\", and g
126ive consent to {envoiceCompanyName} to be handled at discretion in order to expedite the refund process.","related_item":"{ name } x{ quantity }","return_address":"Return Address","return_email_notification":"A copy of the refund details have been sent to your email","return_info":"Return Information","return_instruction":"Return Information","return_item_error":"Please select at least one item to return.","return_msg_Taiwan_shop":"1. If any defects or breakages are found upon receiving the goods, and you need to apply for an exchange or refund, please enter to \"My Account\", find your order and click \"My Order(s)\", then click on \"Apply Refund\" as soon as possible. Please refer to the shop's return policy for detailed information and guidance.\u003cbr\u003e 2. When returning or exchanging goods, please keep the original package intact (including purchased goods, accessories, gifts, etc.).\u003cbr\u003e 3. After receiving the refund application, we will contact you to retrieve the goods. If you have any return questions, you can click \"Message Shop\" on the \"My Order(s)\" page. Please do not send back the goods by yourself.\u003cbr\u003e 4. Please print this application form and send it with the goods.\u003cbr\u003e 5. Once your returned item is received and reviewed, a refund will be made to your original payment method; it would take up to 5 to 10 days until it shows on your bank statement.\u003cbr\u003e","return_msg_not_Taiwan_shop":"1. If you find any defects or breakages upon receiving the goods and wish to apply for an exchange or refund, please log in to \"My Account\", locate your order, and click on \"My Order(s)\". Then select \"Apply Refund\". For detailed information and guidance, refer to the shop's return policy.\u003cbr\u003e 2. When returning or exchanging goods, please ensure that the original packaging is intact, including the purchased items, accessories, gifts, etc.\u003cbr\u003e 3. After receiving your refund application, we will contact you to arrange the retrieval of the goods. If you have any questions about the return, click \"Message Shop\" on the \"My Order(s)\" page. Please do not return the goods on your own.\u003cbr\u003e 4. Print this application form and include it with the returned goods.\u003cbr\u003e Once your returned item is received and reviewed, a refund will be issued to your original payment method or bank account. It may take 7 to 14 days for the refund to appear on your bank statement.","return_product":"Return Product","return_quantity":"Return quantity","return_reason":"Return Reason","shipping_fee":"Shipping Fee","state_placeholder":"Select state / province","tax":"Tax","total_bonus_redemption":"Total Credit Point(s) Redemption","tw_city_placeholder":"County / City","tw_district_placeholder":"District","vip_shipping_free":"Free Shipping For Members","zip":"ZIP / Postcode"},"product_collection":{"check_product":"View"},"product_list":{"must_confirmed":"Please \u003ca href=\"/account\"\u003evalidate your account\u003c/a\u003e to checkout.","must_sign_up":"Please \u003ca href=\"/account/login?{ path }\"\u003elog in\u003c/a\u003e or \u003ca href=\"/account/signup?{ path }\"\u003esign up \u003c/a\u003e to checkout."},"search":{"articles_total":"Total of { totalArticleCounts } Articles","continue_reading":"Continue Reading","search_article_label":"Article results ({ totalArticleCounts })","search_no_result":"Sorry, no results found by searching: { queryString }. Please try a different word.","search_product_label":"Product results ({ totalProductCounts })","search_total":"Search: { queryString } / { totalSearchCount } item(s) found"},"special_collection":{"already_choose_and_buy_more":"Selected {quantity} items, buy {quantity_more} more","buy_more_promotion":"to save more!","buy_quatity":"Buy {quantity} ","need_diopter":"Fill out the lens prescription first","need_login":"Login first","not_choose_items_yet":"No Item Selected Yet","not_choose_yet":"No Item","origin_price":"Original Price:","over_cart_limit":"Quantity exceeds shopping cart limit; please remove some items and place the order again.","over_stock":"Quantity exceeds inventory stock; please decrease the quantity selected","sales_price":"Price","select":"Select","selected":"Selected","special_collection_discount_per":"get every item for {price} off","special_collection_discount_pirce":"get discount of {price}","special_collection_discount_quatity1":"for {price}","special_collection_divided_by_ten":"get {percentage} % off"}},"validation":{"check_email_immediately":"Check your mailbox","click_to_resend_validate_email":"Didn't receive the email? Please check spam or","click_to_resend_validate_sms":"Didn't receive the text message? Please click to resend","go_to_member":"Go to Member Center","resend_too_frequently":"Sent too frequently, please try again in a minute.","resend_validation_email_success":"Account verification letter has been resent","resend_validation_msg_failed":"Failed to resend the account verification message, please try again later.","resend_validation_sms_success":"Account verification SMS has been resent","second":"s","send_valid_email_again":"Resend","send_validation_email1":"We have sent an email to your mailbox { customerEmail }","send_validation_email2":"Please follow the instructions in the email to activate your account","send_validation_sms1":"We have sent a text message to your mobile phone { customerMobile }","send_validation_sms2":"Please follow the text message prompts to complete account activation","validate_your_account":"Just one more step, complete the verification to activate your account.","wait_to_send_valid_email":"Resend after ({ seconds }s)"}}}},
127            hasI18nInContextEditing: false,
128            shopMultipleCurrenciesCheckout: false,
129            hasLocalizedShopPriceFormat: true,
130          }
131        </script>
131
132
133        
134        
134<script
135          src="//cdn-general.cybassets.com/frontend/shop/tolgeeIntegration-3a2e378145f8a165.js">
136        </script>
136
137        
137<script defer>
138          /*
139          * Enable in-context translation for Liquid part on the page.
140          * This must be executed last to prevent conflicts with other Vue apps.
141          * So put it to `onload`, which will be executed after DOM ready's app mount
142          */
143          window.onload = function() {
144            if (
145              window.shopScriptHelper &&
146              window.shopScriptHelper.hasI18nInContextEditing
147            ) {
148              window.initTolgeeForLiquid()
149            }
150          }
151        </script>
151
152
153<script> var google_con_event_labels = []</script>
vendor: 1 bytes, line 153
153
154<script src="//cdn-general.cybassets.com/frontend/shop/pageEventHandler-3a2e378145f8a165.js"></script>
vendor: 1 bytes, line 154
154
155<script src="//cdn-general.cybassets.com/frontend/shop/globalAnalysis-e4c650eb0b.js"></script>
155
156        
156<script>
157          window.c12t = {"customer_id":null,"product":{"id":58021395,"name":"X2 - Smart Cycling Computer","price":2490.0,"brand":"Xplova"}};
158        </script>
158
159
160        <meta name="request-id" content="8A4EFBD45E7B80AE4FAD50E9CB50A52F"/>
161
162<link rel="canonical" href="https://www.xplova.com/en/products/x2">
163<link rel="alternate" hreflang="zh-TW" href="https://www.xplova.com/zh-TW/products/x2">
164<link rel="alternate" hreflang="en" href="https://www.xplova.com/en/products/x2">
165<link rel="alternate" hreflang="ja" href="https://www.xplova.com/ja/products/x2">
166<link rel="alternate" hreflang="x-default" href="https://www.xplova.com/zh-TW/products/x2">
167<script src="//cdn-general.cybassets.com/frontend/shop/carousel-3a2e378145f8a165.js"></script>
167
168          
168<script>
169            window.parent.postMessage({ type: 'previewShopInit', currentUrl: window.location.href }, '*');
170          </script>
170
171
172<script src="//cdn-general.cybassets.com/frontend/appStoreSDK/main.2798231628aa7fab87a9.js"></script>
vendor: 1 bytes, line 172
172
173<script>window.CYBERBIZ_AppScriptSettings = {"shop_add_ons":"W3sidmVuZG9yX3R5cGUiOiJDWUJFUkJJWiBHb29nbGUgQW5hbHl0aWNzIDQi\nLCJhcHBfaWQiOiJRVWo1WnFvZUlPUjlaM2JaS2trMG44N3l5a0FpOWU0NURE\naDJ0YlFnaUJBIiwic2V0dGluZ3MiOnsiZ3RhZ19pZCI6IkctUDM2WUhQM0dW\nRiwgRy00QjdSSzdGSFdIIn19LHsidmVuZG9yX3R5cGUiOiJHb29nbGUgQW5h\nbHl0aWNzIDQiLCJhcHBfaWQiOiJSYkpWMTVFcVZWOHJ1Umo3NVlmV3Z1RUlD\nRm90Q0FPZm0xSDZtZ3hyNkZBIiwic2V0dGluZ3MiOnsiZ3RhZ19pZCI6Ikct\nS0ZQOFpUU0xGWSJ9fSx7InZlbmRvcl90eXBlIjoiQ2hhdCBCb3giLCJhcHBf\naWQiOiJjOWQ4M2YwOTk2MTc0ZmJiYTg2ZWJhMDQxYWU4OThhMiIsInNldHRp\nbmdzIjp7IndpZGdldF9rZXkiOiJ0TFQtaHV2eWVTY3NtOTNOIn19XQ==\n"}
174</script>
vendor: 1 bytes, line 174
174
175<script src="https://cdn.cybassets.com/appmarket/api/common/attachments/entrypoint/9d6f4550aad572e9f70abb70ae5a6552482cf617ea5e4d5a32ed4ebbb5d60d54.js"></script>
vendor: 1 bytes, line 175
175
176<script src="https://cdn.cybassets.com/appmarket/api/common/attachments/entrypoint/a810ec58aab67d16f8de1c4adf06fc7cc9f4477ec503b9cb1a998741bc692652.js"></script>
vendor: 1 bytes, line 176
176
177<script src="https://cdn.cybassets.com/appmarket/api/common/attachments/entrypoint/8766542902afa60f4adda3c555c06025d2c27771ea85a6fc657a91cddbe5c59f.js"></script>
vendor: 1 bytes, line 177
177
178<script>window.CYBERBIZ.initializeSDK.initialize();</script>
vendor: 1 bytes, line 178
178
179<script src="//cdn-general.cybassets.com/frontend/shop/setAffliateCookie-3a2e378145f8a165.js"></script>
179
180
181
182
183
184
185<meta name="title" content="Xplova | X2 - Smart Cycling Computer">
186<meta property="og:title" content="Xplova | X2 - Smart Cycling Computer">
187<meta name="description" content="One of the best cycling computers in the world Superior battery life/ Support Smart Trainers/ Dual mode configuration">
188<meta property="og:description" content="One of the best cycling computers in the world Superior battery life/ Support Smart Trainers/ Dual mode configuration">
189<meta name="keywords" content="xplova, X2">
190<meta property="og:url" content="https://www.xplova.com/en/products/x2">
191<meta property="og:type" content="og:product">
192<script type="application/ld+json">{"@context":"https://schema.org/","@type":"Product","name":"X2 - 智慧車錶","image":"https://cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL3Byb2R1Y3RzLzU4MDIxMzk1LzE3NTM5NTA3NzNfMGY5MDQ5MzhjYzU5YjNlNWE2ZTYucG5nIl0sWyJwIiwidGh1bWIiLCI0ODB4NDgwIl1d.png?sha=699e868f5d1b8407","description":"\u003ca style=\"color: #565656;\"\u003e商品配件 : \u003c/a\u003e \u003cbr\u003e- Xplova X2 主機 *1 \u003cbr\u003e - Micro-USB 傳輸線 *1 \u003cbr\u003e - 車錶固定座 *1 \u003cbr\u003e - 緩衝墊片 *1 \u003cbr\u003e-  橡膠墊圈 *2 \u003cbr\u003e - 快速入門指南 \u003cbr\u003e-  保固手冊","brand":"Xplova","sku":"ZC.X01TA.00L","offers":{"@type":"Offer","url":"https://www.xplova.com/en/products/x2","priceCurrency":"TWD","price":"2490.0","priceValidUntil":"","availability":"OutOfStock"},"productId":58021395}</script>
192
193
194      
194<script>
195        document.addEventListener("DOMContentLoaded", function() {
196          gtag('event', 'view_item', {"items":[{"id":70177313,"name":"X2 - 智慧車錶","price":2490.0}],"send_to":["cyberbiz","dynamic_remarketing"]});
197        })
198      </script>
198
199    
200
201      
201<script>
202        document.addEventListener("DOMContentLoaded", function() {
203          try {
204            var productData = [{"id":"ZC.X01TA.00L","product_id":58021395,"variant_id":70177313,"sku":"ZC.X01TA.00L","name":"X2 - 智慧車錶","price":2490.0,"compare_at_price":2490.0,"currency":"TWD","inventory_quantity_status":"empty","category":null,"categories":["所有產品,自行車周邊"],"properties":[],"list_name":""}];
205
206            if (document.referrer.indexOf('collection') !== -1 || document.referrer.indexOf('products') !== -1) {
207              for (var i = 0; i < productData.length; i++) {
208                productData[i].list_name = sessionStorage.getItem("viewedCollection");
209              }
210            }
211
212            window.CYBERBIZ.eventSDK.callEvent("viewItem", productData)
213
214            window.addEventListener("beforeunload", function(event) {
215              var collection = "Related Products";
216              sessionStorage.setItem("viewedCollection", collection);
217            });
218
219          } catch (error) {
220            console.error('Exception catched in appMarketViewItemEvent')
221          }
222        })
223      </script>
223
224    
225
226<script src="//cdn-general.cybassets.com/frontend/shop/gallery-3a2e378145f8a165.js"></script>
226
227
228    <style id="color_settings">
229  :root {
230    
231      --button: #F15A22;
232    
233
234    
235      --button_text: #FFFFFF;
236    
237
238    
239      --accent: #F15A22;
240    
241
242    
243      --heading: #565656;
244    
245
246    
247      --text: #9A9EA2;
248    
249
250    
251      --price: #F15A22;
252    
253
254    
255      --discount_price: #C39D6F;
256    
257
258    
259      --theme_bg: #FFFFFF;
260    
261
262    
263      --nav_logo_bg: #FFFFFF;
264    
265
266    
267      --nav_menu_bg: #FFFFFF;
268    
269
270    
271      --nav_menu_text: #5F6062;
272    
273
274    
275      --nav_menu_icon: #5F6062;
276    
277
278    
279      --footer_bg: #000000;
280    
281
282    
283      --footer_text: #FFFFFF;
284    
285
286    
287      --checkout_button: #000000;
288    
289
290    
291      --checkout_accent: #F15A22;
292    
293
294    
295      --product_border: #E2E2E2;
296    
297
298    
299      --tips_text: #0C5460;
300    
301
302    
303
304    
305  }
306</style>
307
308
309
310
311
312<meta name="google-site-verification" content="6Lg5o7s6ic1UPLvynerBcWnNnb8lzoTiAWALKkJKsXw" />
313
314  
315        <!-- Global site tag (gtag.js) - Google Analytics -->
vendor: 74 bytes, lines 315-316
315
316          <script async src="https://www.googletagmanager.com/gtag/js?id=
316G-P36YHP3GVF
vendor: 22 bytes, lines 316-317
316"></script>
317          
317<script>
318            window.dataLayer = window.dataLayer || [];
319            function gtag(){dataLayer.push(arguments);}
320            gtag('js', new Date());
321            gtag('config', 'G-P36YHP3GVF', {"groups":"cyberbiz","custom_map":{"dimension1":"shop_id","dimension2":"customer_id","dimension3":"infinite_scroll","dimension4":"dim_affiliate"},"shop_id":33373,"dim_affiliate":null});
322            gtag('config', 'UA-64017614-1', {"groups":"cyberbiz","custom_map":{"dimension1":"shop_id","dimension2":"customer_id","dimension3":"infinite_scroll","dimension4":"dim_affiliate"},"shop_id":33373,"dim_affiliate":null});
323      </script>
323
324      
324<script>
325        (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
326        (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
327        m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
328        })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
329
330        ga('create', '', 'auto', {'name': 'cyberbiz'});
331        ga('cyberbiz.require', 'displayfeatures');
332        ga('cyberbiz.set', 'dimension1', '33373');
333        ga('cyberbiz.require', 'ec');
334        ga('cyberbiz.send', 'pageview');
335      </script>
335
336    </head>
337
338  <body style="display: flex; flex-direction: column;">
vendor: 74 bytes, lines 338-340
338
339      <noscript><iframe
340      src="//www.googletagmanager.com/ns.html?id=
340GTM-TXD9LVJ
vendor: 186 bytes, lines 340-347
340"
341      height="0"
342      width="0"
343      style="display:none;visibility:hidden">
344      </iframe></noscript>
345    
346      <noscript><iframe
347      src="//www.googletagmanager.com/ns.html?id=
347GTM-P7528MQ
vendor: 117 bytes, lines 347-353
347"
348      height="0"
349      width="0"
350      style="display:none;visibility:hidden">
351      </iframe></noscript>
352    
353    
353<!-- Navigation -->
354    <!-- cyb_snippet liquid_helper start -->
355<script>
356	function getDiscountPriceName() {
357		return "false" === "true" ? "" : "";
358	}
359
360	function getDiscountPriceSuggestionName() {
361		return "false" === "true" ? "" : "";
362	}
363
364  document.addEventListener('DOMContentLoaded', function() {
365    const languageHandle = Cookies.get("language");
366    const defaultLanguage = {"handle":"zh-TW","title":"繁體中文","currency_code":"TWD"};
367    const languages = [{"handle":"zh-TW","title":"繁體中文","currency_code":"TWD"},{"handle":"en","title":"English","currency_code":"USD"},{"handle":"ja","title":"日本語","currency_code":"JPY"}];
368    const currency = window.shopScriptHelper.defaultCurrency;
369    const currencies = window.shopScriptHelper.currenciesInfo;
370		window.liquidHelper = {
371			shopInternational: true,
372			defaultLanguage: defaultLanguage,
373			language: languages.find(function(l) {
374				return l.handle === languageHandle;
375			}) || defaultLanguage,
376      shopMultipleCurrenciesCheckout: false,
377			shopMultipleCurrencies: true,
378			defaultCurrencyFormat: "NT${{amount_no_decimals}}",
379			defaultCurrency: currency,
380			getCurrency: function() {
381        const currencyValue = Cookies.get("currencyValue") || currency;
382        return currencies.find(function(c) { return c.code === currencyValue; }
383      )},
384      getDefaultCurrency: function() { return currencies.find(function(c) {
385				return c.code === currency;
386			})},
387      getAvailableCurrencies: function() { return currencies.map(c => c.code) },
388      getCurrencyFormatInfo: function(currency) {
389        const currencyInfo = currencies.find(c => c.code === currency)
390        return _.pick(currencyInfo, [
391          'decimal_precision',
392          'symbol',
393          'money_format',
394          'unit',
395          'trailing_zeros',
396          'html_unit',
397          'code',
398        ]);
399      },
400			cartQuantityLimit: (function() {
401        const limit = Number("0" || undefined);
402        return limit <= 0 || isNaN(limit) ? Number.POSITIVE_INFINITY : limit;
403      })(),
404			isFirstVariantSelected:  false ,
405			isImageColorsUsed:  false ,
406			isEmptyClickable:  true ,
407			hasAddBuyProduct: '' !== "" ? true : false,
408			hasPriceWithDiscountPlugin: 'true' ? true : false,
409      conversionBonus: 1,
410      hasLocalizedShopPriceFormat: true,
411      hasCustomerCartPlugin: true,
412      isCartEnabled: false,
413      cdnHost: '//cdn-general.cybassets.com',
414      hasShopCustomPasswordRulePlugin: false,
415      hasDisableProductQuantityValidation: false,
416      hasBreadcrumbReferrerEnabled: false,
417		};
418	});
419</script>
419
420
421<!-- cyb_snippet liquid_helper end -->
422
423<script src='//cdn-general.cybassets.com/frontend/shop/navbarSection-3a2e378145f8a165.js' type='text/javascript'></script>
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440<style>
441  
442    #navbar {
443      --navbar-pc-title-scale: 0.9;
444      --navbar-pc-body-scale: 1.0;
445      --navbar-mobile-title-scale: 0.9;
446      --navbar-mobile-body-scale: 1.0;
447    }
448  
449
450  
451
452  
453</style>
454
455
456  <span id="navbar" class="drawer drawer--left font-size-setting-enabled">
457    <header id="header" class="qk-w--100vw qk-pos--fixed qk-t--0 qk-l--0">
458      
459
460      
461        <div id="announcement-bar"></div>
462      
463
464      
465      
466        
467
468        <div class="computer_nav row_nav qk-hidden--mobile ">
469          <div class="header_logo qk-bg--nav_logo_bg">
470            <div class="qk-pos--rel">
471              <div class="qk-text--center qk-display--flex">
472                <!-- logo start -->
473                
474                
475                  <nav class="logo qk-display--il_bk">
476                    <a href="/" class="qk-w--100">
477                      <img
478                        src="//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxNDM1MDAxX3hwbG92YV9sb2dvXzEwMC5wbmcucG5nIl1d.png?sha=2390923483f0eb3f"
479                        class="qk-tst qk-tst_dur--15 qk-tst_timing--ease_io qk-tst_prop--pc_logo qk-hidden--mobile"
480                        style="width: auto; height: 52px;"
481                        alt="xplova"
482                        height="52"
483                        width="auto"
484                      >
485                    </a>
486                  </nav>
487                
488                <!-- logo end -->
489                
490                  <div class="header_nav qk-flex--1">
491                    <div class="qk-pos--relative center qk-pd_r--1 qk-w--100">
492                      <!-- main-nav start -->
493                      <nav class="main_nav qk-display--init"></nav>
494                      <!-- main-nav end -->
495                    </div>
496                  </div>
497                
498                <!-- tool-nav start -->
499                
500                  <div style="display: flex; align-items: center; position: relative; top: -12px;">
501                    <!-- cyb_snippet tool_nav start -->
502
503
504
505
506
507
508<nav class="tool-nav qk-pos--rel qk-float--r qk-display--flex">
509  <ul class="link_shelf_top qk-display--flex qk-flex--row qk-justify--end qk-align--center qk-pos--abs qk-r--0">
510    
511    
512      
513      <li class="i18n-selector qk-fs--body qk-text--nav_menu_icon qk-bd--nav_menu_icon qk-btn"></li>
514    
515    <!-- member -->
516    
517      <li class="customer_account qk-pos--rel qk-pd--05">
518        <div class="dropdown qk-pos--static">
519          <div class="qk-cursor--pointer" data-toggle="dropdown">
520            <div data-icon-type="custom_icon_type_account"></div>
521            <span class="text"></span>
522          </div>
523          <div class="member qk-dropdown_menu dropdown-menu qk-pos--abs qk-r--0 qk-bd--default qk-bd--product_border qk-bg--theme_bg" role="menu">
524            <ul id="customer-logined-menu" style="display: none">
525              <li>
526                <div class="qk-fs--body qk-text--heading">
527                  <p class="customer-name qk-whitespace-break-spaces"></p>
528                  <p>Welcome!</p>
529                </div>
530              </li>
531            </ul>
532            <ul id="customer-not-login-menu">
533              <li class="button qk-text--center">
534                <a href="/en/account/login" class="btn-login qk-btn qk-btn--lg qk-btn--primary qk-w--100">Log in</a>
535              </li>
536              <li class="button qk-text--center">
537                <a href="/en/account/signup" class="btn-orders qk-btn qk-btn--lg qk-btn--secondary qk-w--100 qk-bg--transparent">Sign up</a>
538              </li>
539            </ul>
540            <span class="menu-bd qk-bd_t--default qk-bd--product_border"></span>
541            <ul class="member-menu qk-bd_t--default qk-bd--product_border">
542              <li class="qk-bg--mask_hover qk-tst qk-tst_dur--15 qk-tst_timing--ease_io qk-tst_prop--bg">
543                <a href="/en/account/index" class="qk-fs--body qk-text--heading qk-w--100 qk-display--il_bk">My Account</a>
544              </li>
545              <li class="qk-bg--mask_hover qk-tst qk-tst_dur--15 qk-tst_timing--ease_io qk-tst_prop--bg">
546                <a href="/en/account/orders" class="qk-fs--body qk-text--heading qk-w--100 qk-display--il_bk">My Order(s)</a>
547              </li>
548              <li class="qk-bg--mask_hover qk-tst qk-tst_dur--15 qk-tst_timing--ease_io qk-tst_prop--bg">
549                <a href="/en/account/coupons" class="qk-fs--body qk-text--heading qk-w--100 qk-display--il_bk">My Coupon(s)</a>
550              </li>
551              <li class="qk-bg--mask_hover qk-tst qk-tst_dur--15 qk-tst_timing--ease_io qk-tst_prop--bg">
552                <a href="/en/account/tracking_items" class="qk-fs--body qk-text--heading qk-w--100 qk-display--il_bk">My Wishlist</a>
553              </li>
554              <li class="qk-bg--mask_hover qk-tst qk-tst_dur--15 qk-tst_timing--ease_io qk-tst_prop--bg customer-logout-li" style="display: none">
555                <a href="/en/account/logout" class="qk-fs--body qk-text--heading qk-w--100 qk-display--il_bk">Logout</a>
556              </li>
557            </ul>
558          </div>
559        </div>
560      </li>
561    
562    <!-- for money symbol -->
563    <div id="money-symbol" data-money-symbol="NT${{amount_no_decimals}}" hidden></div>
564    <!-- cart -->
565    
566    <!-- search -->
567    
568    <!-- express delivery -->
569    
570  </ul>
571</nav>
572
573<!-- cyb_snippet tool_nav end -->
574                  </div>
575                
576                
577                <!-- tool-nav end -->
578              </div>
579            </div>
580          </div>
581        </div>
582      
583      <div class="qk-hidden--pc  ">
584        <!-- mobile-nav start -->
585        <nav class="mobile-nav qk-bg--nav_logo_bg">
586          <ul class="qk-display--flex qk-flex--row qk-justify--between qk-align--center qk-pd_x--05 qk-pd_y--0">
587            <!-- menu -->
588            
589              <li class="sidebar-menu-icon drawer-toggle qk-text--center qk-pd_x--05 qk-pd_y--0 qk-display--flex qk-align--center">
590                <div data-icon-type="custom_icon_type_menu"></div>
591              </li>
592            
593            <!-- logo -->
594            
595              <li class="logo qk-mg_r--auto qk-pd_x--05 qk-pd_y--0">
596                
597                  <a href="/" class="qk-display--il_flex qk-align--center qk-h--100 qk-hidden--phone">
598                    <img
599                      src="//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxNDM1MDAxX3hwbG92YV9sb2dvXzEwMC5wbmcucG5nIl1d.png?sha=2390923483f0eb3f"
600                      height="25"
601                      width="auto"
602                      alt="xplova"
603                    >
604                  </a>
605                
606                
607                  <a href="/" class="qk-display--il_flex qk-align--center qk-h--100 qk-hidden--tablet">
608                    <img
609                      src="//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxNDM1MDAxX3hwbG92YV9sb2dvXzEwMC5wbmcucG5nIl1d.png?sha=2390923483f0eb3f"
610                      height="25"
611                      width="auto"
612                      alt="xplova"
613                    >
614                  </a>
615                
616              </li>
617            
618            
619              <!-- search -->
620              
621              <!-- express delivery -->
622              
623            
624          </ul>
625        </nav>
626        <!-- mobile-nav end -->
627      </div>
628      
629    </header>
630    
631      <!-- Sidebar -->
632      <nav class="drawer-nav drawer-nav_width qk-bg--nav_menu_bg " role="navigation">
633        <div class="drawer-menu">
634          <!-- cyb_snippet side_menu start -->
635
636
637<ul id="index_sidebar_shelf_top" class="sidebar qk-pd_b--1">
638  
639    <li class="logo qk-pos--rel qk-bg--nav_logo_bg qk-pd_x--1 qk-pd_y--05">
640      <a href="/" class="qk-pd--0">
641        <img src="//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxNDM1MDAxX3hwbG92YV9sb2dvXzEwMC5wbmcucG5nIl1d.png?sha=2390923483f0eb3f" height="32" width="auto" alt="logo">
642      </a>
643      <button class="drawer-toggle qk-pos--abs qk-bg--transparent qk-pd--0"></button>
644    </li>
645  
646  
647    
648
649    
650      <!-- cyb_snippet components/side_menu/menu start -->
651
652  <li class="category_title qk-fs--breadcrumb qk-bd--nav_menu_text qk-text--nav_menu_text qk-bd_b--default qk-fw--500">主選單</li>
653
654
655  
656  
657  
658    <li class="qk-pos--rel qk-pd--0">
659      
660        <a class="qk-fw--bold qk-display--il_bk qk-w--100 qk-text--left qk-fs--body qk-bg--nav_menu_bg qk-text--nav_menu_text" href="/">Home</a>
661      
662    </li>
663  
664
665  
666  
667  
668    <li class="qk-pos--rel qk-pd--0">
669      <button class="linklist bt-toggle qk-fw--bold  qk-display--il_bk qk-w--100 qk-text--left qk-fs--body qk-text--nav_menu_text qk-bg--nav_menu_bg qk-pos--rel" data-toggle="collapse" data-target=".collapse_index_sidebar_2" aria-expanded=" true ">
670        
671          <span class="qk-cursor--pointer qk-text--nav_menu_text"> Updates </span>
672        
673      </button>
674      <ul id="index_sidebar_shelf_second_2" class="collapse_index_sidebar_2 collapse shelf_second  show  qk-pd--0">
675        
676          
677          
678          
679            <li class="qk-pos--rel qk-pd--0">
680              
681                <a class="qk-fw--500 qk-display--il_bk qk-w--100 qk-text--left qk-fs--body qk-bg--nav_menu_bg qk-text--nav_menu_text" href="/blogs/announcement">
682                  Announcement
683                </a>
684              
685            </li>
686          
687        
688          
689          
690          
691            <li class="qk-pos--rel qk-pd--0">
692              
693                <a class="qk-fw--500 qk-display--il_bk qk-w--100 qk-text--left qk-fs--body qk-bg--nav_menu_bg qk-text--nav_menu_text" href="/blogs/news">
694                  News
695                </a>
696              
697            </li>
698          
699        
700      </ul>
701    </li>
702  
703
704  
705  
706  
707    <!-- cyb_snippet components/side_menu/collection_all start -->
708
709
710
711
712  <li class="qk-pos--rel qk-pd--0">
713    <button class="collection_all bt-toggle  qk-display--il_bk qk-w--100 qk-text--left qk-bg--nav_menu_bg qk-bd--none qk-pos--rel qk-fw--bold" data-toggle="collapse" data-target=".collapse_collection_all_index_sidebar_3" aria-expanded=" true ">
714      <a href="/collections/all" class="collection_all_link qk-display--il_bk qk-text--left qk-fs--body qk-fw--bold qk-bg--nav_menu_bg qk-text--nav_menu_text">
715        Products
716      </a>
717    </button>
718    <ul id="index_sidebar_collection_all_shelf_second_3" class="collapse_collection_all_index_sidebar_3 collapse shelf_second qk-pd--0  show ">
719      
720        
721        
722        <li class="qk-pos--rel qk-pd--0">
723          <button class="collection_all qk-fw--500 bt-toggle  qk-display--il_bk qk-w--100 qk-text--left qk-fs--body qk-bg--nav_menu_bg " data-toggle="collapse" data-target=".collapse_collection_all_index_sidebar_3_1" aria-expanded=" true ">
724            <a href="/collections/xplova" class="qk-fw--500 collection_all_link qk-display--il_bk qk-text--left qk-fs--body qk-text--nav_menu_text">
725              All
726            </a>
727          </button>
728          <ul class="qk-bd--nav_menu_text collapse_collection_all_index_sidebar_3_1 collapse shelf_third q
728k-pd--0 show  ">
729            
730              <li class="qk-pos--rel qk-pd--0">
731                <a class="qk-fw--500 qk-display--il_bk qk-w--100 qk-text--left qk-text--nav_menu_text qk-bg--nav_menu_bg qk-fs--body" href="/products/x2">X2 - Smart Cycling Computer</a>
732              </li>
733            
734              <li class="qk-pos--rel qk-pd--0">
735                <a class="qk-fw--500 qk-display--il_bk qk-w--100 qk-text--left qk-text--nav_menu_text qk-bg--nav_menu_bg qk-fs--body" href="/products/mp1">MP1 - Smart Tire Inflator</a>
736              </li>
737            
738              <li class="qk-pos--rel qk-pd--0">
739                <a class="qk-fw--500 qk-display--il_bk qk-w--100 qk-text--left qk-text--nav_menu_text qk-bg--nav_menu_bg qk-fs--body" href="/products/noza-p1-v2">Noza P1(v2) - Power Meter</a>
740              </li>
741            
742              <li class="qk-pos--rel qk-pd--0">
743                <a class="qk-fw--500 qk-display--il_bk qk-w--100 qk-text--left qk-text--nav_menu_text qk-bg--nav_menu_bg qk-fs--body" href="/products/noza-one">Noza One - Bike Power Trainer</a>
744              </li>
745            
746              <li class="qk-pos--rel qk-pd--0">
747                <a class="qk-fw--500 qk-display--il_bk qk-w--100 qk-text--left qk-text--nav_menu_text qk-bg--nav_menu_bg qk-fs--body" href="/products/noza-s">Noza S - Interactive Smart Trainer</a>
748              </li>
749            
750              <li class="qk-pos--rel qk-pd--0">
751                <a class="qk-fw--500 qk-display--il_bk qk-w--100 qk-text--left qk-text--nav_menu_text qk-bg--nav_menu_bg qk-fs--body" href="/products/noza-v">Noza V - Advanced Smart Trainer</a>
752              </li>
753            
754          </ul>
755        </li>
756      
757        
758        
759        <li class="qk-pos--rel qk-pd--0">
760          <button class="collection_all qk-fw--500 bt-toggle  qk-display--il_bk qk-w--100 qk-text--left qk-fs--body qk-bg--nav_menu_bg " data-toggle="collapse" data-target=".collapse_collection_all_index_sidebar_3_2" aria-expanded=" true ">
761            <a href="/collections/accessories" class="qk-fw--500 collection_all_link qk-display--il_bk qk-text--left qk-fs--body qk-text--nav_menu_text">
762              Cycling Accessories
763            </a>
764          </button>
765          <ul class="qk-bd--nav_menu_text collapse_collection_all_index_sidebar_3_2 collapse shelf_third qk-pd--0 show  ">
766            
767              <li class="qk-pos--rel qk-pd--0">
768                <a class="qk-fw--500 qk-display--il_bk qk-w--100 qk-text--left qk-text--nav_menu_text qk-bg--nav_menu_bg qk-fs--body" href="/products/mp1">MP1 - Smart Tire Inflator</a>
769              </li>
770            
771              <li class="qk-pos--rel qk-pd--0">
772                <a class="qk-fw--500 qk-display--il_bk qk-w--100 qk-text--left qk-text--nav_menu_text qk-bg--nav_menu_bg qk-fs--body" href="/products/x2">X2 - Smart Cycling Computer</a>
773              </li>
774            
775          </ul>
776        </li>
777      
778        
779        
780        <li class="qk-pos--rel qk-pd--0">
781          <button class="collection_all qk-fw--500 bt-toggle  qk-display--il_bk qk-w--100 qk-text--left qk-fs--body qk-bg--nav_menu_bg " data-toggle="collapse" data-target=".collapse_collection_all_index_sidebar_3_3" aria-expanded=" true ">
782            <a href="/collections/trainer" class="qk-fw--500 collection_all_link qk-display--il_bk qk-text--left qk-fs--body qk-text--nav_menu_text">
783              Smart Trainer
784            </a>
785          </button>
786          <ul class="qk-bd--nav_menu_text collapse_collection_all_index_sidebar_3_3 collapse shelf_third qk-pd--0 show  ">
787            
788              <li class="qk-pos--rel qk-pd--0">
789                <a class="qk-fw--500 qk-display--il_bk qk-w--100 qk-text--left qk-text--nav_menu_text qk-bg--nav_menu_bg qk-fs--body" href="/products/noza-p1-v2">Noza P1(v2) - Power Meter</a>
790              </li>
791            
792              <li class="qk-pos--rel qk-pd--0">
793                <a class="qk-fw--500 qk-display--il_bk qk-w--100 qk-text--left qk-text--nav_menu_text qk-bg--nav_menu_bg qk-fs--body" href="/products/noza-one">Noza One - Bike Power Trainer</a>
794              </li>
795            
796              <li class="qk-pos--rel qk-pd--0">
797                <a class="qk-fw--500 qk-display--il_bk qk-w--100 qk-text--left qk-text--nav_menu_text qk-bg--nav_menu_bg qk-fs--body" href="/products/noza-s">Noza S - Interactive Smart Trainer</a>
798              </li>
799            
800              <li class="qk-pos--rel qk-pd--0">
801                <a class="qk-fw--500 qk-display--il_bk qk-w--100 qk-text--left qk-text--nav_menu_text qk-bg--nav_menu_bg qk-fs--body" href="/products/noza-v">Noza V - Advanced Smart Trainer</a>
802              </li>
803            
804          </ul>
805        </li>
806      
807    </ul>
808  </li>
809
810
811<!-- cyb_snippet components/side_menu/collection_all end -->
812  
813
814  
815  
816  
817    <li class="qk-pos--rel qk-pd--0">
818      
819        <a class="qk-fw--bold qk-display--il_bk qk-w--100 qk-text--left qk-fs--body qk-bg--nav_menu_bg qk-text--nav_menu_text" href="/pages/wheretobuy">Where to Buy</a>
820      
821    </li>
822  
823
824  
825  
826  
827    <li class="qk-pos--rel qk-pd--0">
828      
829        <a class="qk-fw--bold qk-display--il_bk qk-w--100 qk-text--left qk-fs--body qk-bg--nav_menu_bg qk-text--nav_menu_text" href="/pages/about-us">About Us</a>
830      
831    </li>
832  
833
834
835<script>
836  $('button a').on('click', function(e) {e.stopPropagation()});
837</script>
837
838
839<!-- cyb_snippet components/side_menu/menu end -->
840    
841  
842  
843    
844      <li class="category_account-title qk-bd--nav_menu_text qk-fs--breadcrumb qk-text--nav_menu_text qk-bd_y--default qk-fw--500">Account</li>
845      <li class="qk-pos--rel qk-pd--0">
846        <div class="customer-logined-menu qk-display--il_bk qk-w--100 qk-text--left" style="display: none">
847          <a href="/en/account/index" class="qk-text--nav_menu_text qk-fw--bold qk-fs--body">My Account</a>
848        </div>
849      </li>
850      <li class="qk-pos--rel qk-pd--0">
851        <div class="customer-logined-menu qk-display--il_bk qk-w--100 qk-text--left" style="display: none">
852          <a href="/en/account/orders" class="qk-text--nav_menu_text qk-fw--bold qk-fs--body">My Order(s)</a>
853        </div>
854      </li>
855      <li class="qk-pos--rel qk-pd--0">
856        <div class="customer-logined-menu qk-display--il_bk qk-w--100 qk-text--left" style="display: none">
857          <a href="/en/account/logout" class="qk-text--nav_menu_text qk-fw--bold qk-fs--body">Logout</a>
858        </div>
859      </li>
860      <li class="qk-pos--rel qk-pd--0">
861        <a href="/en/account/login">
862          <div class="customer-not-login-menu qk-bd--nav_menu_text qk-bg--nav_menu_text customer-not-login-menu_login qk-display--il_flex qk-justify--center qk-align--center qk-w--100 qk-text--center ">
863            <span class="qk-text--nav_menu_bg qk-fw--500 qk-fs--body">
864              Log in
865            </span>
866          </div>
867        </a>
868      </li>
869      <li class="qk-pos--rel qk-pd--0">
870        <a href="/en/account/signup">
871          <div class="customer-not-login-menu qk-bd--nav_menu_text customer-not-login-menu_signup qk-display--il_flex qk-justify--center qk-align--center qk-w--100 qk-text--center qk-bd--nav_menu_text qk-bd--default">
872            <span class="qk-text--nav_menu_text qk-fs--body qk-fw--500">
873              Sign up
874            </span>
875          </div>
876        </a>
877      </li>
878    
879    
880    
881    
882      <li class="category_title qk-bd--nav_menu_text qk-fs--breadcrumb qk-text--nav_menu_text qk-bd_y--default qk-fw--500">
883        
884          Language
885        
886        
887          |
888        
889        
890          Currency
891        
892      </li>
893      <li id="side-menu-modal__button" class="qk-text--nav_menu_text qk-fw--bold language_button qk-fs--body qk-text--nav_menu_text">
894      </li>
895    
896  
897</ul>
898
899<link href='//cdn-general.cybassets.com/frontend/shop/beta_theme/css/sidebar-3a2e378145f8a165.css' rel='stylesheet' type='text/css' media='all' />
900
901<script>
902  $(document).ready(function(){
903    // 側邊選單
904    if ($('.drawer').length){
905      $('.drawer').drawer();
906      $('.bt-toggle').click(function(){
907        setTimeout(function(){
908          $('.drawer')[0].iScroll.refresh()
909        },500)
910      })
911    }
912  });
913</script>
913
914
915<script>
916  $(document).ready(function(){
917    const languageSize = 3
918    const currencySize = 1
919
920    const initLanguageAndCurrency = ({language,code})=> {
921      const contentSelector = $("#side-menu-modal__button");
922      let content = ''
923      const isMutipleCurrencies = true
924      const isMultiLanguages = true
925      if ( isMultiLanguages && languageSize > 1 ) content = language || (liquidHelper.language && liquidHelper.language.title)
926      if ( isMutipleCurrencies && (code && content === '')) content = code
927      else if (isMutipleCurrencies && (code && content !=='')) content = `${content}|${code}`
928      contentSelector.text(content)
929    }
930
931    let code = ''
932    let language = ''
933    if (liquidHelper.language) language  = liquidHelper.language
934    if (liquidHelper.getCurrency()) code = liquidHelper.getCurrency().code
935
936    initLanguageAndCurrency({ language:language.title, code })
937
938    $("#side-menu-modal__button").click(function() {
939      const clickable = languageSize > 1 || currencySize > 1
940      if (clickable) {
941        $('.drawer').drawer('close');
942        const event = new CustomEvent("i18n_selector_clicked");
943        document.dispatchEvent(event);
944      }
945    });
946
947    document.addEventListener('i18n_modal_confirmed', (e) => {
948      const { languageTitle, currency } = e.detail;
949      initLanguageAndCurrency({ language: languageTitle, code: currency });
950    });
951  });
952
953</script>
953
954
955
956<!-- cyb_snippet side_menu end -->
957
958        </div>
959      </nav>
960      <!-- Bottombar -->
961      
962    
963  </span>
964
965<div id="index-popular-tags"></div>
966
967<style id="timer_color">
968  :root {
969    
970      --timer_text: #c39d6f;
971    
972
973    
974      --timer_bg: #2b2b6e;
975    
976  }
977</style>
978
979<script>
980  window.language = {"account_name":"Bank Account Name","add_cart_error_try_again":"Network error, please try again.","add_to_cart":"ADD TO CART","addcart_rate_limit_desc":"seconds until you can try again. We recommend staying on this page.","address1":"Return Address","all_filters":"All Filters","apply_fail":"Application Failed","apply_return":"Return Application","apply_return_success":"Refund Request Sent","apply_success":"Successful Application","arrive_soon":"Arriving Soon","articles_total":"Total of {{ totalArticleCounts }} Articles","bank_account":"Bank Account","bank_branch_name":"Name of Branch","bonus_redemption":"Exchange Credit Point(s)","cancel":"Cancel","cart_price_total":"Total","check_order":"My Order(s)","choose_branch_bank":"Select Bank Branch","choose_return_reason":"Select Return Reason","city":"City","common_price":"Retail Price","comply_group_number":"Comply {{comply_group_number}} group(s) of discount, ","confirm":"Confirm","confirm_return":"Apply Refund","confirm_submit":"Submit","congratulations_for_verify_mobile_success":"Congratulations, you've successfully verified your phone!","contact_form":"Contact Form","continue_reading":"Continue Reading","country_placeholder":"Select country","coupon_free_shipping":"Free Shipping Coupon","coupon_items":"Coupon Discount Item","date_error":"Date error","default_sort":"Store Recommendations","deliver_error":"Delivery Error","discount_detail":"Discount Details","email":"Email Address","email_placeholder":"Enter your email, e.g.: [email protected]","enter_account_name":"Enter bank account name","enter_bank_account":"Enter bank account number","enter_return_reason":"Please specify the return reason","error_message":"An error has occurred when sending a verification message; please try again later.","fail_operation":"Something went wrong; please try again later!","filter_button":"Filter","filter_no_result":"Sorry, no results","free":"Free","gift_price":"Add-on Price","gift_purchase":"Gift with purchase","go_check_email":"Please check your mailbox; we've just sent you an email.","group_percent_discount":"{{percent_discount}} % off item(s) in the group.","has_stock":"In Stock","include_discount_and_shipping_fee":"Including discount and shipping fee","invalid_email":"Invalid Email","invalid_name":"Name required","invalid_phone_number":"Phone Number Required","invalid_question_content":"Please enter your message","keep_shopping":"Keep Shopping","keyin_address1":"Please enter the address we should collect the returning goods","keyin_city":"Please enter city name","keyin_zip":"Please enter postal code","less_then_one":"Quantity must be greater than 0; please select the amount to purchase.","line_item_quantity":"Quantity: {{ lineItemQuantity }}","literal_points":"point(s)","login_btn":"Log in","mail_send_fail":"Failed to send mail.","message_confirmation_token_error":"Error in verification code.","messenger_error_please_try_again":"An error has occurred when sending the message; please try again later.","mobile_number_error":"Mobile phone number in error.","name":"Name","name_placeholder":"Enter your name","new_password_is_sent":"New password is sent.","new_product_defect":"Defect on New Product","nn_collection_save_more_money_title":"for {{price}}","no_stock":"Out of Stock","notification_enabled":"Notification Enabled","notify_me_when_stock_arrives":"Sold out!","onsale":"On Sale","order_date":"Order Date","order_number":"Order Number","order_retrun_confirm":"Are you sure you want to request a refund?","ori_price":"Original Price","others":"Others","over_cart_limit":"Quantity exceeds shopping cart limit; please remove some items and place the order again.","over_product_quantity":"Quantity exceeds the purchase limit; please reduce the quantity selected.","over_stock_count":"Quantity exceeds inventory stock. Remaining {{ count }}","over_stock_quantity":"The quantity entered exceeds the stock quantity. Please decrease your order.","phone_number":"Phone Number","phone_number_placeholder":"Enter your phone number","piece":"{{quantity}} item(s)","please_choose_bank":"Select Bank","please_choose_product":"Please select specifications.","please_choose_variant":"Please select specifications","please_enter_number":"Please enter a number.","please_reselect":"Try removing some filters to 
980see more items","please_send_and_confirm_verify_code":"Please send and confirm the verification code.","pre_order":"Pre-order Goods","price_asc":"Price Low To High","price_desc":"Price High To Low","price_filter":"Price","price_includes_tax":"(includes consumption tax of {{ tax }})","product_content_defect":"Wrong Product or Incomplete Product","product_defect":"Defective Product","product_limit_buy":"Limited purchase of this product {{ count }} items","product_rate_limit_btn":"Re-enter product page","product_rate_limit_desc":"seconds until you can re-enter the product page. We recommend staying on this page.","product_rate_limit_title":"High demand right now, please wait","product_rate_limit_warn":"Leaving this page may increase your wait time.","product_sold":"Sold {{ productSold }} products","products_total":"Total of {{ totalProductCounts }} Products","quantity":"Quantity","quantity_over_product_stock":"The quantity entered exceeds available product stock. Please decrease your order.","question_content":"Message","question_content_placeholder":"Please enter your message","question_submit_fail":"Something went wrong; please try again later!","question_submit_success":"The question has been sent successfully. We will contact you as soon as possible!","question_type":"Question Type","reached_favorable":"Promotion Reached","recent_days_sold_desc":"Best Seller","reenter_password_still_error":"Error: Password does not match.","refund":"Refund Amount","refund_account":"Refund Account","refund_info":"Refund Information","refund_invoice_check":"I agree to the cancellation of the invoice or the \"Tax Payment Certificate\", and give consent to {{ envoiceCompanyName }} to be handled at discretion in order to expedite the refund process.","resend_verify_code":"Resend verification code.","reset_all_filters":"Reset All Filters","reset_filter_button":"Reset Filter","return":"Return","return_address":"Return Address","return_email_notification":"A copy of the refund details have been sent to your email","return_info":"Return Information","return_instruction":"Return Information","return_msg_Australia":"1. If any defects or breakages are found upon receiving the goods, and you need to apply for an exchange or refund, please enter \"My Account\", find your order and click \"View Status\", then click on \"Apply Refund\" as soon as possible.\u003cbr\u003e 2. After receiving the refund application, we will contact you to retrieve the goods. If you have any return questions, you can leave a message to the shop on the \"Order(s)\" page. Please do not send back the goods before confirming with the shop.\u003cbr\u003e 3. When returning or exchanging goods, please keep the original package intact (including purchased goods, accessories, gifts, etc.).\u003cbr\u003e 4. Once your returned item is received and inspected, an exchange or a refund will be made according to the shop's return policy.\u003cbr\u003e 5. Please refer to the shop's return policy for detailed information and guidance.\u003cbr\u003e","return_msg_Japan":"1. If any defects or breakages are found upon receiving the goods, and you need to apply for an exchange or refund, please enter \"My Account\", find your order and click \"View Status\", then click on \"Apply Refund\" as soon as possible. Please refer to the shop's return policy for detailed information and guidance.\u003cbr\u003e 2. When returning or exchanging goods, please keep the original package intact (including purchased goods, accessories, gifts, etc.).\u003cbr\u003e 3. After receiving the refund application, we will contact you to retrieve the goods. \u003cbr\u003e 4. If you have any return questions, you can leave a message to the shop on the \"Order(s)\" page. Please do not send back the goods before confirming with the shop.\u003cbr\u003e 5. Once your returned item is received and inspected, an exchange or a refund will be made according to the shop's return policy.\u003cbr\u003e","return_msg_Japan_to_Taiwan":"1. If any defects or breakages are found upon receiving the goods, and you need to apply for an exchange or refund, please enter \"My Account\", find your order and click \"View Status\", then click on \"Apply Refund\" as soon as possible. Please refer to the shop's return policy for detailed information and guidance.\u003cbr\u003e 2. When returning or exchanging goods, please keep the original package intact (including purchased goods, accessories, gifts, etc.).\u003cbr\u003e 3. After receiving the refund application, we will c
980ontact you to retrieve the goods. \u003cbr\u003e 4. If you have any return questions, you can leave a message to the shop on the \"Order(s)\" page. Please do not send back the goods before confirming with the shop.\u003cbr\u003e 5. Once your returned item is received and inspected, an exchange or a refund will be made according to the shop's return policy.\u003cbr\u003e","return_msg_SEA":"1. If any defects or breakages are found upon receiving the goods, and you need to apply for an exchange or refund, please enter \"My Account\", find your order and click \"View Status\", then click on \"Apply Refund\" as soon as possible. Please refer to the shop's return policy for detailed information and guidance.\u003cbr\u003e 2. When returning or exchanging goods, please keep the original package intact (including purchased goods, accessories, gifts, etc.).\u003cbr\u003e 3. After receiving the refund application, we will contact you to retrieve the goods. \u003cbr\u003e 4. If you have any return questions, you can leave a message to the shop on the \"Order(s)\" page. Please do not send back the goods before confirming with the shop.\u003cbr\u003e 5. Once your returned item is received and inspected, an exchange or a refund will be made according to the shop's return policy.\u003cbr\u003e","return_msg_Taiwan":"1. If any defects or breakages are found upon receiving the goods, and you need to apply for an exchange or refund, please enter to \" My Account\", find your order and click \"My Order(s)\", then click on \"Apply Refund\" as soon as possible. Please refer to the shop's return policy for detailed information and guidance.\u003cbr\u003e 2. When returning or exchanging goods, please keep the original package intact (including purchased goods, accessories, gifts, etc.).\u003cbr\u003e 3. After receiving the refund application, we will contact you to retrieve the goods. If you have any return questions, you can click \"Message Shop\" on the \"My Order(s)\" page. Please do not send back the goods by yourself.\u003cbr\u003e 4. Please print this application form and send it with the goods.\u003cbr\u003e 5. Once your returned item is received and reviewed, a refund will be made to your original payment method; it would take up to 5 to 10 days until it shows on your bank statement.\u003cbr\u003e","return_msg_USA":"1. If any defects or breakages are found upon receiving the goods, and you need to apply for an exchange or refund, please enter \"My Account\", find your order and click \"View Status\", then click on \"Apply Refund\" as soon as possible. Please refer to the shop's return policy for detailed information and guidance.\u003cbr\u003e 2. When returning or exchanging goods, please keep the original package intact (including purchased goods, accessories, gifts, etc.).\u003cbr\u003e 3. After receiving the refund application, we will contact you to retrieve the goods. \u003cbr\u003e 4. If you have any return questions, you can leave a message to the shop on the \"Order(s)\" page. Please do not send back the goods before confirming with the shop.\u003cbr\u003e 5. Once your returned item is received and inspected, an exchange or a refund will be made according to the shop's return policy.\u003cbr\u003e","return_product":"Product Return Request","return_reason":"Return Reason","save_more_money_discount":"to enjoy {{percent_discount}}% off.","save_more_money_dollar":"Get {{dollar}} discount","search_article_label":"Article results ({{ totalArticleCounts }})","search_no_result":"Sorry, no results found by searching: {{ queryString }}. Please try a different word.","search_product_label":"Product results ({{ totalProductCounts }})","search_total":"Search: {{ queryString }} / {{ totalSearchCount }} item(s) found","select_sort_by":"Sort By","sell_from_asc":"Listing date, old to new","sell_from_desc":"Listing date, new to old","send_too_many_times_try_again_later":"Sent too many times, please try again later.","sending_msg_few_minutes_get":"SMS sending… You'll receive a verification code in a few minutes.","shipping_fee":"Shipping Fee","sold_out":"Sold Out","state_placeholder":"Select state / province","submit":"Submit","subtotal":"Subtotal","success_operation":"Message Sent!","successfully_copy_tracking_number":"Tracking number copied successfully","system_busy_try_again":"System busy; please try again later.","tax":"Tax","thanks_for_advise":"Thanks for your feedback.","thanks_you_have_signed_up":"Thanks for registering!","total_bonus_redemption":"Total Credit Point(s) Redemption","tw_city_placeholder":"County / City","tw_district_placeholder":"District","unreach_favorable":"Promotion Unreached","verification_error_please_correct":"Error during verification, please try again.","verify_success":"Verification code confirmed.","view_product":"View Product","vip_shipping_free":"Free Shipping For Members","zip":"ZIP / Postcode"}
981  $(document).ready(function(){
982    if(window.location.pathname != '' && window.location.pathname != '/' ){
983      document.getElementById('index-popular-tags').style.display = 'none'
984    }
985    // 倒數計時
986    
987
988    function adjustContentTop() {
989      
990      const isNavbarTransparent = false;
991      let headerHeight = $("#header").outerHeight();
992      if (isNavbarTransparent && $('#template').width() >= 992) {
993        headerHeight -= $('.computer_nav').height();
994      }
995      const floatFilterHeight = $('#float-filter').innerHeight() || 0;
996      $("body").css({
997        "padding-top": (headerHeight - floatFilterHeight) + "px",
998      });
999    }
1000
1001    window.adjustContentTop = adjustContentTop;
1002
1003    // navbar設定透明
1004    
1005
1006    // Call it first once DOM is ready to prevent CLS
1007    adjustContentTop();
1008
1009    // 延遲初始化,等待 app banner 初始化完成
1010    $(window).on("resize", adjustContentTop);
1011
1012    // 使用 setTimeout 確保 banner 狀態已經確定
1013    $(window).on("load", function() {
1014      setTimeout(function() {
1015        adjustContentTop();
1016      }, 200); // 給 banner 足夠時間初始化
1017    });
1018
1019    $('img.header_banner').on('load', adjustContentTop);
1020
1021    window.renderNavbarSection('.main_nav', {
1022        navbarCollections: [{"title":"All","url":"/collections/xplova","products":[{"title":"X2 - Smart Cycling Computer","url":"/products/x2"},{"title":"MP1 - Smart Tire Inflator","url":"/products/mp1"},{"title":"Noza P1(v2) - Power Meter","url":"/products/noza-p1-v2"},{"title":"Noza One - Bike Power Trainer","url":"/products/noza-one"},{"title":"Noza S - Interactive Smart Trainer","url":"/products/noza-s"},{"title":"Noza V - Advanced Smart Trainer","url":"/products/noza-v"}]},{"title":"Cycling Accessories","url":"/collections/accessories","products":[{"title":"MP1 - Smart Tire Inflator","url":"/products/mp1"},{"title":"X2 - Smart Cycling Computer","url":"/products/x2"}]},{"title":"Smart Trainer","url":"/collections/trainer","products":[{"title":"Noza P1(v2) - Power Meter","url":"/products/noza-p1-v2"},{"title":"Noza One - Bike Power Trainer","url":"/products/noza-one"},{"title":"Noza S - Interactive Smart Trainer","url":"/products/noza-s"},{"title":"Noza V - Advanced Smart Trainer","url":"/products/noza-v"}]}],
1023        navbarItems: [{"id":1703959,"title":"Home","url":"/","item_type":"frontpage","subtitle":null,"icon_image_url":null,"menuItems":null},{"id":1720808,"title":"Updates","url":"","item_type":"linklist","subtitle":null,"icon_image_url":null,"menuItems":[{"id":1720814,"title":"Announcement","url":"/blogs/announcement","item_type":"blog","subtitle":null,"icon_image_url":null,"menuItems":null},{"id":1720815,"title":"News","url":"/blogs/news","item_type":"blog","subtitle":null,"icon_image_url":null,"menuItems":null}]},{"id":1703960,"title":"Products","url":"/collections/all","item_type":"collections_all","subtitle":null,"icon_image_url":null,"menuItems":null},{"id":1708274,"title":"Where to Buy","url":"/pages/wheretobuy","item_type":"page","subtitle":null,"icon_image_url":null,"menuItems":null},{"id":1703962,"title":"About Us","url":"/pages/about-us","item_type":"page","subtitle":null,"icon_image_url":null,"menuItems":null}],
1024        settings: {
1025          menuDisplayStyle: "three_dimension_menu",
1026          pcLogoImgUrl: "//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxNDM1MDAxX3hwbG92YV9sb2dvXzEwMC5wbmcucG5nIl1d.png?sha=2390923483f0eb3f",
1027          mobileLogoImgUrl: "//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL2F0dGFjaGVkX3Bob3Rvcy8xNzUxNDM1MDAxX3hwbG92YV9sb2dvXzEwMC5wbmcucG5nIl1d.png?sha=2390923483f0eb3f",
1028          navbarDisplayStyle: "rowNav",
1029        }
1030      }
1031    );
1032
1033
1034    // for link menu
1035    const linkMenuElement = document.querySelector('.link-nav');
1036    const data = []
1037    data.forEach((item) => {
1038      const wrapper = document.createElement('a');
1039      const link = document.createElement('ul');
1040
1041      wrapper.href = item.url;
1042      link.textContent = item.title;
1043      link.classList.add('link-item');
1044
1045      wrapper.appendChild(link);
1046      linkMenuElement.appendChild(wrapper);
1047    });
1048
1049    // for safe-area space on iOS devices
1050    const userAgent = navigator.userAgent;
1051    const isIOS = /iPad|iPhone|iPod/.test(userAgent) && !window.MSStream;
1052    const isLiff = /Line\/[\d.]+/i.test(userAgent);
1053    const $mobileBottomBar = $('#mobile-bottom-bar');
1054
1055    if ($mobileBottomBar.length && isIOS && isLiff) {
1056      $mobileBottomBar.addClass('is-ios-liff');
1057    }
1058  });
1059  document.addEventListener('DOMContentLoaded', function() {
1060    window.getCartAmount = function() {
1061      return parseInt($('.global-cart-count').html());
1062    };
1063  });
1064</script>
1064
1065
1066<script src='//cdn-general.cybassets.com/frontend/shop/beta_theme/js/navbar-3a2e378145f8a165.js' type='text/javascript'></script>
vendor: 1 bytes, line 1066
1066
1067<script src='//cdn-general.cybassets.com/frontend/shop/beta_theme/js/currencies-3a2e378145f8a165.js' type='text/javascript'></script>
1067
1068<!-- cyb_snippet i18n_modal start -->
1069
1070  
1070<script src='//cdn-general.cybassets.com/frontend/shop/i18nSetting-3a2e378145f8a165.js' type='text/javascript'></script>
1070
1071  
1071<script type="text/javascript">
1072    $(document).ready(function() {
1073      const props = {
1074        isMultiLanguages: true,
1075        isMultiCurrencies: true,
1076      }
1077      
1078        props.languageOptions = [{"handle":"zh-TW","title":"繁體中文","currency_code":"TWD"},{"handle":"en","title":"English","currency_code":"USD"},{"handle":"ja","title":"日本語","currency_code":"JPY"}]
1079      
1080      
1081        props.currencyOptions = [{"code":"TWD","money_format":"%u%n","decimal_precision":0,"email":"NT${{amount_no_decimals}}","unit":"","symbol":"NT$","email_unit":"NT${{amount_no_decimals}}","html_unit":"NT${{amount_no_decimals}}","format":"NT${{amount_no_decimals}}","html":"NT${{amount_no_decimals}}","trailing_zeros":false,"name":"新台幣 (TWD)"}]
1082      
1083      window.renderI18nSetting('.i18n-selector', props)
1084    })
1085  </script>
1085
1086
1087
1088<!-- cyb_snippet i18n_modal end -->
1089<!-- cyb_snippet _load_fonts start -->
1090<script src='//cdn-general.cybassets.com/frontend/shop/beta_theme/js/load_fonts-3a2e378145f8a165.js' type='text/javascript'></script>
vendor: 1 bytes, line 1090
1090
1091<script>
1092  document.addEventListener('DOMContentLoaded', function() {
1093    window.loadFontSetting("{'ja':{'value':'Noto Sans JP'},'zh-TW':{'value':'Noto Sans TC'},'en':{'value':'Noto Sans TC'},'zh-CN':{'value':'Noto Sans TC'}}")
1094  })
1095</script>
1095
1096
1097<!-- cyb_snippet _load_fonts end -->
1098<!-- cyb_snippet _custom_icon start -->
1099<script src='//cdn-general.cybassets.com/frontend/shop/navIcon-3a2e378145f8a165.js' type='text/javascript'></script>
1099
1100
1101<script>
1102  (function() {
1103    const iconUrlMap = new Map([
1104      ['custom_icon_type_home', null],
1105      ['custom_icon_type_tracking_items', null],
1106      ['custom_icon_type_account', null],
1107      ['custom_icon_type_cart', null],
1108      ['custom_icon_type_search', null],
1109      ['custom_icon_type_menu', null]
1110    ]);
1111    const elements = document.querySelectorAll('[data-icon-type]');
1112    elements.forEach((element, index) => {
1113      const iconAttributes = element.getAttribute('data-icon-type');
1114
1115      const uniqueId = `icon_${iconAttributes}_${index}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
1116      element.id = uniqueId;
1117      window.renderNavCustomIcon(`#${uniqueId}`, {
1118        navIconStyle: "icon_type_rounded",
1119        customIconUrl: iconUrlMap.get(iconAttributes) || '',
1120        iconAttributes: iconAttributes,
1121        currentTemplate: "product",
1122      });
1123    });
1124  })();
1125</script>
1125
1126
1127<!-- cyb_snippet _custom_icon end -->
1128
1129
1130
1131    
1132  
1133    
1133<script src='//cdn-general.cybassets.com/frontend/shop/announcementBar-3a2e378145f8a165.js' type='text/javascript'></script>
1133
1134
1135    
1136
1137    
1138
1139    
1139<script>
1140      $(document).ready(function() {
1141        window.renderAnnouncementBar('#announcement-bar', {
1142          sectionId: "announcement_bar",
1143          isIndex: false,
1144        });
1145      });
1146    </script>
1146
1147  
1148
1149
1150
1151
1152
1153    <!-- template -->
1154    <div id="template" style="flex:1 0 auto; background-color: var(--theme_bg);">
1155      <!-- cyb_snippet breadcrumb start -->
1156
1157<link href='//cdn-general.cybassets.com/frontend/shop/beta_theme/css/breadcrumb-3a2e378145f8a165.css' rel='stylesheet' type='text/css' media='all' />
1158
1159
1160<div id="site_path" class="qk-bd_b--default qk-bd--product_border">
1161  <!-- mobile: toggle button (hidden on PC) -->
1162  <div class="qk-container qk-hidden--pc">
1163    <div class="breadcrumb qk-bg--theme_bg qk-pd_x--0 qk-mg--0 qk-fs--breadcrumb">
1164      <button
1165        class="bt-toggle qk-bg--theme_bg qk-pd_x--0 qk-w--100 qk-text--left qk-bd--none qk-pos--rel collapsed"
1166        data-toggle="collapse"
1167        data-target=".breadcrumb-content"
1168      >
1169        <a href="/" class="qk-text--text">
1170          <i class="fas fa-home"></i>
1171        </a>
1172      </button>
1173    </div>
1174  </div>
1175  <!-- breadcrumb nav: single DOM, PC always visible, mobile as collapse dropdown -->
1176  <div class="breadcrumb-content qk-bg--theme_bg collapse">
1177    <div class="qk-container">
1178      <!-- cyb_snippet breadcrumb_nav start -->
1179<!-- 主題版型麵包屑 -->
1180<nav aria-label="breadcrumb">
1181  <ol
1182    class="breadcrumb qk-bg--theme_bg qk-pd_x--0 qk-mg--0 qk-fs--breadcrumb"
1183    itemscope
1184    itemtype="http://schema.org/BreadcrumbList"
1185  >
1186    
1187      <li
1188        class="breadcrumb-item
1189        
1190        "
1191        itemprop="itemListElement"
1192        itemscope itemtype="http://schema.org/ListItem">
1193        <!-- home -->
1194        
1195          <a href="/" class="qk-text--text" itemprop="item">
1196            <i class="fas fa-home"></i>
1197            <span class="qk-display--none" itemprop="name">Home</span>
1198          </a>
1199        <!-- account -->
1200        
1201        <meta itemprop="position" content="1"/>
1202      </li>
1203    
1204      <li
1205        class="breadcrumb-item
1206        
1207        "
1208        itemprop="itemListElement"
1209        itemscope itemtype="http://schema.org/ListItem">
1210        <!-- home -->
1211        
1212          
1213            <a href="#" itemprop="item" style="display: none;">
1214              <span itemprop="name">商品</span>
1215            </a>
1216          
1217          
1218            <span class="qk-text--text" data-breadcrumb-links>
1219              <a href='/collections/xplova' class='qk-text--text' itemprop='item'><span itemprop='name'>All</span></a>, <a href='/collections/accessories' class='qk-text--text' itemprop='item'><span itemprop='name'>Cycling Accessories</span></a>
1220            </span>
1221          
1222        <!-- product -->
1223        
1224        <meta itemprop="position" content="2"/>
1225      </li>
1226    
1227      <li
1228        class="breadcrumb-item
1229        
1230         active "
1231        itemprop="itemListElement"
1232        itemscope itemtype="http://schema.org/ListItem">
1233        <!-- home -->
1234        
1235          <a href="/en/products/x2" class="qk-text--text" itemprop="item">
1236            <span itemprop="name">X2 - Smart Cycling Computer</span>
1237          </a>
1238        <!-- search -->
1239        
1240        <meta itemprop="position" content="3"/>
1241      </li>
1242    
1243  </ol>
1244</nav>
1245<script>
1246  $(document).ready(function () {
1247    if (!window.liquidHelper || !window.liquidHelper.hasBreadcrumbReferrerEnabled) return;
1248
1249    var $collections = $('[data-breadcrumb-links]');
1250    if (!$collections.length) return;
1251
1252    var refMatch = document.referrer.match(/\/collections\/([^/?#]+)/);
1253    if (!refMatch || refMatch[1] === 'all') return;
1254
1255    var referrerHandle = decodeURIComponent(refMatch[1]);
1256
1257    function getCollectionHandle(url) {
1258      if (!url) return null;
1259      try {
1260        var pathname = new URL(url, location.origin).pathname;
1261        var parts = pathname.split('/');
1262        var idx = parts.indexOf('collections');
1263        if (idx === -1 || !parts[idx + 1]) return null;
1264        return decodeURIComponent(parts[idx + 1]);
1265      } catch (e) {
1266        return null;
1267      }
1268    }
1269
1270    var $link = $collections.find('a').filter(function () {
1271      return getCollectionHandle(this.href) === referrerHandle;
1272    });
1273
1274    if ($link.length) {
1275      $collections.siblings('a.qk-text--accent[href="#"]').remove();
1276      $collections.empty().append($link);
1277    }
1278  });
1279</script>
1279
1280
1281<!-- cyb_snippet breadcrumb_nav end -->
1282    </div>
1283  </div>
1284</div>
1285
1286
1287<!-- cyb_snippet breadcrumb end -->
1288
1289<div id="img"></div>
1290
1291
1292
1293
1294
1295<script>
1296  var gallery_img = undefined;
1297  document.addEventListener("DOMContentLoaded", function(){
1298    gallery_img = renderGallery(
1299      '#img',
1300      {
1301        urls: ["//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL3Byb2R1Y3RzLzU4MDIxMzk1LzE3NTM5NTA3NzNfMGY5MDQ5MzhjYzU5YjNlNWE2ZTYucG5nIl0sWyJwIiwidGh1bWIiLCIyMDQ4eDIwNDgiXV0.png?sha=d2b8c5b29f716556","//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL3Byb2R1Y3RzLzU4MDIxMzk1LzE3NTM5NTE4OTZfY2JkNzYyYWY3N2EzZjZhMGQyNTIucG5nIl0sWyJwIiwidGh1bWIiLCIyMDQ4eDIwNDgiXV0.png?sha=412a7481e081846d","//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL3Byb2R1Y3RzLzU4MDIxMzk1LzE3NTM5NTE4OTZfMjdkYzc4MjhhZTI5OWRiZDU3NTEucG5nIl0sWyJwIiwidGh1bWIiLCIyMDQ4eDIwNDgiXV0.png?sha=076001ecd59b77f5","//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL3Byb2R1Y3RzLzU4MDIxMzk1LzE3NTM5NTE4OTZfNmE3NWNhNGQ1ZWEyOWEyMDc0MjgucG5nIl0sWyJwIiwidGh1bWIiLCIyMDQ4eDIwNDgiXV0.png?sha=496f495d10a31584"],
1302        onSwiperGalleryChange: function (payload) {
1303          var eventPayload = Object.assign({ galleryName: "img" }, payload);
1304          $(document).trigger('swiper-gallery-change', [eventPayload]);
1305        },
1306      },
1307    );
1308  });
1309</script>
1309
1310
1311<div id="product" class="product">
1312  <div class="qk-container">
1313    
1314
1315
1316
1317
1318
1319
1320 
1321
1322<div id="product_info" class="product_info qk-display--grid" data-purchase-eligibility='{"required":false,"eligible":true,"status":"eligible"}' data-hide-price="false" data-sales-mode-purchasable="true">
1323  <!-- product image start -->
1324  <div id="variant_photos" class="variant_photos">
1325    
1326    
1327    
1328    
1329    <variant-photos-block
1330      :product-photos-json="'[{\'id\':29316038,\'imageUrl\':\'//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL3Byb2R1Y3RzLzU4MDIxMzk1LzE3NTM5NTA3NzNfMGY5MDQ5MzhjYzU5YjNlNWE2ZTYucG5nIl0sWyJwIiwidGh1bWIiLCI2MDB4NjAwIl1d.png?sha=f82201060579a604\',\'imageMaxUrl\':\'//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL3Byb2R1Y3RzLzU4MDIxMzk1LzE3NTM5NTA3NzNfMGY5MDQ5MzhjYzU5YjNlNWE2ZTYucG5nIl0sWyJwIiwidGh1bWIiLCIyMDQ4eDIwNDgiXV0.png?sha=d2b8c5b29f716556\'}, {\'id\':29316549,\'imageUrl\':\'//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL3Byb2R1Y3RzLzU4MDIxMzk1LzE3NTM5NTE4OTZfY2JkNzYyYWY3N2EzZjZhMGQyNTIucG5nIl0sWyJwIiwidGh1bWIiLCI2MDB4NjAwIl1d.png?sha=3c0f70e89a2381cc\',\'imageMaxUrl\':\'//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL3Byb2R1Y3RzLzU4MDIxMzk1LzE3NTM5NTE4OTZfY2JkNzYyYWY3N2EzZjZhMGQyNTIucG5nIl0sWyJwIiwidGh1bWIiLCIyMDQ4eDIwNDgiXV0.png?sha=412a7481e081846d\'}, {\'id\':29316550,\'imageUrl\':\'//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL3Byb2R1Y3RzLzU4MDIxMzk1LzE3NTM5NTE4OTZfMjdkYzc4MjhhZTI5OWRiZDU3NTEucG5nIl0sWyJwIiwidGh1bWIiLCI2MDB4NjAwIl1d.png?sha=c993936f7498f4d1\',\'imageMaxUrl\':\'//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL3Byb2R1Y3RzLzU4MDIxMzk1LzE3NTM5NTE4OTZfMjdkYzc4MjhhZTI5OWRiZDU3NTEucG5nIl0sWyJwIiwidGh1bWIiLCIyMDQ4eDIwNDgiXV0.png?sha=076001ecd59b77f5\'}, {\'id\':29316551,\'imageUrl\':\'//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL3Byb2R1Y3RzLzU4MDIxMzk1LzE3NTM5NTE4OTZfNmE3NWNhNGQ1ZWEyOWEyMDc0MjgucG5nIl0sWyJwIiwidGh1bWIiLCI2MDB4NjAwIl1d.png?sha=d444a296dc94ccb7\',\'imageMaxUrl\':\'//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL3Byb2R1Y3RzLzU4MDIxMzk1LzE3NTM5NTE4OTZfNmE3NWNhNGQ1ZWEyOWEyMDc0MjgucG5nIl0sWyJwIiwidGh1bWIiLCIyMDQ4eDIwNDgiXV0.png?sha=496f495d10a31584\'}]'"
1331      :display-product-images-color=false
1332      :product-id="58021395"
1333      product-title="X2 - Smart Cycling Computer"
1334      
1335        :product-video={"id":null,"url":null}
1336        video-display-location="before"
1337      
1338    />
1339  </div>
1340  <!-- product image end -->
1341  <!-- product content start -->
1342  <div id="product_content" class="product_content qk-display--flex" data-tracking-variant-ids="null">
1343    
1344    <!-- 標題 -->
1345    <div class="product_title">
1346      <h1 class="qk-text--heading qk-fs--hd1 qk-fw--bold qk-mg--0">X2 - Smart Cycling Computer</h1>
1347    </div>
1348    
1349    <!-- ç°¡è¿° -->
1350    
1351      <div class="product_brief qk-text--text qk-fs--body">
1352        <a style="color: #565656;">Product Accessories : </a> <br>- Xplova X2 Cycle Computer *1 <br> - Micro-USB Cable *1 <br> - Handlebar Mounts *1 <br> - Handlebar Mounts Pad *1 <br>-  Rubber Strap *2 <br> - Quick Start Guide <br>-  Warranty Card 
1353      </div>
1354    
1355    <!-- 廠商,標語 -->
1356    <div class="product_vendor_slogan qk-display--il_bk qk-align--center">
1357      
1358      
1359        <span class="product_slogan qk-text--heading qk-fs--body">One of the best cycling computers in the world Superior battery life/ Support Smart Trainers/ Dual mode configuration</span>
1360      
1361    </div>
1362    <!-- 商品售價 -->
1363    
1364    
1365    
1366    <div
1367      class="product_price"
1368      id="price_title"
1369      data-discount-price-name=""
1370      data-discount-price-suggestion-name="">
1371      <!-- 價格title -->
1372      
1373        
1374      
1375
1376      <!-- 商品價格 -->
1377      <div class="qk-display--il_bk">
1378        <span class="qk-text--price price qk-fs--hd1 qk-fw--bold qk-display--il_bk qk-vert--mid"><span class="money_tag multi_currencies" data-currency-from="TWD" data-amount="2490.0">NT$2,490</span></span>
1379      </div>
1380      <del class="qk-text--text qk-fs--body qk-pd_l--05 qk-display--il_bk qk-vert--mid"></del>
1381
1382      <!--會員可見價-->
1383      
1384    </div>
1385    
1386    <!-- 商品sku -->
1387    
1388      <div class="product_sku qk-text--heading qk-fs--body">
1389        <span>Item No.:
1390        </span>
1391        <span class="val">ZC.X01TA.00L</span>
1392      </div>
1393    
1394    <!-- 供貨狀況 -->
1395    
1396
1397    <!-- 商品款式 -->
1398    <div id="variant_options" class="variant_options">
1399      <variant-options-block
1400        :product-api-url="'/products/x2'"
1401        :sku="sku"
1402        :auto-select-variant-by-sku="true"
1403        :hide-other-variants-by-sku="false"
1404        :hide-single-variant-options="false"
1405        :sales-mode-purchasable="true"
1406        default-price="NT$2,490"
1407        default-compare-price=""
1408        :default-discounted="false"
1409        @set-choose="getSelectedDatas"
1410        @get-option-image="getCurrentImage"></variant-options-block>
1411    </div>
1412
1413    <div id="product-tags"></div>
1414
1415    <!-- product discounts_list start -->
1416    <div class="product_discounts_list force-show-scrollbar hide qk-bd--default qk-bd--product_border qk-pd--1 qk-of_y--auto qk-of_x--hidden  hide ">
1417      <div class="list_block custom-scrollbar qk-of_x--hidden">
1418        <p class="qk-text--heading qk-fs--body qk-mg_b--05">Applicable Promotions</p>
1419        
1420          
1421        
1422      </div>
1423    </div>
1424    <!-- product discounts_list end -->
1425
1426    <!-- 規格,數量 -->
1427    
1428      <div class="product_button_mobile qk-display--flex qk-align--center qk-hidden--pc">
1429        <span class="product_love_mobile qk-display--il_bk">
1430          <input
1431            type="hidden"
1432            class="product-variant-id"
1433            value="70177313"
1434            data-sku="ZC.X01TA.00L"
1435            data-price="2490.0"
1436            data-compare_at_price="2490.0"
1437            data-variant=""
1438            data-inventory_quantity="0">
1439          <a
1440            class="btn_love scupio-add-wishlist qk-text--text qk-fs--body qk-cursor--pointer"
1441            data-itemid="ZC.X01TA.00L"
1442            
1443          >
1444          <div data-icon-type="custom_icon_type_tracking_items" ></div>
1445
1446          </a>
1447        </span>
1448        
1449      </div>
1450      
1451      
1452      
1453      
1454      
1455    <!-- 加入最愛,銷售數量,紅利折抵 -->
1456    <div class="product_others qk-display--flex qk-flex--wrap qk-align--center">
1457      <span class="product_love qk-display--il_bk qk-hidden--phone">
1458        <input
1459          type="hidden"
1460          class="product-variant-id"
1461          value="70177313"
1462          data-sku="ZC.X01TA.00L"
1463          data-price="2490.0"
1464          data-compare_at_price="2490.0"
1465          data-variant=""
1466          data-inventory_quantity="0">
1467        <a
1468          class="btn_love scupio-add-wishlist qk-text--text qk-fs--body qk-bd--default qk-bd--product_border qk-cursor--pointer qk-display--flex qk-align--center"
1469          data-itemid="ZC.X01TA.00L"
1470          
1471        >
1472          <svg
1473            width="15"
1474            height="15"
1475            viewBox="0 0 24 24"
1476            fill="none"
1477            xmlns="http://www.w3.org/2000/svg">
1478            <path
1479              d="M21.3899 4.54287C20.8146 4.01265 20.1366 3.60344 19.3969 3.34002C18.6572 3.0766 17.8711 2.96444 17.0863 3.01034C16.5593 3.01219 16.0362 3.09923 15.5375 3.26802C15.0194 3.44412 14.5265 3.68572 14.071 3.98682C13.6676 4.25092 13.2787 4.53613 12.906 4.84124C12.5762 5.09996 12.2648 5.38092 11.974 5.6821C11.6833 5.38092 11.3719 5.09996 11.042 4.84124C10.6516 4.53452 10.2443 4.24928 9.82221 3.98682C9.3967 3.69278 8.93642 3.45138 8.45163 3.26802C7.93995 3.0948 7.40254 3.0077 6.86175 3.01034C6.07688 2.96365 5.2906 3.07544 4.55076 3.3389C3.81091 3.60236 3.13296 4.01199 2.55813 4.54287C2.02401 5.11052 1.61146 5.77922 1.3453 6.50873C1.07914 7.23825 0.964875 8.01351 1.00937 8.78786C1.01359 9.36893 1.11073 9.94569 1.29719 10.4967C1.45989 11.0166 1.68054 11.517 1.95507 11.9886C2.20373 12.4073 2.47838 12.8104 2.77742 13.1956C3.09266 13.5889 3.32566 13.8601 3.46271 14.0093C3.56921 14.1255 3.6837 14.2343 3.80536 14.3348L11.4395 21.7669C11.5066 21.8412 11.5891 21.9002 11.6813 21.94C11.7736 21.9798 11.8734 21.9994 11.974 21.9975C12.0836 22.0067 12.1938 21.9906 12.296 21.9506C12.3983 21.9106 12.4898 21.8477 12.5634 21.7669L20.1838 14.3484C21.8272 12.9359 22.8376 10.9363 22.9935 8.78786C23.0307 8.0097 22.9078 7.23217 22.6321 6.50246C22.3565 5.77274 21.9339 5.10606 21.3899 4.54287V4.54287Z"
1480              stroke="currentColor"
1481              stroke-width="2"
1482              stroke-linecap="round"
1483              stroke-linejoin="round" />
1484          </svg>
1485          Add to Wishlist
1486        </a>
1487      </span>
1488      
1489      <span
1490        class="product_bonus qk-text--text qk-fs--body qk-display--il_bk"
1491        
1492        hidden
1493        >
1494        Redeemable credit(s) per item
1495        <span class="val">0</span>
1496        credit(s)
1497        
1498        equivalent to <span class="money_tag multi_currencies" data-currency-from="TWD" data-amount="0">NT$0</span>
1499      </span>
1500    </div>
1501  </div>
1502  <!-- product content end -->
1503</div>
1504<div class="add-buy-products-container">
1505  <!-- cyb_snippet add_buy_products start -->
1506
1507
1508
1509
1510<!-- cyb_snippet add_buy_products end -->
1511
1512</div>
1513
1514<script src='//cdn-general.cybassets.com/frontend/shop/beta_theme/js/cart-3a2e378145f8a165.js' type='text/javascript'></script>
vendor: 1 bytes, line 1514
1514
1515<script src='//cdn-general.cybassets.com/frontend/shop/beta_theme/js/product_variant-3a2e378145f8a165.js' type='text/javascript'></script>
1515
1516<link href='//cdn-general.cybassets.com/frontend/shop/beta_theme/css/product-3a2e378145f8a165.css' rel='stylesheet' type='text/css' media='all' />
1517<script src='//cdn-general.cybassets.com/frontend/shop/beta_theme/js/product_info-3a2e378145f8a165.js' type='text/javascript'></script>
1517
1518
1519<!-- cyb_snippet new_addcart_modal start -->
1520<link href='//cdn-general.cybassets.com/frontend/shop/beta_theme/css/vue_product_modal-3a2e378145f8a165.css' rel='stylesheet' type='text/css' media='all' />
1521
1522<div id="new-addcart-modal" class="container">
1523  <transition name="modal">
1524    <product-modal
1525      v-if="showProductModal"
1526      :only-description="onlyDescription"
1527      :product-url="popProductUrl"
1528      :color="color"
1529      :is-collection="isCollection"
1530      :is-show-description="isShowDescription"
1531      :is-quick-buy="isQuickBuy"
1532      :selected-variant-id="selectedVariantId"
1533      :categories="categories"
1534      :call-back="checkoutAddToCartCallback"
1535      ref="productModal"
1536    >
1537    </product-modal>
1538  </transition>
1539</div>
1540
1541<!-- cyb_snippet components/product_modal/product_modal start -->
1542<script type="text/x-template" id="product-modal">
1543  <div class="modal-mask qk-h--100 qk-w--100 qk-l--0 qk-t--0 qk-pos--fixed" @click="closeModal">
1544    <div class="modal-content qk-bd--none qk-center qk-bg--theme_bg" :class="{'only-description': onlyDescription}" @click.stop>
1545      <button class="btn-close qk-circle qk-circle--md qk-pos--abs qk-op--100 qk-bg--theme_bg qk-text--heading qk-bd--product_border qk-bd--default" @click="closeModal"></button>
1546      <div class="modal-body custom-scrollbar qk-w--100">
1547        <div v-if="!isLoading">
1548          <div id="checkout-product" class="row">
1549            <div class="col-sm-6 col-xs-4">
1550              <photo-swiper
1551                :mediaItems="swiperItems"
1552                :current-image-index="currentImageIndex"
1553                :current-variant="currentVariant"
1554                :video-after-image="videoAfterImage"
1555              ></photo-swiper>
1556            </div>
1557            <div class="col-sm-6 col-xs-8">
1558              <h4 class="qk-fs--hd2 qk-fw--bold qk-text--heading qk-mg--0" v-html="product.title"></h4>
1559              <p class="product_brief qk-text--text qk-fs--body" v-html="product.brief"></p>
1560              <p class="product_slogan qk-text--heading qk-fs--body" v-html="product.slogan"></p>
1561              <div class="swiper_thumbnails" style="margin-bottom: 10px;">
1562                <swiper-thumbnails
1563                  :mediaItems="swiperItems"
1564                  :current-image-index="currentImageIndex"
1565                  :title="product.title"
1566                  @update-current-image-index="(thumbnailIndex) => { currentImageIndex = thumbnailIndex }"
1567                ></swiper-thumbnails>
1568              </div>
1569              
1570              <div v-if="!hidePrice" style="margin-bottom: 10px;">
1571                
1572                <span class="price-title qk-fs--body qk-fw--500 qk-text--heading">${ priceTitleTag }</span>
1573                
1574                <div>
1575                  <span v-html="variantPrice" class="variant-price qk-fs--hd1 qk-fw--bold" :class="[isDiscountPrice ? 'qk-text--discount_price' : 'qk-text--price']"></span>
1576                  <del v-html="marketPrice" class="variant-del-price qk-fs--body qk-fw--500 qk-text--text"></del>
1577                </div>
1578              </div>
1579              <div v-if="!onlyDescription" class="controls">
1580                <div class="variant-quantity qk-display--flex qk-flex--column">
1581                  <div v-if="hasVariant" class="product-variant-options">
1582                    <div v-for="(option, index) in optionInfo" class="product-variant-option" :class="{'product-variant-option--hidden': shouldHideSingleVariantOptions}">
1583                      <div class="advance variant-select-option" v-if="styledShopMenu==='dropDownType'">
1584                      
1585                        <label>${option.name}</label>
1586                        <svg height="20" width="20" viewBox="0 0 20 20" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"><path d="M4.516 7.548c0.436-0.446 1.043-0.481 1.576 0l3.908 3.747 3.908-3.747c0.533-0.481 1.141-0.446 1.574 0 0.436 0.445 0.408 1.197 0 1.615-0.406 0.418-4.695 4.502-4.695 4.502-0.217 0.223-0.502 0.335-0.787 0.335s-0.57-0.112-0.789-0.335c0 0-4.287-4.084-4.695-4.502s-0.436-1.17 0-1.615z"> </path></svg>
1587                        <select class="qk-bg--theme_bg" :class="{'select_placeholder-color': currentOption[`option${index + 1}`] === null}" v-show="!isMobileSize" :value="String(currentOption[`option${index + 1}`])" @change="setOption(`option${index + 1}`, $event.target.value, option.types )" @click="onClickSelectModal(option,`option${index + 1}`)">
1588                          <option value="null" class="select_option-hidden">Please select ${option.name}</option>
1589                          <option :style="{ visibility : isMobileSize ? 'hidden' : 'visible' }" v-for="(types) in option.types" :disabled="!types.isValid" :value="types.name">${types.name}</option>
1590                        </select>
1591                        <span class="select_placeholder-color" v-if="currentOption[`option${index + 1}`] === null" v-show="isMobileSize" @click="onClickSelectModal(option,`option${index + 1}`)">Please select ${option.name}</span>
1592                        <span v-else :value="currentOption[`option${index + 1}`]" v-show="isMobileSize" @click="onClickSelectModal(option,`option${index + 1}`)" v-html="currentOption[`option${index + 1}`]"></span>
1593                      </div>
1594                      <advance-option v-else :option-key="'option' + (index + 1)" :option="option" :current-option="currentOption" :toggle-current-option="toggleCurrentOption"/>
1595                    </div>
1596                  </div>
1597                  <div class="product_discounts_list qk-bg--theme_bg qk-bd--default qk-bd--product_border qk-pd--1 qk-mg_b--1" v-show="displayProductDiscountsList && ((displayPeriodicSalesPages && product.showableSalesPages.length > 0) || !!discountsList)">
1598                    <div class="list_block custom-scrollbar qk-of_x--hidden">
1599                      <h4 class="qk-text--heading qk-fs--body">Applicable Promotions
1600                      </h4>
1601                      <template v-if="displayPeriodicSalesPages">
1602                        <div v-for="salesPage in product.showableSalesPages" class="discount-list">
1603                          <span class="discount-label qk-fs--breadcrumb qk-bd--default qk-bd--accent qk-bg--white qk-display--il_bk qk-text--accent">Subscription
1604                          </span>
1605                          <a class="discount-title qk-text--accent qk-fs--body" :href="salesPage.path">${ salesPage.title }</a>
1606                        </div>
1607                      </template>
1608                      <template v-for="discounts in discountsList">
1609                        <div v-for="discount in discounts" class="discount-list">
1610                          <a v-if="discount.url" :href="discount.url" class="discount-title qk-text--accent qk-fs--body">
1611                            ${ discount.title }
1612                          </a>
1613                          <span v-else class="discount-title qk-text--accent qk-fs--body">${ discount.title }</span>
1614                        </div>
1615                      </template>
1616                    </div>
1617                  </div>
1618                  <div v-if="showPurchaseControls" class="product-quantity qk-bd--product_border" v-show="!isMobileSize">
1619                    <div class="btn-group qk-w--100" role="group" aria-label="First group">
1620                      <button class="btn add-down qk-bd--default qk-bd--border qk-text--text" type="button" @click="quantityDecrease">-</button>
1621                      <input class="btn item-quantity qk-bd--default qk-bd--border qk-w--100 qk-text--heading" type="text" name="quantity" :value="quantity" @change="quantityChange">
1622                      <button class="btn add-up qk-bd--default qk-bd--border qk-text--text" type="button" @click="quantityIncrease">+</button>
1623                    </div>
1624                  </div>
1625                </div>
1626                <div v-if="showPurchaseControls" class="add-button-wrapper">
1627                  <!-- cyb_snippet _product_modal_button start -->
1628<button
1629  class="btn btn-default add-button qk-cursor--pointer qk-w--100 qk-btn--primary"
1630  :class="{selected: isChoose, adding: adding || isHideAddCartBtn, secondary: isSecondaryBtn, 'qk-btn--disabled': isHideAddCartBtn && isNewNnCollection, 'qk-bd--none': isHideAddCartBtn && isNewNnCollection}"
1631  type="button"
1632  :disabled="isHideAddCartBtn"
1633  @click="addProduct"
1634>
1635  ${ addCartText }
1636</button>
1637
1638<!-- cyb_snippet _product_modal_button end -->
1639                </div>
1640                <div class="product-others qk-fs--body">
1641                  <span class="product-love">
1642                    <a class="btn-love qk-text--text qk-bg--theme_bg qk-bd--default qk-bd--product_border qk-display--il_bk qk-text--center qk-cursor--pointer qk-tst qk-tst_timing--ease_io qk-tst_dur--15" @click="addWishList">
1643                      <svg
1644                        width="15"
1645                        height="15"
1646                        viewBox="0 0 24 24"
1647                        fill="none"
1648                        xmlns="http://www.w3.org/2000/svg">
1649                        <path
1650                          d="M21.3899 4.54287C20.8146 4.01265 20.1366 3.60344 19.3969 3.34002C18.6572 3.0766 17.8711 2.96444 17.0863 3.01034C16.5593 3.01219 16.0362 3.09923 15.5375 3.26802C15.0194 3.44412 14.5265 3.68572 14.071 3.98682C13.6676 4.25092 13.2787 4.53613 12.906 4.84124C12.5762 5.09996 12.2648 5.38092 11.974 5.6821C11.6833 5.38092 11.3719 5.09996 11.042 4.84124C10.6516 4.53452 10.2443 4.24928 9.82221 3.98682C9.3967 3.69278 8.93642 3.45138 8.45163 3.26802C7.93995 3.0948 7.40254 3.0077 6.86175 3.01034C6.07688 2.96365 5.2906 3.07544 4.55076 3.3389C3.81091 3.60236 3.13296 4.01199 2.55813 4.54287C2.02401 5.11052 1.61146 5.77922 1.3453 6.50873C1.07914 7.23825 0.964875 8.01351 1.00937 8.78786C1.01359 9.36893 1.11073 9.94569 1.29719 10.4967C1.45989 11.0166 1.68054 11.517 1.95507 11.9886C2.20373 12.4073 2.47838 12.8104 2.77742 13.1956C3.09266 13.5889 3.32566 13.8601 3.46271 14.0093C3.56921 14.1255 3.6837 14.2343 3.80536 14.3348L11.4395 21.7669C11.5066 21.8412 11.5891 21.9002 11.6813 21.94C11.7736 21.9798 11.8734 21.9994 11.974 21.9975C12.0836 22.0067 12.1938 21.9906 12.296 21.9506C12.3983 21.9106 12.4898 21.8477 12.5634 21.7669L20.1838 14.3484C21.8272 12.9359 22.8376 10.9363 22.9935 8.78786C23.0307 8.0097 22.9078 7.23217 22.6321 6.50246C22.3565 5.77274 21.9339 5.10606 21.3899 4.54287V4.54287Z"
1651                          stroke="currentColor"
1652                          stroke-width="2"
1653                          stroke-linecap="round"
1654                          stroke-linejoin="round" />
1655                      </svg>
1656                      Add to Wishlist
1657                    </a>
1658                  </span>
1659                  <span class="product_sold qk-text--text" v-if="false">
1660                    <span>Sold : 
1661                      ${ product.totalSold }
1662                      Item(s)
1663                    </span>
1664                  </span>
1665                  <span class="product_bonus qk-text--text" v-if="false">
1666                    Redeemable credit(s) per item
1667                    <span class="val qk-fw--600 qk-fs--hd2" v-if="currentVariant">${currentVariant.maxUsableBonus}</span>
1668                    <span class="val qk-fw--600 qk-fs--hd2" v-else>${maxUsableBonus}</span>
1669                    credit(s)
1670                    <span v-html="bonusToPrice"/>
1671                  </span>
1672                </div>
1673                <div class='product_limit_buy qk-fs--body' v-show="product.minBuy > 0 || product.limitBuy > 0">
1674                  ${limitBuyText}
1675                </div>
1676              </div>
1677            </div>
1678          </div>
1679          <div v-if="isShowDescription" class="row">
1680            <div class="col-sm-12">
1681              
1682                <div v-if="product.bodyHtml">
1683                  <h5 class="section-heading qk-bd--heading qk-fs--hd2 qk-text--heading">
1684                    Description
1685                  </h5>
1686                  <div class="ckeditor">
1687                    <div v-html="product.bodyHtml"></div>
1688                  </div>
1689                </div>
1690              
1691              
1692                <div v-if="otherDescriptions['product_description_section_spec']">
1693                  <h5 class="section-heading qk-bd--heading qk-fs--hd2 qk-text--heading">
1694                    Specifications
1695                  </h5>
1696                  <div class="ckeditor">
1697                    <div v-html="otherDescriptions['product_description_section_spec']"></div>
1698                  </div>
1699                </div>
1700              
1701              
1702            </div>
1703          </div>
1704        </div>
1705        <div v-show="isLoading" style="text-align: center; padding-bottom: 20px;">
1706          <i class="fas fa-spinner fa-spin fa-fw fa-2x"></i>
1707        </div>
1708      </div>
1709        <!-- cyb_snippet _product_modal_button_mobile start -->
1710 <div
1711  v-if="showPurchaseControls"
1712  v-show="isMobileSize"
1713  class="mobile_footer"
1714  :class="{'mobile_footer-z': variantSize > 1 }">
1715        <div class="product-quantity">
1716          <div class="btn-group qk-w--100" role="group" aria-label="First group">
1717            <button class="btn add-down qk-bd--default qk-bd--border qk-text--text" type="button" @click="quantityDecrease">-</button>
1718            <input class="btn item-quantity qk-bd--default qk-bd--border qk-w--100 qk-text--heading" type="text" name="quantity" :value="quantity" @change="quantityChange">
1719            <button class="btn add-up qk-bd--default qk-bd--border qk-text--text" type="button" @click="quantityIncrease">+</button>
1720          </div>
1721        </div>
1722        <button
1723          v-if="!isLoading && !onlyDescription"
1724          class="btn btn-mobile add-button qk-btn qk-btn--primary qk-btn--lg"
1725          :class="{selected: isChoose, adding: adding || isHideAddCartBtn, 'qk-btn--disabled': isHideAddCartBtn && isNewNnCollection, 'qk-bd--none': isHideAddCartBtn && isNewNnCollection}"
1726          type="button"
1727          :disabled="isHideAddCartBtn"
1728          @click="addProduct">
1729            ${ addCartText }
1730        </button>
1731</div>
1732<div
1733  class="mobile-modal"
1734  :class="{ 'modal-open': isModalSelectShow && isMobileSize }">
1735        <div class="mobile_modal-content">
1736          <div class="modal_close-button">
1737            <button class="btn-close qk-circle qk-circle--md qk-pos--abs qk-op--100  qk-text--heading qk-bd--product_border qk-bd--default" @click="onChangeModalSelect(false,true)"></button>
1738          </div>
1739          
1740          <p>Please select ${modalOption.name}</p>
1741          <div class="modal_select-templete qk-display--flex qk-of_y--auto qk-w--100">
1742            <div class="options-container">
1743              <label :class="{'seleced-option': currentOption && currentOption[selectOption] === data.name, 'avoid-clicks':!data.isValid}" v-for="data in modalOption.types" @click="setOption(selectOption, data.name, modalOption.types)">${data.name}</label>
1744            </div>
1745          </div>
1746          <div v-if="variantSize > 1" class="modal_select_footer qk-display--flex">
1747            <button type="button" class="modal_cancel qk-bd--default qk-btn--secondary qk-bd--button qk-text--button" @click="onChangeModalSelect(false,false)">Cancel</button>
1748            <button type="button" class="qk-btn qk-btn--primary qk-btn--lg qk-fs--body qk-bd--button qk-test--button_text" @click="onChangeModalSelect(false,true)">Finish</button>
1749          </div>
1750        </div>
1751</div>
1752
1753<!-- cyb_snippet _product_modal_button_mobile end -->
1754    </div>
1755  </div>
1756</script>
1756
1757
1758<!-- cyb_snippet components/product_modal/color_image_option start -->
1759<script id="color-image-option" type="text/x-template">
1760  <div class="color-image qk-display--flex qk-flex--wrap qk-align--center">
1761    <div class="title">Color</div>
1762    <div
1763      v-for="(imageColor, index) in imageColors"
1764      :class="{
1765        'focus': !currentOption[optionKey] === option.types[index].name && currentImageIndex === index,
1766        'selected': currentOption[optionKey] === option.types[index].name,
1767        'disabled': !option.types[index].isValid
1768      }"
1769      class="image-option img-flex qk-bd--default qk-bd--transparent qk-display--block qk-pos--rel"
1770      @mouseleave="setCurrentImageIndex(index)"
1771      @mouseover="getOptionImageIndex(index)"
1772      @click="setOption(optionKey, index)"
1773    >
1774      <img v-if="imageColor !== 'noColorImage'" :src="imageColor.large" alt="image">
1775      <img v-else src="/assets/no-image-large.png" alt="image">
1776    </div>
1777  </div>
1778</script>
1778
1779
1780<script type="text/javascript">
1781  $(document).ready(function() {
1782    window.themeHelper.productModalComponents['color-image-option'] = {
1783      template: '#color-image-option',
1784      delimiters: ['${', '}'],
1785      props: {
1786        optionKey: String,
1787        option: Object,
1788        product: Object,
1789        imageColors: Array,
1790        isChoose: Boolean,
1791        currentImageIndex: Number,
1792        setCurrentImageIndex: Function,
1793        getOptionImageIndex: Function,
1794        currentOption: Object,
1795        toggleCurrentOption: Function,
1796      },
1797      methods: {
1798        setOption: function(optionKey, index) {
1799          const type = this.option.types[index];
1800          if(type.isValid){
1801            this.toggleCurrentOption(optionKey, type.name);
1802          }
1803        }
1804      }
1805    };
1806  });
1807</script>
1807
1808
1809<!-- cyb_snippet components/product_modal/color_image_option end -->
1810<!-- cyb_snippet components/product_modal/advance_option start -->
1811<script id="advance-option" type="text/x-template">
1812  <div class="advance">
1813    <div class="title qk-text--heading qk-fs--body">${option.name}</div>
1814    <div
1815      v-for="type in option.types"
1816      :class="{
1817        'selected': currentOption[optionKey] === type.name,
1818        'disabled': !type.isValid
1819      }"
1820      @click="setOption(optionKey, type)"
1821      class="option qk-btn  qk-bd--button qk-text--button qk-pd_x--1"
1822    >
1823      ${type.name}
1824    </div>
1825  </div>
1826</script>
1826
1827
1828<script type="text/javascript">
1829  $(document).ready(function() {
1830    window.themeHelper.productModalComponents['advance-option'] = {
1831      template: '#advance-option',
1832      delimiters: ['${', '}'],
1833      props: {
1834        optionKey: String,
1835        option: Object,
1836        product: Object,
1837        currentOption: Object,
1838        toggleCurrentOption: Function,
1839      },
1840      methods: {
1841        setOption: function(optionKey, type) {
1842          if(type.isValid){
1843            this.toggleCurrentOption(optionKey, type.name);
1844          }
1845        }
1846      }
1847    };
1848  });
1849</script>
1849
1850
1851<!-- cyb_snippet components/product_modal/advance_option end -->
1852
1853<!-- cyb_snippet components/product_modal/photo_swiper start -->
1854
1855
1856<script id="photo-swiper" type="text/x-template">
1857  <div ref="photoSwiper" id="photo_swiper" class="photos swiper swiper-container">
1858    <div class="swiper-wrapper">
1859      <template v-if="hasImage">
1860        <div v-for="(item, index) in mediaItems" :key="index" class="photo swiper-slide qk-align--center qk-display--flex qk-justify--center qk-vert--text_top default_scale">
1861          <video-player v-if="item.url" :video="item"
1862            :video-poster=" !!mediaItems[firstImageIndex] ? mediaItems[firstImageIndex].large : '//cdn-general.cybassets.com/img_loading.svg' "
1863          >
1864          </video-player>
1865          <img v-else class="qk-center" :src="item.large" alt="image"/>
1866        </div>
1867      </template>
1868      <div v-else class="photo swiper-slide qk-align--center qk-display--flex qk-justify--center qk-vert--text_top default_scale">
1869        <img src="//cdn-general.cybassets.com/assets/no-image-large-2b95ea56c455be9ce081d81c14eded925df68bf8fa38809e46f6af8fcdd5f9bc.png" alt="image" />
1870      </div>
1871    </div>
1872    <div v-show="showBtn" class="photo-prev qk-swiper_btn--prev  qk-hidden--mobile qk-swiper_btn qk-swiper_btn--lg qk-swiper_btn--v2 qk-mg_l--05"></div>
1873    <div v-show="showBtn" class="photo-next qk-swiper_btn--next  qk-hidden--mobile qk-swiper_btn qk-swiper_btn--lg qk-swiper_btn--v2 qk-mg_l--05"></div>
1874
1875    <div class="photo-pagination qk-bd--default qk-bd--body qk-text--center qk-text--body qk-fs--breadcrumb qk-visible-sm">
1876        <span class="current-index qk-text--default_dark">${currentImageIndex +1 }</span><span class="pagination-slash">/</span>
1877        <span>${mediaItems.length}</span>
1878      </div>
1879  </div>
1880</script>
1880
1881
1882<script>
1883  $(document).ready(function () {
1884    window.themeHelper.productModalComponents['photo-swiper'] = {
1885      template: '#photo-swiper',
1886      delimiters: ['${', '}'],
1887      props: {
1888        mediaItems: Array,
1889        currentImageIndex: Number,
1890        currentVariant: Object,
1891        videoAfterImage: Boolean,
1892      },
1893      data: function () {
1894        return {
1895          swiper: {},
1896          swiperOption: {
1897            preventInteractionOnTransition: true,
1898            rewind: true,
1899            spaceBetween: 5,
1900            slidesPerView: 1,
1901            navigation: {
1902              nextEl: '.photo-next',
1903              prevEl: '.photo-prev'
1904            }
1905          },
1906          showBtn: true,
1907          isVariantReposition: false,
1908        }
1909      },
1910      mounted: function() {
1911        this.swiper = new Swiper('#photo_swiper', this.swiperOption);
1912        this.swiper.on('slideChange', this.slideOnChange);
1913      },
1914      watch: {
1915        currentImageIndex: function() {
1916          this.slideToIndex();
1917        },
1918        currentVariant: {
1919          immediate: true,
1920          handler: function() {
1921            this.showBtn = this.mediaItems.length > 1;
1922            this.isVariantReposition = true;
1923            this.$nextTick(() => {
1924              if (this.swiper) {
1925                this.swiper.update();
1926                this.swiper.slideToLoop(this.initialItemIndex)
1927                this.slideOnChange();
1928                this.isVariantReposition = false;
1929              }
1930            });
1931          },
1932        },
1933      },
1934      computed: {
1935        hasImage: function() {
1936          return this.mediaItems.length > 0;
1937        },
1938        hasVideo: function() {
1939          return this.mediaItems.findIndex(item => !!item.url) !== -1;
1940        },
1941        variantPhotos: function() {
1942          if (this.currentVariant?.photos?.length) {
1943            return this.currentVariant.photos;
1944          } else  {
1945            return null;
1946          }
1947        },
1948        initialItemIndex: function() {
1949          if (this.hasVideo && !this.videoAfterImage) {
1950            // Focus on photo if "variant with photos" selected, video otherwise
1951            return this.variantPhotos?.length ? 1 : 0;
1952          } else {
1953            // Focus on first photo
1954            return 0;
1955          }
1956        },
1957      },
1958      methods: {
1959        slideOnChange: function() {
1960          themeHelper.EventBus.$emit('photoOnChange', this.swiper.realIndex, this.isVariantReposition);
1961        },
1962        slideToIndex: function() {
1963          if(this.swiper.realIndex != this.currentImageIndex) {
1964            this.swiper.slideToLoop(this.currentImageIndex);
1965            this.swiper.update();
1966          }
1967        },
1968      }
1969    };
1970  });
1971</script>
1971
1972
1973
1974<!-- cyb_snippet components/product_modal/video_player start -->
1975<script id="video-player" type="text/x-template">
1976  <div class="videoPlayer__wrapper" @click="handleVideoClick">
1977    <video 
1978      id='modal-video'
1979      class="videoPlayer__video qk-cursor--pointer qk-center" 
1980      :poster="videoPoster"
1981      loop defaultMuted muted playsinline webkit-playsinline autoplay
1982    >
1983      <source :src="videoUrl" type="video/mp4">
1984      <p>Your browser does not support HTML 5 video.</p>
1985    </video>
1986    <button id="modal-video-button" class="videoPlayer__pauseButton"></button>
1987  </div>
1988</script>
1988
1989
1990<script>
1991  $(document).ready(function () {
1992    window.themeHelper.productModalComponents['video-player'] = {
1993      template: '#video-player',
1994      delimiters: ['${', '}'],
1995      props: {
1996        video: Object,
1997        videoPoster: String,
1998      },
1999      data: function() {
2000        return {
2001          videoElement: null,
2002          buttonElement: null,
2003        };
2004      },
2005      mounted: function() {
2006        this.videoElement = $('#modal-video')[0];
2007        this.buttonElement = $('#modal-video-button');
2008        this.setVideoVolumeZero();
2009        this.videoElement.addEventListener('canplay', (event) => {
2010          this.sendGtag('play');
2011        }, { once: true });
2012      },
2013      computed: {
2014        videoUrl: function() {
2015          return this.video.url;
2016        }
2017      },
2018      methods: {
2019        sendGtag: function(action) {
2020          window.productVideoView && productVideoView(action);
2021        },
2022        setVideoVolumeZero: function() {
2023          this.videoElement.volume = 0;
2024        },
2025        handleVideoClick: function() {
2026          if (this.videoElement.paused){
2027            this.videoElement.play();
2028            this.sendGtag('play');
2029          } else {
2030            this.videoElement.pause();
2031            this.sendGtag('paused');
2032          }
2033          this.handleVideoButtonDisplay(this.buttonElement, this.videoElement);
2034        },
2035        handleVideoButtonDisplay: function(button, video) {
2036          button.toggleClass('videoPlayer__playButton', video.paused);
2037          button.toggleClass('videoPlayer__pauseButton', !video.paused);
2038        },
2039      }
2040    };
2041  });
2042</script>
2042
2043
2044<!-- cyb_snippet components/product_modal/video_player end -->
2045
2046<!-- cyb_snippet components/product_modal/photo_swiper end -->
2047<!-- cyb_snippet components/product_modal/swiper_thumbnails start -->
2048<script id="swiper-thumbnails" type="text/x-template">
2049  <div
2050    v-for="(thumbnail, index) in allThumbnails"
2051    :key="index"
2052    class="product-thumbnail img-flex qk-of--hidden qk-display--il_bk qk-cursor--pointer qk-bd--default qk-bd--transparent default_scale"
2053    :class="{ focus: index === currentImageIndex }"
2054    @mouseover="updateCurrentImageIndex(index)"
2055  >
2056    <template v-if="thumbnail.isVideo">
2057      <video class="qk-w--100 qk-h--100" :src="thumbnail.url" defaultMuted playsinline></video>
2058      <button class="videoPlayer__playButton"></button>
2059    </template>
2060    <img v-else :src="thumbnail.url" :alt="title" class="qk-w--100 qk-h--100">
2061  </div>
2062</script>
2062
2063
2064<script type="text/javascript">
2065  $(document).ready(function () {
2066    window.themeHelper.productModalComponents['swiper-thumbnails'] = {
2067      template: '#swiper-thumbnails',
2068      delimiters: ['${', '}'],
2069      props: {
2070        title: String,
2071        mediaItems: Array,
2072        currentImageIndex: Number,
2073      },
2074      emits: ['updateCurrentImageIndex'],
2075      methods: {
2076        updateCurrentImageIndex: function(thumbnailIndex) {
2077          if (thumbnailIndex !== this.currentImageIndex ) {
2078            this.$emit('updateCurrentImageIndex', thumbnailIndex);
2079          }
2080        },
2081      },
2082      mounted() {
2083        // can be removed after replacing video thumbnail with img
2084        const thumbnailVideo = $('.product-thumbnail video')[0];
2085        if (!!thumbnailVideo) {
2086          thumbnailVideo.volume = 0;
2087          const promise = thumbnailVideo.play();
2088          promise.then(() => {
2089            thumbnailVideo.pause();
2090          })
2091        }
2092      },
2093      computed: {
2094        allThumbnails: function() {
2095          return this.mediaItems.map(item => ({
2096            isVideo: !!item.url,
2097            url: item.url || item.medium
2098          }));
2099        },
2100      },
2101      watch: {
2102        allThumbnails: {
2103          handler(){
2104            this.updateCurrentImageIndex(this.currentImageIndex);
2105          }
2106        }
2107      }
2108    };
2109  });
2110</script>
2110
2111
2112<!-- cyb_snippet components/product_modal/swiper_thumbnails end -->
2113
2114
2115<!-- cyb_snippet _product_modal_js start -->
2116<script type="text/javascript">
2117  $(document).ready(function() {
2118    var categoryLevels = [];
2119    var productCategoryLevels = ["All,Cycling Accessories"];
2120    var pageMainProductId = 58021395;
2121    window.themeHelper.productModalComponents['product-modal'] = {
2122      template: '#product-modal',
2123      delimiters: [
2124        '${', '}'
2125      ],
2126      props: {
2127        onlyDescription: Boolean,
2128        cartItems: Array,
2129        groupId: Number,
2130        productUrl: String,
2131        color: String, // unused
2132        collectionId: Number,
2133        categories: Array,
2134        // 判斷是否有色票展開
2135        isCollection: {
2136          type: Boolean,
2137          required: false,
2138          default: false,
2139        },
2140        // 判斷加入購物車的方法
2141        isNnCollection: Boolean,
2142        isNewNnCollection: Boolean,
2143        isBundleDiscount: Boolean,
2144
2145        // 判斷是否顯示商品描述
2146        isShowDescription: {
2147          type: Boolean,
2148          default: true
2149        },
2150
2151        // 判斷是否為立即購買
2152        isQuickBuy: {
2153          type: Boolean,
2154          default: false
2155        },
2156        selectedVariantId: Number,
2157        callBack: Function
2158      },
2159      data: function() {
2160        return {
2161          styledShopMenu: "buttonType",
2162          selectOption: '',
2163          selectCurrentStr:'',
2164          isModalSelectShow: false,
2165          modalOption: {},
2166          adding: false,
2167          currentImageIndex: 0,
2168          _navState: { variantId: null, photoIndex: 0 },
2169          currentOption: {
2170            option1: null,
2171            option2: null,
2172            option3: null
2173          },
2174          currentVariant: null,
2175          variantNotifications: null,
2176          currentVariantIndex: null,
2177          product: {},
2178          isChoose: false,
2179          isLoading: true,
2180          isEmptyClickable: liquidHelper.isEmptyClickable,
2181          quantity: 1,
2182          maxUsableBonus: 0,
2183          isDiscountPrice: false,
2184          displayProductDiscountsList: false,
2185          displayPeriodicSalesPages:true,
2186          discountsList: null,
2187          hasVideoPlugin: true,
2188          videoDisplayLocation: "before",
2189          hasStockNotificationPlugin: true,
2190          isDisplayPriceRange: null,
2191          hasVariantPriceRangePlugin: true,
2192          hasHideSingleVariantOptionsPlugin: false,
2193        }
2194      },
2195      mounted: function() {
2196        this.getProductDetail();
2197        $('.custom-scrollbar').addCustomScrollbar();
2198        themeHelper.EventBus.$on('photoOnChange', this.photoOnChange);
2199      },
2200      beforeUnmount: function() {
2201        themeHelper.EventBus.$off('photoOnChange', this.photoOnChange);
2202      },
2203      computed: {
2204        photoUrls: function() {
2205          return this.product.photoUrls.length > 0
2206            ? this.product.photoUrls
2207            : [this.featuredImage];
2208        },
2209        photoUrlsMap: function() {
2210          var map = {};
2211          var urls = this.product.photoUrls;
2212          this.product.photos.forEach(function(photo, index) {
2213            map[photo.photo.id] = urls[index];
2214          });
2215
2216          return map;
2217        },
2218        featuredImage: function() {
2219          return this.product.featuredImage;
2220        },
2221        swiperPhotos: function() {
2222          if (!this.photoUrls.length) {
2223            return [this.featuredImage];
2224          }
2225
2226          if (this.currentVariant && this.currentVariant.photos.length) {
2227            var map = this.photoUrlsMap;
2228            return this.currentVariant.photos.map(function(p) {
2229              return map[p.id];
2230            });
2231          }
2232
2233          return this.photoUrls;
2234        },
2235        productVideo: function() {
2236          return this.product.video;
2237        },
2238        videoAfterImage: function() {
2239          return this.videoDisplayLocation === 'after';
2240        },
2241        swiperItems: function() {
2242          const media = [...this.swiperPhotos];
2243          if (
2244            this.hasVideoPlugin && this.productVideo.url
2245          ) {
2246            this.videoAfterImage
2247              ? media.push(this.productVideo)
2248              : media.unshift(this.productVideo);
2249          }
2250          return media;
2251        },
2252        firstImageIndex: function() {
2253          return this.hasVideoPlugin && this.productVideo.url && !this.videoAfterImage
2254            ? 1
2255            : 0
2256        },
2257        otherDescriptions: function() {
2258          var descriptions = {};
2259          this.product.otherDescriptions.forEach(function(od) {
2260            descriptions[od.settingName] = od.bodyHtml;
2261          })
2262          return descriptions
2263        },
2264        variantOptions: function() {
2265          return themeHelper.variantOptions(this.product);
2266        },
2267        firstValidVariant: function() {
2268          var self = this;
2269          var result = this.product.variants.find(function(variant) {
2270            // 增加 product modal 聯絡店家 property
2271            variant.imgUrl = "";
2272            variant.productTitle = "";
2273
2274            return variant.available;
2275          });
2276
2277          return result
2278            ? result
2279            : null;
2280        },
2281        selectedValidVariant: function() {
2282          var self = this;
2283          var result = this.variantOptions.find(function(variant) {
2284            return variant.id === self.selectedVariantId;
2285          });
2286
2287          return result
2288            ? result
2289            : null;
2290        },
2291        totalInventoryQuantity: function(product) {
2292          return themeHelper.totalInventoryQuantity(this.product)
2293        },
2294        addCartText: function() {
2295          var variants = parseInt("0");
2296          let isRegisteredNotification = this.currentVariant && this.variantNotifications && this.variantNotifications[this.currentVariant.id]
2297          if (this.isNnCollection || this.isBundleDiscount) {
2298            if (this.currentVariant && !themeHelper.variantIsAvailable(this.currentVariant)) {
2299              if (this.currentVariant.inventoryPolicy === 'continue') {
2300                if (this.isNnCollection) {
2301                  return this.isChoose && !this.isNewNnCollection
2302                    ? 'Ordered'
2303                    : 'Pre-order';
2304                }
2305              } else {
2306                return 'Sold out';
2307              }
2308            }
2309            if (this.totalInventoryQuantity === 0) {
2310              return 'Sold out';
2311            }
2312            return this.isChoose && !this.isNewNnCollection
2313              ? 'Selected'
2314              : 'Select';
2315          } else {
2316            if (this.isQuickBuy) {
2317              if (this.currentVariant && !themeHelper.variantIsAvailable(this.currentVariant)) {
2318                if (this.currentVariant.inventoryPolicy === 'continue'){
2319                  return 'Order Now'
2320                }
2321                return this.hasStockNotificationPlugin
2322                  ? (isRegisteredNotification
2323                    ? 'Notification Enabled'
2324                    : 'Sold out! Notify me when the product is available.')
2325                  : 'Contact Shop'
2326              }
2327              return 'BUY NOW';
2328            } else {
2329              if (this.currentVariant) {
2330                if (!themeHelper.variantIsAvailable(this.currentVariant)) {
2331                  if (this.currentVariant.inventoryPolicy === 'continue'){
2332                    return 'Pre-order'
2333                  }
2334                  return this.hasStockNotificationPlugin
2335                    ? (isRegisteredNotification
2336                      ? 'Notification Enabled'
2337                      : 'Sold out! Notify me when the product is available.')
2338                    : 'Contact Shop'
2339                }
2340              } else {
2341                if (this.totalInventoryQuantity === 0) {
2342                  return 'Sold out';
2343                }
2344              }
2345              return 'ADD TO CART';
2346            }
2347          }
2348        },
2349        cartItem: function() {
2350          if (!this.currentVariant) {
2351            return null
2352          }
2353          return {
2354            id: this.currentVariant.id,
2355            groupId: this.groupId,
2356            productId: this.product.id,
2357            title: this.product.title,
2358            photo: this.currentVariant.imgUrl || this.featuredImage.large,
2359            quantity: this.quantity,
2360            price: this.currentVariant.price,
2361            variant: this.currentVariant,
2362            product: this.product
2363          }
2364        },
2365        options: function() {
2366          return this.product.options;
2367        },
2368        optionTypes: function() {
2369
2370          // 先根據設定的variants來排序
2371          var self = this;
2372
2373          var option1 = [];
2374          var option2 = [];
2375          var option3 = [];
2376          this.product.variants.forEach(function(item) {
2377            if (item.option1 !== null) {
2378              option1.push(item.option1);
2379            }
2380            if (item.option2 !== null) {
2381              option2.push(item.option2);
2382            }
2383            if (item.option3 !== null) {
2384              option3.push(item.option3);
2385            }
2386          })
2387          var filteredOptionTypes = [];
2388          this.product.optionTypes.forEach(function(item, index) {
2389            filteredOptionTypes.push(self.getUniqueVariant(eval('option' + (
2390              index + 1
2391            ))).join(','));
2392          });
2393          return filteredOptionTypes;
2394        },
2395        optionInfo: function() {
2396          var self = this;
2397
2398          return self.options.map(function(option, index) {
2399            return {
2400              name: option,
2401              types: self.getOptions('option' + (
2402                index + 1
2403              ), self.optionTypes[index].split(','))
2404            }
2405          });
2406        },
2407        hasVariant: function() {
2408          return this.product.options.length > 0;
2409        },
2410        shouldHideSingleVariantOptions: function() {
2411          return this.hasHideSingleVariantOptionsPlugin &&
2412                 this.product.variants &&
2413                 this.product.variants.length <= 1;
2414        },
2415        variantSize: function() {
2416          if(this.product.options){
2417          return this.product.options.length;
2418          }
2419        },
2420        firstVariant: function() {
2421          return this.product.variants[0];
2422        },
2423        firstCheapestVariant: function() {
2424          return this.product.variants.find((v)=> (v.price === this.priceStats.minPrice));
2425        },
2426        priceStats: function() {
2427          return this.product.variants.reduce(function(acc, variant) {
2428            return {
2429              minPrice: variant.price < acc.minPrice ? variant.price : acc.minPrice,
2430              maxPrice: variant.price > acc.maxPrice ? variant.price : acc.maxPrice,
2431            };
2432          }, {
2433            minPrice: this.firstVariant.price,
2434            maxPrice: this.firstVariant.price,
2435          });
2436        },
2437        hidePrice: function() {
2438          return this.product && this.product.hidePrice === true;
2439        },
2440        salesModePurchasable: function() {
2441          return !(this.product && this.product.salesModePurchasable === false);
2442        },
2443         // - 任選折扣/紅配綠:「選擇」只是加進試算清單,不會直接下單,故只擋藏價商品
2444        // - 其他情境(商品頁、群組頁、多層級分類、搜尋、首頁商品區塊):不可購買(含藏價)就整組收掉
2445        showPurchaseControls: function() {
2446          if (this.isNnCollection || this.isBundleDiscount) {
2447            return !this.hidePrice;
2448          }
2449          return this.salesModePurchasable;
2450        },
2451        variantPrice: function() {
2452          if (this.hidePrice) {
2453            return '';
2454          }
2455          var from = liquidHelper.defaultCurrency;
2456          if (this.currentVariant) {
2457            return moneySymbol(this.currentVariant.price, from);
2458          }
2459          if (this.product.variants.length === 1) {
2460            return moneySymbol(this.firstVariant.price, from);
2461          }
2462
2463          var minPrice = this.priceStats.minPrice;
2464          var maxPrice = this.priceStats.maxPrice;
2465
2466          if (minPrice !== maxPrice && (!this.hasVariantPriceRangePlugin || this.isDisplayPriceRange)) {
2467            this.isDiscountPrice = false;
2468            return moneySymbol(minPrice, from) + '~' + moneySymbol(maxPrice, from);
2469          } else {
2470            return moneySymbol(minPrice, from);
2471          }
2472        },
2473        marketPrice: function() {
2474          if (this.hidePrice) {
2475            this.isDiscountPrice = false;
2476            return;
2477          }
2478          var from = liquidHelper.defaultCurrency;
2479          if (this.currentVariant) {
2480            this.isDiscountPrice = false;
2481            if (this.currentVariant.compareAtPrice && this.currentVariant.compareAtPrice > this.currentVariant.price) {
2482              this.isDiscountPrice = true;
2483              return moneySymbol(this.currentVariant.compareAtPrice, from);
2484            }
2485          } else {
2486            if (!_.includes(this.variantPrice, '~')) {
2487              const price =  Number(this.variantPrice.replace(/[^0-9.
2487-]/g, ""))
2488              // 未選擇款式也不顯示區間時,顯示第一個最便宜的款式的定價
2489              if (this.firstCheapestVariant.compareAtPrice && this.firstCheapestVariant.compareAtPrice > price){
2490                this.isDiscountPrice = true;
2491                return moneySymbol(this.firstCheapestVariant.compareAtPrice, from);
2492              }
2493              // 未選擇款式時要改回一般價格顏色
2494              this.isDiscountPrice = false;
2495            }
2496          }
2497        },
2498        isShowDropdownList: function() {
2499          if (this.product.options.length > 0) {
2500            return true;
2501          }
2502          return this.product.variants.length > 1
2503        },
2504        priceTitleTag: function() {
2505          return this.marketPrice
2506            ? getDiscountPriceName()
2507            : getDiscountPriceSuggestionName();
2508        },
2509        isHideAddCartBtn: function() {
2510          if (this.addCartText === 'Sold out') {
2511            return true;
2512          }
2513          return false;
2514        },
2515        isSecondaryBtn: function() {
2516          if (this.addCartText === 'Contact Shop') {
2517            return true;
2518          }
2519          return false;
2520        },
2521        variantsMaxUsableBonus: function() {
2522          var variants = this.product.variants;
2523          var maxUsableBonusArray = variants.map(function(item) {
2524            return item.maxUsableBonus
2525          });
2526          return Math.max.apply(null, maxUsableBonusArray);
2527        },
2528        bonusToPrice: function() {
2529          const bonus = this.currentVariant
2530            ? this.currentVariant.maxUsableBonus
2531            : this.maxUsableBonus;
2532          const price = Math.floor(bonus / window.liquidHelper.conversionBonus);
2533          const priceWithMoney = window.themeHelper.productDisplayCurrencyBlock(price);
2534          return "equivalent to value".replace('value', priceWithMoney);
2535        },
2536        isMobileSize: function() {
2537          return window.innerWidth <= 580
2538        },
2539        limitBuyText: function () {
2540          const minCount = this.product.minBuy;
2541          const maxCount = this.product.limitBuy;
2542          if (minCount > 0 && maxCount > 0) {
2543            return 'For this product, each order requires a minimum purchase of minCount units and allows a maximum purchase of maxCount units.'.replace('minCount', minCount).replace('maxCount', maxCount);
2544          }
2545          if (minCount > 0) {
2546            return 'This product requires a minimum order of minCount pieces per order'.replace('minCount', minCount);
2547          }
2548          if (maxCount > 0) {
2549            return 'For this product, each order allows a maximum purchase of maxCount units.'.replace('maxCount', maxCount);
2550          }
2551          return '';
2552        }
2553      },
2554      methods: {
2555        onClickSelectModal: function(objData, selectOptionStr) {
2556          this.isModalSelectShow = true;
2557          this.modalOption = objData;
2558          this.selectOption = selectOptionStr
2559          this.selectCurrentStr = this.currentOption && (String(this.currentOption[selectOptionStr]) || null)
2560        },
2561        onChangeModalSelect: function(flag, isSelect) {
2562          if(!isSelect){
2563            this.setOption(this.selectOption,this.selectCurrentStr,this.modalOption.types)
2564          }
2565          this.isModalSelectShow = flag;
2566        },
2567        setOption: function(optionKey, type, dataArr) {
2568          let flag = true
2569          dataArr.forEach(item => {
2570            if (item.name === type) {
2571              flag = item.isValid
2572            }
2573          })
2574          if (flag) {
2575            this.toggleCurrentOption(optionKey, type)
2576          }
2577        },
2578        addToWishListEvent: function() {
2579          try {
2580            if (appMarketAddToWishListEvent) {
2581              var product = this.product;
2582              var currentVariant = this.currentVariant
2583              var element = $(`.btn[data-id=${product.id}]`);
2584              var index;
2585              var listName;
2586              if (element) {
2587                index = element.data('position')
2588                listName = element.data('list')
2589              }
2590              // sku_properties:選中款式的 option pairs(當前語系),類型名 zip 值
2591              var optionValues = [currentVariant.option1, currentVariant.option2, currentVariant.option3];
2592              var properties = [];
2593              (product.options || []).forEach(function(optionName, i) {
2594                if (optionName && optionValues[i]) {
2595                  properties.push({ name: optionName, value: optionValues[i] });
2596                }
2597              });
2598              var dataSet = {
2599                name: product.title,
2600                category: product.productType,
2601                categories: (this.categories && this.categories.length) ? this.categories : (categoryLevels.length ? categoryLevels : (product.id === pageMainProductId ? productCategoryLevels : undefined)),
2602                sku: currentVariant.sku,
2603                price: currentVariant.price,
2604                compare_at_price: currentVariant.compareAtPrice,
2605                properties: properties,
2606                quantity: currentVariant.inventoryQuantity,
2607                variant: currentVariant.title,
2608                listName: listName || null,
2609                productId: product.id,
2610                variantId: currentVariant.id,
2611                index: Number(index) || 0,
2612              }
2613              appMarketAddToWishListEvent(dataSet)
2614            }
2615          } catch (e) {
2616            console.error(e)
2617          }
2618        },
2619        addWishList: function() {
2620          if (this.currentVariant === null) {
2621            window.msg('Please select product specifications', 'warning').show();
2622            return;
2623          }
2624          var productVariantId = this.currentVariant.id;
2625          var addToWishListEvent = this.addToWishListEvent
2626          $.ajax({
2627            method: 'POST',
2628            url: '/tracking_items',
2629            dataType: 'json',
2630            data: {
2631              product_variant_id: productVariantId
2632            },
2633            success: function(response) {
2634              if (response.message) {
2635                window.msg(response.message, 'success').show();
2636                addToWishListEvent()
2637              }
2638
2639              if (response.error) {
2640                window.msg(response.error, 'error').show();
2641
2642              }
2643              if (response.info) {
2644                window.msg(response.info, 'info').show();
2645              }
2646              if (response.success === false) {
2647                if (window.liquidHelper && window.liquidHelper.language && window.liquidHelper.language.handle) {
2648                  window.location = "/" + window.liquidHelper.language.handle + "/account/login";
2649                } else {
2650                  window.location = "/account/login";
2651                }
2652              }
2653            }
2654          });
2655        },
2656        setChoose: function(currentVariant) {
2657          this.maxUsableBonus = 0;
2658          var quantity = 1;
2659          var cartItem = null;
2660          if (!this.isNnCollection && this.cartItems) {
2661            cartItem = this.normalGetChoosenItem(currentVariant);
2662          }
2663          if (this.isNnCollection) {
2664            cartItem = this.nnCollectionGetChoosenItem(currentVariant);
2665          }
2666          this.isChoose = !! cartItem;
2667          if (this.isNewNnCollection) {
2668            return
2669          }
2670          this.quantity = cartItem
2671            ? cartItem.quantity
2672            : this.quantity;
2673
2674          // product modal 聯絡店家情境
2675          if (currentVariant) {
2676            var photoIndex = 0;
2677            if (! currentVariant.imgUrl) {
2678              currentVariant.imgUrl = this.swiperPhotos.length > 0
2679                ? (this.swiperPhotos[photoIndex] && this.swiperPhotos[photoIndex].large)
2680                : this.featuredImage.large;
2681            }
2682            currentVariant.productTitle = this.product.title + ' - ' + this.currentVariant.title;
2683          }
2684        },
2685        normalGetChoosenItem: function(currentVariant) {
2686          return this.cartItems.find(function(cartItem) {
2687            return currentVariant && cartItem.id === currentVariant.id;
2688          });
2689        },
2690        nnCollectionGetChoosenItem: function(currentVariant) {
2691          var isSelected = null;
2692          if (! currentVariant) {
2693            return isSelected;
2694          }
2695          if (this.isNewNnCollection) {
2696            var cart = store.get(`SpecialCollectionCart_${this.collectionId}`);
2697            isSelected = cart && cart.find((item) => item.variant_id == currentVariant.id) || null;
2698          } else {
2699            store.each(function(value, key) {
2700              var productId = _.includes(key, 'Pro' + currentVariant.productId);
2701              var variantID = _.includes(key, 'Var' + currentVariant.id);
2702              if (productId && variantID) {
2703                isSelected = store.get(key);
2704              }
2705            });
2706          }
2707
2708          return isSelected;
2709        },
2710        // get product detail
2711        getProductDetail: function() {
2712          var self = this;
2713
2714          $.ajax({
2715            url: self.productUrl + '.json',
2716            type: 'GET',
2717            timeout: 30000,
2718            beforeSend: function() {
2719              self.isLoading = true;
2720            },
2721            error: function(xhr) {
2722              self.closeModal();
2723              if (xhr.status === 429) {
2724                window.showAddCartRateLimitModal(5);
2725                return;
2726              }
2727              window.msg('Network error, please try again later', 'error').show();
2728            }
2729          }).done(function(data) {
2730            if (data.id) {
2731              var productData = [themeHelper.toCamelCase(data)];
2732              self.product = themeHelper.priceWithDiscount(productData, liquidHelper.hasPriceWithDiscountPlugin)[0];
2733              self.maxUsableBonus = self.variantsMaxUsableBonus;
2734              if (self.product.variants.length === 1 || liquidHelper.isFirstVariantSelected || self.selectedVariantId) {
2735                self.currentVariant = self.firstValidVariant;
2736                // 如果已經自選商品,則商品頁下滑加入購物車顯示自選商品
2737                if (self.selectedVariantId) {
2738                  self.currentVariant = self.selectedValidVariant;
2739                }
2740                if (self.currentVariant) {
2741                  self.setChoose(self.currentVariant);
2742                  self.setDefaultOption();
2743                }
2744              }
2745              if (self.displayProductDiscountsList) {
2746                self.setUpDiscountsTag(data);
2747              }
2748              self.isLoading = false;
2749              if (self.product && self.product.variants) {
2750                self.product.variants.forEach(function(discountedVariant) {
2751                  var rawVariant = data.variants.find(function(v) { return v.id === discountedVariant.id; });
2752                  if (rawVariant) { rawVariant.price = discountedVariant.price; }
2753                });
2754              }
2755              viewItem && viewItem(data, { collectionId: '', collectionName: null, categories: (self.categories && self.categories.length) ? self.categories : (categoryLevels.length ? categoryLevels : (data.id === pageMainProductId ? productCategoryLevels : undefined)) });
2756
2757              (function() {
2758                // Read login status from cacheable, skip GET /pv_notification if not login.
2759                if (window.store && window.store.get('customer')) {
2760                  var cacheableCustomer = window.store.get('customer');
2761                  if (cacheableCustomer.notLogin) {
2762                    return;
2763                  }
2764                }
2765                $.ajax({
2766                  url: '/pv_notification',
2767                  method: 'GET',
2768                  dataType: 'json',
2769                  data: {
2770                    product_id: parseInt(data.id)
2771                  },
2772                  success: function(response) {
2773                    self.variantNotifications = response.variants;
2774                  }
2775                })
2776              })();
2777            } else {
2778              window.msg('Network error, please try again later', 'error').show();
2779              self.closeModal()
2780            }
2781          })
2782        },
2783        // product image btn
2784        photoOnChange: function(photoIndex, isVariantReposition) {
2785          var visiblePhotos = (this.currentVariant && this.currentVariant.photos.length)
2786            ? this.currentVariant.photos
2787            : this.product.photos.map(function(p) { return p.photo; });
2788          var result = themeHelper.buildNavigateItemImagePayload(this._navState, {
2789            product: this.product,
2790            currentVariant: this.currentVariant,
2791            visiblePhotos: visiblePhotos,
2792            slideIndex: photoIndex,
2793            videoOffset: this.firstImageIndex,
2794          });
2795          this._navState = result.nextState;
2796          if (result.payload && !isVariantReposition) {
2797            window.navigateItemImage(result.payload);
2798          }
2799          this.currentImageIndex = photoIndex;
2800        },
2801        toggleCurrentOption: function(key, value) {
2802          this.currentOption[key] =
2803            (this.currentOption[key] === value || value === 'null') ? null : value;
2804          var variantIndex = this.getVariantIndex();
2805          if (variantIndex !== -1) {
2806            this.currentVariant = this.product.variants[variantIndex];
2807          } else {
2808            this.currentVariant = null;
2809          }
2810          this.setChoose(this.product.variants[variantIndex]);
2811          if (this.currentOption[key] !== null) {
2812            var optionIndex = parseInt(key.replace('option', '')) - 1;
2813            appStoreSelectItemEvent(this.product, this.product.options[optionIndex], this.currentOption[key], this.currentVariant);
2814          }
2815        },
2816        toggleNotification: function() {
2817          var self = this;
2818          var variantId = this.currentVariant.id;
2819
2820          $.ajax({
2821            url: '/toggle_pv_notification',
2822            method: 'POST',
2823            dataType: 'json',
2824            data: {
2825              product_variant_id: variantId
2826            },
2827            success: function(response) {
2828              self.variantNotifications[variantId] = response.notice;
2829              window.msg(response.message, "success").show();
2830            },
2831            error: function(xhr) {
2832              var response = xhr.responseJSON;
2833              var msg = response && response.error || "Network error, please try again later";
2834              window.msg(msg, "error").show();
2835            }
2836          })
2837        },
2838        getOptionImageIndex: function(index) {
2839          this.currentImageIndex = index;
2840        },
2841        quantityDecrease: function() {
2842          if (this.cartItem) {
2843            themeHelper.EventBus.$emit('quantityDecrease', this.cartItem, false);
2844            this.quantity = this.cartItem.quantity
2845          } else {
2846            window.msg("Please select product specifications", 'warning').show();
2847          }
2848        },
2849        quantityIncrease: function() {
2850          if (this.cartItem) {
2851            themeHelper.EventBus.$emit('quantityIncrease', this.cartItem, false);
2852            this.quantity = this.cartItem.quantity
2853          } else {
2854            window.msg("Please select product specifications", 'warning').show();
2855          }
2856        },
2857        quantityChange: function(el) {
2858          if (this.cartItem) {
2859            themeHelper.EventBus.$emit('quantityChange', parseInt(el.target.value), this.cartItem, false);
2860            this.quantity = this.cartItem.quantity;
2861            el.target.value = this.cartItem.quantity;
2862          } else {
2863            window.msg("Please select product specifications", 'warning').show();
2864          }
2865        },
2866        addProduct: function() {
2867          if (this.addCartText === 'Contact Shop') {
2868            $('#messagebuy-Modal').data('variant', this.currentVariant);
2869            $('#messagebuy-Modal').modal('show');
2870            $('#messagebuy-Modal').css("background-color", "rgba(0, 0, 0, .6)");
2871          } else if (
2872            this.addCartText === 'Notification Enabled' ||
2873            this.addCartText === 'Sold out! Notify me when the product is available.'
2874          ) {
2875              this.toggleNotification();
2876          } else {
2877            if (this.cartItem) {
2878              try {
2879                if (this.isChoose) {
2880                  themeHelper.EventBus.$emit('updateStore', 'update', this.cartItem, this.callBack)
2881                } else {
2882                  themeHelper.EventBus.$emit('updateStore', 'add', this.cartItem, this.callBack)
2883                }
2884
2885                this.adding = true;
2886                this.closeModal();
2887              } catch (e) {
2888                window.msg("Unusual product specification; please select again.", 'error').show();
2889              }
2890            } else {
2891              window.msg("Please select product specifications", 'warning').show();
2892            }
2893          }
2894        },
2895        closeModal: function() {
2896          themeHelper.EventBus.$emit('closeProductModal');
2897        },
2898        setDefaultOption: function() {
2899          var self = this;
2900          Object.keys(self.currentOption).map(function(optionKey) {
2901            self.currentOption[optionKey] = self.currentVariant[optionKey];
2902          });
2903        },
2904        getVariantIndex: function() {
2905          var self = this;
2906          return self.product.variants.findIndex(function(variant, index) {
2907            var isVariant = true;
2908            Object.keys(self.currentOption).forEach(function(option) {
2909              if (variant[option] !== self.currentOption[option]) {
2910                isVariant = false;
2911              }
2912            });
2913            return isVariant;
2914          });
2915        },
2916
2917        // 篩選重複品項
2918        getUniqueVariant: function(variants) {
2919          return variants.filter(function(value, index, self) {
2920            return self.indexOf(value) === index;
2921          });
2922        },
2923        groupBy(xs, key) {
2924          return xs.reduce(function(rv, x) {
2925            (rv[x[key]] = rv[x[key]] || []).push(x);
2926            return rv;
2927          }, {});
2928        },
2929        setUpDiscountsTag(data) {
2930          var self = this;
2931          var languagePrefix = '/' + ((window.shopScriptHelper && window.shopScriptHelper.i18nLocale) || 'zh-TW');
2932          $.ajax({
2933            url: languagePrefix + self.productUrl + '/discounts_list',
2934            method: 'GET',
2935            success: function(result) {
2936              if (result.length > 0) {
2937                var discounts_list = self.groupBy(result, 'campaign_type');
2938                self.discountsList = discounts_list;
2939              } else {
2940                self.discountsList = null;
2941              }
2942            }
2943          });
2944        },
2945        getOptions: function(optionKey, optionTypes) {
2946          var self = this;
2947          return optionTypes.map(function(optionType, index) {
2948            var isValid = true;
2949
2950            // 選出包含目前type的variant
2951            var matchVariants = self.product.variants.filter(function(variant) {
2952              return variant[optionKey] === optionType;
2953            });
2954
2955            // 篩選已勾選type
2956            Object.keys(self.currentOption).forEach(function(currentOptionKey) {
2957              if (currentOptionKey !== optionKey) {
2958                matchVariants = matchVariants.filter(function(variant) {
2959                  if (self.currentOption[currentOptionKey]) {
2960                    return variant[currentOptionKey] === self.currentOption[currentOptionKey]
2961                  } else {
2962                    return true;
2963                  }
2964                });
2965              }
2966            });
2967            if (matchVariants.length === 0) {
2968              isValid = false;
2969            }
2970            if (! self.isEmptyClickable) {
2971              isValid = false;
2972              matchVariants.find(function(item) {
2973                if (item.inventoryQuantity === null || item.inventoryQuantity > 0 || item.inventoryPolicy === 'continue') {
2974                  isValid = true;
2975                }
2976              });
2977            }
2978            return {name: optionType, isValid: isValid}
2979          });
2980        }
2981      }
2982    };
2983  });
2984</script>
2984
2985
2986<!-- cyb_snippet _product_modal_js end -->
2987
2988<!-- cyb_snippet components/product_modal/product_modal end -->
2989
2990<!-- cyb_snippet messagebuy_modal start -->
2991
2992
2993<!-- cyb_snippet messagebuy_modal end -->
2994<!-- cyb_snippet components/rate_limit_modal start -->
2995<link href='//cdn-general.cybassets.com/frontend/shop/beta_theme/css/rate_limit_modal-3a2e378145f8a165.css' rel='stylesheet' type='text/css' media='all' />
2996
2997<div class="modal fade" id="rate-limit-modal" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" data-keyboard="false">
2998  <div class="modal-dialog modal-dialog-centered" role="document">
2999    <div class="modal-content">
3000      <div class="modal-body">
3001        <div class="qk-text--default_dark rate-limit-text">
3002          <p id="rate-limit-title">High demand right now, please wait</p>
3003          <p class="qk-fs--body qk-fw--500 rate-limit-message">
3004            <span class="qk-text--error" id="rate-limit-countdown"></span>
3005            <span id="rate-limit-desc"></span>
3006          </p>
3007          <p class="qk-fs--body qk-fw--500 rate-limit-message" id="rate-limit-warn">Leaving this page may increase your wait time.</p>
3008        </div>
3009        <button id="rate-limit-btn" class="btn qk-btn qk-btn--primary" disabled>Re-enter product page</button>
3010      </div>
3011    </div>
3012  </div>
3013</div>
3014
3015<script>
3016  window.showRateLimitModal = function(countdownSec) {
3017    var countdown = countdownSec || 5;
3018    var $modal = $('#rate-limit-modal');
3019    var $btn = $modal.find('#rate-limit-btn');
3020    var $countdownEl = $modal.find('#rate-limit-countdown');
3021
3022    $btn.show();
3023    $modal.find('#rate-limit-desc').text(language["product_rate_limit_desc"]);
3024    $countdownEl.text(countdown);
3025    $btn.prop('disabled', true);
3026    $modal.modal('show');
3027
3028    var timer = setInterval(function() {
3029      countdown--;
3030      $countdownEl.text(countdown);
3031      if (countdown <= 0) {
3032        clearInterval(timer);
3033        $btn.prop('disabled', false);
3034      }
3035    }, 1000);
3036
3037    $btn.off('click').on('click', function() {
3038      location.reload();
3039    });
3040  }
3041
3042  window.showAddCartRateLimitModal = function(countdownSec) {
3043    var countdown = countdownSec || 5;
3044    var $modal = $('#rate-limit-modal');
3045    var $countdownEl = $modal.find('#rate-limit-countdown');
3046
3047    $modal.find('#rate-limit-btn').hide();
3048    $modal.find('#rate-limit-desc').text(language["addcart_rate_limit_desc"]);
3049    $countdownEl.text(countdown);
3050    $modal.modal('show');
3051
3052    var timer = setInterval(function() {
3053      countdown--;
3054      $countdownEl.text(countdown);
3055      if (countdown <= 0) {
3056        clearInterval(timer);
3057        $modal.modal('hide');
3058      }
3059    }, 1000);
3060  }
3061</script>
3061
3062
3063<!-- cyb_snippet components/rate_limit_modal end -->
3064
3065<script>
3066  $(document).ready(function() {
3067    const shouldSkipQuantityCheck = false;
3068    const newAddCartModalApp = new window.themeHelper.LiquidVueHandler({
3069      componentNames: Object.keys(window.themeHelper.productModalComponents),
3070      mountSelector: '#new-addcart-modal',
3071      autoMount: false,
3072    });
3073
3074    newAddCartModalApp.createApp({
3075      el: '#new-addcart-modal',
3076      delimiters: ['${', '}'],
3077      data() {
3078        return {
3079          collectionId: 0,
3080          categories: [],
3081          color: '', // unused
3082          isCollection: true,
3083          productQuantity: 0,
3084          onlyDescription: false,
3085          showProductModal: false,
3086          popProductUrl: '',
3087          loading: false,
3088        };
3089      },
3090      mounted: function() {
3091        themeHelper.EventBus.$on('closeProductModal',this.closeProductModal);
3092        themeHelper.EventBus.$on('updateStore', this.addProduct);
3093        themeHelper.EventBus.$on('quantityDecrease', this.quantityDecrease);
3094        themeHelper.EventBus.$on('quantityIncrease', this.quantityIncrease);
3095        themeHelper.EventBus.$on('quantityChange', this.quantityChange);
3096      },
3097      methods: {
3098        addProduct: function(actionType, productData, checkoutAddToCartCallback){
3099          var self = this;
3100          var pageViewId = window.CYBERBIZ && window.CYBERBIZ.dis && window.CYBERBIZ.dis.pageViewId;
3101          $.ajax({
3102            method: 'POST',
3103            url: '/cart/add',
3104            headers: pageViewId ? { 'X-Cyb-Page-View-Id': pageViewId } : {},
3105            data: {
3106              id: productData.id,
3107              quantity: productData.quantity,
3108            },
3109            dataType: 'json',
3110            beforeSend: function() {
3111              self.loading = true;
3112              themeHelper.ajaxLoadingMsg('loading');
3113              $('.shopcart').dropdown('hide')
3114              $('.global-cart-count').hide();
3115              $('.global-cart-loading').show();
3116              $('.global-cart-loading').html('<i class="fa fa-spinner fa-pulse" style="vertical-align: middle;"></i>');
3117            },
3118            error: function(xhr) {
3119              $('.global-cart-loading').hide();
3120              $('.global-cart-count').show();
3121              self.loading = false;
3122              if (xhr.status === 429) {
3123                themeHelper.ajaxLoadingMsg('hide', 0);
3124                self.closeProductModal();
3125                window.showAddCartRateLimitModal(5);
3126                return;
3127              }
3128              themeHelper.ajaxLoadingMsg('fail', 2000);
3129            }
3130          }).done(function(data, status, request){
3131            // product modal 立即購買按鈕
3132            window.sendAddToCartEvent && sendAddToCartEvent({
3133              price: productData.price,
3134              quantity: productData.quantity,
3135              id: productData.product.id,
3136              name: productData.product.title,
3137              category: productData.product.productType,
3138              brand: productData.product.vendor,
3139              qc: productData.variant.qc,
3140              variant: {
3141                id: productData.variant.id,
3142                title: productData.variant.title,
3143                sku: productData.variant.sku,
3144                price: productData.variant.price,
3145                qc: productData.variant.qc,
3146              },
3147              position: "商品彈出視窗",
3148              request,
3149            })
3150            if (self.isQuickBuy) {
3151              if (window.liquidHelper && window.liquidHelper.language && window.liquidHelper.language.handle) {
3152                window.location = "/" + window.liquidHelper.language.handle + "/cart";
3153              } else {
3154                window.location = "/cart";
3155              }
3156            } else {
3157              themeHelper.ajaxLoadingMsg('success');
3158              pullNavCart();
3159              $('.shopcart').dropdown('show')
3160              $('.global-cart-loading').hide();
3161              self.loading = false;
3162            }
3163            if(typeof checkoutAddToCartCallback === 'function'){
3164              var callbackData = {
3165                id: productData.id,
3166                quantity: productData.quantity,
3167                title: productData.product ? productData.product.title : productData.title || ''
3168              };
3169              checkoutAddToCartCallback(callbackData)
3170            }
3171            peh.emit('product:add_to_cart', [{
3172              variantId: productData.id,
3173              quantity: productData.quantity
3174            }], self.collectionId);
3175          }).fail(function(e){
3176            if (e.status === 429) {
3177              return;
3178            }
3179            let err_msg = e.responseJSON.err_msg;
3180            err_msg && err_msg.length > 0 ?
3181              window.msg(e.responseJSON.err_msg, 'warning').show():
3182              window.msg("Network error, please try again.", 'warning').show();
3183          })
3184        },
3185        quantityDecrease: function(cartItem, isAdded){
3186          if (cartItem.quantity > 1) {
3187            cartItem.quantity -= 1;
3188          } else {
3189            window.msg("Quantity must be greater than 0;
3189 please select the amount to purchase.", 'warning').show();
3190          }
3191        },
3192        quantityIncrease: function(cartItem, isAdded){
3193          const limitQuantity = cartItem.variant.inventoryQuantity;
3194          const limitBuy = cartItem.product.limitBuy
3195          if (limitBuy && cartItem.quantity >= limitBuy) {
3196            product_limit_buy = "Limited purchase of this product limitBuy items".replace('limitBuy', limitBuy)
3197            window.msg(product_limit_buy, 'warning').show();
3198            return;
3199          } else if (cartItem.quantity >= liquidHelper.cartQuantityLimit) {
3200            window.msg("Quantity exceeds shopping cart limit; please remove some items and place the order again.", 'warning').show();
3201          } else if ( cartItem.quantity < limitQuantity || limitQuantity === null ||
3202            cartItem.variant.inventoryPolicy == "continue" || shouldSkipQuantityCheck) {
3203            cartItem.quantity += 1;
3204          } else {
3205            this.showInventoryMessage(limitQuantity);
3206          }
3207        },
3208        quantityChange: function(quantity, cartItem, isAdded){
3209          const limitBuy = cartItem.product.limitBuy
3210          var limitQuantity = cartItem.variant.inventoryQuantity;
3211          var inventoryPolicy = cartItem.variant.inventoryPolicy;
3212          if (Number.isInteger(quantity)) {
3213            if (quantity >= 1) {
3214              if (limitBuy && quantity >= limitBuy) {
3215                product_limit_buy = "Limited purchase of this product limitBuy items".replace('limitBuy', limitBuy)
3216                window.msg(product_limit_buy, 'warning').show();
3217              } else if (quantity > liquidHelper.cartQuantityLimit) {
3218                window.msg("Quantity exceeds shopping cart limit; please remove some items and place the order again.", 'warning').show();
3219              } else if (quantity <= limitQuantity || limitQuantity === null || inventoryPolicy == "continue" || shouldSkipQuantityCheck) {
3220                cartItem.quantity = quantity;
3221              } else {
3222                cartItem.quantity = limitQuantity;
3223                this.showInventoryMessage(limitQuantity);
3224              }
3225            } else {
3226              window.msg("Quantity must be greater than 0; please select the amount to purchase.", 'warning').show();
3227            }
3228          } else {
3229            window.msg("Quantity input error", 'warning').show();
3230          }
3231        },
3232        popModal: function(productUrl, collectionId, color, isCollection, isShowDescription, isQuickBuy, variantId, checkoutAddToCartCallback, categories){
3233          this.showProductModal = true;
3234          this.collectionId = collectionId;
3235          this.categories = categories || [];
3236          this.popProductUrl = productUrl;
3237          this.color = color || ''; // unused
3238          this.isCollection = isCollection || false;
3239          this.isShowDescription = isShowDescription != false;
3240          this.isQuickBuy = isQuickBuy || false;
3241          this.selectedVariantId = parseInt(variantId) || undefined;
3242          this.checkoutAddToCartCallback = checkoutAddToCartCallback;
3243          document.body.style.overflow = "hidden";
3244        },
3245        closeProductModal: function() {
3246          this.showProductModal = false;
3247          document.body.style.overflow = "";
3248        },
3249        showInventoryMessage: function(inventoryQuantity) {
3250          const stockMessage = "Quantity exceeds inventory stock. Remaining count".replace('count', inventoryQuantity || 0);
3251          window.msg(stockMessage, 'warning').show();
3252        },
3253      }
3254    });
3255
3256    for (const componentName in window.themeHelper.productModalComponents) {
3257      newAddCartModalApp.component(
3258        componentName,
3259        window.themeHelper.productModalComponents[componentName],
3260      );
3261    }
3262
3263    window.new_addcart_modal = newAddCartModalApp.mount();
3264  });
3265</script>
3265
3266
3267<!-- cyb_snippet new_addcart_modal end -->
3268<!-- cyb_snippet components/variant_options/variant_photos_block start -->
3269<script type="text/x-template" id="variant-photos-block">
3270  <div class="product_photos qk-w--100">
3271    <!-- 有色票 -->
3272    <div class="product_photo img-flex qk-text--center" v-if="displayProductImagesColor">
3273      <img id="photo_with_images_color" class="img-lazy" :src="imgLoadingImage" data-src="//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL3Byb2R1Y3RzLzU4MDIxMzk1LzE3NTM5NTA3NzNfMGY5MDQ5MzhjYzU5YjNlNWE2ZTYucG5nIl0sWyJwIiwidGh1bWIiLCI2MDB4NjAwIl1d.png?sha=f82201060579a604" alt="X2 - Smart Cycling Computer" width="450" height="450">
3274    </div>
3275    <!-- 沒色票 -->
3276    <div class="swiper swiper-container product_img_swiper" v-else>
3277      <ul class="swiper-wrapper qk-pd--0 qk-mg--0">
3278        <video-display
3279          v-if="shouldShowVideo && !videoAfterImage"
3280          :poster="!!showPhotos.length ? showPhotos[0].imageUrl : imgLoadingImage"
3281          :videoUrl="videoUrl"
3282        ></video-display>
3283        <li class="swiper-slide product_photo img-flex qk-text--center qk-of--hidden default_scale"
3284          v-for="photo in showPhotos"
3285          :key="photo.id"
3286        >
3287          <img
3288            :data-src="photo.imageUrl"
3289            width="450"
3290            height="450"
3291            class="swiper-lazy"
3292            alt="X2 - Smart Cycling Computer"
3293            @click="onEnlargePhotos()"
3294          />
3295          <div class="swiper-lazy-preloader"></div>
3296        </li>
3297        <li v-if="showDefault" class="swiper-slide product_photo img-flex qk-text--center qk-of--hidden default_scale">
3298          <img :src="imgLoadingImage" data-src="//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL3Byb2R1Y3RzLzU4MDIxMzk1LzE3NTM5NTA3NzNfMGY5MDQ5MzhjYzU5YjNlNWE2ZTYucG5nIl0sWyJwIiwidGh1bWIiLCI2MDB4NjAwIl1d.png?sha=f82201060579a604" alt="X2 - Smart Cycling Computer" width="450" height="450" class="swiper-lazy">
3299        </li>
3300        <video-display
3301          v-if="shouldShowVideo && videoAfterImage"
3302          :poster="!!showPhotos.length ? showPhotos[0].imageUrl : imgLoadingImage"
3303          :videoUrl="videoUrl"
3304        ></video-display>
3305      </ul>
3306      <!-- Add Arrows -->
3307      <div class="photo-swiper-next qk-swiper_btn qk-swiper_btn--lg qk-swiper_btn--v1 qk-swiper_btn--next qk-hidden--mobile"></div>
3308      <div class="photo-swiper-prev qk-swiper_btn qk-swiper_btn--lg qk-swiper_btn--v1 qk-swiper_btn--prev qk-hidden--mobile"></div>
3309      <div class="photo-pagination qk-bd--default qk-bd--body qk-text--center qk-text--body qk-fs--breadcrumb qk-visible-sm">
3310        <span class="current-index qk-text--default_dark">${activePhotoIndex + 1}</span><span class="pagination-slash">/</span>
3311        <span>${shouldShowVideo ? (showPhotos.length ? showPhotos.length + 1 : 2) : showPhotos.length || 1}</span>
3312      </div>
3313    </div>
3314    <!-- 圖片頁碼 -->
3315    <div v-if="showThumbnails" class="thumb qk-of--auto qk-hidden--phone">
3316      <ul class="thumb-container qk-display--il_flex">
3317        <video-thumbnail
3318          v-if="shouldShowVideo && !videoAfterImage"
3319          :active="isVideoActive"
3320          :video-url="videoUrl"
3321          @click="onClickThumbnail(videoIndex)"
3322        ></video-thumbnail>
3323        <li class="img-flex qk-bd--default qk-bd--border qk-cursor--pointer qk-of--hidden qk-display--il_flex"
3324          :class="{active: (shouldShowVideo && !videoAfterImage ? index + 1 : index) === activePhotoIndex}"
3325          v-for="(photo, index) in showPhotos"
3326          :key="photo.id"
3327          @click="onClickThumbnail(shouldShowVideo && !videoAfterImage ? index + 1 : index)"
3328        >
3329          <img class="img-lazy" :src="imgLoadingImage" :data-src="photo.imageUrl" alt="X2 - Smart Cycling Computer" width="50" height="50">
3330        </li>
3331        <li v-if="showDefault"
3332          class="img-flex qk-bd--default qk-bd--border qk-of--hidden qk-display--il_flex"
3333          :class="{active: (shouldShowVideo && !videoAfterImage ? 1 : 0) === activePhotoIndex}"
3334        >
3335          <img class="img-lazy" :src="imgLoadingImage" data-src="//cdn-general.cybassets.com/media/W1siZiIsIjMzMzczL3Byb2R1Y3RzLzU4MDIxMzk1LzE3NTM5NTA3NzNfMGY5MDQ5MzhjYzU5YjNlNWE2ZTYucG5nIl0sWyJwIiwidGh1bWIiLCI2MDB4NjAwIl1d.png?sha=f82201060579a604" alt="X2 - Smart Cycling Computer" width="50" height="50">
3336        </li>
3337        <video-thumbnail
3338          v-if="shouldShowVideo && videoAfterImage"
3339          :active="isVideoActive"
3340          :video-url="videoUrl"
3341          @click="onClickThumbnail(videoIndex)"
3342        ></video-thumbnail>
3343      </ul>
3344    </div>
3345  </div>
3346</script>
3346
3347
3348<script type="text/javascript">
3349  $(document).ready(function() {
3350    var autoSelectVariantBySku = true;
3351
3352    themeHelper.variantPhotosBlock.component('variant-photos-block', {
3353      template: '#variant-photos-block',
3354      delimiters: ['${', '}'],
3355      data: function() {
3356        return {
3357          variantPhotos: null,
3358          productPhotosMap: {},
3359          productPhotos: [],
3360          manualSelectedVariant: false,
3361          activePhotoIndex: 0,
3362          _navState: { variantId: null, photoIndex: 0 },
3363          suppressNavigateEvent: false,
3364          currentVariantForEvent: null,
3365          swiperPhotos: null,
3366          swiperGalleryChangeHandler: null,
3367          showDefault: true,
3368          videoUrl: '',
3369          videoAfterImage: false,
3370          imgLoadingImage:"//cdn-general.cybassets.com/img_loading.svg",
3371          thumbScrollHandler: null,
3372          thumbScrollTimeout: null,
3373          showThumbnails: false,
3374        }
3375      },
3376      props: {
3377        displayProductImagesColor: Boolean,
3378        productPhotosJson: String,
3379        productVideo: Object,
3380        videoDisplayLocation: String,
3381        productId: [String, Number],
3382        productTitle: String,
3383      },
3384      mounted: async function() {
3385        this.productPhotos = JSON.parse(this.productPhotosJson.replace(/'/g, '"'));
3386        this.productPhotosMap =
3387          this.productPhotos.reduce((acc, cur) => {
3388            acc[cur.id] = cur;
3389            return acc;
3390          }, {});
3391        this.videoUrl = !!this.productVideo && this.productVideo.url;
3392        this.showDefault = !this.showPhotos.length;
3393        this.videoAfterImage = this.videoDisplayLocation === 'after';
3394        themeHelper.EventBus.$on('updatePhotos', this.onUpdatePhotos);
3395        this.swiperGalleryChangeHandler = (_event, payload) => this.onSwiperGalleryChange(payload);
3396        $(document).on('swiper-gallery-change', this.swiperGalleryChangeHandler);
3397
3398        var sku = window.getURLParameter('sku');
3399
3400        if (sku && autoSelectVariantBySku) {
3401          themeHelper.EventBus.$on('skuReady', this.onSkuReady);
3402        } else {
3403          this.showThumbnails = true;
3404          await this.initPhotosUI();
3405        }
3406      },
3407      beforeUnmount: function() {
3408        this.removeThumbScrollListener();
3409        if (this.swiperGalleryChangeHandler) {
3410          $(document).off('swiper-gallery-change', this.swiperGalleryChangeHandler);
3411        }
3412      },
3413      methods: {
3414        navigateItemImagePayload: function(state, slideIndex, videoOffset) {
3415          return themeHelper.buildNavigateItemImagePayload(state, {
3416            product: { id: this.productId, title: this.productTitle },
3417            currentVariant: this.currentVariantForEvent,
3418            visiblePhotos: this.showPhotos,
3419            slideIndex: slideIndex,
3420            videoOffset: videoOffset,
3421          });
3422        },
3423        initPhotosUI: async function() {
3424          await this.$nextTick();
3425          this.initSwiper();
3426
3427          this._navState = this.navigateItemImagePayload(this._navState, this.initialItemIndex, this.videoOffset).nextState;
3428
3429          // 初始化縮圖滾動監聽
3430          this.initThumbScrollListener();
3431
3432          const videoElement = $('.product_video.swiper-slide-active video')[0];
3433          if (videoElement) {
3434            videoElement.addEventListener('canplay', (event) => {
3435              this.sendGtag('play');
3436            }, { once: true });
3437          }
3438        },
3439        onSkuReady: async function() {
3440          await this.initPhotosUI();
3441          this.showThumbnails = true;
3442          await this.$nextTick();
3443          imgLazyLoad.update();
3444          themeHelper.EventBus.$emit('skuPhotosReady');
3445        },
3446        initThumbScrollListener: function() {
3447          const thumbScrollContainer = this.$el.querySelector('.thumb');
3448
3449          if (thumbScrollContainer) {
3450            this.removeThumbScrollListener();
3451            this.thumbScrollHandler = () => {
3452              clearTimeout(this.thumbScrollTimeout);
3453              this.thumbScrollTimeout = setTimeout(() => {
3454                if (window.imgLazyLoad) {
3455                  imgLazyLoad.update();
3456                }
3457              }, 100);
3458            };
3459            thumbScrollContainer.addEventListener('scroll', this.thumbScrollHandler);
3460          }
3461        },
3462        removeThumbScrollListener: function() {
3463          const thumbScrollContainer = this.$el.querySelector('.thumb');
3464
3465          if (thumbScrollContainer && this.thumbScrollHandler) {
3466            thumbScrollContainer.removeEventListener('scroll', this.thumbScrollHandler);
3467            clearTimeout(this.thumbScrollTimeout);
3468            this.thumbScrollHandler = null;
3469          }
3470        },
3471        sendGtag: function(action){
3472          window.productVideoView && productVideoView(action);
3473        },
3474        handleVideoClick: function() {
3475          const video = $('.product_video.swiper-slide-active video')[0];
3476          const button = $('.product_video.swiper-slide-active button');
3477          if (video.paused){
3478            video.play();
3479            this.sendGtag('play');
3480          } else {
3481            video.pause();
3482            this.sendGtag('paused');
3483          }
3484          this.handleVideoButtonDisplay(button, video);
3485        },
3486        handleVideoButtonDisplay: function(button, video) {
3487          button.toggleClass('videoPlayer__playButton', video.paused);
3488          button.toggleClass('videoPlayer__pauseButton', !video.paused);
3489        },
3490        onUpdatePhotos: async function(currentVariant) {
3491          this.suppressNavigateEvent = true;
3492          this.currentVariantForEvent = currentVariant && currentVariant.variant
3493            ? { id: currentVariant.variant.id, sku: currentVariant.variant.sku }
3494            : null;
3495          if (this.swiperPhotos) {
3496            this.swiperPhotos.destroy(true, true);
3497          }
3498          $('.product_img_swiper .swiper-slide-duplicate').remove();
3499          $('.product_img_swiper .swiper-lazy-loading').removeClass('swiper-lazy-loading');
3500          this.manualSelectedVariant = currentVariant ? currentVariant.withSpecificVariant : false;
3501          if (currentVariant && currentVariant.photos.length) {
3502            this.variantPhotos = currentVariant.photos.map(p => this.productPhotosMap[p.id]);
3503          } else  {
3504            this.variantPhotos = null;
3505          }
3506
3507          this.activePhotoIndex = this.initialItemIndex;
3508
3509          this._navState = this.navigateItemImagePayload(this._navState, this.activePhotoIndex, this.videoOffset).nextState;
3510          await this.$nextTick();
3511          imgLazyLoad.update();
3512          this.initSwiper();
3513          this.suppressNavigateEvent = false;
3514        },
3515        onEnlargePhotos: function() {
3516          gallery_img.updateImgs(this.maxPhotos);
3517          gallery_img.toggleGallery(true, {
3518            index: this.swiperPhotos.realIndex - this.videoOffset
3519          });
3520        },
3521        onSwiperGalleryChange: function(payload) {
3522          if (!payload || payload.galleryName !== 'img') return;
3523
3524          var result = this.navigateItemImagePayload(
3525            {
3526              variantId: this.currentVariantForEvent ? this.currentVariantForEvent.id : null,
3527              photoIndex: payload.fromIndex,
3528            },
3529            payload.toIndex,
3530            0
3531          );
3532
3533          if (result.payload && !this.suppressNavigateEvent) {
3534            window.navigateItemImage(result.payload);
3535          }
3536        },
3537        onClickThumbnail: function(index) {
3538          this.activePhotoIndex = index;
3539          this.swiperPhotos.slideTo(index + 1, 500);
3540        },
3541        setVideosVolumeZero: function() {
3542          // video duplication because of swiper loop mode
3543          const videos = $('.product_video video');
3544          videos.each((_index, el)=> {
3545              el.volume = 0;
3546          });
3547        },
3548        initSwiper: function() {
3549          var self = this;
3550          this.swiperPhotos = new Swiper('.product_img_swiper', {
3551            preloadImages: false,
3552            lazy: {
3553              loadPrevNext: true,
3554            },
3555            loop: true,
3556            navigation: {
3557              nextEl: '.photo-swiper-next',
3558              prevEl: '.photo-swiper-prev',
3559            },
3560            initialSlide: this.initialItemIndex,
3561          });
3562          if (self.videoUrl) {
3563            self.setVideosVolumeZero();
3564          }
3565          this.swiperPhotos.on('touchEnd', function () {
3566            setTimeout(function() {
3567              self.activePhotoIndex = self.swiperPhotos.realIndex;
3568            }, 300);
3569          });
3570          this.swiperPhotos.on('activeIndexChange', function() {
3571            self.activePhotoIndex = self.swiperPhotos.realIndex;
3572          });
3573          this.swiperPhotos.on('click', function () {
3574            if (self.isVideoActive) {
3575              self.handleVideoClick()
3576            }
3577          });
3578          this.swiperPhotos.on('transitionEnd', function () {
3579            if (self.isVideoActive) {
3580              const video = $('.product_video.swiper-slide-active video')[0];
3581              const button = $('.product_video.swiper-slide-active button');
3582              self.handleVideoButtonDisplay(button, video);
3583            }
3584          });
3585        }
3586      },
3587      computed: {
3588        shouldShowVideo: function() {
3589          return !!this.videoUrl;
3590        },
3591        initialItemIndex: function() {
3592          if (this.shouldShowVideo && !this.videoAfterImage) {
3593            // Focus on photo if "variant with photos" selected, video otherwise
3594            return (this.manualSelectedVariant && !!this.variantPhotos?.length) ? 1 : 0;
3595          } else {
3596            // Focus on first photo
3597            return 0;
3598          }
3599        },
3600        isVideoActive: function() {
3601          return this.shouldShowVideo && this.activePhotoIndex === this.videoIndex;
3602        },
3603        showPhotos: function() {
3604          return this.variantPhotos || this.productPhotos;
3605        },
3606        maxPhotos: function() {
3607          return this.showPhotos.map(p => p.imageMaxUrl);
3608        },
3609        videoIndex: function(){
3610          return this.videoAfterImage
3611            ? this.manualSelectedVariant && !!this.variantPhotos?.length
3612              ? this.variantPhotos?.length
3613              : this.showPhotos.length || 1
3614            : 0
3615        },
3616        videoOffset: function() {
3617          return (this.shouldShowVideo && !this.videoAfterImage) ? 1 : 0;
3618        },
3619      },
3620      watch: {
3621        activePhotoIndex: function(newIndex) {
3622          var result = this.navigateItemImagePayload(this._navState, newIndex, this.videoOffset);
3623          this._navState = result.nextState;
3624          if (result.payload && !this.suppressNavigateEvent) {
3625            window.navigateItemImage(result.payload);
3626          }
3627        },
3628      }
3629    });
3630  })
3631</script>
3631
3632
3633<!-- cyb_snippet components/variant_options/video_display start -->
3634<script type="text/x-template" id="video-display">
3635  <li
3636    class="swiper-slide product_video img-flex qk-text--center qk-of--hidden default_scale">
3637    <div class="videoPlayer__wrapper qk-of--hidden">
3638      <video
3639        class="videoPlayer__video qk-cursor--pointer"
3640        :poster="poster"
3641        loop defaultMuted muted playsinline webkit-playsinline autoplay
3642      >
3643        <source :src="videoUrl" type="video/mp4">
3644        <p>Your browser does not support HTML 5 video.</p>
3645      </video>
3646      <button class="videoPlayer__pauseButton"></button>
3647    </div>
3648  </li>
3649</script>
3649
3650
3651<script type="text/javascript">
3652  $(document).ready(function() {
3653    themeHelper.variantPhotosBlock.component('video-display', {
3654      template: '#video-display',
3655      delimiters: ['${', '}'],
3656      data: function() {
3657        return {
3658          imgLoadingImage:"//cdn-general.cybassets.com/img_loading.svg",
3659        }
3660      },
3661      props: {
3662        poster: String,
3663        showPhotos: Object,
3664        videoUrl: String,
3665      },
3666    });
3667  })
3668</script>
3668
3669
3670<!-- cyb_snippet components/variant_options/video_display end -->
3671<!-- cyb_snippet components/variant_options/video_thumbnail start -->
3672<script type="text/x-template" id="video-thumbnail">
3673  <li
3674    :class="{active}"
3675    class="img-flex qk-bd--default qk-bd--border qk-cursor--pointer qk-of--hidden qk-display--il_flex"
3676    @click="click"
3677  >
3678    <video width="50" height="50">
3679      <source :src="videoUrl" type="video/mp4">
3680    </video>
3681    <button class="videoPlayer__playButton"></button>
3682  </li>
3683</script>
3683
3684
3685<script type="text/javascript">
3686  $(document).ready(function() {
3687    themeHelper.variantPhotosBlock.component('video-thumbnail', {
3688      template: '#video-thumbnail',
3689      delimiters: ['${', '}'],
3690      props: {
3691        active: Boolean,
3692        click: Function,
3693        videoUrl: String,
3694      },
3695    });
3696  })
3697</script>
3697
3698
3699<!-- cyb_snippet components/variant_options/video_thumbnail end -->
3700
3701<!-- cyb_snippet components/variant_options/variant_photos_block end -->
3702<!-- cyb_snippet components/variant_options/variant_options_block start -->
3703<script type="text/x-template" id="variant-options-block">
3704  <div>
3705    <div v-for="(option, index) in optionInfo" class="product-variant-option" :class="{'product-variant-option--hidden': shouldHideSingleVariantOptions}">
3706        <p></p>
3707        <color-option
3708          v-if="isImageColor && option.name === '顏色'"
3709          :option-key="'option' + (index + 1)"
3710          :option="option"
3711          :image-colors="imageColors"
3712          :current-image-index="currentImageIndex"
3713          :set-current-image-index="setCurrentImageIndex"
3714          :get-option-image-index="getOptionImageIndex"
3715          :current-option="currentOption"
3716        />
3717        <div class="advance variant-select-option" v-else-if="styledShopMenu==='dropDownType'">
3718          
3719          <label>${option.name}</label>
3720          <svg height="20" width="20" viewBox="0 0 20 20" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"><path d="M4.516 7.548c0.436-0.446 1.043-0.481 1.576 0l3.908 3.747 3.908-3.747c0.533-0.481 1.141-0.446 1.574 0 0.436 0.445 0.408 1.197 0 1.615-0.406 0.418-4.695 4.502-4.695 4.502-0.217 0.223-0.502 0.335-0.787 0.335s-0.57-0.112-0.789-0.335c0 0-4.287-4.084-4.695-4.502s-0.436-1.17 0-1.615z"> </path></svg>
3721          <select v-show="!isMobileSize" class="qk-bg--theme_bg" :class="{'select_placeholder-color': currentOption[`option${index + 1}`] === null}" :value="String(currentOption[`option${index + 1}`])" @change="setOption(`option${index + 1}`, $event.target.value, option.types )" >
3722            <option value="null" class="select_option-hidden">Please select ${option.name}</option>
3723            <option  v-for="(types) in option.types" :disabled="!types.isValid" :value="types.name">${types.name}</option>
3724          </select>
3725          <span class="select_placeholder-color" v-if="currentOption[`option${index + 1}`] === null" v-show="isMobileSize" @click="onClickSelectModal(option,`option${index + 1}`)">Please select ${option.name}</span>
3726          <span v-else :value="currentOption[`option${index + 1}`]" v-show="isMobileSize" @click="onClickSelectModal(option,`option${index + 1}`)" v-html="currentOption[`option${index + 1}`]"></span>
3727        </div>
3728        <advance-variant-option
3729          v-else
3730          :option-key="'option' + (index + 1)"
3731          :option="option"
3732          :current-option="currentOption"
3733        />
3734      </div>
3735    <div class="mobile-modal" :class="{ 'modal-open': isModalSelectShow && isMobileSize }">
3736        <div class="mobile_modal-content">
3737          
3738          <div class="modal_close-button">
3739            <button class="btn-close qk-circle qk-circle--md qk-pos--abs qk-op--100  qk-text--heading qk-bd--product_border qk-bd--default" @click="onChangeModalSelect(false,true)"></button>
3740          </div>
3741          <p>Please select ${modalOption.name}</p>
3742          <div class="modal_select-templete qk-display--flex qk-of_y--auto qk-w--100">
3743            <div class="options-container">
3744              <label :class="{'seleced-option': currentOption && currentOption[selectOption] === data.name, 'avoid-clicks':!data.isValid}" v-for="data in modalOption.types" @click="setOption(selectOption, data.name, modalOption.types)">${data.name}</label>
3745            </div>
3746          </div>
3747          <div v-if="isCartEnabled && salesModePurchasable" class="modal_select_footer qk-display--flex qk-hidden--pc">
3748            <div v-show="variantSize === 1" class="qk-display--flex qk-w--100">
3749              <div class="product_variant_quantity">
3750                <span class="product_quantity">
3751                  <div v-if="isModalSelectShow && isMobileSize" class="btn-group" role="group" aria-label="First group">
3752                    <button class="btn add-down qk-bd--product_border" type="button" @click="quantityChange(false)" ></button>
3753                    <input class="btn item-quantity qk-text--heading qk-bd--product_border" type="text" name="quantity" value="1" data-old-value="1">
3754                    <button class="btn add-up qk-bd--product_border" type="button" @click="quantityChange(true)"></button>
3755                  </div>
3756                </span>
3757              </div>
3758              <button
3759                class="btn addToCart_mobile btn_to_cart_mobile open_product_modal qk-btn qk-btn--secondary qk-flex--1 qk-fs--breadcrumb qk-text-truncate"
3760                data-handle="x2">
3761                ADD TO CART</button>
3762            </div>
3763            <div v-show="variantSize > 1" class="qk-display--flex qk-w--100">
3764              <button type="button" class="modal_cancel qk-w--50 qk-bd--default qk-btn--secondary qk-bd--button qk-text--button" @click="onChangeModalSelect(false,false)">Cancel</button>
3765              <button type="button" class="qk-btn qk-w--50 qk-btn--primary qk-btn--lg qk-fs--body qk-bd--button qk-test--button_text" @click="onChangeModalSelect(false,true)">Finish</button>
3766            </div>
3767          </div>
3768        </div>
3769    </div>
3770  </div>
3771</script>
3771
3772
3773<!-- cyb_snippet components/variant_options/color_image_option start -->
3774<script id="color-option" type="text/x-template">
3775  <div class="option color_option">
3776    <span class="title qk-text--heading">Color:</span>
3777    <label
3778      v-for="(imageColor, index) in imageColors"
3779      :class="{
3780        'image-option': true,
3781        'selected': selectedClass(index),
3782        'disabled': disabledClass(index),
3783      }"
3784      @mouseleave="setCurrentImageIndex(index)"
3785      @mouseover="getOptionImageIndex(index)"
3786      @click="setOption(optionKey, index)"
3787      class="qk-bd--default qk-bd--border"
3788    >
3789      <span class="img-flex qk-display--il_bk">
3790        <img v-if="imageColor !== 'noColorImage'" :src="imageColor.large" alt="image">
3791        <img v-else src="/assets/no-image-large.png" alt="image">
3792      </span>
3793    </label>
3794  </div>
3795</script>
3795
3796
3797<script type="text/javascript">
3798  $(document).ready(function () {
3799    themeHelper.variantOptionsBlock.component('color-option', {
3800      template: '#color-option',
3801      delimiters: ['${', '}'],
3802      props: {
3803        optionKey: String,
3804        option: Object,
3805        imageColors: Array,
3806        setCurrentImageIndex: Function,
3807        getOptionImageIndex: Function,
3808        currentOption: Object,
3809      },
3810      methods: {
3811        setOption: function(optionKey, index) {
3812          var type = this.option.types[index];
3813          if (type.isValid) {
3814            themeHelper.EventBus.$emit('toggleCurrentOption', optionKey, type.name);
3815          }
3816        },
3817        selectedClass: function(index) {
3818          return this.currentOption[this.optionKey] === this.option.types[index].name;
3819        },
3820        disabledClass: function(index) {
3821          return !this.option.types[index].isValid;
3822        },
3823      },
3824    });
3825  });
3826</script>
3826
3827
3828<!-- cyb_snippet components/variant_options/color_image_option end -->
3829<!-- cyb_snippet components/variant_options/advance_option start -->
3830<script id="advance-variant-option" type="text/x-template">
3831  <div class="advance">
3832    <div class="option_title qk-text--heading">${option.name}</div>
3833    <label
3834      v-for="type in option.types"
3835      :class="{
3836        'selected': selectedClass(type),
3837        'disabled': disabledClass(type),
3838      }"
3839      @click="setOption(optionKey, type)"
3840      class="option qk-btn qk-btn--md qk-bd--button qk-text--button qk-text--center qk-pd_x--1"
3841    >
3842      <span class="text">${type.name}</span>
3843    </label>
3844  </div>
3845</script>
3845
3846
3847<script type="text/javascript">
3848  $(document).ready(function() {
3849    themeHelper.variantOptionsBlock.component('advance-variant-option', {
3850      template: '#advance-variant-option',
3851      delimiters: ['${', '}'],
3852      props: {
3853        optionKey: String,
3854        option: Object,
3855        currentOption: Object,
3856      },
3857      methods: {
3858        setOption: function(optionKey, type) {
3859          if(type.isValid){
3860            themeHelper.EventBus.$emit('toggleCurrentOption', optionKey, type.name);
3861          }
3862        },
3863        selectedClass: function(type) {
3864          return this.currentOption[this.optionKey] === type.name;
3865        },
3866        disabledClass: function(type) {
3867          return !type.isValid;
3868        },
3869      }
3870    });
3871  });
3872</script>
3872
3873
3874<!-- cyb_snippet components/variant_options/advance_option end -->
3875
3876
3877<!-- cyb_snippet _variant_options_block_js start -->
3878<script type="text/javascript">
3879  $(document).ready(function() {
3880    themeHelper.variantOptionsBlock.component('variant-options-block', {
3881      template: '#variant-options-block',
3882      delimiters: ['${', '}'],
3883      props: {
3884        productApiUrl: String,
3885        sku: String,
3886        autoSelectVariantBySku: Boolean,
3887        hideOtherVariantsBySku: Boolean,
3888        hideSingleVariantOptions: Boolean,
3889        salesModePurchasable: Boolean,
3890        defaultPrice: String,
3891        defaultComparePrice: String,
3892        defaultDiscounted: Boolean,
3893      },
3894      data: function() {
3895        return {
3896          styledShopMenu: "buttonType",
3897          currentImageIndex: 0,
3898          isModalSelectShow: false,
3899          selectOption: '',
3900          selectCurrentStr:'',
3901          modalOption: {},
3902          currentOption: {
3903            option1: null,
3904            option2: null,
3905            option3: null,
3906          },
3907          currentVariant: null,
3908          product: {},
3909          isLoading: true,
3910          isImageColorsUsed: liquidHelper.isImageColorsUsed,
3911          isEmptyClickable: liquidHelper.isEmptyClickable,
3912          hasPriceWithDiscountPlugin: liquidHelper.hasPriceWithDiscountPlugin,
3913          isCartEnabled: liquidHelper.isCartEnabled,
3914        }
3915      },
3916      mounted: function() {
3917        this.getProductDetail();
3918        themeHelper.EventBus.$on('toggleCurrentOption',this.toggleCurrentOption);
3919      },
3920      computed: {
3921        imageColors: function() {
3922          //色票一定成對
3923          var self = this;
3924          var images = this.photoUrls.slice(0);
3925          var imageColorNum = this.colorOption.length;
3926          for(var i = imageColorNum; i < imageColorNum * 2; i++) {
3927            if(!images[i]) {
3928              images.push('noColorImage');
3929            }
3930          }
3931          return images.slice(imageColorNum, imageColorNum * 2);
3932        },
3933        photoUrls: function() {
3934          return this.product.photoUrls.length > 0 ? this.product.photoUrls : [this.featuredImage];
3935        },
3936        featuredImage: function() {
3937          return this.product.featuredImage;
3938        },
3939        swiperPhotos: function() {
3940          if(this.isImageColor) {
3941            return this.photoUrls.slice(0, this.colorOption.length);
3942          }
3943          return this.photoUrls.length > 0 ? this.photoUrls : [this.featuredImage];
3944        },
3945        firstValidVariant: function() {
3946          var self = this;
3947          var result = this.product.variants.find(function(variant) {
3948            return variant.available;
3949          });
3950
3951          return result ? result : null;
3952        },
3953        shouldHideOtherVariants: function() {
3954          return this.hideOtherVariantsBySku &&
3955                 this.sku &&
3956                 this.currentVariant &&
3957                 this.currentVariant.sku === this.sku;
3958        },
3959        shouldHideSingleVariantOptions: function() {
3960          return this.hideSingleVariantOptions &&
3961                 this.product.variants &&
3962                 this.product.variants.length <= 1;
3963        },
3964        options: function() {
3965          return this.product.options;
3966        },
3967        optionTypes: function() {
3968          // 先根據設定的variants來排序
3969          var self = this;
3970
3971          var option1 = [];
3972          var option2 = [];
3973          var option3 = [];
3974          this.product.variants.forEach(function(item) {
3975            if (item.option1 !== null) option1.push(item.option1);
3976            if (item.option2 !== null) option2.push(item.option2);
3977            if (item.option3 !== null) option3.push(item.option3);
3978          })
3979
3980          var filteredOptionTypes = [];
3981          this.product.optionTypes.forEach(function(item, index) {
3982            filteredOptionTypes.push(self.getUniqueVariant(eval('option' + (index + 1))).join(','));
3983          });
3984
3985          return filteredOptionTypes;
3986        },
3987        optionInfo: function() {
3988          var self = this;
3989
3990          if (self.options) {
3991            return self.options.map(function(option, index) {
3992              return {
3993                name: option,
3994                types: self.getOptions('option' + (index + 1), self.optionTypes[index].split(','))
3995              }
3996            });
3997          }
3998        },
3999        colorOptionIndex: function() {
4000          return this.options.findIndex(function(option) {
4001            return option === '顏色';
4002          });
4003        },
4004        colorOption: function() {
4005          var optionIndex = this.colorOptionIndex
4006          return optionIndex === -1 ? null : this.optionTypes[optionIndex].split(',');
4007        },
4008        isImageColor: function() {
4009          return this.isImageColorsUsed && _.includes(this.product.options, '顏色');
4010        },
4011        isMobileSize: function() {
4012          return window.innerWidth <= 580
4013        },
4014        variantSize: function() {
4015          if(this.product.options){
4016          return this.product.options.length;
4017          }
4018        },
4019        isAutoSelectVariantBySku: function() {
4020          return this.sku && this.autoSelectVariantBySku;
4021        },
4022      },
4023      methods: {
4024        onClickSelectModal: function(objData, selectOptionStr) {
4025          this.isModalSelectShow = true;
4026          this.modalOption = objData;
4027          this.selectOption = selectOptionStr
4028        },
4029        onChangeModalSelect: function(flag, isSelect) {
4030          if(!isSelect){
4031            this.setOption(this.selectOption,this.selectCurrentStr,this.modalOption.types)
4032          }
4033          this.isModalSelectShow = flag;
4034        },
4035        setOption: function(optionKey, type, dataArr) {
4036          let flag = true
4037          dataArr.forEach(item => {
4038            if (item.name === type) {
4039              flag = item.isValid
4040            }
4041          })
4042          if (flag) {
4043            this.toggleCurrentOption(optionKey, type)
4044          }
4045        },
4046        setChoose: function(currentVariant) {
4047          var currentVariantData = {};
4048          if (currentVariant) {
4049            currentVariantData = {
4050              id: this.currentVariant.id,
4051              bonus: this.currentVariant.maxUsableBonus,
4052              name: this.currentVariant.title,
4053              inventoryPolicy: this.currentVariant.inventoryPolicy,
4054              compareAtPrice: this.currentVariant.compareAtPrice,
4055              imgUrl: this.currentVariant.imgUrl,
4056              inventoryQuantity: this.currentVariant.inventoryQuantity,
4057              option1: this.currentVariant.option1,
4058              option2: this.currentVariant.option2,
4059              option3: this.currentVariant.option3,
4060              price: this.currentVariant.price,
4061              productId: this.currentVariant.productId,
4062              sku: this.currentVariant.sku,
4063              qc: this.currentVariant.qc,
4064              hidePrice: this.product.hidePrice === true,
4065            };
4066          } else {
4067            currentVariantData = {
4068              price: this.defaultPrice,
4069              compareAtPrice: this.defaultComparePrice,
4070              isDiscounted: this.defaultDiscounted,
4071              hidePrice: this.product.hidePrice === true,
4072            }
4073          }
4074          const isUpcomingProduct = this.isSellTimeAfterNow(this.product.sellFrom);
4075          this.$emit('set-choose', currentVariantData, isUpcomingProduct);
4076        },
4077        onError: function() {
4078          window.msg("", 'error').show();
4079        },
4080        showRateLimitPopup: function() {
4081          showRateLimitModal(5);
4082        },
4083
4084        // get product detail
4085        getProductDetail: function() {
4086          var self = this;
4087          $.ajax({
4088            url: self.productApiUrl + '.json',
4089            type: 'GET',
4090            timeout: 30000,
4091            beforeSend: function() {
4092              self.isLoading = true;
4093            },
4094            error: function(xhr){
4095              if (xhr.status === 429) {
4096                self.isLoading = false;
4097                self.showRateLimitPopup();
4098              } else {
4099                self.onError();
4100              }
4101            }
4102          }).done(function(data){
4103            if (!data.id) {
4104              self.onError();
4105              return;
4106            }
4107
4108            var productData = [themeHelper.toCamelCase(data)];
4109            self.product = themeHelper.priceWithDiscount(productData, self.hasPriceWithDiscountPlugin)[0];
4110
4111            var shouldSkipAutoSelected = false;
4112
4113            if (self.isAutoSelectVariantBySku) {
4114              var skuVariant = self.product.variants.find(function(variant) {
4115                return variant.sku === self.sku;
4116              });
4117
4118              if (skuVariant) {
4119                if (self.isEmptyClickable ||
4120                  skuVariant.inventoryPolicy === "continue" ||
4121                  skuVariant.inventoryQuantity > 0) {
4122                  self.applyVariant(skuVariant, true);
4123                  themeHelper.EventBus.$emit('skuReady');
4124                  self.isLoading = false;
4125                  return;
4126                } else {
4127                  // 若 sku 存在但不可購買,則跳過第一個款式選擇
4128                  shouldSkipAutoSelected = true;
4129                }
4130              } else {
4131                // 若 sku 不存在,則跳過第一個款式選擇
4132                shouldSkipAutoSelected = true;
4133              }
4134              themeHelper.EventBus.$emit('skuReady');
4135            }
4136
4137            if (
4138              !shouldSkipAutoSelected && (
4139              self.product.variants.length === 1 ||
4140              liquidHelper.isFirstVariantSelected
4141            )) {
4142              var variant = self.product.variants.length === 1 ? self.product.variants[0] : self.firstValidVariant;
4143              if (!variant) {
4144                self.isLoading = false;
4145                return;
4146              }
4147
4148              if (
4149                !self.isEmptyClickable &&
4150                variant.inventoryPolicy === "deny" &&
4151                variant.inventoryQuantity === 0
4152              ) {
4153                self.isLoading = false;
4154                return;
4155              }
4156
4157              self.applyVariant(variant, false);
4158              if (self.isImageColorsUsed) { // 若有顯示色票且有預選第一個款式的更換圖片
4159                var firstValidColorIndex = self.colorOption.findIndex(function(item) {
4160                  return item === variant.option1
4161                });
4162                self.$emit('get-option-image', self.photoUrls[firstValidColorIndex].grande);
4163              }
4164            }
4165
4166            self.isLoading = false;
4167          })
4168        },
4169        applyVariant: function(variant, waitPhotosReady) {
4170          var self = this;
4171          this.currentVariant = variant;
4172          this.setChoose(variant);
4173          this.setDefaultOption();
4174
4175          if (waitPhotosReady) {
4176            themeHelper.EventBus.$on('skuPhotosReady', function () {
4177              if (variant.photos && variant.photos.length > 0) {
4178                self.setVariantPhotos();
4179              }
4180            });
4181          } else {
4182            this.setVariantPhotos();
4183          }
4184        },
4185        toggleCurrentOption: function(key, value) {
4186          if (this.product.variants.length === 1) {
4187            return;
4188          }
4189
4190          if (this.shouldHideOtherVariants) {
4191            return;
4192          }
4193
4194          this.currentOption[key] =
4195            (this.currentOption[key] === value || value === 'null') ? null : value;
4196          var variantIndex = this.getVariantIndex();
4197          if(variantIndex !== -1) {
4198            this.currentVariant = this.product.variants[variantIndex];
4199          } else {
4200            this.currentVariant = null;
4201          }
4202          this.setChoose(this.product.variants[variantIndex]);
4203          if (this.currentOption[key] !== null) {
4204            var optionIndex = parseInt(key.replace('option', '')) - 1;
4205            appStoreSelectItemEvent(this.product, this.product.options[optionIndex], this.currentOption[key], this.currentVariant);
4206          }
4207          if (Object.values(this.currentOption).every(v => v === null) || this.currentVariant) {
4208            this.setVariantPhotos();
4209          }
4210        },
4211        setCurrentImageIndex: function(index) {
4212          this.currentImageIndex = this.getSelectedColorIndex();
4213          if (this.currentImageIndex > -1) {
4214            var currentImageIndex = this.currentImageIndex;
4215          } else {
4216            var currentImageIndex = 0;
4217          }
4218
4219          this.$emit('get-option-image', this.photoUrls[currentImageIndex].grande);
4220        },
4221        getOptionImageIndex: function(index) {
4222          this.currentImageIndex = index;
4223          this.$emit('get-option-image', this.photoUrls[index].grande);
4224        },
4225        setDefaultOption: function() {
4226          var self = this;
4227          Object.keys(self.currentOption).forEach(function(optionKey) {
4228            self.currentOption[optionKey] = self.currentVariant[optionKey];
4229          });
4230        },
4231        getVariantIndex: function() {
4232          var self = this;
4233          return self.product.variants.findIndex(function(variant, index) {
4234            var isVariant = true;
4235            Object.keys(self.currentOption).forEach(function(option) {
4236              if(variant[option] !== self.currentOption[option]){
4237                isVariant = false;
4238              }
4239            });
4240            return isVariant;
4241          });
4242        },
4243        // 篩選重複品項
4244        getUniqueVariant: function(variants) {
4245          return variants.filter(function(value, index, self) {
4246            return self.indexOf(value) === index;
4247          });
4248        },
4249        // 取得已選取的color index
4250        getSelectedColorIndex: function() {
4251          var self = this;
4252          var optionIndex = _.indexOf(self.options, '顏色') + 1;
4253          var color = self.currentOption['option' + optionIndex];
4254
4255          return _.indexOf(self.colorOption, color);
4256        },
4257        getOptions: function(optionKey, optionTypes) {
4258          var self = this;
4259
4260          // 透過 sku 預選且有對應的 variant,則只顯示該 variant 的 option
4261          if (this.shouldHideOtherVariants) {
4262            var currentOptionValue = this.currentVariant[optionKey];
4263            var isValid = true;
4264
4265            if (!this.isEmptyClickable) {
4266              isValid = this.currentVariant.inventoryQuantity === null ||
4267                        this.currentVariant.inventoryQuantity > 0 ||
4268                        this.currentVariant.inventoryPolicy === 'continue';
4269            }
4270
4271            return [{
4272              name: currentOptionValue,
4273              isValid: isValid
4274            }];
4275          }
4276
4277          return optionTypes.map(function(optionType, index) {
4278            var isValid = true;
4279
4280            // 選出包含目前type的variant
4281            var matchVariants = self.product.variants.filter(function(variant) {
4282              return variant[optionKey] === optionType;
4283            });
4284            // 篩選已勾選type
4285            Object.keys(self.currentOption).forEach(function(currentOptionKey) {
4286              if(currentOptionKey !== optionKey){
4287                matchVariants = matchVariants.filter(function(variant) {
4288                  if(self.currentOption[currentOptionKey]) {
4289                    return variant[currentOptionKey] === self.currentOption[currentOptionKey]
4290                  } else {
4291                    return true;
4292                  }
4293                });
4294              }
4295            });
4296            // 無variant代表此type不可選
4297            if(matchVariants.length === 0) {
4298              isValid = false;
4299            }
4300
4301            if (!self.isEmptyClickable) {
4302              isValid = false;
4303              matchVariants.find(function(item) {
4304                if (item.inventoryQuantity === null || item.inventoryQuantity > 0 || item.inventoryPolicy === 'continue') {
4305                  isValid = true;
4306                }
4307              });
4308            }
4309
4310            return {
4311              name: optionType,
4312              isValid: isValid
4313            }
4314          });
4315        },
4316        getVariantPhotos: function() {
4317          if (!this.currentVariant) {
4318            return null;
4319          }
4320
4321          if (!this.currentVariant.photos || this.currentVariant.photos.length === 0) {
4322            return {
4323              withSpecificVariant: !!this.currentVariant.option1,
4324              photos: [],
4325              variant: {
4326                id: this.currentVariant.id,
4327                sku: this.currentVariant.sku
4328              },
4329            };
4330          }
4331
4332          var sortedPhotos = this.currentVariant.photos.sort(function(prev, next) {
4333            return prev.position - next.position;
4334          });
4335
4336          return {
4337            withSpecificVariant: !!this.currentVariant.option1,
4338            photos: sortedPhotos,
4339            variant: {
4340              id: this.currentVariant.id,
4341              sku: this.currentVariant.sku
4342            },
4343          };
4344        },
4345        setVariantPhotos: function() {
4346          themeHelper.EventBus.$emit('updatePhotos', this.getVariantPhotos());
4347        },
4348        cartQuantityCheck({quantity, limitQuantity, cartLimit, inventoryPolicy}){
4349          if(quantity < 1){
4350            return 'less_then_1';
4351          }
4352          if(quantity > limitQuantity && limitQuantity !== null && inventoryPolicy !== "continue") {
4353            return 'over_product_quantity';
4354          }
4355          if(quantity > cartLimit){
4356            return 'over_cart_limit';
4357          }
4358          if(isNaN(quantity)){
4359            return 'not_a_number';
4360          }
4361          return '';
4362        },
4363        changeQuantity({elType, errType, quantity, addToCart, quantityInput, limitQuantity, cartLimit}){
4364          if(errType === ''){
4365            if(elType === 'btn'){
4366              quantityInput.val(quantity);
4367              quantityInput.trigger('change');
4368            }
4369            var old = quantityInput.data("old-value");
4370            if(quantity === old){
4371              quantityInput.data("old-value", quantity);
4372            }
4373            // for GA
4374            addToCart.data("quantity", quantity);
4375          } else {
4376            var old_value = quantityInput.data("old-value");
4377            if(elType === 'input'){
4378              switch(errType){
4379                case 'less_then_1':
4380                  quantityInput.val(1);
4381                  break;
4382                case 'over_product_quantity':
4383                  quantityInput.val(limitQuantity);
4384                  break;
4385                case 'over_cart_limit':
4386                  quantityInput.val(cartLimit);
4387                  break;
4388                default:
4389                  quantityInput.val(old_value);
4390                  break;
4391              }
4392            }
4393            this.cartQuantityMessage(errType)
4394          }
4395        },
4396        cartQuantityMessage(errType) {
4397          switch(errType){
4398            case 'less_then_1':
4399              window.msg(language["less_then_one"], 'warning').show();
4400              break;
4401            case 'over_product_quantity':
4402              window.msg(language["over_product_quantity"], 'warning').show();
4403              break;
4404            case 'over_cart_limit':
4405              window.msg(language["over_cart_limit"], 'warning').show();
4406              break;
4407            case 'not_a_number':
4408              window.msg(language["please_enter_number"], 'warning').show();
4409              break;
4410            default:
4411              break;
4412          }
4413        },
4414        quantityChange(isPluSquantity){
4415          if (!this.findVariant()) {
4416            return;
4417          }
4418          let errType           = '';
4419          let el                = $('#product');
4420          let cartLimit         = this.getCartQuantityLimit(el);
4421          let limitQuantity     = selectedVariant.inventoryQuantity;
4422          let inventoryPolicy   = selectedVariant.inventoryPolicy;
4423          let quantityInput     = el.find(".product_quantity input");
4424          let quantity          = parseInt($(quantityInput).val());
4425          let addToCart         = el.find('.addToCart');
4426          isPluSquantity ? quantity += 1: quantity -= 1
4427          errType = this.cartQuantityCheck({quantity, limitQuantity, cartLimit, inventoryPolicy});
4428          this.changeQuantity({ elType: 'btn', errType, quantity, addToCart, quantityInput, limitQuantity, cartLimit});
4429        },
4430        findVariant() {
4431          if (typeof selectedVariant === 'undefined' || !$.isNumeric(selectedVariant.id)) {
4432            window.msg(language["please_choose_product"], 'info').show();
4433            return false;
4434          } else {
4435            return true;
4436          }
4437        },
4438        getCartQuantityLimit(el) {
4439          return el.data('cart_quantity_limit');
4440        },
4441        isSellTimeAfterNow(sellTime) {
4442          if (!sellTime) return false;
4443          const saleTime = new Date(sellTime);
4444          const now = new Date();
4445          return saleTime > now;
4446        },
4447      }
4448    });
4449  });
4450</script>
4450
4451
4452<!-- cyb_snippet _variant_options_block_js end -->
4453
4454<!-- cyb_snippet components/variant_options/variant_options_block end -->
4455<!-- cyb_snippet _custom_icon start -->
4456<script src='//cdn-general.cybassets.com/frontend/shop/navIcon-3a2e378145f8a165.js' type='text/javascript'></script>
4456
4457
4458<script>
4459  (function() {
4460    const iconUrlMap = new Map([
4461      ['custom_icon_type_home', null],
4462      ['custom_icon_type_tracking_items', null],
4463      ['custom_icon_type_account', null],
4464      ['custom_icon_type_cart', null],
4465      ['custom_icon_type_search', null],
4466      ['custom_icon_type_menu', null]
4467    ]);
4468    const elements = document.querySelectorAll('[data-icon-type]');
4469    elements.forEach((element, index) => {
4470      const iconAttributes = element.getAttribute('data-icon-type');
4471
4472      const uniqueId = `icon_${iconAttributes}_${index}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
4473      element.id = uniqueId;
4474      window.renderNavCustomIcon(`#${uniqueId}`, {
4475        navIconStyle: "icon_type_rounded",
4476        customIconUrl: iconUrlMap.get(iconAttributes) || '',
4477        iconAttributes: iconAttributes,
4478        currentTemplate: "product",
4479      });
4480    });
4481  })();
4482</script>
4482
4483
4484<!-- cyb_snippet _custom_icon end -->
4485
4486<script>
4487  // 設定款式資訊/顯示款式資訊
4488  function getURLParameter(name) {
4489    return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [null, ''])[1].replace(/\+/g, '%20')) || null;
4490  }
4491  // sku_properties:各款式的 option pairs(當前語系,後端 drop 已翻譯),事件用 variantId 查表
4492  var variantProperties = {
4493    
4494  };
4495  function addToWishListEvent(id, data) {
4496    try {
4497      if (appMarketAddToWishListEvent && data) {
4498        var dataSet = {
4499          name: "X2 - Smart Cycling Computer",
4500          category: null,
4501          categories: ["All,Cycling Accessories"],
4502          sku: data.sku,
4503          price: data.price,
4504          compare_at_price: data.compare_at_price,
4505          properties: variantProperties[id] || [],
4506          quantity: data.inventory_quantity,
4507          variant: data.variant,
4508          listName: "Product Features" || null,
4509          productId: 58021395,
4510          variantId: id,
4511        }
4512        appMarketAddToWishListEvent(dataSet)
4513      }
4514    } catch (e) {
4515      console.error(e);
4516    }
4517  }
4518  function removeFromWishListEvent(id, data) {
4519    try {
4520      if (appMarketRemoveFromWishListEvent && data) {
4521        var dataSet = {
4522          name: "X2 - Smart Cycling Computer",
4523          category: null,
4524          categories: ["All,Cycling Accessories"],
4525          sku: data.sku,
4526          price: data.price,
4527          compare_at_price: data.compare_at_price,
4528          properties: variantProperties[id] || [],
4529          quantity: data.inventory_quantity,
4530          variant: data.variant,
4531          listName: "Product Features" || null,
4532          productId: 58021395,
4533          variantId: id,
4534        }
4535        appMarketRemoveFromWishListEvent(dataSet)
4536      }
4537    } catch (e) {
4538      console.error(e);
4539    }
4540  }
4541  function isSellTimeAfterNow(sellTime) {
4542    if (!sellTime) return false;
4543    const saleTime = new Date(sellTime);
4544    const now = new Date();
4545    return saleTime > now;
4546  }
4547  $(document).ready(function() {
4548  var ProductInfoObject =  new ProductInfo()
4549    ProductInfoObject.init({
4550      additionalPrice: "Add-on Price",
4551      sellFrom: "" ,
4552      productId:"58021395",
4553      productTitle: "X2 - Smart Cycling Computer",
4554      productPreOrder: "Pre-order",
4555      productExistingVariantsFirstId: '70177313',
4556      productNotificationEnabled: 'Notification Enabled',
4557      productNotifyMeWhenStockArrives: 'Sold out! Notify me when the product is available.',
4558      productOptionsSize: "0",
4559      productPleaseChooseProduct: "Please select specifications",
4560      generalInternetError: "Network error, please try again later",
4561      productVariantsInfo: "70177313,ZC.X01TA.00L,2490.0,0,2490.0,deny,0.0,,X2 - 智慧車錶 - ,cyberbiz,",
4562      productLimitBuy:  null,
4563      purchaseEligibility: {"required":false,"eligible":true,"status":"eligible"},
4564      salesModePurchasable: true,
4565    });
4566    // 商品款式
4567    var isUpcomingProduct = isSellTimeAfterNow("") && null;
4568    // 初始化,取得消費者所有品項的通知設定
4569    var variantNotifications = {};
4570    
4571      ProductInfoObject.initVariantNotifications();
4572    
4573    // 初始化,檢查所有商品的庫存,判斷購物車按鈕和庫存顯示狀態
4574    ProductInfoObject.checkButtonStatus(isUpcomingProduct);
4575    // 加入購物車 open product modal
4576    ProductInfoObject.initOpenProductModal();
4577    // 立即購買 mobile product modal
4578    ProductInfoObject.initMobileProductModal()
4579    // 聯絡商家
4580    ProductInfoObject.initContactTheMerchant()
4581    // 貨到通知
4582    ProductInfoObject.initGoodsArrivalNotification();
4583    ProductInfoObject.checkInWishList(window.$('.product-variant-id').val())
4584    
4585    
4586    })
4587
4588    const userAgent = navigator.userAgent;
4589    const isIOS = /iPad|iPhone|iPod/.test(userAgent) && !window.MSStream;
4590    const isLiff = /Line\/[\d.]+/i.test(userAgent);
4591    const $productButtonMobile = $('.product_button_mobile');
4592
4593    if ($productButtonMobile.length && isIOS && isLiff) {
4594      $productButtonMobile.addClass('is-ios-liff');
4595    }
4596</script>
4596
4597
4598
4599<div id="product_description" class="product_description">
4600  <div class="desc_sections">
4601    <ul class="qk-bg--theme_bg qk-display--flex qk-mg--0 qk-pd--0 qk-bd--default qk-bd--product_border qk-bd_r--none">
4602      <!-- 商品介紹 -->
4603      
4604        <li class="qk-flex--1">
4605          <a href="#desc_section_1" class="scroll active qk-text--text qk-fs--title qk-display--il_bk qk-text--center qk-w--100 qk-vert--bottom">
4606            Description
4607          </a>
4608        </li>
4609      
4610      <!-- 規格說明 -->
4611      
4612        <li class="qk-flex--1 qk-bd--product_border">
4613          <a href="#desc_section_2" class="scroll qk-text--text qk-fs--title qk-display--il_bk qk-text--center qk-w--100 qk-vert--bottom">
4614            <div>Specifications</div>
4615          </a>
4616        </li>
4617      
4618      <!-- 運送方式 -->
4619      
4620      <!-- 票券注意事項 -->
4621      
4622      <!-- 加入購物車modal -->
4623      
4624    </ul>
4625  </div>
4626  <div class="desc_body">
4627    <div id="ckeditor">
4628      
4629        <div id="desc_section_1" class="desc_section qk-pd_t--2">
4630          <h5 class="section-heading qk-text--heading qk-fs--hd2 qk-bd_l--default qk-bd--heading qk-pd_l--05">Description</h5>
4631          <div class="ckeditor qk-mg_t--1"><style scoped  type="text/css">.feature-section {
4632      width: 100%;
4633    }
4634
4635    .feature-block {
4636      position: relative;
4637      width: 100%;
4638      padding-top: 56.25%; /* 16:9 比例 */
4639      background-size: cover;
4640      background-position: center;
4641    }
4642
4643    .text-overlay {
4644      position: absolute;
4645      color: white;
4646      text-shadow: 0 2px 6px rgba(0,0,0,0.6);
4647      opacity: 0;
4648      transform: translateY(20px);
4649      transition: opacity 1s ease, transform 1s ease;
4650    }
4651
4652    .text-overlay.visible {
4653      opacity: 1;
4654      transform: translateY(0);
4655
4656    }
4657
4658    .title-overlay {
4659      width: 45%;
4660    }
4661
4662    .desc-overlay {
4663      width: 45%;
4664    }
4665
4666    .title-overlay h2 {
4667      margin: 0 0 10px;
4668      font-size: clamp(16px, 2.5vw, 32px);
4669      text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
4670      font-weight: 900;
4671
4672    }
4673
4674    .desc-overlay p {
4675      margin: 0;
4676      font-size: clamp(14px, 1.5vw, 18px);
4677      color: rgba(255, 255, 255, 0.8);
4678      text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
4679    }
4680
4681    .description-block {
4682      display: none;
4683      padding: 20px;
4684      font-size: 16px;
4685      background: #f9f9f9;
4686      color: #5F6062;
4687      line-height: 1.5;
4688      padding-bottom: 100px;
4689    }
4690
4691    /* 四張圖的背景設定 */
4692    .feature1 { background-image: url('//cdn.cybassets.com/s/files/33373/ckeditor/pictures/content_4b93681d-f118-443c-ac1d-20f90b07b74f.jpg'); }
4693    .feature2 { background-image: url('//cdn.cybassets.com/s/files/33373/ckeditor/pictures/content_1ac9e724-c3e8-440b-b70c-f43466a457b9.jpg'); }
4694    .feature3 { background-image: url('//cdn.cybassets.com/s/files/33373/ckeditor/pictures/content_2840ba95-798a-4b8e-8c5c-556443b49b16.jpg'); }
4695    .feature4 { background-image: url('//cdn.cybassets.com/s/files/33373/ckeditor/pictures/content_f7ef9cf9-a560-4eda-be3d-79215f35fc53.jpg'); }
4696    .feature5 { background-image: url('//cdn.cybassets.com/s/files/33373/ckeditor/pictures/content_e846bef9-db26-49e1-95bf-63708c22f4ae.jpg'); }
4697    .feature6 { background-image: url('//cdn.cybassets.com/s/files/33373/ckeditor/pictures/content_5ae3eeb7-d496-4c81-b7c6-6f46d8917f85.jpg'); }
4698    .feature7 { background-image: url('//cdn.cybassets.com/s/files/33373/ckeditor/pictures/content_2d6ca3ae-82b3-40f6-b0a8-a23938fa873e.jpg'); }
4699    .feature8 { background-image: url('//cdn.cybassets.com/s/files/33373/ckeditor/pictures/content_d9933233-f5bc-409a-9384-385343af1e95.jpg'); }
4700    .feature9 { background-image: url('//cdn.cybassets.com/s/files/33373/ckeditor/pictures/content_90af3fd1-978d-4ad4-ac72-69ab29932ad8.jpg'); }
4701
4702    /* 各文字區位置 - 桌機版 */
4703    .feature1 .title-overlay { top: 40%; left: 15%; }
4704    .feature1 .desc-overlay  { top: 60%; left: 15%; }
4705
4706    .feature2 .title-overlay { top: 60%; left: 50%; }
4707    .feature2 .desc-overlay  { top: 70%; left: 50%; }
4708
4709    .feature3 .title-overlay { top: 30%; left: 15%; }
4710    .feature3 .desc-overlay  { top: 55%; left: 15%; }
4711
4712    .feature4 .title-overlay { top: 30%; left: 55%; }
4713    .feature4 .desc-overlay  { top: 55%; left: 55%; }
4714
4715    .feature5 .title-overlay { top: 40%; left: 15%; }
4716    .feature5 .desc-overlay  { top: 65%; left: 15%; }
4717
4718    .feature6 .title-overlay { top: 40%; left: 15%; }
4719    .feature6 .desc-overlay  { top: 65%; left: 15%; }
4720
4721    .feature7 .title-overlay { top: 30%; left: 52%; }
4722    .feature7 .desc-overlay  { top: 55%; left: 52%; }
4723
4724    .feature8 .title-overlay { top: 40%; left: 15%; }
4725    .feature8 .desc-overlay  { top: 65%; left: 15%; }
4726
4727    .feature9 .title-overlay { top: 15%; left: 28%; }
4728    .feature9 .desc-overlay  { top: 25%; left: 23%; }
4729
4730    @media (max-width: 800px) {
4731      .title-overlay {
4732        width: 90%;
4733        font-size: 20px;
4734      }
4735
4736      .desc-overlay {
4737        display: none;
4738      }
4739
4740      .feature1 .title-overlay { top: 40%; left: 15%; }
4741      .feature2 .title-overlay { top: 70%; left: 55%; }
4742      .feature3 .title-overlay { top: 30%; left: 15%; }
4743      .feature4 .title-overlay { top: 30%; left: 55%; }
4744      .feature5 .title-overlay { top: 40%; left: 15%; }
4745      .feature6 .title-overlay { top: 40%; left: 15%; }
4746      .feature7 .title-overlay { top: 30%; left: 52%; }
4747      .feature8 .title-overlay { top: 40%; left: 15%; }
4748      .feature9 .title-overlay { top: 15%; left: 25%; }
4749
4750
4751      .description-block {
4752        display: block;
4753      }
4754    }
4755
4756
4757@keyframes rotateBounce {
4758  0% {
4759    transform: rotate(0deg);
4760  }
4761  50% {
4762    transform: rotate(20deg);
4763  }
4764  100% {
4765    transform: rotate(0deg);
4766  }
4767}
4768
4769.icon-rotate {
4770  transition: transform 0.4s ease;
4771}
4772
4773.icon-rotate.animate {
4774  animation: rotateBounce 0.6s ease;
4775}
4776</style>
4777<div class="feature-section"><!-- section 1 -->
4778<div class="feature-block feature1">
4779<div class="text-overlay title-overlay">
4780<h2><svg class="bi bi-battery-full icon-rotate" fill="currentColor" height="44" viewBox="0 0 16 16" width="44" xmlns="http://www.w3.org/2000/svg"> <path d="M2 6h10v4H2z"></path> <path d="M2 4a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2zm10 1a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1zm4 3a1.5 1.5 0 0 1-1.5 1.5v-3A1.5 1.5 0 0 1 16 8"></path> </svg><br>
4781Power UP</h2>
4782</div>
4783
4784<div class="text-overlay desc-overlay">
4785<p>Up to 40 hours on a single charge,<br>
4786Longest battery life among products in the same class.</p>
4787</div>
4788</div>
4789
4790<div class="description-block">Up to 40 hours on a single charge,<br>
4791Longest battery life among products in the same class.</div>
4792<!-- section 2 -->
4793
4794<div class="feature-block feature2">
4795<div class="text-overlay title-overlay">
4796<h2 style="color: rgba(0, 0, 0, 0.9);">Connect to Smart Trainers</h2>
4797</div>
4798
4799<div class="text-overlay desc-overlay" style="width: 45%">
4800<p style="color: rgba(0, 0, 0, 0.65);">Download training schedules to <strong>Xplova X2</strong>. Instantly simulate a workout ride via ANT+ for smart training.<br>
4801(Needs Speed/Cadence Sensor, HRM for a complete training course)</p>
4802</div>
4803</div>
4804
4805<div class="description-block">Download training schedules to <strong>Xplova X2</strong>. Instantly simulate a workout ride via ANT+ for smart training.<br>
4806(Needs Speed/Cadence Sensor, HRM for a complete training course)</div>
4807<!-- section 3 -->
4808
4809<div class="feature-block feature3">
4810<div class="text-overlay title-overlay">
4811<h2><svg class="bi bi-arrow-left-right icon-rotate" fill="currentColor" height="36" viewBox="0 0 16 16" width="36" xmlns="http://www.w3.org/2000/svg"> <path d="M1 11.5a.5.5 0 0 0 .5.5h11.793l-3.147 3.146a.5.5 0 0 0 .708.708l4-4a.5.5 0 0 0 0-.708l-4-4a.5.5 0 0 0-.708.708L13.293 11H1.5a.5.5 0 0 0-.5.5m14-7a.5.5 0 0 1-.5.5H2.707l3.147 3.146a.5.5 0 1 1-.708.708l-4-4a.5.5 0 0 1 0-.708l4-4a.5.5 0 1 1 .708.708L2.707 4H14.5a.5.5 0 0 1 .5.5" fill-rule="evenodd"></path> </svg><br>
4812<br>
4813Dual Mode Configuration</h2>
4814</div>
4815
4816<div class="text-overlay desc-overlay" style="width: 45%">
4817<p>Set up <strong>Xplova X2</strong> pages easily via smartphones,<br>
4818Streamline your setup for greater efficiency.</p>
4819</div>
4820</div>
4821
4822<div class="description-block">Set up <strong>Xplova X2</strong> pages easily via smartphones,<br>
4823Streamline your setup for greater efficiency.</div>
4824<!-- section 4 -->
4825
4826<div class="feature-block feature4">
4827<div class="text-overlay title-overlay">
4828<h2><svg class="bi bi-bell icon-rotate" fill="currentColor" height="36" viewBox="0 0 16 16" width="36" xmlns="http://www.w3.org/2000/svg"> <path d="M8 16a2 2 0 0 0 2-2H6a2 2 0 0 0 2 2M8 1.918l-.797.161A4 4 0 0 0 4 6c0 .628-.134 2.197-.459 3.742-.16.767-.376 1.566-.663 2.258h10.244c-.287-.692-.502-1.49-.663-2.258C12.134 8.197 12 6.628 12 6a4 4 0 0 0-3.203-3.92zM14.22 12c.223.447.481.801.78 1H1c.299-.199.557-.553.78-1C2.68 10.2 3 6.88 3 6c0-2.42 1.72-4.44 4.005-4.901a1 1 0 1 1 1.99 0A5 5 0 0 1 13 6c0 .88.32 4.2 1.22 6"></path> </svg><br>
4829<br>
4830Smart Notification</h2>
4831</div>
4832
4833<div class="text-overlay desc-overlay" style="width: 40%">
4834<p>Built-in caller ID notification, See who's calling at a glance. Stay focused on your ride at all times.</p>
4835</div>
4836</div>
4837
4838<div class="description-block">Built-in caller ID notification, See who's calling at a glance.<br>
4839Stay focused on your ride at all times.</div>
4840</div>
4841<!-- section 5 -->
4842
4843<div class="feature-block feature5">
4844<div class="text-overlay title-overlay">
4845<h2><svg class="bi bi-crosshair icon-rotate" fill="currentColor" height="40" viewBox="0 0 16 16" width="40" xmlns="http://www.w3.org/2000/svg"> <path d="M8.5.5a.5.5 0 0 0-1 0v.518A7 7 0 0 0 1.018 7.5H.5a.5.5 0 0 0 0 1h.518A7 7 0 0 0 7.5 14.982v.518a.5.5 0 0 0 1 0v-.518A7 7 0 0 0 14.982 8.5h.518a.5.5 0 0 0 0-1h-.518A7 7 0 0 0 8.5 1.018zm-6.48 7A6 6 0 0 1 7.5 2.02v.48a.5.5 0 0 0 1 0v-.48a6 6 0 0 1 5.48 5.48h-.48a.5.5 0 0 0 0 1h.48a6 6 0 0 1-5.48 5.48v-.48a.5.5 0 0 0-1 0v.48A6 6 0 0 1 2.02 8.5h.48a.5.5 0 0 0 0-1zM8 10a2 2 0 1 0 0-4 2 2 0 0 0 0 4"></path> </svg><br>
4846<br>
4847Quick turn-by-turn guidance</h2>
4848</div>
4849
4850<div class="text-overlay desc-overlay">
4851<p>Direct cyclists to their destination and how far away they are with turn-by-turn simplicity.</p>
4852</div>
4853</div>
4854
4855<div class="description-block">Direct cyclists to their destination and how far away they are with turn-by-turn simplicity.</div>
4856<!-- section 6 -->
4857
4858<div class="feature-block feature6">
4859<div class="text-overlay title-overlay">
4860<h2 style="color: rgba(0, 0, 0, 0.9);"><svg class="bi bi-cloud-upload icon-rotate" fill="currentColor" height="40" viewBox="0 0 16 16" width="40" xmlns="http://www.w3.org/2000/svg"> <path d="M4.406 1.342A5.53 5.53 0 0 1 8 0c2.69 0 4.923 2 5.166 4.579C14.758 4.804 16 6.137 16 7.773 16 9.569 14.502 11 12.687 11H10a.5.5 0 0 1 0-1h2.688C13.979 10 15 8.988 15 7.773c0-1.216-1.02-2.228-2.313-2.228h-.5v-.5C12.188 2.825 10.328 1 8 1a4.53 4.53 0 0 0-2.941 1.1c-.757.652-1.153 1.438-1.153 2.055v.448l-.445.049C2.064 4.805 1 5.952 1 7.318 1 8.785 2.23 10 3.781 10H6a.5.5 0 0 1 0 1H3.781C1.708 11 0 9.366 0 7.318c0-1.763 1.266-3.223 2.942-3.593.143-.863.698-1.723 1.464-2.383" fill-rule="evenodd"></path> <path d="M7.646 4.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1-.708.708L8.5 5.707V14.5a.5.5 0 0 1-1 0V5.707L5.354 7.854a.5.5 0 1 1-.708-.708z" fill-rule="evenodd"></path> </svg><br>
4861<br>
4862Support ANT+ &amp; BLE</h2>
4863</div>
4864
4865<div class="text-overlay desc-overlay">
4866<p style="color: rgba(0, 0, 0, 0.65);">ANT+ compatible to multiple sensors.<br>
4867Display and record your riding data, upload to Xplova Connect App and social platforms instantly.</p>
4868</div>
4869</div>
4870
4871<div class="description-block">ANT+ compatible to multiple sensors.<br>
4872Display and record your riding data, upload to Xplova Connect App and social platforms instantly.</div>
4873<!-- section 7 -->
4874
4875<div class="feature-block feature7">
4876<div class="text-overlay title-overlay">
4877<h2><svg class="bi bi-feather icon-rotate" fill="currentColor" height="36" viewBox="0 0 16 16" width="36" xmlns="http://www.w3.org/2000/svg"> <path d="M15.807.531c-.174-.177-.41-.289-.64-.363a3.8 3.8 0 0 0-.833-.15c-.62-.049-1.394 0-2.252.175C10.365.545 8.264 1.415 6.315 3.1S3.147 6.824 2.557 8.523c-.294.847-.44 1.634
4877-.429 2.268.005.316.05.62.154.88q.025.061.056.122A68 68 0 0 0 .08 15.198a.53.53 0 0 0 .157.72.504.504 0 0 0 .705-.16 68 68 0 0 1 2.158-3.26c.285.141.616.195.958.182.513-.02 1.098-.188 1.723-.49 1.25-.605 2.744-1.787 4.303-3.642l1.518-1.55a.53.53 0 0 0 0-.739l-.729-.744 1.311.209a.5.5 0 0 0 .443-.15l.663-.684c.663-.68 1.292-1.325 1.763-1.892.314-.378.585-.752.754-1.107.163-.345.278-.773.112-1.188a.5.5 0 0 0-.112-.172M3.733 11.62C5.385 9.374 7.24 7.215 9.309 5.394l1.21 1.234-1.171 1.196-.027.03c-1.5 1.789-2.891 2.867-3.977 3.393-.544.263-.99.378-1.324.39a1.3 1.3 0 0 1-.287-.018Zm6.769-7.22c1.31-1.028 2.7-1.914 4.172-2.6a7 7 0 0 1-.4.523c-.442.533-1.028 1.134-1.681 1.804l-.51.524zm3.346-3.357C9.594 3.147 6.045 6.8 3.149 10.678c.007-.464.121-1.086.37-1.806.533-1.535 1.65-3.415 3.455-4.976 1.807-1.561 3.746-2.36 5.31-2.68a8 8 0 0 1 1.564-.173"></path> </svg><br>
4878<br>
4879Lightweight and easy to install</h2>
4880</div>
4881
4882<div class="text-overlay desc-overlay" tyle="width: 40%">
4883<p>Total weight 65 gram, ultra lightweight, Enhance your riding performance.</p>
4884</div>
4885</div>
4886
4887<div class="description-block">Total weight 65 gram, ultra lightweight, Enhance your riding performance.</div>
4888<!-- section 8 -->
4889
4890<div class="feature-block feature8">
4891<div class="text-overlay title-overlay">
4892<h2><svg class="bi bi-globe-americas icon-rotate" fill="currentColor" height="40" viewBox="0 0 16 16" width="40" xmlns="http://www.w3.org/2000/svg"> <path d="M8 0a8 8 0 1 0 0 16A8 8 0 0 0 8 0M2.04 4.326c.325 1.329 2.532 2.54 3.717 3.19.48.263.793.434.743.484q-.121.12-.242.234c-.416.396-.787.749-.758 1.266.035.634.618.824 1.214 1.017.577.188 1.168.38 1.286.983.082.417-.075.988-.22 1.52-.215.782-.406 1.48.22 1.48 1.5-.5 3.798-3.186 4-5 .138-1.243-2-2-3.5-2.5-.478-.16-.755.081-.99.284-.172.15-.322.279-.51.216-.445-.148-2.5-2-1.5-2.5.78-.39.952-.171 1.227.182.078.099.163.208.273.318.609.304.662-.132.723-.633.039-.322.081-.671.277-.867.434-.434 1.265-.791 2.028-1.12.712-.306 1.365-.587 1.579-.88A7 7 0 1 1 2.04 4.327Z"></path> </svg><br>
4893<br>
4894Dual Satillites positioning</h2>
4895</div>
4896
4897<div class="text-overlay desc-overlay">
4898<p>Sensity and quick GPS or Beiduo sensors positioning locations.</p>
4899</div>
4900</div>
4901
4902<div class="description-block">Sensity and quick GPS or Beiduo sensors positioning locations.</div>
4903<!-- section 9 -->
4904
4905<div class="feature-block feature9">
4906<div class="text-overlay title-overlay" style="width: 60%">
4907
4908
4909<h2 style="color: rgba(0, 0, 0, 0.9);">Riding data upload and sharing</h2>
4910</div>
4911
4912<div class="text-overlay desc-overlay" style="width: 60%">
4913<p style="color: rgba(0, 0, 0, 0.65);">Synchronize riding data with 3rd party social platform such as Strava and TrainingPeaks.</p>
4914</div>
4915</div>
4916
4917<div class="description-block">Synchronize riding data with 3rd party social platform such as Strava and TrainingPeaks.</div>
4918
4919<div class="youtube-embed-wrapper" style="position:relative;padding-bottom:56.25%;height:0;overflow:hidden"><iframe allow="autoplay;" allowfullscreen="" frameborder="0" height="360" src="https://www.youtube-nocookie.com/embed/gQ-CrBfzP3c?rel=0&amp;autoplay=1&amp;controls=0&amp;start=0" style="position:absolute;top:0;left:0;width:100%;height:100%" width="640"></iframe></div>
4920
4921<script>
4922  // 針對每一個 feature-block
4923document.querySelectorAll('.feature-block').forEach(block => {
4924  const svg = block.querySelector('svg.icon-rotate');
4925  if (svg) {
4926    block.addEventListener('mouseenter', () => {
4927      svg.classList.add('animate');
4928      setTimeout(() => {
4929        svg.classList.remove('animate');
4930      }, 500);
4931    });
4932  }
4933});
4934</script>
4934<script>
4935  const observer = new IntersectionObserver((entries) => {
4936    entries.forEach(entry => {
4937      if (entry.isIntersecting) {
4938        entry.target.classList.add('visible');
4939        observer.unobserve(entry.target);
4940      }
4941    });
4942  }, {
4943    threshold: 0.1
4944  });
4945
4946  document.querySelectorAll('.text-overlay').forEach(el => {
4947    observer.observe(el);
4948  });
4949
4950</script>
4950</div>
4951        </div>
4952      
4953      
4954        <div id="desc_section_2" class="desc_section qk-pd_t--2">
4955          <h5 class="section-heading qk-text--heading qk-fs--hd2 qk-bd_l--default qk-bd--heading qk-pd_l--05">Specifications</h5>
4956          <div class="ckeditor qk-mg_t--1"><style scoped  type="text/css">
4957  .spec-table {
4958    width: 100%;
4959    max-width: 960px;
4960    margin: 0 auto;
4961    border-collapse: collapse;
4962  }
4963
4964  .spec-table tr {
4965    border-bottom: 1px solid #B6B8BA;
4966  }
4967
4968  .spec-table tr:last-child {
4969    border-bottom: none;
4970  }
4971
4972  .spec-label {
4973    color: #000000;
4974    font-weight: bold;
4975    padding: 24px 8px;
4976    text-align: left;
4977    vertical-align: top;
4978    width: 30%;
4979  }
4980
4981  .spec-value {
4982    color: #5F6062;
4983    padding: 24px 8px;
4984    text-align: left;
4985    vertical-align: top;
4986    width: 70%;
4987    transition: color 0.3s ease;
4988  }
4989
4990  .spec-table tr:hover .spec-value {
4991    color: #F15A22;
4992  }
4993</style>
4994
4995<table class="spec-table">
4996  <tbody>
4997    <tr>
4998      <td class="spec-label">Receiver Chip</td>
4999      <td class="spec-value">Built-in high sensitivity GPS + BeiDou receiver chip</td>
5000    </tr>
5001    <tr>
5002      <td class="spec-label">Storage Memory</td>
5003      <td class="spec-value">16 Mbyte (up to 200 hours of riding history)</td>
5004    </tr>
5005    <tr>
5006      <td class="spec-label">Display</td>
5007      <td class="spec-value">2.3 inch black/white FSTN dot-matrix, 128×160 pixel, trans-reflective LCD with backlight</td>
5008    </tr>
5009    <tr>
5010      <td class="spec-label">Built-in Sensors</td>
5011      <td class="spec-value">Temperature sensor, barometric altimeter</td>
5012    </tr>
5013    <tr>
5014      <td class="spec-label">Wireless Transfer</td>
5015      <td class="spec-value">Data transfer: BLE 5.0<br>External connection: ANT+ (supports speed sensor, cadence, HRM belt, power meter, smart trainer)</td>
5016    </tr>
5017    <tr>
5018      <td class="spec-label">Charging Interface</td>
5019      <td class="spec-value">Micro USB, supports charging and data transfer</td>
5020    </tr>
5021    <tr>
5022      <td class="spec-label">Buttons</td>
5023      <td class="spec-value">Total 5 buttons</td>
5024    </tr>
5025    <tr>
5026      <td class="spec-label">Buzzer</td>
5027      <td class="spec-value">Yes</td>
5028    </tr>
5029    <tr>
5030      <td class="spec-label">Battery</td>
5031      <td class="spec-value">Built-in 880mAh rechargeable lithium battery</td>
5032    </tr>
5033    <tr>
5034      <td class="spec-label">Battery Life</td>
5035      <td class="spec-value">Up to 40 hours (under normal GPS signal)</td>
5036    </tr>
5037    <tr>
5038      <td class="spec-label">Water Resistance Rating</td>
5039      <td class="spec-value">IPX7</td>
5040    </tr>
5041    <tr>
5042      <td class="spec-label">Operating Temperature</td>
5043      <td class="spec-value">-10°C to 50°C</td>
5044    </tr>
5045    <tr>
5046      <td class="spec-label">Size / Weight</td>
5047      <td class="spec-value">Size: 82 x 54 x 21 mm<br>Weight: 65 g</td>
5048    </tr>
5049  </tbody>
5050</table>
5051</div>
5052        </div>
5053      
5054      
5055      
5056    </div>
5057  </div>
5058  <div id="product-recommendation"></div>
5059</div>
5060
5061<script>
5062  $(document).ready(function() {
5063    // 商品說明介紹標籤
5064    $(".desc_sections li").on('click', function() {
5065      $(this).children().addClass('active');
5066      $(this).siblings().children().removeClass('active');
5067    });
5068
5069    // 滑動設置
5070    var prevScrollPos = window.pageYOffset;
5071    var prevScrollInformationPos = window.pageYOffset;
5072    $(window).on('scroll load resize', function(e) {
5073      var headerHeight = $("#header").height()
5074      var desc_sections = $(".desc_sections");
5075      var desc_section_list = $(".desc_section");
5076      var descSectionHeight = $(".desc_sections").height()
5077      var descSectionTop = $(".desc_sections").offset().top - headerHeight
5078      var product_window = $(this);
5079      var currentScrollPos = window.pageYOffset;
5080
5081      // 滑動固定產品說明
5082      if (product_window.scrollTop() > descSectionTop) {
5083        desc_sections.find("ul").css({"top": 0});
5084        if (currentScrollPos > prevScrollPos && product_window.scrollTop() > descSectionTop + headerHeight) {
5085          desc_sections
5086            .stop()
5087            .addClass("desc_sections_hold")
5088            .css({"min-height": descSectionHeight})
5089            .find("ul")
5090            .css({"top": 0});
5091        } else if (prevScrollPos > currentScrollPos) {
5092          desc_sections
5093            .stop()
5094            .addClass("desc_sections_hold")
5095            .css({"min-height": descSectionHeight})
5096            .find("ul")
5097            .css({"top": headerHeight});
5098        } else {
5099          prevScrollPos = 0;
5100        } prevScrollPos = currentScrollPos;
5101        if ($(window).width() < 768) {
5102          $("body").css("padding-bottom", "68px");
5103        }
5104      } else {
5105        prevScrollPos = 0;
5106        desc_sections.stop().removeClass("desc_sections_hold")
5107        if ($(window).width() < 768) {
5108          $("body").css("padding-bottom", "68px");
5109        }
5110      }
5111
5112      // 點選產品說明滑動
5113      $(".desc_sections a.scroll").bind("click", function(event) {
5114        var targetScrollTop = parseInt($($(this).attr("href")).offset().top - descSectionHeight + 1);
5115        if (targetScrollTop > window.scrollY + 1) {
5116          $("html, body").stop().animate({
5117            scrollTop: targetScrollTop
5118          }, 300);
5119        } else {
5120          $("html, body").stop().animate({
5121            scrollTop: targetScrollTop - headerHeight
5122          }, 300);
5123        }
5124      });
5125
5126      // 顯示當前產品說明
5127      if (currentScrollPos > prevScrollInformationPos) {
5128        $.each(desc_section_list, function(index, desc_section) {
5129          var desc_sectionTop = $(desc_section).offset().top - descSectionHeight - 1
5130          var desc_sectionHeight = $(desc_section).height()
5131          var current_desc_section = $("a.scroll[href$='" + $(desc_section).attr("id") + "']");
5132          if (product_window.scrollTop() > desc_sectionTop || index === 0) {
5133            current_desc_section
5134              .stop()
5135              .addClass('active')
5136              .parent()
5137              .siblings()
5138              .find("a")
5139              .removeClass('active');
5140          } else {
5141            current_desc_section.removeClass('active');
5142          } prevScrollInformationPos = currentScrollPos;
5143        });
5144      } else {
5145        $.each(desc_section_list, function(index, desc_section) {
5146          var desc_sectionTop = $(desc_section).offset().top - descSectionHeight - 1
5147          var desc_sectionHeight = $(desc_section).height()
5148          var current_desc_section = $("a.scroll[href$='" + $(desc_section).attr("id") + "']");
5149          if (product_window.scrollTop() + headerHeight > desc_sectionTop) {
5150            current_desc_section
5151              .stop()
5152              .addClass('active')
5153              .parent()
5154              .siblings()
5155              .find("a")
5156              .removeClass('active');
5157          } else {
5158            current_desc_section.removeClass('active');
5159          }
5160        });
5161        prevScrollInformationPos = currentScrollPos;
5162      }
5163    });
5164  })
5165</script>
5165
5166
5167
5168
5169
5170
5171<div id="related-products" class="qk-pos--rel">
5172  
5173  
5174  
5175  
5176</div>
5177
5178
5179
5180  </div>
5181</div>
5182
5183    </div>
5184
5185    <!-- Footer -->
5186    
5187
5188
5189
5190
5191
5192
5193<style>
5194  
5195  
5196  @media(min-width: 991px) {
5197    .display_x .left-content > div {
5198      max-width: calc(100% / 1);
5199    }
5200  }
5201</style>
5202
5203<div id="index-recommendation"></div>
5204
5205<footer id="footer" class="qk-fs--body qk-bg--footer_bg">
5206  
5207    
5208    <div class="qk-container display_x">
5209      <div class="footer_content qk-mg--0 qk-display--flex qk-justify--between">
5210        <div class="left-content qk-flex--1">
5211          
5212            
5213              <div class="link-list-container">
5214                
5215                  <p class="footer_title qk-fs--title qk-text--footer_text">About Xplova</p>
5216                
5217                <div class="item horizontal qk-text--left">
5218                  <ul class="qk-display--flex qk-flex--wrap">
5219                    
5220                      
5221                        <li class="qk-display--il_bk">
5222                          
5223                            <a
5224                              class="qk-text--footer_text"
5225                              href="/blogs/announcement"
5226                              rel="noopener noreferrer"
5227                              target="_blank">Announcement</a>
5228                          
5229                        </li>
5230                      
5231                        <li class="qk-display--il_bk">
5232                          
5233                            <a
5234                              class="qk-text--footer_text"
5235                              href="/blogs/news"
5236                              rel="noopener noreferrer"
5237                              target="_blank">News</a>
5238                          
5239                        </li>
5240                      
5241                        <li class="qk-display--il_bk">
5242                          
5243                            <a
5244                              class="qk-text--footer_text"
5245                              href="/pages/about-us"
5246                              rel="noopener noreferrer"
5247                              target="_blank">About Us</a>
5248                          
5249                        </li>
5250                      
5251                        <li class="qk-display--il_bk">
5252                          
5253                            <a
5254                              class="qk-text--footer_text"
5255                              href="/pages/privacy"
5256                              rel="noopener noreferrer"
5257                              target="_blank">Privacy Policy</a>
5258                          
5259                        </li>
5260                      
5261                        <li class="qk-display--il_bk">
5262                          
5263                            <a
5264                              class="qk-text--footer_text"
5265                              href="/pages/terms"
5266                              rel="noopener noreferrer"
5267                              target="_blank">Terms of Service</a>
5268                          
5269                        </li>
5270                      
5271                        <li class="qk-display--il_bk">
5272                          
5273                            <a
5274                              class="qk-text--footer_text"
5275                              href="/pages/service-center"
5276                              rel="noopener noreferrer"
5277                              target="_blank">Service Center</a>
5278                          
5279                        </li>
5280                      
5281                    
5282                  </ul>
5283                </div>
5284              </div>
5285              
5286          
5287        </div>
5288        <div class="right-content qk-display--flex qk-flex--column">
5289          
5290          <div class="media qk-display--il">
5291            <div class="item social_media qk-h--auto qk-float--l">
5292              <ul>
5293                
5294                  <li class="qk-display--il_bk">
5295                    <a target="_blank" rel="noopener noreferrer" href="https://www.facebook.com/acergadget.xplova/">
5296                      <svg
5297                        class="facebook-svg"
5298                        xmlns="http://www.w3.org/2000/svg"
5299                        width="40"
5300                        height="40"
5301                        viewBox="0 0 40 40">
5302                        <path class="qk-svg--footer_text" d="M40 20.1208C40 30.1027 32.6767 38.3778 23.1167 39.8795V25.9409H27.765L28.65 20.1742H23.1167V16.4324C23.1167 14.8541 23.89 13.3174 26.3667 13.3174H28.8817V8.4073C28.8817 8.4073 26.5983 8.01729 24.4167 8.01729C19.86 8.01729 16.8833 10.779 16.8833 15.7774V20.1725H11.8183V25.9393H16.8833V39.8779C7.325 38.3745 0 30.101 0 20.1208C0 9.07564 8.955 0.120483 20 0.120483C31.045 0.120483 40 9.07398 40 20.1208Z" />
5303                      </svg>
5304                    </a>
5305                  </li>
5306                
5307                
5308                  <li class="qk-display--il_bk">
5309                    <a target="_blank" rel="noopener noreferrer" href="https://www.instagram.com/xplova.global/">
5310                      <svg
5311                        class="instagram-svg"
5312                        xmlns="http://www.w3.org/2000/svg"
5313                        width="40"
5314                        height="40"
5315                        viewBox="0 0 40 40">
5316                        <rect class="qk-svg--footer_text" width="40" height="40" rx="20" />
5317                        <path class="qk-svg--footer_bg" d="M15.0302 8.08393C13.7534 8.14417 12.8814 8.34793 12.1192 8.64745C11.3303 8.95489 10.6616 9.36745 9.99636 10.0351C9.33107 10.7028 8.92139 11.3719 8.61611 12.162C8.32066 12.9259 8.1205 13.7986 8.0641 15.0761C8.0077 16.3536 7.99522 16.7643 8.00146 20.023C8.0077 23.2817 8.0221 23.6902 8.08402 24.9704C8.14498 26.2469 8.34802 27.1186 8.64755 27.8811C8.95547 28.67 9.36755 29.3384 10.0355 30.0039C10.7034 30.6694 
531711.3721 31.0782 12.1641 31.3839C12.9273 31.6789 13.8002 31.88 15.0775 31.9359C16.3547 31.9918 16.7659 32.0048 20.0237 31.9986C23.2815 31.9923 23.6916 31.9779 24.9716 31.9172C26.2515 31.8565 27.1186 31.652 27.8813 31.3539C28.6702 31.0453 29.3391 30.6339 30.0042 29.9658C30.6692 29.2976 31.0787 28.628 31.3837 27.8374C31.6794 27.0742 31.8803 26.2013 31.9357 24.925C31.9916 23.6441 32.0048 23.2352 31.9986 19.9769C31.9923 16.7187 31.9777 16.3102 31.917 15.0305C31.8563 13.7508 31.653 12.8818 31.3537 12.1188C31.0453 11.3299 30.6337 10.662 29.966 9.99601C29.2983 9.33001 28.6282 8.92081 27.8379 8.61649C27.0742 8.32105 26.2018 8.11969 24.9245 8.06449C23.6472 8.00929 23.2361 7.99513 19.9771 8.00137C16.7181 8.00761 16.3101 8.02153 15.0302 8.08393ZM15.1703 29.7771C14.0003 29.7262 13.365 29.5318 12.9417 29.3691C12.381 29.1531 11.9817 28.892 11.5597 28.4742C11.1378 28.0563 10.8786 27.6555 10.6597 27.0961C10.4953 26.6727 10.2973 26.0381 10.2426 24.8681C10.1831 23.6036 10.1706 23.2239 10.1636 20.0201C10.1567 16.8164 10.1689 16.4372 10.2244 15.1721C10.2743 14.0031 10.4699 13.3671 10.6324 12.9439C10.8484 12.3826 11.1085 11.9839 11.5273 11.5623C11.9461 11.1406 12.3457 10.8809 12.9057 10.662C13.3286 10.4969 13.9631 10.3006 15.1327 10.2449C16.3982 10.1849 16.7774 10.1729 19.9807 10.1659C23.184 10.159 23.5642 10.171 24.8302 10.2267C25.9992 10.2775 26.6355 10.4712 27.0581 10.6347C27.619 10.8507 28.0181 11.1101 28.4398 11.5296C28.8615 11.9491 29.1214 12.3473 29.3403 12.9084C29.5057 13.3301 29.702 13.9644 29.7572 15.1347C29.8174 16.4002 29.8311 16.7796 29.8369 19.9827C29.8426 23.1857 29.8314 23.5661 29.7759 24.8307C29.7248 26.0007 29.5309 26.6362 29.3679 27.0601C29.1519 27.6205 28.8915 28.0201 28.4725 28.4415C28.0534 28.863 27.6543 29.1226 27.0941 29.3415C26.6717 29.5064 26.0364 29.7032 24.8679 29.7589C23.6023 29.8184 23.2231 29.8309 20.0186 29.8378C16.8141 29.8448 16.4361 29.8318 15.1706 29.7771M24.9531 13.5864C24.9535 13.8713 25.0385 14.1495 25.1971 14.3861C25.3558 14.6226 25.581 14.8068 25.8443 14.9154C26.1077 15.0239 26.3973 15.0519 26.6765 14.9959C26.9558 14.9398 27.2122 14.8022 27.4132 14.6004C27.6142 14.3986 27.7509 14.1418 27.806 13.8623C27.861 13.5828 27.8319 13.2933 27.7224 13.0304C27.6129 12.7675 27.4279 12.5429 27.1908 12.3851C26.9536 12.2274 26.675 12.1435 26.3902 12.144C26.0084 12.1448 25.6425 12.2972 25.373 12.5677C25.1035 12.8381 24.9524 13.2046 24.9531 13.5864ZM13.8386 20.012C13.8453 23.4152 16.6091 26.1677 20.0117 26.1613C23.4142 26.1548 26.1687 23.3912 26.1622 19.988C26.1557 16.5848 23.3911 13.8315 19.9881 13.8382C16.5851 13.8449 13.8321 16.6092 13.8386 20.012ZM16 20.0076C15.9985 19.2165 16.2315 18.4427 16.6698 17.784C17.108 17.1253 17.7317 16.6114 18.462 16.3072C19.1924 16.003 19.9965 15.9222 20.7727 16.075C21.549 16.2278 22.2625 16.6073 22.823 17.1656C23.3836 17.724 23.766 18.436 23.9218 19.2116C24.0777 19.9872 24.0001 20.7917 23.6988 21.5232C23.3975 22.2547 22.886 22.8804 22.2291 23.3213C21.5721 23.7621 20.7992 23.9983 20.0081 23.9998C19.4827 24.0009 18.9623 23.8985 18.4766 23.6985C17.9909 23.4985 17.5493 23.2047 17.1771 22.834C16.8049 22.4632 16.5094 22.0228 16.3074 21.5379C16.1054 21.0529 16.001 20.533 16 20.0076Z" />
5318                      </svg>
5319                    </a>
5320                  </li>
5321                
5322                
5323                
5324                  <li class="qk-display--il_bk">
5325                    <a target="_blank" rel="noopener noreferrer" href="https://www.youtube.com/c/XplovaPoweredbyAcer">
5326                      <svg
5327                        class="youtube-svg"
5328                        xmlns="http://www.w3.org/2000/svg"
5329                        width="40"
5330                        height="40"
5331                        viewBox="0 0 40 40">
5332                        <rect class="qk-svg--footer_text" width="40" height="40" rx="20" />
5333                        <path class="qk-svg--footer_bg" d="M27.3078 11H12.6922C9.82462 11 7.5 13.3653 7.5 16.283V23.717C7.5 26.6347 9.82462 29 12.6922 29H27.3078C30.1754 29 32.5 26.6347 32.5 23.717V16.283C32.5 13.3653 30.1754 11 27.3078 11ZM23.7964 20.3617L16.9602 23.6792C16.778 23.7676 16.5676 23.6324 16.5676 23.4271V16.5848C16.5676 16.3766 16.7835 16.2416 16.9661 16.3357L23.8023 19.8606C24.0055 19.9653 24.002 20.2619 23.7964 20.3617Z" />
5334                      </svg>
5335                    </a>
5336                  </li>
5337                
5338              </ul>
5339            </div>
5340          </div>
5341        </div>
5342      </div>
5343    </div>
5344    
5345  <div class="copyright qk-text--footer_text qk-bd--footer_text qk-text--left qk-bd_t--default">
5346    <div class="qk-container container qk-fw--500">
5347      <span>Copyright ©</span>
5348      <a class="qk-text--link" href="/">
5349        <span>Xplova</span>
5350      </a>
5351      <span>All Rights Reserved.</span>
5352      <span>Designed by
5353      </span>
5354      <a
5355        class="qk-text--link"
5356        href="https://www.cyberbiz.io?utm_source=poweredbycyberbiz"
5357        target="_blank"
5358        rel="noopener noreferrer"
5359        title="Designed by CYBERBIZ">CYBERBIZ</a>.
5360    </div>
5361  </div>
5362  
5363</footer>
5364<script>
5365  $(document).ready(function() {
5366    let isDynamicLoading = false;
5367
5368    let menusData = {
5369      
5370        
5371          "footer-menu-en": {
5372            
5373              "type": "items",
5374              "data": [
5375                
5376                
5377                  
5378                    {
5379                      "title": "Announcement",
5380                      "url": "/blogs/announcement",
5381                      "item_type": "blog"
5382                    },
5383                  
5384                    {
5385                      "title": "News",
5386                      "url": "/blogs/news",
5387                      "item_type": "blog"
5388                    },
5389                  
5390                    {
5391                      "title": "About Us",
5392                      "url": "/pages/about-us",
5393                      "item_type": "page"
5394                    },
5395                  
5396                    {
5397                      "title": "Privacy Policy",
5398                      "url": "/pages/privacy",
5399                      "item_type": "page"
5400                    },
5401                  
5402                    {
5403                      "title": "Terms of Service",
5404                      "url": "/pages/terms",
5405                      "item_type": "page"
5406                    },
5407                  
5408                    {
5409                      "title": "Service Center",
5410                      "url": "/pages/service-center",
5411                      "item_type": "page"
5412                    }
5413                  
5414                
5415              ]
5416            
5417          }
5418        
5419      
5420    };
5421
5422    if (isDynamicLoading) {
5423      window.DynamicLoading.setupComponent({
5424          sectionId: '#footer',
5425          callbackData:{
5426            section: {"type":"footer","visible":true,"settings":{"footer_link":"footer","display_facebook":true,"shop_facebook":"https://www.facebook.com/acergadget.xplova/","display_instagram":true,"shop_instagram":"https://www.instagram.com/xplova.global/","display_line":false,"shop_line":"https://line.me/zh-hant/","display_youtube":true,"shop_youtube":"https://www.youtube.com/c/XplovaPoweredbyAcer","footer_link_arrangement":"display_x"},"block_order":["default_link_list","default_contact_info"],"blocks":{"default_link_list":{"type":"link_list_setting","thumbnail":"list","draggable":true,"visible":true,"settings":{"dict_link_list_block_title":"About Xplova","footer_link":"footer-menu-en"},"custom_name":"選單"},"default_contact_info":{"type":"contact_info_setting","thumbnail":"contactInfo","draggable":true,"visible":false,"settings":{"dict_contact_info_block_title":"Contact Info","display_phone":false,"dict_phone_number":"+886-2-2790-3878","display_fax_number":false,"dict_shop_fax_number":"","display_shop_email":"true","dict_shop_email":"[email protected]","display_shop_address":false,"dict_shop_address":"","display_office_time":false,"dict_shop_office_time":"10:00-17:00","display_tax_id":true,"dict_tax_id":"22089345"},"custom_name":"聯絡資訊"}},"custom_name":"頁腳"},
5427            shop: {
5428              name: 'Xplova',
5429              cyberbiz_link: 'https://www.cyberbiz.io?utm_source=poweredbycyberbiz',
5430              facebook_fan_page: '',
5431            },
5432            menus: menusData,
5433            is_display_facebook_fan_block: false
5434            },
5435          entryName:'renderFooterSection',
5436          source:'//cdn-general.cybassets.com/frontend/shop/footerSection-3a2e378145f8a165.js',
5437        });
5438    }
5439  });
5440</script>
5440
5441
5442<!-- cyb_snippet _tracking_code start -->
5443      
5443<script>
5444        window.fbAsyncInit = function() {
5445          FB.init({
5446          appId : '715014966289821',
5447          xfbml : true,
5448          version : 'v24.0',
5449          });
5450        };
5451        (function(d, s, id){
5452          var js, fjs = d.getElementsByTagName(s)[0];
5453          if (d.getElementById(id)) {return;}
5454          js = d.createElement(s);
5455          js.id = id;
5456          js.src = 'https://connect.facebook.net/zh_TW/sdk.js';
5457          fjs.parentNode.insertBefore(js, fjs);
5458        }(document, 'script', 'facebook-jssdk'));
5459      </script>
5459
5460
5461
5462<script>
5463  // for scupio
5464  if (document.querySelector("meta[name=\"scupio_mid\"]")) {
5465    mid = document.querySelector("meta[name=\"scupio_mid\"]").content;
5466  } else {
5467    mid = "";
5468  }
5469  if (!window.is_scupio_sent && mid) {
5470    window._bwtm = window._bwtm || []
5471    window._bwtm.push({
5472      "mid": mid,
5473      "uid": ""
5474    });
5475  }
5476</script>
5476
5477
5478<!-- cyb_snippet _tracking_code end -->
5479
5480<script>
5481  $(document).ready(function(){
5482    if(window.location.pathname != '' && window.location.pathname != '/' ){
5483      document.getElementById('index-recommendation').style.display = 'none'
5484    }
5485  });
5486</script>
5486
5487
5488
5489
5490    <!-- Fast-Events -->
5491    <!-- cyb_snippet fast_events start -->
5492
5493
5494<script src='//cdn-general.cybassets.com/frontend/shop/beta_theme/js/fast_events-3a2e378145f8a165.js' type='text/javascript'></script>
5494
5495<link href='//cdn-general.cybassets.com/frontend/shop/beta_theme/css/fast_events-3a2e378145f8a165.css' rel='stylesheet' type='text/css' media='all' />
5496
5497<!-- cyb_snippet fast_events end -->
5498
5499    <div class="bottom-right qk-pos--fixed">
5500      <!-- gototop -->
5501      <div id="gototop" class="qk-display--none qk-text--center">
5502        <a href="javascript:void(0)" class="qk-circle qk-circle--lg qk-pos--relative qk-text--center">
5503          <i class="fas fa-chevron-up"></i>
5504        </a>
5505      </div>
5506
5507      <!-- popup -->
5508      
5509
5510
5511
5512<div id="popup-wrapper" class="qk-display--none"></div>
5513
5514<template id="popup-template">
5515  <div
5516    :class="status"
5517    v-if="hasContent"
5518    id="popup-section"
5519  >
5520    <transition name="backdrop">
5521      <div
5522        v-if="shouldShowPopup"
5523        @click.capture="minifyPopup"
5524        id="popup-backdrop"
5525        class="qk-w--100vw qk-h--100vh qk-pos--fixed qk-t--0 qk-l--0 qk-tst"
5526      >
5527      </div>
5528    </transition>
5529    <transition name="onShow">
5530      <div
5531        @click.self="showPopup"
5532        @transitionstart="updateGameStatus('start', this)"
5533        @transitionend="updateGameStatus('end', this)"
5534        class="popup-content qk-display--flex qk-align--center qk-tst qk-tst_dur--30 qk-tst_timing--ease_o"
5535      >
5536        <div
5537          v-for="block in blocks"
5538          :key="block.id"
5539          :class="[block.type, minifiedBlockClasses, block.settings.icon_size]"
5540          class="block qk-tst qk-tst_dur--30 qk-tst_timing--ease_o qk-of--auto"
5541        >
5542          <div v-if="block.type === 'image'" class="qk-pos--rel">
5543            <img
5544              v-show="!shouldShowPopup"
5545              :src="block.settings.dict_icon_image_url"
5546              class="qk-tst qk-tst_dur--30 qk-tst_timing--ease_o"
5547              alt="popup button"
5548            >
5549            <a
5550              v-show="shouldShowPopup"
5551              :href="block.settings.dict_link"
5552              :target="block.settings.target"
5553              :rel="block.settings.rel"
5554              class="qk-display--flex qk-align--center"
5555              @click="linkClicked"
5556            >
5557              <picture>
5558                <source :srcset="block.settings.dict_mobile_image_url" media="(max-width: 576px)">
5559                <source :srcset="block.settings.dict_tablet_image_url" media="(max-width: 992px)">
5560                <img
5561                  :src="block.settings.dict_image_url"
5562                  class="qk-tst qk-tst_dur--30 qk-tst_timing--ease_o"
5563                  alt="popup picture"
5564                />
5565              </picture>
5566            </a>
5567          </div>
5568          <div v-if="block.type === 'video'">
5569            <iframe
5570              :src="block.settings.dict_video_link"
5571              frameborder="0"
5572              class="qk-center--y qk-w--100 qk-h--100"
5573            ></iframe>
5574          </div>
5575          <div v-if="block.type === 'game'">
5576            <div v-show="gameStatus === 'show'" :class="{ 'show-game': gameStatus === 'show' }">
5577              <iframe
5578                class="cb-game-iframe iframe-loading"
5579                :src="getGameIframeSrc(block)"
5580                style="border: none;"
5581              >
5582                Loading
5583              </iframe>
5584            </div>
5585            <div v-show="gameStatus === 'minified'">
5586              <img
5587                src="//cdn-general.cybassets.com/game_assets/game_minified_new.png"
5588                class="qk-h--100 qk-w--100"
5589                alt="game minified icon"
5590              />
5591            </div>
5592          </div>
5593          <div
5594            v-if="block.type === 'carousel'"
5595            :id="`popup-carousel-${block.id}`"
5596          >
5597          </div>
5598        </div>
5599      </div>
5600    </transition>
5601    <transition name="backdrop">
5602      <div
5603        v-if="shouldShowPopup"
5604        @click.capture="minifyPopup"
5605        class="minify-popup qk-circle qk-circle--md qk-text--black qk-bg--white qk-bd--default qk-bd--border qk-text--center qk-cursor--pointer qk-pos--fixed"
5606      >
5607      </div>
5608    </transition>
5609  </div>
5610</template>
5611
5612<script>
5613  $(document).ready(function() {
5614    const CDN_HOST = '//cdn-general.cybassets.com';
5615    const section = {"type":"popup","visible":true,"blocks":{"popup_block_1":{"type":"image","visible":false,"settings":{"dict_image_url":"/theme_src/i18n_shoestore/default_img/popup_default.jpg","icon_size":"small"},"custom_name":"圖片"}},"block_order":["popup_block_1"],"settings":{},"custom_name":"彈窗廣告"};
5616    var popupSection = Vue.createApp({
5617      template: '#popup-template',
5618      delimiters: ['${', '}'],
5619      data() {
5620        const isOmniauthPage = ['omniauth_terms_agreement', 'omniauth_mobile/']
5621          .some(path => location.pathname.includes(path));
5622        return {
5623          status: 'minified',
5624          gameStatus: 'show',
5625          blocks: isOmniauthPage
5626            ? []
5627            : section.block_order && section.block_order.reduce(
5628                function(acc, blockId) {
5629                  const block = section.blocks[blockId];
5630                  if (block && block.visible) {
5631                    acc.push({
5632                      ...block,
5633                      id: blockId,
5634                    });
5635                  }
5636                  return acc;
5637                },
5638                [],
5639              ),
5640          hasAddedGameScript: false,
5641        };
5642      },
5643      computed: {
5644        hasContent: function() {
5645          return !!(this.blocks && this.blocks.length > 0);
5646        },
5647        minifiedBlockClasses: function() {
5648          return this.status === 'minified' ? 'qk-pointer--none qk-unselectable' : '';
5649        },
5650        shouldShowPopup: function() {
5651          return this.status === 'show';
5652        }
5653      },
5654      methods: {
5655        unhidePopup: function(storedStatus) {
5656          this.status = storedStatus;
5657          $('#popup-wrapper').removeClass('qk-display--none');
5658        },
5659        showPopup: function() {
5660          if (this.status !== 'show') {
5661            this.status = 'show';
5662            this.saveStatus(this.status);
5663          }
5664        },
5665        minifyPopup: function() {
5666          this.status = 'minified';
5667          this.saveStatus('minified');
5668        },
5669        loadStatus: function() {
5670          return JSON.parse(localStorage.getItem('popupStatus'));
5671        },
5672        saveStatus: function(status) {
5673          if (status) {
5674            localStorage.setItem('popupStatus', JSON.stringify({
5675              status: status,
5676              setTime: new Date().getTime(),
5677            }));
5678          }
5679        },
5680        linkClicked: function() {
5681          this.saveStatus('minified');
5682        },
5683        parseVideoLink: function(settings) {
5684          settings.dict_video_link = themeHelper.parseYtUrl(settings.dict_video_link);
5685        },
5686        setupImageSrc: function (settings) {
5687          settings.dict_image_url = this.addCdnHost(settings.dict_image_url);
5688          if (settings.dict_tablet_image_url) {
5689            settings.dict_tablet_image_url = this.addCdnHost(settings.dict_tablet_image_url);
5690          }
5691          if (settings.dict_mobile_image_url) {
5692            settings.dict_mobile_image_url = this.addCdnHost(settings.dict_mobile_image_url);
5693          }
5694          settings.dict_icon_image_url = this.addCdnHost(settings.dict_icon_image_url) || settings.dict_image_url;
5695        },
5696        addCdnHost: function(url) {
5697          if (!url) {
5698            return url; // only add cdn host if url is not empty
5699          }
5700
5701          try {
5702            new URL(url);
5703            return url; // already a valid url, cdn host not needed
5704          } catch {
5705            return `${CDN_HOST}${url}`;
5706          }
5707        },
5708        initStatus: function() {
5709          let newStatus = 'show';
5710          const popupStatus = this.loadStatus();
5711          const currentTime = new Date().getTime();
5712          const oneDay = 1000 * 60 * 60 * 24;
5713          const hasStoredStatus = popupStatus && currentTime - popupStatus.setTime < oneDay;
5714          const redirectedByGameLogin = !this.hasRedirectUrl() && this.redirectedByGameLogin();
5715          const isLoggingIn = this.isLoggingIn();
5716          const isCartPage = window.location.pathname.split('/').includes('carts');
5717
5718          if (hasStoredStatus && !redirectedByGameLogin) {
5719            newStatus = popupStatus.status;
5720          }
5721
5722          if (isLoggingIn) {
5723            newStatus = 'minified';
5724          } else {
5725            localStorage.removeItem('redirectedByPopup');
5726          }
5727
5728          setTimeout(() => {
5729            this.status = newStatus;
5730            this.gameStatus = newStatus;
5731            this.saveStatus(newStatus);
5732            if(!isCartPage){
5733              this.unhidePopup(newStatus);
5734            }
5735          }, 1000);
5736        },
5737        initBlocks: function() {
5738          if (this.hasContent) {
5739            this.blocks.forEach(block => {
5740              switch(block.type) {
5741                case 'image':
5742                  this.setupImageSrc(block.settings);
5743
5744                  const isOpenInNewTab = block.settings.link_open_in_new_tab;
5745                  if (isOpenInNewTab) {
5746                    block.settings.target = '_blank';
5747                    block.settings.rel = 'noopener noreferrer';
5748                  }
5749
5750                  break;
5751                case 'video':
5752                  this.parseVideoLink(block.settings);
5753                  break;
5754              }
5755            })
5756          }
5757        },
5758        getGameIframeSrc: function (block) {
5759          return `/games/${block.settings.dict_game_handle}`
5760        },
5761        updateGameStatus: function(type, element) {
5762          if (
5763            (type === 'start' && this.status === 'minified')
5764            || (type === 'end' && this.status === 'show')
5765          ) {
5766            this.gameStatus = this.status;
5767          }
5768        },
5769        setupGameRedirects: function() {
5770          window.addEventListener('pagehide', () => {
5771            const isGameActive = document.body.getElementsByClassName('show-game').length;
5772            if (isGameActive) {
5773              localStorage.setItem('redirectedByPopup', 'true');
5774              this.saveStatus('minified');
5775            }
5776          });
5777        },
5778        hasRedirectUrl: function() {
5779          return (new URLSearchParams(location.search)).has('redirect_url');
5780        },
5781        redirectedByGameLogin: function() {
5782          return localStorage.getItem('redirectedByPopup');
5783        },
5784        isLoggingIn: function() {
5785          const loginRelatedPathnames = [
5786            'account/signup',
5787            'account/login',
5788            'account/customer/password/new',
5789            'pages/terms'
5790          ];
5791          return loginRelatedPathnames.some(path => location.pathname.includes(path));
5792        }
5793      },
5794      created: function() {
5795        this.initStatus();
5796        this.initBlocks();
5797        this.setupGameRedirects();
5798      },
5799      mounted: function() {
5800        this.blocks.forEach((block) => {
5801          if (block.type === 'carousel' && block.settings.dict_c
5801arousel) {
5802            renderCarousel(`#popup-carousel-${block.id}`, {
5803              title: block.settings.dict_carousel,
5804              CDN_HOST,
5805              onLinkClick: () => this.linkClicked(),
5806            });
5807          }
5808        });
5809      },
5810    });
5811    popupSection.mount('#popup-wrapper');
5812  });
5813</script>
5813
5814
5815
5816
5817    </div>
5818
5819    <!-- ajaxloading -->
5820    <div id="ajaxloading" class="qk-display--none qk-h--100vh qk-w--100vw qk-l--0 qk-t--0 qk-pos--fixed">
5821      <div class="ajaxbody qk-pos--abs qk-l--50 qk-t--50 qk-text--center">
5822        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="73.4" height="73.4" viewBox="0 0 73.4 73.4">
5823          <circle class="circle" fill="none" stroke="#898989" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" cx="36.7" cy="36.7" r="35.2"/>
5824          <polyline class="success_path" fill="none" stroke="#898989" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="23.7,36.8 32.4,45.4 49.7,28 "/>
5825          <path class="success_icon" fill="#898989" d="M32.5,46.9c-0.4,0-0.8-0.2-1.1-0.4l-8.6-8.6c-0.6-0.6-0.6-1.5,0-2.1s1.5-0.6,2.1,0l7.5,7.5L48.6,27c0.6-0.6,1.5-0.6,2.1,0s0.6,1.5,0,2.1L33.5,46.5C33.2,46.7,32.9,46.9,32.5,46.9L32.5,46.9z"/>
5826          <line class="fail_path" fill="none" stroke="#898989" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="26.6" y1="26.6" x2="46.8" y2="46.8"/>
5827          <line class="fail_path" fill="none" stroke="#898989" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" x1="46.8" y1="26.6" x2="26.6" y2="46.8"/>
5828          <path class="fail_icon" fill="#898989" d="M38.7,36.7l9.1-9.1c0.6-0.6,0.6-1.5,0-2.1s-1.5-0.6-2.1,0l-9.1,9.1l-9.1-9.1c-0.6-0.6-1.5-0.6-2.1,0s-0.6,1.5,0,2.1l9.1,9.1l-9.1,9.1c-0.6,0.6-0.6,1.5,0,2.1c0.3,0.3,0.7,0.4,1.1,0.4s0.8-0.1,1.1-0.4l9.1-9.1l9.1,9.1c0.3,0.3,0.7,0.4,1.1,0.4s0.8-0.1,1.1-0.4c0.6-0.6,0.6-1.5,0-2.1L38.7,36.7z"/>
5829        </svg>
5830        <div class="success_msg title qk-display--none qk-pos--abs qk-l--0 qk-w--100 qk-text--center">Added to Cart</div>
5831        <div class="success_update_msg title qk-display--none qk-pos--abs qk-l--0 qk-w--100 qk-text--center">Shopping Cart Updated</div>
5832        <div class="fail_msg title qk-display--none qk-pos--abs qk-l--0 qk-w--100 qk-text--center">Network error, please try again!</div>
5833      </div>
5834    </div>
5835  
5835<script src="//cdn-general.cybassets.com/assets/referral-code-trace-5fcbbe026a61c36b5f09a1615a1c168688205205d9d3e7ee854181a66b64a6ed.js"></script>
5835
5836      
5836<script>
5837      cyb.push({
5838        'event': 'productDetails',
5839        'ecommerce': {
5840          'currencyCode': 'TWD',
5841          'detail': {
5842            'products': [{"id":58021395,"name":"X2 - 智慧車錶","price":2490.0,"brand":null,"category":null,"variant":""}]
5843           }
5844         }
5845      });
5846      </script>
5846
5847    
5848      
5848<script>
5849        if (window.fbq) {
5850          fbq("track", "ViewContent", {
5851            content_name: "X2 - 智慧車錶",
5852            content_ids: "70177313",
5853            content_type: "product",
5854            value: 2490.0,
5855            currency: "TWD",
5856            contents: [{"id":70177313,"price":2490.0,"quantity":0}],
5857            content_category: null
5858          },{
5859            eventID: "ViewContent_8A4EFBD45E7B80AE4FAD50E9CB50A52F"
5860          });
5861        }
5862      </script>
5862
5863    </body>
5864
5865  
5865<script src='//cdn-general.cybassets.com/frontend/shop/beta_theme/js/sub_vendor-3a2e378145f8a165.js' type='text/javascript'></script>
5865
5866  
5866<script src='//cdn-general.cybassets.com/frontend/shop/beta_theme/js/theme_helper-3a2e378145f8a165.js' type='text/javascript'></script>
5866
5867
5868  <!-- theme assets -->
5869  
5869<script src='//cdn-general.cybassets.com/s/files/33373/theme/121378/assets/js/1751424603_5d7068a0_main.js?1751424603' type='text/javascript'></script>
5869
5870  
5870<script src='//cdn-general.cybassets.com/frontend/shop/beta_theme/js/theme-3a2e378145f8a165.js' type='text/javascript'></script>
5870
5871
5872  <!-- for cache -->
5873  
5873<script src='//cdn-general.cybassets.com/frontend/shop/beta_theme/js/cacheable-3a2e378145f8a165.js' type='text/javascript'></script>
5873
5874</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.