1(function(){ 2 3 var bootstrap = {"title":"Widget PDP","type":"tvpwidget","layout":"solo-cta","name":"widget-pdp","url":"tvpwidget/widget-pdp","loginId":"1759380","channelid":"","description":"","advertising":{"adinterval":0,"adserverurl":null,"adtimeout":2000,"enabled":false,"maxads":100},"analytics":true,"api_base_url":"//api.tvpage.com/v1","autonext":true,"autoplay":true,"firstpartycookies":true,"fix_page_scroll":true,"fonts":["//fonts.googleapis.com/css?family=Open+Sans:600,700,800"],"merchandise":false,"modal_title_position":"top","no_products_banner":"","no_products_banner_height":0,"no_products_banner_margin":0,"no_products_banner_padding":0,"no_products_banner_width":"inherit","play_button_background_color":"#333","play_button_border_color":"transparent","play_button_border_radius":"50%","play_button_border_style":"solid","play_button_border_width":0,"play_button_icon_color":"#fff","player_version":"master","preload":false,"product_popup_cta_text":"View Details","product_rating_attribute":"rating","product_review_attribute":"review_count","product_sku_prefix":"","product_sku_show":false,"products_headline_display":"block","products_headline_text":"Related Products","products_info_tooltip":false,"products_message":""}; 4 bootstrap.dependencyRoot = "https://static.prod.tvpage.com/1759380/"; 5 bootstrap.clientConfig = {"client":{"affiliate_network":"","ambassador":{"default_profile_cover_url":"https://sitecdn.tvpage.com/static/images/default_cover_photo.jpg","default_profile_photo_url":"https://sitecdn.tvpage.com/static/images/default_profile_photo.jpg","messaging":{"facebook":{"dashboard":["merchant","ambassador"],"editable":["ambassador"],"helper_text":"Insert your Facebook Messenger chat URL to enable a customer to chat with you on Facebook Messenger","label":"Facebook Messenger Link","order":2,"show_errors_on_focus":true,"type":"text","validations":[{"error_message":"This doesn't appear to be a valid Facebook Messenger Link. Check the link and try again or message the program administrator if the problem persists.","regexp":"^http[s]?://m\\.me/([a-zA-Z\\-\\_\\.0-9]+[/]?)$","type":"regexp"}]},"whatsapp":{"dashboard":["merchant","ambassador"],"default_error_message":"This phone number doesn't seem quite right. For US phone numbers, include \"+1\" at the beginning of your entry.","editable":["ambassador"],"helper_text":"Insert your Whatsapp Messenger chat URL to enable a customer to chat with you on Whatsapp Messenger","label":"WhatsApp Chat","order":7,"show_errors_on_focus":true,"type":"text","validations":[{"error_message":"This doesn't appear to be a valid Whatsapp Messenger Link. Check the link and try again or message the program administrator if the problem persists.","regexp":"^http[s]?://wa\\.me/[0-9]+[/]?(\\?text=.*)?$","type":"regexp"}]}},"social_handles":{"facebook_url":{"dashboard":["merchant","ambassador"],"editable":["ambassador"],"helper_text":"Insert your Facebook page URL to enable a customer to follow you on Facebook","label":"Facebook URL","order":2,"show_errors_on_focus":true,"type":"text","validations":[{"error_message":"This doesn't appear to be a valid Facebook page URL. Check the URL and try again or message the program administrator if the problem persists.","regexp":"^(([hH][tT][tT][pP][sS]?://)?(www\\.)?facebook\\.com/((profile\\.php\\?id=\\d+[/]?)|(pages/[a-zA-Z\\-\\_\\.0-9]+/\\d+[/]?)|([a-zA-Z\\-\\_\\.0-9]+[/]?))|@?[a-zA-Z\\-\\_\\.0-9]+[/]?)$","type":"regexp"}]},"instagram_url":{"dashboard":["merchant","ambassador"],"editable":["ambassador"],"helper_text":"Insert your Instagram profile URL to enable a customer to follow you on Instagram","label":"Instagram URL","order":1,"show_errors_on_focus":true,"type":"text","validations":[{"error_message":"This doesn't appear to be a valid Instagram profile URL. Check the URL and try again or message the program administrator if the problem persists.","regexp":"^(([hH][tT][tT][pP][sS]?://)?(www\\.)?instagram\\.com/|@?)[a-zA-Z\\-\\_\\.0-9]+[/]?(\\?.*)*$","type":"regexp"}]},"linkedin_url":{"dashboard":["merchant","ambassador"],"editable":["ambassador"],"helper_text":"Insert your LinkedIn profile URL to enable a customer to follow you on LinkedIn","label":"LinkedIn URL","order":8,"show_errors_on_focus":true,"type":"text","validations":[{"error_message":"This doesn't appear to be a valid LinkedIn profile URL. Check the URL and try again or message the program administrator if the problem persists.","regexp":"^(([hH][tT][tT][pP][sS]?://)?(www\\.)?linkedin\\.com/in/|@?)[a-zA-Z\\-\\_\\.0-9]+[/]?$","type":"regexp"}]},"pinterest_url":{"dashboard":["merchant","ambassador"],"editable":["ambassador"],"helper_text":"Insert your Pinterest profile URL to enable a customer to follow you on Pinterest","label":"Pinterest URL","order":4,"show_errors_on_focus":true,"type":"text","validations":[{"error_message":"This doesn't appear to be a valid Pinterest profile URL. Check the URL and try again or message the program administrator if the problem persists.","regexp":"^(([hH][tT][tT][pP][sS]?://)?(www\\.)?pinterest\\.com/|@?)[a-zA-Z\\-\\_\\.0-9]+[/]?$","type":"regexp"}]},"snapchat_url":{"dashboard":["merchant","ambassador"],"editable":["ambassador"],"helper_text":"Insert your Snapchat profile URL to enable a customer to follow you on Snapchat","label":"Snapchat URL","order":5,"show_errors_on_focus":true,"type":"text","validations":[{"error_message":"This doesn't appear to be a valid Snapchat profile URL. Check the URL and try again or message the program administrator if the problem persists.","regexp":"^(([hH][tT][tT][pP][sS]?://)?(www\\.)?snapchat\\.com/(add/|@)?|@?)[a-zA-Z\\-\\_\\.0-9]+[/]?$","type":"regexp"}]},"tiktok_url":{"dashboard":["merchant","ambassador"],"editable":["ambassador"],"helper_text":"Insert your TikTok profile URL to enable a customer to follow you on TikTok","label":"TikTok URL","order":6,"show_errors_on_focus":true,"type":"text","validations":[{"error_message":"This doesn't appear to be a valid TikTok profile URL. Check the URL and try again or message the program administrator if the problem persists.","regexp":"^(([hH][tT][tT][pP][sS]?://)?(www\\.)?tiktok\\.com/@?|([hH][tT][tT][pP][sS]?://vm\\.tiktok\\.com/)|@?)[a-zA-Z\\-\\_\\.0-9]+[/]?(\\?.*)*$","type":"regexp"}]},"twitter_url":{"dashboard":["merchant","ambassador"],"editable":["ambassador"],"helper_text":"Insert your X profile URL to enable a customer to follow you on X","label":"X URL","order":3,"show_errors_on_focus":true,"type":"text","validations":[{"error_message":"This doesn't appear to be a valid X profile URL. Check the URL and try again or message the program administrator if the problem persists.","regexp":"^(([hH][tT][tT][pP][sS]?://)?(www\\.)?(twitter|x)\\.com/|@?)[a-zA-Z\\-\\_\\.0-9]+[/]?$","type":"regexp"}]},"whatsapp_chat":{"dashboard":["merchant","ambassador"],"default_error_message":"This phone number doesn't seem quite right. For US phone numbers, include \"+1\" at the beginning of your entry.","editable":["ambassador"],"helper_text":"Insert your mobile number to enable a customer to communicate with you on WhatsApp. For US phone numbers, include \"+1\" at the beginning of your entry.","label":"WhatsApp Chat","order":7,"show_errors_on_focus":true,"type":"intl_phone"},"youtube_url":{"dashboard":["merchant","ambassador"],"editable":["ambassador"],"helper_text":"Insert your YouTube channel URL to enable a customer to follow you on YouTube","label":"YouTube URL","order":9,"show_errors_on_focus":true,"type":"text","validations":[{"error_message":"This doesn't appear to be a valid YouTube channel URL. Check the URL and try again or message the program administrator if the problem persists.","regexp":"^(([hH][tT][tT][pP][sS]?://)?(www\\.)?youtube\\.com/((channel|user|c)/[a-zA-Z\\-\\_\\.0-9]+[/]?|@?[a-zA-Z\\-\\_\\.0-9]+[/]?)|@?[a-zA-Z\\-\\_\\.0-9]+)$","type":"regexp"}]}},"storefront_details":{"creator_bio":{"dashboard":["merchant","ambassador"],"editable":["ambassador"],"helper_text":"Tell us about you!","hide":false,"label":"Bio","max_length":500,"order":2,"rows":4,"show_errors_on_focus":true,"show_length_counter":true,"type":"textarea"}
5,"display_name":{"dashboard":["merchant","ambassador"],"editable":["ambassador"],"helper_text":"This name will be displayed under your profile photo on your storefront.","label":"Display Name","max_length":25,"order":1,"show_errors_on_focus":true,"show_length_counter":true,"type":"text"},"welcome_text_1":{"dashboard":["merchant","ambassador"],"editable":["ambassador"],"helper_text":"This text will be displayed under your display name on your storefront. If no text is provided, none will be displayed.","hide":true,"label":"Welcome Text (Line 1/2)","max_length":50,"order":3,"show_errors_on_focus":true,"show_length_counter":true,"type":"text"},"welcome_text_2":{"dashboard":["merchant","ambassador"],"editable":["ambassador"],"helper_text":"This text will be displayed under your display name on your storefront. If no text is provided, none will be displayed.","hide":true,"label":"Welcome Text (Line 2/2)","max_length":50,"order":4,"show_errors_on_focus":true,"show_length_counter":true,"type":"text"}},"storefront_live_meeting":{"background_color":{"dashboard":["merchant","ambassador"],"editable":["ambassador"],"label":"Background Color","order":7,"type":"text"},"button_color":{"dashboard":["merchant","ambassador"],"editable":["ambassador"],"label":"Button Color","order":8,"type":"text"},"date":{"dashboard":["merchant","ambassador"],"editable":["ambassador"],"label":"Date","order":3,"type":"date"},"duration":{"dashboard":["merchant","ambassador"],"data":{"options":[{"label":"15 minutes","value":"15"},{"label":"30 minutes","value":"30"},{"label":"45 minutes","value":"45"},{"label":"60 minutes","value":"60"},{"label":"90 minutes","value":"90"},{"label":"120 minutes","value":"120"}]},"editable":["ambassador"],"label":"Duration","order":6,"type":"select"},"enable":{"dashboard":["merchant","ambassador"],"editable":["ambassador"],"label":"Enable","order":1,"type":"switch"},"event_title":{"dashboard":["merchant","ambassador"],"editable":["ambassador"],"label":"Event Title","order":1,"type":"text"},"link":{"dashboard":["merchant","ambassador"],"editable":["ambassador"],"label":"Link","order":2,"show_errors_on_focus":true,"type":"text","validations":[{"error_message":"This doesn't appear to be a valid Zoom link. Check the link and try again or message the program administrator if the problem persists.","regexp":"^[hH][tT][tT][pP][sS]?://([a-z0-9]+[.])*zoom\\.us/.+","type":"regexp"}]},"service_logo_url":{"dashboard":["merchant","ambassador"],"editable":["ambassador"],"label":"Service Logo Url","order":9,"type":"text"},"time":{"dashboard":["merchant","ambassador"],"editable":["ambassador"],"label":"Time","order":4,"show_errors_on_focus":true,"type":"time"},"timezone":{"dashboard":["merchant","ambassador"],"editable":["ambassador"],"label":"Timezone","order":5,"show_errors_on_focus":true,"type":"timezone"}}},"ambassador_program_default_auto_publish":true,"ambassador_program_default_bio":"Welcome to my storefront!","ambassador_program_default_commission":3,"ambassador_program_default_welcome_text_1":"Welcome to my storefront!","ambassador_program_default_welcome_text_2":"Browse and shop below","ambassador_program_enabled":true,"brand":{"account_manager":304636,"logo":{"default":"https://static.prod.tvpage.com/1759380/static/images/logo.png","favicon":"https://static.prod.tvpage.com/1759380/static/favicon/favicon.ico","square":"https://sitecdn.tvpage.com/clients/production/1759380/program-default-square-195-1678130818.935.png"},"name":"Academy Sports + Outdoors","sales_manager":null},"campaigns":{"management_emails":{"email_notifications_enabled":true,"recipients":["[email protected]"]},"marketplace_campaign":{"fee_enabled":true,"fee_pennies":20000,"fee_percentage":"0.25"},"program_campaign":{"fee_enabled":true,"fee_pennies":20000,"fee_percentage":"0.25"}},"commerce_platform":"","custom_fields":{"asset":{"category":{"dashboard":["merchant","ambassador"],"data":{"options":[{"label":"Academy Brands","value":"academy_brands"},{"label":"Baseball","value":"baseball"},{"label":"Boating","value":"boating"},{"label":"Buying Guides","value":"buying_guides"},{"label":"Camping","value":"camping"},{"label":"Clothing","value":"clothing"},{"label":"Firearms","value":"firearms"},{"label":"Fishing","value":"fishing"},{"label":"Fitness","value":"fitness"},{"label":"Football","value":"football"},{"label":"Footwear","value":"footwear"},{"label":"Hunting","value":"hunting"},{"label":"Outdoor Cooking","value":"outdoor_cooking"},{"label":"SEC Traditions","value":"sec_traditions"},{"label":"Soccer","value":"soccer"}]},"editable":["merchant","ambassador"],"entity_type":["photo","video"],"label":"Category","order":2,"required":["ambassador"],"type":"select"},"no_index":{"dashboard":["merchant","ambassador"],"data":{"options":[{"label":"Yes","value":"yes"},{"label":"No","value":"no"}]},"editable":["merchant","ambassador"],"entity_type":["photo","video"],"label":"No Index","order":3,"required":[],"type":"select"},"pim_video_id":{"dashboard":["merchant","ambassador"],"editable":["merchant","ambassador"],"entity_type":["photo","video"],"label":"PIM Video ID","order":4,"required":[],"type":"text"}},"user":{"affiliate_id":{"dashboard":[],"editable":["merchant","ambassador"],"label":"Affiliate ID","order":5,"required":["ambassador"],"type":"text"},"ambassador_type":{"dashboard":["signup","merchant","ambassador"],"data":{"hide_default_option":true,"options":[{"label":"Employee","value":1},{"label":"External","value":2}]},"editable":["signup","merchant","ambassador"],"label":"Ambassador Type","order":1,"required":["signup","ambassador"],"type":"select"},"employee_id":{"dashboard":[],"editable":[],"label":"Employee ID","order":2,"required":false,"type":"text"}}},"hash":"8f503cf4","id":1759380,"links":{"home":"https://www.academy.com","privacy_policy":"https://www.creatable.io/privacy","support":"https://tvpage-support.zendesk.com/hc/en-us/sections/1500002219582-Guide-for-Creators","terms":"https://www.creatable.io/terms"},"tracking_parameters":{"campaign":[],"data_transformation":[],"global":[],"hub":[],"photo":[],"product":[],"social_platform":[],"storefront":[],"video":[]}},"dashboards":{"ambassador":{"age_verification":{"enabled":false,"error_message":"You must confirm that you are 21+ years of age","label_message":"I confirm that I am 21+ years of age"},"approval_team_creator":{"enabled":true,"message":"Congratulations! You can now login to the Creatable app to access the program.","title":"Youâve been approved by {{company_name}}"},"disable_for_employees_message":"Employee applications are currently not being accepted","disable_for_external_message":"External applications are currently not being accepted","enable_chat":true,"enable_for_employees":true,"enable_for_external":true,"enable_product_short_link":true,"enable_support_chat":false,"new_account_video":"","notifications":{"label_to_all_recipients":"All Ambassadors","title":"Ambassador Program"},"reject_team_creator":{"enabled":true,"message":"{{company_name}} is unable to accept your application to the program at this time.","title":"Thank y
5ou for your interest in {{company_name}}"},"show_analytics_external":true,"show_analytics_internal":true,"show_analytics_sales_report_commission_external":true,"show_analytics_sales_report_commission_internal":true,"show_analytics_sales_report_external":true,"show_analytics_sales_report_internal":true,"show_conversions_menu_external":true,"show_conversions_menu_internal":true,"show_payments_external":true,"show_payments_internal":true,"show_performance_menu_external":true,"show_performance_menu_internal":true,"show_profile_commission_detail_external":true,"show_profile_commission_detail_internal":true,"show_statements_external":true,"show_statements_internal":true,"signup_form":{"terms_label":"I agree to the Terms of Service"},"splash_modal":{"cookie_hash":"1","enabled":false,"message":"","title":""},"status_messages":{"pending_icon":"access_time","pending_message":"Your account has been created, please allow up to 48 hours for your account to be approved.","suspended_icon":"warning","suspended_message":"Your account has been suspended, please contact the program administrator with any questions.","temporarily_suspended_icon":"error","temporarily_suspended_message":"Your account has been temporarily suspended, please contact the program administrator with any questions."},"sub_title":"Ambassador Program Application","theme":{"primary_color":"#05a"},"title":"Academy Sports + Outdoors.","tracking_pixel_apply":"","tracking_pixel_apply_confirmation":"","tracking_pixel_landing":""},"maintenance_message":"Sorry for the inconvenience but we are performing some maintenance at the moment. We'll back online shortly.","maintenance_mode":false,"maintenance_title":"We'll back soon!","merchant":{"notifications":{"label_to_all_recipients":"All Ambassadors","title":"Ambassador Program"}}},"experiences":{"currency_symbol":"$","enable_affiliate_short_link":false,"enable_experiences":true,"first_party_cookie_domain":"academy.com","hub":{"base_url":"https://academy.com","channels":{"ambassador":0,"conversion":0,"engagement":0,"latest":226243777,"related":227228953},"product_cta_modal_text":"BUY NOW","product_cta_text":"BUY NOW","sharing":{"base_url":"","enabled":false,"networks":["facebook","twitter","pinterest","email"]},"sign_in":{"apply_text":"APPLY NOW","button_border_radius":0,"payment_terms":{"payment_description":"Get monthly statements and payouts from the mobile app.","payment_rate":"5%","payment_title":"Payment terms","payment_type":"Commission"},"primary_color":"#F68C2C","program_benefits":{"benefit_1":"Post shoppable videos & photos","benefit_2":"Run virtual meetings","benefit_3":"Make money from your videos","benefit_4":"Make money from your photos","benefit_5":"Make money from product links","benefit_description_1":"Match your content with products from the catalog","benefit_description_2":"Promote live shopping events on your website","benefit_description_3":"Get paid on all orders placed by video viewers","benefit_description_4":"Get paid on all orders placed by photo viewers","benefit_description_5":"Get paid on all orders placed from link clicks","benefits_image":"https://sitecdn.tvpage.com/static/images/marketing-page/default_benefits.jpeg","benefits_image_radius":0,"benefits_title":"Program benefits"},"program_feature":{"feature_description":"Cash in on your content and followers. Run your storefront on our website and get in front of our customers. Share on social to boost your sales! Sell any of our products to anyone - turn your followers into customers.","feature_image":"https://sitecdn.tvpage.com/static/images/marketing-page/default_feature.jpeg","feature_image_radius":0,"feature_title":"An exclusive program for you"},"secondary_color":"#ffffff","top_hero":{"hero_background_gradient":"","hero_image":"https://sitecdn.tvpage.com/static/images/marketing-page/default_hero.jpeg","hero_image_mobile":"https://sitecdn.tvpage.com/static/images/default_hero_mobile.jpg","hero_text_1":"Join our brand. Make money.","hero_text_1_color":"#fff","hero_text_1_shadow":"0px 2px 6px rgba(0,0,0,0.7)","hero_text_2":"Work with us.","hero_text_2_color":"#fff","hero_text_2_shadow":"0px 2px 4px rgba(0,0,0,0.7)","hero_text_3":"","hero_text_3_color":"","hero_text_3_shadow":"","hero_video_embed":""}},"site_verification":"4CtQpyRSALO7LmyAi1P0J9VCz9igczLlnxM_XhFUssE","static_asset_path":"https://static.prod.tvpage.com","sub_folder":"","theme":{"custom_breakpoints":[{"breakpoint":"screen","selectors":[{"properties":{"margin_top":"20px !important"},"selector":".document-body"},{"properties":{"display":"none !important"},"selector":".sign-in"},{"properties":{"display":"block","overflow":"hidden","text_overflow":"ellipsis","white_space":"nowrap"}
5,"selector":".grid-item .item-box h3"}]}],"font_family":"'Open Sans', sans-serif","hub_wrapper_css_class":null,"play_icon_color":"#788693","play_icon_color_center":"#ffffff","player_progressbar_color":"#05a","primary_button_color":"#05a","primary_color":"#05a"},"title":"Academy"},"player_version":"tvp-master","publishing":{"aliases":["www-academy-com"],"public_base_url":"https://www.academy.com","public_domain":"www.academy.com","publish_metadata_json":false,"response_content_type":"text/html","robocop_enabled":true,"sub_folder":"/videos"},"social_data":{"platforms":{"facebook":{"enabled":true},"instagram":{"enabled":true},"tiktok":{"enabled":true},"twitter":{"enabled":true},"youtube":{"enabled":true}}},"text_direction":"","widgets":{"sharing":{"base_url":"https://site.app.tvpage.com/","enabled":false,"networks":["facebook","twitter","pinterest","email"]},"sources":{"carousel":"https://cdn.tvpagewidgets.com/v2/carousel/master.js","inline":"https://cdn.tvpagewidgets.com/v2/inline/master.js","solo":"https://cdn.tvpagewidgets.com/v2/solo/master.js","solo_cta":"https://cdn.tvpagewidgets.com/v2/solo_cta/master.js"},"theme":{"player":{}}}},"mobile_app":{"android":{"current_version":"2.33.506","minimum_required_version":"2.33.506"},"ios":{"current_version":"2.33.506","minimum_required_version":"2.33.506"}}}; 6 bootstrap.cookiedomain = ""; 7 bootstrap.baseUrl = ""; 8 bootstrap.domain_name = "https://site.app.tvpage.com/1759380"; 9 bootstrap.apiUrl = "https://app.tvpage.com/api/" || "https:\/\/api.tvpage.com\/v1"; 10 bootstrap.newApiBaseUrl = "https://app.tvpage.com/v2/api" || "https:\/\/api.tvpage.com\/v2\/api"; 11 12 bootstrap.templates = { 13 cta: 14 '<div class="tvp-cta-overlay-cover"></div>' + 15 '<svg class="tvp-cta-play" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">' + 16 '<polygon points="70, 55 70, 145 145, 100"></polygon>' + 17 '</svg>', 18 modal:{ 19 'modal': 20 '<div id="tvp-modal-overlay-{id}" class="tvp-modal-overlay tvp-hidden"></div>' + 21 '<div id="tvp-modal-{id}" class="tvp-modal tvp-hidden">' + 22 '<div class="tvp-modal-wrapper">' + 23 '<div class="tvp-modal-content">' + 24 '<div id="tvp-modal-header-{id}" class="tvp-modal-header">' + 25 '<div id="tvp-modal-close-{id}" class="tvp-modal-close">' + 26 '<svg class="tvp-modal-close-svg" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">' + 27 '<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path>' + 28 '<path d="M0 0h24v24H0z"></path>' + 29 '</svg>' + 30 '</div>' + 31 '<h4 id="tvp-modal-title-{id}" class="tvp-modal-title"></h4>' + 32 '</div>' + 33 '<div class="tvp-modal-body">' + 34 '<div id="tvp-modal-iframe-holder-{id}" class="tvp-modal-iframe-holder"></div>' + 35 '</div>' + 36 '</div>' + 37 '</div>' + 38 '</div>', 39 'tooltip': 40 '<svg class="tvp-info-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">' + 41 '<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"></path>' + 42 '</svg>' + 43 '<span class="tvp-products-message"></span>' 44 }, 45 "modal-content":{ 46 'body': 47 '<div id="{id}" class="tvp-clearfix iframe-content">' + 48 '<div class="tvp-player-holder">' + 49 '<div class="tvp-player">' + 50 '<div id="tvp-player-el"></div>' + 51 '</div>' + 52 '</div>' + 53 54 '<div class="tvp-products-holder">' + 55 '<div class="tvp-products">' + 56 '<div class="tvp-products-headline tvp-clearfix">'+ 57 '<p class="tvp-products-text"></p>' + 58 '</div>' + 59 '<div class="tvp-products-vertical"></div>' + 60 '</div>' + 61 '<div class="tvp-arrow-indicator"></div>' + 62 '<div class="tvp-popups"></div>' + 63 '</div>' + 64 '</div>', 65 'product': 66 '<a class="tvp-product" id="tvp-product-{id}
66" data-vd="{entityIdParent}" href="{linkUrl}">' + 67 '<div class="tvp-product-image" style="background-image:url({imageUrl});">' + 68 '<div class="tvp-product-image-overlay"></div>' + 69 '</div>' + 70 '</a>', 71 'popup': 72 '<a class="tvp-product-popup" id="tvp-product-popup-{id}" data-vd="{entityIdParent}" href="{linkUrl}">' + 73 '<div class="tvp-product-popup-image" style="background-image:url({imageUrl});"></div>'+ 74 '<p class="tvp-product-title">{title}</p>' + 75 '<p class="tvp-product-price">{price}</p>' + 76 '{ratingReviews}' + 77 '<button class="tvp-product-cta">View Details</button>' + 78 '</a>' 79 }, 80 "modal-content-mobile":{ 81 'body': 82 '<div id="{id}" class="tvp-clearfix iframe-content">' + 83 '<div class="tvp-player-holder">' + 84 '<div class="tvp-player">' + 85 '<div id="tvp-player-el"></div>' + 86 '</div>' + 87 '</div>' + 88 '<div class="tvp-products">' + 89 '<div class="tvp-products-headline tvp-clearfix">'+ 90 '<p class="tvp-products-text"></p>' + 91 '</div>' + 92 '</div>' + 93 '</div>', 94 'products': 95 '<a id="tvp-product-{id}" class="tvp-product" data-vd="{entityIdParent}" href="{linkUrl}">'+ 96 '<div class="tvp-product-image" style="background-image:url({imageUrl})"></div>' + 97 '<div class="tvp-product-data">'+ 98 '<p class="tvp-product-title">{title}</p>' + 99 '<h2 class="tvp-product-price">{price}</h2>' + 100 '<button class="tvp-product-cta">View Details</button>' + 101 '</div>' + 102 '</a>', 103 'tooltip': 104 '<svg class="tvp-info-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">' + 105 '<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"></path>' + 106 '</svg>' + 107 '<span class="tvp-products-message"></span>' 108 } 109 }; 110 111 var utils = { 112 isFirefox: /Firefox/i.test(navigator.userAgent), 113 isMobile: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent), 114 isIOS: /iPad|iPhone|iPod|iPhone Simulator|iPad Simulator/.test(navigator.userAgent) && !window.MSStream, 115 isset: function(o, p) { 116 var val = o; 117 if (p) val = o[p]; 118 return "undefined" !== typeof val; 119 }, 120 getIframeHtml: function(options) { 121 var html = '<head><base target="_blank" /></head><body class="' + (options.className || '') + '" data-domain="' + 122 (options.domain || '') + '" data-id="' + (options.id || '') + '" onload="' + 123 'var d = document, head = d.getElementsByTagName(\'head\')[0],' + 124 'addJS = function(u){ var s = d.createElement(\'script\');s.src=u;d.body.appendChild(s);},' + 125 'addCSS = function(h){ var l = d.createElement(\'link\');l.rel=\'stylesheet\';l.href=h;head.appendChild(l);};'; 126 127 var js = options.js || []; 128 if ('function' === typeof js) { 129 js = js(); 130 } 131 132 js = js.filter(Boolean); 133 for (var i = 0; i < js.length; i++) { 134 html += 'addJS(\'' + js[i] + '\');'; 135 } 136 137 var css = options.css || []; 138 if ('function' === typeof css) { 139 css = css(); 140 } 141
142 css = css.filter(Boolean); 143 for (var i = 0; i < css.length; i++) { 144 html += 'addCSS(\'' + css[i] + '\');'; 145 } 146 147 html += '"><style>' + (options.style || '') + '</style>'; 148 149 var content = options.html || ''; 150 if ('function' === typeof content) { 151 html += content(); 152 } else if (content.trim().length) { 153 html += content; 154 } 155 156 return html; 157 }, 158 addClass: function(obj, c) { 159 if (!obj || !c) return; 160 if ('string' === typeof obj) { 161 document.getElementById(obj).classList.add(c); 162 } else { 163 obj.classList.add(c); 164 } 165 }, 166 removeClass: function(obj, c) { 167 if (!obj || !c) return; 168 if ('string' === typeof obj) { 169 document.getElementById(obj).classList.remove(c); 170 } else { 171 obj.classList.remove(c); 172 } 173 }, 174 extend: function(out) { 175 out = out || {}; 176 for (var i = 1; i < arguments.length; i++) { 177 if (!arguments[i]) 178 continue; 179 180 for (var key in arguments[i]) { 181 if (arguments[i].hasOwnProperty(key)) 182 out[key] = arguments[i][key]; 183 } 184 } 185 return out; 186 }, 187 tmpl:function(template, data) { 188 if (template && 'object' == typeof data) { 189 return template.replace(/\{([\w\.]*)\}/g, function(str, key) { 190 var keys = key.split("."), 191 v = data[keys.shift()]; 192 for (var i = 0, l = keys.length; i < l; i++) v = v[keys[i]]; 193 return (typeof v !== "undefined" && v !== null) ? v : ""; 194 }); 195 } 196 } 197 }; 198 199 if (typeof bootstrap !== "object" || !bootstrap.hasOwnProperty('name') || bootstrap.name.length <= 0) { 200 throw new Error('Must pass bootstrap and boostrap.name'); 201 } 202 203 var id = bootstrap.name; 204 if(utils.isset(window.__TVPage__) && utils.isset(__TVPage__, "config") && !utils.isset(__TVPage__.config,id)){ 205 for (var i in window.__TVPage__.config){ 206 if(window.__TVPage__.config[i].type === "pdp"){ 207 id = i; 208 } 209 } 210 } 211 212 //If there's config object for this specific widget, then we merged in... extend? 213 window.__TVPage__ = window.__TVPage__ || {}; 214 __TVPage__.config = __TVPage__.config || {}; 215 216 if ("object" === typeof __TVPage__.config[id]) { 217 __TVPage__.config[id] = utils.extend(bootstrap, __TVPage__.config[id]); 218 } else { 219 __TVPage__.config[id] = bootstrap; 220 } 221 222 var __windowCallbackFunc__ = null; 223 if (__TVPage__.config[id].hasOwnProperty('onChange') && typeof __TVPage__.config[id].onChange == "function") { 224 __windowCallbackFunc__ = __TVPage__.config[id].onChange; 225 delete __TVPage__.config[id].onChange; 226 } 227 228 var config = utils.isset(window.__TVPage__) && utils.isset(__TVPage__, "config") && utils.isset(__TVPage__.config, id) ? __TVPage__.config[id] : {}; 229 delete __TVPage__.config[id]; 230 231 // hardcode merchandise as per client request 232 config.merchandise = false; 233 234 if (config.hasOwnProperty('targetEl')) { 235 if(Array.isArray(config.targetEl) && config.targetEl.length >0){ 236 config.targetEl.map(function(item, index){ 237 if(!document.getElementById(item)){ 238 throw new Error ( "targetEl: "+ item +" not found in DOM"); 239 } 240 }); 241 }else if(!document.getElementById(config.targetEl)){ 242 throw new Error ( "targetEl: "+ config.targetEl +" not found in DOM"); 243 } 244 } 245 else{ 246 throw new Error ( "Must provide a targetEl on snippet"); 247 } 248 249 var customClass = config.hasOwnProperty('wrapperCustomClassName') ? config.wrapperCustomClassName : ''; 250 var hostCss = bootstrap.domain_name + "/tvpwidget/solo-cta/css/styles.min.css"; 251 if(Array.isArray(config.targetEl) && config.targetEl.length >0){ 252 var hostCssLink = document.createElement('link'); 253 hostCssLink.type = 'text/css'; 254 hostCssLink.rel = 'stylesheet'; 255 hostCssLink.href = hostCss; 256 document.getElementsByTagName('head')[0].appendChild(hostCssLink); 257 config.targetEl.map(function(item, index){ 258 var targetElement = document.getElementById(item); 259 targetElement.insertAdjacentHTML('beforebegin', "<div class=\"tvp-wrapper "+customClass+"\"><div id=\"" + item + "-holder\" class=\"tvp-solo-cta-holder\"></div></div>"); 260 targetElement.parentNode.removeChild(targetElement); 261 }); 262 }else { 263 var targetElement = document.getElementById(config.targetEl); 264 targetElement.insertAdjacentHTML('beforebegin', "<link type=\"text/css\" rel=\"stylesheet\" href=\"" + hostCss + "\" /><div class=\"tvp-wrapper "+customClass+"\"><div id=\"" + id + "-holder\" class=\"tvp-solo-cta-holder\"></div></div>"); 265 targetElement.parentNode.removeChild(targetElement); 266 } 267 268 config.id = id; 269 config.staticPath = bootstrap.domain_name + "/tvpwidget/solo-cta"; 270 config.mobilePath = utils.isMobile ? '' : '';
271 config.distPath = '/'; 272 config.cssPath = config.staticPath + config.distPath + 'css/'; 273 config.jsPath = config.staticPath + config.distPath + 'js/'; 274 config.eventPrefix = ("tvp_" + config.id).replace(/-/g, '_'); 275 276 //Append templates that live in the host page. 277 var modalContainer = document.createElement("div"); 278 modalContainer.innerHTML = utils.tmpl(config.templates['modal'].modal,config); 279 document.body.appendChild(modalContainer); 280 281 var holder = document.getElementById(config.id + "-holder"); 282 var channel = config.channel || {}; 283 var channelId = channel.id ? channel.id : (config.channelid || 0); 284 if (!channelId && !config.data) { 285 holder.parentNode.removeChild(holder); 286 } 287 288 var clickData = {}; 289 290 var handleVideoClick = function(e) { 291 updateModalTitle(clickData.selectedVideo.title); 292 utils.removeClass('tvp-modal-' + config.id, 'tvp-hidden'); 293 utils.removeClass('tvp-modal-overlay-' + config.id, 'tvp-hidden'); 294 295 if (config.fix_page_scroll) { 296 utils.addClass(document.body, 'tvp-modal-open'); 297 } 298 299 iframeModalHolder.innerHTML = '<iframe class="tvp-iframe-modal" src="about:blank" allowfullscreen frameborder="0" scrolling="no"></iframe>'; 300 iframeModal = iframeModalHolder.querySelector('.tvp-iframe-modal'); 301 iframeModalDocument = iframeModal.contentWindow.document; 302 303 //Some logic to include the player library.. we support diff things. 304 var playerUrl = "https://cdnjs.tvpage.com/tvplayer/tvp-master.min.js"; 305 if (config.player_url && (config.player_url + "").trim().length) { 306 playerUrl = config.player_url; 307 } 308 //html - remove logic to get template based on device type 309 iframeModalDocument.open().write(utils.getIframeHtml({ 310 id: config.id, 311 domain: bootstrap.domain_name, 312 className: utils.isMobile ? "" : "", 313 html: utils.tmpl(config.templates["modal-content"].body,config), 314 js: [ 315 "//a.tvpage.com/tvpa.min.js", 316 '//imasdk.googleapis.com/js/sdkloader/ima3.js', 317 playerUrl, 318 config.debug ? config.jsPath + "/vendor/jquery.js" : "", 319 config.debug ? config.jsPath + "/vendor/perfect-scrollbar.min.js" : "", 320 config.debug ? config.jsPath + "libs/utils.js" : "", 321 config.debug ? config.jsPath + "libs/analytics.js" : "", 322 config.debug ? config.jsPath + "libs/player.js" : "", 323 config.debug ? config.jsPath + "/" + config.mobilePath + "modal/index.js" : "", 324 config.debug ? "" : config.jsPath + config.mobilePath + "modal/scripts.min.js" 325 ], 326 css: [ 327 config.debug ? config.cssPath + "/" + config.mobilePath + "modal/styles.css" : "", 328 config.debug && utils.isMobile ? config.cssPath + "/vendor/slick.css" : "", 329 config.debug && !utils.isMobile ? config.cssPath + "/vendor/perfect-scrollbar.min.css" : "", 330 config.debug ? "" : config.cssPath + config.mobilePath + "modal/styles.min.css" 331 ] 332 })); 333 334 iframeModalDocument.close(); 335 }; 336 337 var renderCustomThumb = function(){ 338 // store target container (carousel) 339 var target = document.getElementById('tvPageThumbnailBtn'); 340 341 // create new icon 342 var img = document.createElement('img'); 343 img.alt = 'TV Page'; 344 img.classList = 'thumb-item custom'; 345 img.src = 'https://static.prod.tvpage.com/1759380/static/images/play.svg'; 346 347 // append inside target element 348 if(target) { 349 target.innerHTML = ""; 350 target.appendChild(img); 351 } 352 }; 353 354 //Loading the videos. 355 var jsonpScript = document.createElement('script'); 356 var cbName = 'tvp_' + Math.floor(Math.random() * 50005); 357 var jsonpScriptSrc = config.api_base_url + '/channels/' + channelId + '/videos?X-login-id=' + (config.loginId || config.loginid); 358 359 var params = channel.parameters || {}; 360 for (var p in params) { 361 jsonpScriptSrc += '&' + p + '=' + params[p]; 362 } 363 364 jsonpScriptSrc += "&callback=" + cbName; 365 jsonpScript.src = jsonpScriptSrc; 366 367 function renderCustomHandle() { 368 if(config && config.renderCallback && typeof config.renderCallback === "function"){ 369 config.renderCallback(); 370 } 371 renderCustomThumb(); 372 } 373 374 var buildPDP = function(videos){ 375 holder.classList.add("initialized"); 376 var video = videos[0]; 377 var overlayEl = document.createElement("div"); 378 overlayEl.className = "tvp-cta-overlay"; 379 overlayEl.style.backgroundImage = "url(" + video.asset.thumbnailUrl + ")"; 380 var template = config.templates.cta; 381 if (utils.isset(video, 'title')) { 382 template += "<div class='tvp-cta-text'>" + video.title + "</div>"; 383 } 384 385 overlayEl.innerHTML = template; 386 387 clickData = { 388 data: videos, 389 selectedVideo: video, 390 runTime: config 391 }; 392 393 if(Array.isArray(config.targetEl) && config.targetEl.length >0){ 394 config.targetEl.map(function(item, index){ 395 var holderEl = document.getElementById(item + "-holder"); 396 var dupOverlayEl = overlayEl.cloneNode(true); 397 398 dupOverlayEl.removeEventListener("click", handleVideoClick, false); 399 dupOverlayEl.addEventListener("click", handleVideoClick, false); 400 401 holderEl.classList.add("initialized"); 402 holderEl.appendChild(dupOverlayEl); 403 }); 404 }else{ 405 overlayEl.removeEventListener("click", handleVideoClick, false); 406 overlayEl.addEventListener("click", handleVideoClick, false); 407 holder.appendChild(overlayEl); 408 } 409 renderCustomHandle(); 410 }; 411 window[cbName] = function(data) { 412 if (data.length) { 413 buildPDP(data) 414 } 415 }; 416 if (config && config.data && config.data.length>0){ 417 buildPDP(config.data); 418 }else{ 419 document.body.appendChild(jsonpScript); 420 } 421 422 423 var isEvent = function(e, type) { 424 return (e && utils.isset(e, "data") && utils.isset(e.data, "event") && config.eventPrefix + type === e.data.event); 425 }; 426 427 var updateModalTitle = function(title) { 428 document.getElementById('tvp-modal-title-' + config.id).innerHTML = title || ""; 429 }; 430 431 var iframeModalHolder = document.getElementById('tvp-modal-iframe-holder-' + config.id); 432 var iframeModal = null; 433 var iframeModalDocument = null; 434 435 var getEventType = function(e) { 436 var evt = null 437 if (e && utils.isset(e, "data") && utils.isset(e.data, "event")) { 438 evt = e.data.event; 439 } 440 441 if (evt && evt.length && evt.substr(0, config.eventPrefix.length) === config.eventPrefix) { 442 return evt.substr(config.eventPrefix.length + 1); 443 } 444 445 return null; 446 }; 447 448 function handlePostMessages(e) { 449 var eventType = getEventType(e); 450 switch (eventType) { 451 case 'modal_initialized': 452 handleModalInitialized(e); 453 break; 454 case 'modal_no_products': 455 handleModalNoProducts(e); 456 break; 457 case 'modal_products': 458 handleModalProducts(e); 459 break; 460 case 'player_next': 461 handlePlayerNext(e); 462 break; 463 case 'modal_resize': 464 handleModalResize(e); 465 break; 466 default: 467 // do nothing 468 } 469 470 handleCallback(e); 471 } 472 473 function handleModalResize(e) { 474 iframeModal.style.height = e.data.height; 475 } 476 477 function handleCallback(e) { 478 if (__windowCallbackFunc__) 479 __windowCallbackFunc__(e); 480 } 481 482 window.addEventListener("message", function(e) { 483 handlePostMessages(e); 484 }); 485 486 function handleModalInitialized(e) { 487 if (iframeModal.contentWindow) { 488 var clicked = JSON.parse(JSON.stringify(clickData)); 489 iframeModal.contentWindow.postMessage({ 490 event: config.eventPrefix + ':modal_data', 491 data: clicked.data, 492 selectedVideo: clicked.selectedVideo, 493 runTime: clicked.runTime 494 }, '*'); 495 } 496 497 if (utils.isIOS) { 498 var onOrientationChange = function() { 499 if (iframeModal && iframeModal.contentWindow) { 500 setTimeout(function() { 501 var currentWidth = iframeModal.parentNode.offsetWidth; 502 var widthModalOffset = 20; 503 var heightModalOffset = 13; 504 iframeModal.contentWindow.window.postMessage({ 505 event: config.eventPrefix + ':modal_holder_resize', 506 size: [currentWidth - widthModalOffset, currentWidth * (9 / 16) - heightModalOffset] 507 }, '*'); 508 }, 500); 509 } 510 }; 511 var orientationChangeEvent = 'onorientationchange' in window ? 'orientationchange' : 'resize'; 512 window.removeEventListener(orientationChangeEvent, onOrientationChange, false); 513 window.addEventListener(orientationChangeEvent, onOrientationChange, false); 514 } 515 }; 516 517 function handleModalProducts(e) { 518 if (!document.getElementById('tvp-products-headline-' + config.id) && config.products_headline_display) { 519 var label = document.createElement('div'); 520 label.className = 'tvp-products-headline'; 521 label.id = 'tvp-products-headline-' + config.id; 522 label.innerHTML = config.products_headline_text; 523 524 if (config.products_info_tooltip && config.products_message.trim().length) { 525 var tooltipHtml = config.templates['modal'].tooltip; 526 var tooltipDiv = document.createElement('div'); 527 tooltipDiv.classList.add('tvp-tooltip'); 528 tooltipDiv.innerHTML = tooltipHtml; 529 tooltipDiv.getElementsByClassName('tvp-products-message')[0].innerHTML = config.products_message; 530 label.appendChild(tooltipDiv); 531 } 532 533 label.onclick = function() { 534 this.classList.contains('active') ? this.classList.remove('active') : this.classList.add('active'); 535 }; 536 537 var modalHeader = document.getElementById('tvp-modal-header-' + config.id); 538 modalHeader.appendChild(label); 539 } 540 541 utils.removeClass(iframeModalHolder, 'no-products'); 542 utils.addClass(iframeModalHolder, 'products'); 543 } 544 545 function handleModalNoProducts(e) { 546 var label = document.getElementById('tvp-products-headline-' + config.id); 547 if (label) { 548 label.parentNode.removeChild(label); 549 } 550 551 if (config.no_products_banner && config.merchandise) { 552 var bannerHtml = ""; 553 if ("function" === typeof config.no_products_banner) { 554 bannerHtml = config.no_products_banner(); 555 } else if (String(config.no_products_banner).trim().length) { 556 bannerHtml = config.no_products_banner.trim(); 557 } 558 559 var bannerDiv = document.createElement('div'); 560 utils.addClass(bannerDiv, 'tvp-no-products-banner'); 561 bannerDiv.innerHTML = bannerHtml; 562 //modal.querySelector('.tvp-modal-content').appendChild(bannerDiv); 563 } 564 565 utils.removeClass(iframeModalHolder, 'products'); 566 utils.addClass(iframeModalHolder, 'no-products'); 567 } 568 569 var removeBannerEl = function() { 570 var noProductsBanner = modal.querySelector('.tvp-no-products-banner'); 571 if (noProductsBanner) { 572 modal.querySelector('.tvp-modal-content').removeChild(noProductsBanner); 573 } 574 }; 575 576 function handlePlayerNext(e) { 577 updateModalTitle(e.data.next.assetTitle); 578 //removeBannerEl(); 579 } 580 581 var closeModal = function() { 582 utils.addClass('tvp-modal-' + config.id, 'tvp-hidden'); 583 utils.addClass('tvp-modal-overlay-' + config.id, 'tvp-hidden'); 584 585 if (config.fix_page_scroll) { 586 utils.removeClass(document.body, 'tvp-modal-open'); 587 } 588 589 utils.removeClass(iframeModalHolder, 'products'); 590 utils.removeClass(iframeModalHolder, 'no-products'); 591 iframeModal.parentNode.removeChild(iframeModal); 592 if (window && (window.$ || 'undefined' !== typeof window.$) && window.$('.swiper-container').length){ 593 const swiperEl = window.$('.swiper-container')[0]; 594 swiperEl.swiper.allowSlideNext = true; 595 swiperEl.swiper.allowSlidePrev = true;
596 swiperEl.swiper.update(); 597 } 598 }; 599 600 document.getElementById("tvp-modal-close-" + config.id).addEventListener('click', closeModal, false); 601 602 var modalEl = document.getElementById("tvp-modal-" + config.id); 603 modalEl.addEventListener('click', function(e) { 604 if (e.target === modalEl || !modalEl.contains(e.target)) { 605 closeModal(); 606 } 607 }, false); 608 609 // specific client implementation 610 function debounce(func) { 611 var wait = arguments.length <= 1 || arguments[1] === undefined ? 100 : arguments[1]; 612 var timeout = void 0; 613 return function () { 614 var _this = this; 615 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { 616 args[_key] = arguments[_key]; 617 } 618 clearTimeout(timeout); 619 timeout = setTimeout(function () { 620 func.apply(_this, args); 621 }, wait); 622 }; 623 } 624 625 var observerHolder = document.getElementById("tvPageThumbnailBtn"); 626 627 if (observerHolder) { 628 629 // listen for "img.rounded-circle" element clicks (client's child SKU prods) 630 // and re-trigger custom render callback FN 631 632 var clientChildrenSkuElements = document.querySelectorAll("img.rounded-circle"); 633 if (clientChildrenSkuElements && clientChildrenSkuElements.length){ 634 var debouncedFN = debounce(renderCustomHandle,100); 635 clientChildrenSkuElements.forEach(function(item) { 636 item.removeEventListener("click", debouncedFN, false); 637 item.addEventListener("click", debouncedFN, false); 638 }); 639 } 640 } 641}());
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.