1<!DOCTYPE html> 2<html lang="en" translate="no" class="zs js flexbox flexboxlegacy canvas canvastext webgl no-touch geolocation postmessage no-websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers no-applicationcache svg inlinesvg smil svgclippaths webkit chrome linux size-xxl shop-page-buy" style=""><head><meta http-equiv="origin-trial" content="A7vZI3v+Gz7JfuRolKNM4Aff6zaGuT7X0mf3wtoZTnKv6497cVMnhy03KDqX7kBz/q/iidW7srW31oQbBt4VhgoAAACUeyJvcmlnaW4iOiJodHRwczovL3d3dy5nb29nbGUuY29tOjQ0MyIsImZlYXR1cmUiOiJEaXNhYmxlVGhpcmRQYXJ0eVN0b3JhZ2VQYXJ0aXRpb25pbmczIiwiZXhwaXJ5IjoxNzU3OTgwODAwLCJpc1N1YmRvbWFpbiI6dHJ1ZSwiaXNUaGlyZFBhcnR5Ijp0cnVlfQ=="> 3 <meta charset="utf-8"> 4 <title>Südtirol Skipass 2027 Standard | Online Ticketshop - Buy your lift tickets and skipasses online</title> 5 <meta name="description" content="For seniors, adults, youths and children â one ticket valid for the entire year."> 6 <meta name="author" content="See ski pass and ticket prices and buy online for"> 7 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> 8 9 <!-- Facebook Open Graph --> 10 <meta property="fb:app_id" content="207420479451117"> 11 <meta property="og:site_name" content="Online Ticketshop"> 12 <meta property="og:type" content="website"> 13 <meta property="og:title" content="Online Ticketshop"> 14 <meta property="og:url" content="https://shop.suedtirolskiarena.com/en/store"> 15 <meta property="og:description" content="See ski pass and ticket prices online. Always buy ski pass and tickets online go directly to the slopes"> 16 <meta property="og:locale" content="en_US"> 17 <meta property="og:image" content="https://cloud.skiperformance.com/media/merchants/suedtirolskiarena.skiperformance.com/img/custom/default/bg-main.jpg"> 18 <!-- End Facebook Open Graph --> 19 20 <!-- Twitter Open Graph --> 21 <meta name="twitter:card" content="summary_large_image"> 22 <meta name="twitter:site" content="@skiperformance"> 23 <meta name="twitter:creator" content="@skiperformance"> 24 <meta name="twitter:title" content="Online Ticketshop"> 25 <meta name="twitter:description" content="See ski pass and ticket prices online. Always buy ski pass and tickets online go directly to the slopes"> 26 <meta name="twitter:image" content="https://cloud.skiperformance.com/media/merchants/suedtirolskiarena.skiperformance.com/img/custom/default/bg-main.jpg"> 27 <link rel="stylesheet" type="text/css" media="screen" href="https://cloud.skiperformance.com/media/css/shop-plugins.css"> 28 <link rel="stylesheet" type="text/css" media="screen" href="https://cloud.skiperformance.com/media/css/shop.css"> 29 <link rel="stylesheet" type="text/css" media="screen" href="https://cloud.skiperformance.com/media/css/merchants/suedtirolskiarena.css"> 30 <!--FRAGMENT echoed: FRAG$shop.suedtirolskiarena.com$en$568$css_17_outer_page_css--> <link rel="shortcut icon" href="https://cloud.skiperformance.com/media/merchants/suedtirolskiarena.skiperformance.com/img/custom/default/favicon.png" type="image/png"> 31 <link rel="icon" href="https://cloud.skiperformance.com/media/merchants/suedtirolskiarena.skiperformance.com/img/custom/default/favicon.png" type="image/png"> 32 33 <!--script type="text/javascript" async="" charset="utf-8" src="https://www.gstatic.com/recaptcha/releases/nY0xPItgwtlvjEjk2TqdwOQz/recaptcha__en.js" crossorigin="anonymous" integrity="sha384-Kt1i/5gBObCvMXB/a7GvZUElKpjCg0ZvOYHqbaCbuEa+xwyOQ3474yVQP0XEfD36"></script--><!--script src="https://www.google.com/recaptcha/enterprise.js?render=6LeX30kpAAAAAIZ-HrmlHKwbyirY6T1HDYl3Wnqs"></script--> 34 <!--script src="https://cloud.skiperformance.com/media/js/jquery.min.js"></script--> 35 <!--script src="https://cloud.skiperformance.com/media/js/chosen.jquery.min.js"></script--> 36 <!--script src="https://cloud.skiperformance.com/media/zostrap/js/zostrap.min.js"></script--> 37 <!--script src="https://cloud.skiperformance.com/media/js/modernizr-2.8.3.
37js"></script--> 38 <!--script src="https://cloud.skiperformance.com/media/js/moment-2.24.0.js"></script--> 39 <!--script src="https://cloud.skiperformance.com/media/js/vue/vue-2.6.11.min.js"></script--> 40 <!--script src="https://cloud.skiperformance.com/media/js/shop/skp/skpStorage.js"></script--> 41 <!--script src="https://cloud.skiperformance.com/media/js/shop/widget/buy/wallet_connector.js"></script--> 42 <!--FRAGMENT echoed: FRAG$shop.suedtirolskiarena.com$en$568$js_17_outer_page_header_scripts--> 43 <!--script> 44 $(document).on('ZoStrap-preautobinder', function() { 45 $.datepicker.setDefaults({ 46 closeText: 'Apply', 47 currentText: 'Today', 48 firstDay: 1, 49 dateFormat: 'dd/mm/yy', 50 changeMonth: false, 51 changeYear: false, 52 beforeShow: function(input, inst) { 53 var calendar = inst.dpDiv; 54 requestAnimationFrame(function() { 55 calendar.position({ 56 my: 'left top', 57 at: 'left bottom', 58 collision: 'none', 59 of: input, 60 }); 61 }); 62 } 63 }); 64 $.timepicker.setDefaults({ 65 beforeShow: function(input, inst) { 66 var calendar = inst.dpDiv; 67 requestAnimationFrame(function() { 68 calendar.position({ 69 my: 'left top', 70 at: 'left bottom', 71 collision: 'none', 72 of: input, 73 }); 74 }); 75 } 76 }); 77 }); 78 $(document).on('ZoStrap-ready', function() { 79 if (ZoStrap.css_browser_selector_find.search("ie1") < 0) { 80 App.globals.loader_height = 150; 81 App.globals.zostrap_script_loaded = true; 82 // All scripts loaded 83 if (App.datatable_scripts_loaded) { 84 notifyAllScriptsLoaded(); 85 } else { 86 $(window).off('datatable_scripts_loaded', null, notifyAllScriptsLoaded) 87 .on('datatable_scripts_loaded', notifyAllScriptsLoaded); 88 } 89 // this prevent open keyboard in mobile 90 $(document).ajaxComplete(function(event, request, settings) { 91 if ($('html').hasClass('mobile')) { 92 $('.datepicker, .zs-datepicker, .js-zostrap-datepicker').prop('readonly', true); 93 } 94 }); 95 } else { 96 $('#content').remove(); 97 } 98 }); 99 100 function onContextmenu(event) { 101 var custom_tag = $(event.target).children('trk:first'); 102 if (custom_tag.length > 0) { 103 event.preventDefault(); 104 var tmp_bg_color = custom_tag.css('background-color'); 105 // console.log(tmp_bg_color); 106 custom_tag 107 .css({'background-color': '#3cbce1'}) 108 .animate({'backgroundColor': tmp_bg_color}, 1500); 109 var text = custom_tag.data('trk'); 110 ZoStrap.copyToClipboard(text); 111 } 112 } 113 </script--> 114 115 <!--script> 116 window.checkTermsAndPrivacyAuths = function () { 117 const cb = $('#register-form [type=checkbox][name^="auth_"]'); 118 119 return (cb.length === 0 || cb.valid()); 120 } 121 122 function Skp_AuthenticationManager() { 123 this.callbackUrl = null; 124 this.connectUrl = null; 125 this.state = null; 126 this.service_id = null; 127 this.access_mode = null; 128 129 this.getAccessMode = function () { 130 return this.access_mode; 131 } 132 133 this.setAccessMode = function (mode) { 134 this.access_mode = mode; 135 } 136 137 this.setCallbackUrl = function (callback_url) { 138 this.callbackUrl = callback_url; 139 } 140 141 this.hasServiceError = function () { 142 return window.authmanager_service_error; 143 } 144 145 this.getServiceErrorMessage = function () { 146 if (this.hasServiceError()) { 147 return window.authmanager_service_error.error_message; 148 } 149 return false; 150 } 151 152 this.clearError = function () { 153 window.authmanager_service_error = false; 154 } 155 156 this.removeStateFromUrl = function (url) { 157 const parsedUrl = new URL(url); 158 const searchParams = parsedUrl.searchParams; 159 searchParams.delete('state'); 160 161 return parsedUrl.origin + parsedUrl.pathname + searchParams.toString(); 162 } 163 164 this.addStateInConnectUrl = function () { 165 let url = this.connectUrl; 166 167 // removing eventually blank state 168 url = url.replace("&state&", "&"); 169 170 // creating the state payload 171 const json_payload = JSON.stringify(this.state); 172 173 // adding it to the url 174 const statevar = "&state=" + this.rawurlencode(json_payload); 175 176 url += statevar; 177 this.connectUrl = url; 178 179 return url; 180 } 181 182 this.rawurlencode = function (str) { 183 return encodeURIComponent(str) 184 .replace(/!/g, '%21') 185 .replace(/'/g, '%27') 186 .replace(/\(/g, '%28') 187 .replace(/\)/g, '%29') 188 .replace(/\*/g, '%2A'); 189 } 190 191 this.openConnectUrl = function (connectUrl, serviceId, mode, action, callback_route) { 192 if (checkTermsAndPrivacyAuths()) { 193 this.connectUrl = connectUrl; 194 this.state.id_service = serviceId; 195 this.state.redirect_url = this.callbackUrl; 196 this.state.mode = mode; 197
198 App.setCookie( 199 'authinfo_state', 200 JSON.stringify({action: action, id_service: serviceId, callback_route: callback_route}), 201 0.005, 202 window.location.hostname 203 ); 204 205 const self = this; 206 $('#register-form [type=checkbox][name^="auth_"]').each( 207 function (idx, elem) { 208 self.state[elem.name] = elem.checked ? "Y" : "N"; 209 } 210 ) 211 212 this.state.user_operation = $('[type="hidden"][name="user_operation"]').val() || $('[type="radio"][name="user_operation"]:checked').val(); 213 214 this.redirect_url = this.callbackUrl; 215 216 window.open(this.addStateInConnectUrl(), "_self"); 217 } 218 } 219 } 220 221 window.Skp_AuthenticationManager = Skp_AuthenticationManager; 222 223 /** 224 * @return {Skp_AuthenticationManager} 225 */ 226 Skp_AuthenticationManager.getInstance = function () { 227 if (!window.authmanager) { 228 window.authmanager = new Skp_AuthenticationManager(); 229 } 230 return window.authmanager; 231 } 232 233 function AuthmanagerInit(callbackUrl) { 234 window.authmanager = new Skp_AuthenticationManager(); 235 window.authmanager.setCallbackUrl(callbackUrl); 236 window.authmanager.state = {"id_service":0,"mode":"frontend","redirect_url":""}; 237 } 238 239 window.authmanager_ready = true; 240 241 function togglePasswordType(elem) { 242 var icon = $(elem).find('.icon'); 243 var input = $(elem).siblings('[name=password]'); 244 if (input.is('[type="password"]')) { 245 icon.removeClass('zs-icon-eye').addClass('zs-icon-eye-bar'); 246 input.attr('type', 'text'); 247 } else { 248 icon.removeClass('zs-icon-eye-bar').addClass('zs-icon-eye'); 249 input.attr('type', 'password'); 250 } 251 } 252 253 if (Skp_AuthenticationManager.getInstance().hasServiceError()) { 254 const authmanager = Skp_AuthenticationManager.getInstance(); 255 const error_element = 'authmanager_error_message';
256 document.getElementById(error_element).innerHTML = authmanager.getServiceErrorMessage(); 257 // clearing error so that it will not show on next login/register action 258 authmanager.clearError(); 259 } 260</script--> 261 <!--script> 262 try { 263 AuthmanagerInit("https:\/\/shop.suedtirolskiarena.com\/en\/store\/login"); 264 } catch (e) { 265 location.reload(); 266 } 267 </script--> 268 269 <!--script src="https://cloud.skiperformance.com/media/js/datatables/datatables.min.js" id="media-js-datatables-datatables-min-js"></script--><!--script id="jquery_ui" data-isloaded="true" src="https://cloud.skiperformance.com/media/zostrap/js/jquery-ui-1.14.1.min.js"></script--><!--script id="jquery.ui.touch-punch" data-isloaded="true" src="https://cloud.skiperformance.com/media/zostrap/js/jquery.ui.touch-punch.min.js"></script--><!--script id="jquery-ui-sliderAccess" data-isloaded="true" src="https://cloud.skiperformance.com/media/zostrap/js/jquery-ui-sliderAccess.min.js"></script--><!--script id="jquery-ui-timepicker-addon" data-isloaded="true" src="https://cloud.skiperformance.com/media/zostrap/js/jquery-ui-timepicker-addon.min.js"></script--><!--script src="https://cloud.skiperformance.com/media/js/jquery-multiselect/jquery.multiselect.js" id="media-js-jquery-multiselect-jquery-multiselect-js"></script--></head> 270 <body class="xs-relative skp-production"> 271 <div class="loader-wrapper xs-gray-f0f0f0-fill"><div class="loader"><span></span></div></div> 272 <!-- BEGINNING OF PAGE CONTROLLER: Shop - ACTION: init - VIEW: shop/pages/outer_page --> 273 <!-- HEADER --> 274 <header id="js-page-header" class="page-header xs-fixed xs-r0 xs-l0 xs-t0 lg-relative xs-text-14 lg-text-16 xs-relative xs-z1"> 275 <div class="top-header xs-relative xs-z2 xs-hide lg-block"> 276 <div class="container"> 277 <ul class="list-unstyled xs-text-right"> 278 <!-- help link --> 279 <li class="xs-inline-block xs-align-top xs-pr1"> 280 <a href="#" class="help-link top-level hover-underline" onclick="App.goTo('/en/support/help'); return false;">Help</a> 281 </li> 282 <!-- season menu --> 283 <li class="header-season-menu xs-inline-block xs-text-left"> 284 <div class="zs-navbar"> 285 <ul class="zs-dropdown-menu"> 286 </ul> 287 </div> 288 </li> 289 <!-- language menu --> 290 <li class="header-language-menu xs-inline-block xs-text-left"> 291 <div class="zs-navbar"> 292 <ul class="zs-dropdown-menu"> 293 </ul> 294 </div> 295 </li> 296 </ul> 297 </div> 298</div> 299<div class="js-zostrap-sticky-wrapper"> 300 <div id="js-main-header" class="main-header xs-white-fill js-zostrap-sticky"> 301 <div class="container"> 302 <div class=" grid xs-grid--center xs-height-full"> 303 <!-- mobile menu --> 304 <div class="header-mobile-menu gc lg-hide"> 305 <div class="header-menu-button pointer js-zs-accordion-menu-mobile-toggle xs-text-center xs-relative" data-nav_id="js-zs-nav-mobile"> 306 <i class="zs-accordion-menu-mobile-toggle zs-icon-mobile-menu xs-text-32 xs-center"></i> 307 </div> 308 </div> 309 <!-- logo --> 310 <div class="header-logo-wrapper gc lg-gc--none xs-text-center lg-text-left lg-mr3"> 311 <a href="https://shop.suedtirolskiarena.com/en/store" class="header-logo"> 312 <img src="https://cloud.skiperformance.com/media/merchants/suedtirolskiarena.skiperformance.com/img/custom/default/logo.png"> 313 </a> 314 </div> 315 <!-- product and support menus --> 316 <div class="header-desktop-menu gc xs-hide lg-block"> 317 <div id="zs-dropdown-menu-header-left" class="zs-navbar"> 318 <ul class="left-menu zs-dropdown-menu js-zs-dropdown-menu"> 319 <!-- product menu --> 320 </ul> 321 </div> 322 </div> 323 </div> 324 </div> 325 </div> 326</div> 327 </header> 328 <!-- END HEADER --> 329 330 <div id="js-page-content_wrapper" class="content-wrapper"> 331 <div id="home-message" class="home-message xs-py4 xs-px2 xs-text-center xs-relative" style="background-image: url(https://cloud.skiperformance.com/media/merchants/suedtirolskiarena.skiperformance.com/img/custom/default/bg-main.jpg)"> 332 <section class="home-message-text xs-r0 xs-l0"> 333 <div class="container">
334 <h1 class="page-title xs-mx-auto xs-p2 sm-inline-block md-px4 md-py3"> 335 <span>Welcome!<p>Buy tickets online</p></span> 336 </h1> 337 <button class="button home-message-button xs-width-full sm-block sm-width-auto sm-mx-auto sm-mt2 md-mt3 lg-button--lg" onclick="App.goTo('/en/support/help');return false;" type="button">How does it work?</button> 338 </div> 339 </section> 340 </div> 341 <!-- what is this? --> 342 <div id="js-top-user_merchant_message" class="top-banner page-message page-message--error" style="display:none;"></div> 343 344 <!-- ribbon --> 345 <div id="ribbon" class="ribbon xs-hide md-block md-py3 md-text-14"> 346 <div class="container"> 347 <ol class="breadcrumb"><li class="js-bc-home home-breadcrumb active"><a href="#/en/buy">Home</a></li></ol> 348 </div> 349 </div> 350 351 <!-- content --> 352 <div id="content" class="content" style="opacity: 1;"><!-- BEGINNING OF PAGE CONTROLLER: Shop_Page_Buy - ACTION: home - VIEW: shop/pages/buy --> 353<div id="js-buy-widget" class="shoptabs-widget"> 354 355 <div class="shoptab-wrapper js-zostrap-sticky-wrapper js-buy-shoptab-wrapper xs-relative xs-z3"> 356 <h1 class="xs-p2 xs-mb0 xs-text-28 lg-hide ">Buy Tickets</h1> 357 <div class="shoptab-wrapper-sticky js-zostrap-sticky" data-sticky_device="desktop"><ul class="shoptab-links list-unstyled xs-mx2 xs-mb2 xs-border-top xs-border-right xs-border-left lg-border-none lg-m0 lg-px3 lg-py12 lg-white-fill lg-text-center "> 358 <li id="Tab_7103" class="tab-group active" data-id="7103" data-is_promo="0" data-active="true"> 359 <a data-toggle="tab" href="/en/products/suedtirol-skipass-2027/7103" class="tab-link bold xs-text-20 lg-text-16"> 360 Südtirol Skipass 2027 <i class="zs-icon-caret-down xs-text-24"></i> 361 <i class="zs-icon-caret-right xs-text-24"></i> 362 <i class="caret-down"></i> 363 </a> 364 </li> 365 <li id="Tab_promo_356" class="tab-group tab-promo" data-id="promo_356" data-is_promo="1" data-active="false"> 366 <a data-toggle="tab" href="javascript:void(0)" onclick="promoTab(356); return false;" class="tab-link bold xs-text-20 lg-text-16 "> 367 Promo <i class="zs-icon-caret-down xs-text-24"></i> 368 <i class="zs-icon-caret-right xs-text-24"></i> 369 <i class="caret-down"></i> 370 </a> 371 </li> 372 </ul></div> 373 </div> 374 375 376 <div class="shoptab-container" id="js-buy-shoptab-container"><!-- BEGINNING OF PAGE CONTROLLER: Shop_Widget_Buy - ACTION: wrapper - VIEW: shop/widgets/buy/wrapper --> 377 378 <section class="shoptab-header"> 379 <div class="container"> 380 <div class="lg-hide"> 381 <a href="javascript:void(backToSkugroups(null))" class="buy-back-link bold main-color xs-px1 xs-py12 xs-text-20 xs-border-bottom xs-block lg-text-16 lg-border-bottom-none lg-pt3 lg-pb0 lg-mb3 lg-ml12- js-buy-content-header-back"> 382 <i class="zs-icon-caret-left xs-mr04"></i> Buy tickets </a> 383 <h1 class="shoptab-name xs-pt3 xs-px2">Südtirol Skipass 2027</h1> 384</div> 385 386 387<div class="shoptab-text p-mb0 xs-px2 lg-mt3 lg-px0 js-buy-content-header-shoptab-text"> 388 <div class="shoptab-description js-shoptab-description-0 p-mb0 xs-my2 md-my3" style="color:#000000;"> 389 <div class="text-wrapper"> 390 <p>For price information, please contact <a href="mailto://[email protected]" target="_blank">[email protected]</a> and indicate your municipality of residence, the number of adults and the birth years of the children.<br></p> </div> 391 </div> 392<!--script> 393 $('.js-shoptab-description-0 :is(h1, h2, h3, h4, h5)').each(function() { 394 $(this).css('color', '#000000'); 395 }); 396</script--> 397 398</div> 399 400 <section id="js-shoptab-filters-wrapper" class="lg-mt3 js-hide"> 401<div class="xs-m2 js-shoptab-filters-open_modal js-hide"> 402 <button class="filters-button button xs-width-full js-zostrap-show-modal" data-modal-id="js-shoptab-filters-modal"> 403 Filter <span class="js-shoptab-filters-open_modal-count_active js-hide"></span> 404 </button> 405</div> 406<div id="js-shoptab-filters-modal" class="shoptab-filters-modal zs-modal md-modal md-py5 js-zostrap-hide-modal zs-modal-fullscreen"> 407 <div class="modal__content"> 408 <header class="modal__header"> 409 <a class="modal__close "><i class="zs-icon-close-thin main-color xs-text-24 js-zostrap-hide-modal"></i></a> 410 <h2 class="modal__title"></h2> 411 </header> 412 <div class="modal__body"> 413 </div> 414 </div> 415</div> 416 417 418<!--script> 419 var empty_until_filtered = false;
420 var date_filter_type = "no"; 421 var date_filter_selector = 'input.js-df-group-f, select.js-df-group-f, textarea.js-df-group-f'; 422 var cascade_enabled = false; 423 var data_fields_grouped = {}; 424 425 function load_tickets() { 426 var original = App.showLoading; 427 // important keep this line before the .html at next line 428 var f_ext = ZoStrap.serializeFrom($('[form="js-buy-header-filters-form"]')); 429 $('.js-buy-content').html('<div class="xs-relative xs-h2">' + 430 '<div class="loader active"><span></span></div>' + 431 '</div>'); 432 if ($('.js-datefilter-fieldset-pools').length === 0) $('[name="pool_id"]').val(''); 433 var f = $('#js-buy-header-filters-form'); 434 if (f_ext.length > 0) { 435 f_ext = '&' + f_ext; 436 } 437 if (typeof App.globals.switchSubTab !== 'undefined') { 438 App.globals.switchSubTab.abort(); 439 } 440 App.globals.switchSubTab = App.getHtml( 441 '/en/ajax/html/shop_widget_buy/viewable_list', 442 f.serialize() + f_ext, 443 $('.js-buy-content'), 444 function () { 445 delete App.globals.switchSubTab; 446 App.enableGUI(); 447 App.showLoading = original; 448 cascadeFilter(); 449 filterDataField(); 450 countFilterActive(); 451 } 452 ); 453 } 454 455 function filterDataField() { 456 var skugroup_id = "7103"; 457 var filter_values = {}; 458 var data_selector = ''; 459 var data_selector_array = []; 460 $('.js-buy-header-filters-dataprofile') 461 .find(date_filter_selector) 462 .each(function (index, elem) { 463 let field_name = $(elem).attr('name'); 464 field_name = (field_name > '' ? field_name.replace('[]', '') : ''); 465 var field_value = $(elem).val(); 466 if ( 467 $(elem).prop('type').toLowerCase() === 'radio' && $(elem).prop('checked') 468 || $(elem).prop('type').toLowerCase() !== 'radio' 469 ) { 470 filter_values[field_name] = field_value; 471 } 472 if ($(elem).prop('type').toLowerCase() === 'radio' && !$(elem).prop('checked')) { 473 field_value = ''; 474 } 475 if (field_value != '' && field_value != null) { 476 if (Array.isArray(field_value)) { 477 var multiselect = []; 478 for (var i in field_value) { 479 var selector = '[data-' + field_name + '*="' + field_value[i] + '"]'; 480 if (data_selector_array.length === 0) { 481 multiselect.push(selector); 482 } else { 483 for (var j in data_selector_array) { 484 multiselect.push(data_selector_array[j] + selector); 485 } 486 } 487 } 488 if (multiselect.length > 0) { 489 data_selector_array = multiselect; 490 } 491 } else { 492 data_selector += '[data-' + field_name + '*="' + field_value + '"]'; 493 } 494 } 495 }); 496 App.saveInStorage('skugroup_filter_' + skugroup_id, filter_values); 497 countFilterActive(); 498 var filterable_data_selector = '.js-buy-content-filterable' + data_selector; 499 if (data_selector_array.length > 0) { 500 var full_data_selector = data_selector; 501 var full_filterable_data_selector = filterable_data_selector; 502 for (var i in data_selector_array) { 503 full_data_selector += (i > 0 ? ', ' + data_selector : '') + data_selector_array[i]; 504 full_filterable_data_selector += (i > 0 ? ', ' + filterable_data_selector : '') + data_selector_array[i]; 505 } 506 data_selector = full_data_selector; 507 filterable_data_selector = full_filterable_data_selector; 508 } 509 if (data_selector) { 510 $('.js-buy-content-filterable').not(data_selector).addClass('js-hide'); 511 } 512 $(filterable_data_selector).removeClass('js-hide'); 513 514 showNoViewableFound(); 515 } 516 517 function showNoViewableFound() { 518 if ($('.js-buy-content-filterable').length === $('.js-buy-content-filterable.js-hide').length) { 519 $('.js-buy-content-no_viewable_found').removeClass('js-hide'); 520 } else { 521 $('.js-buy-content-no_viewable_found').addClass('js-hide'); 522 } 523 } 524 525 function countFilterActive() { 526 var serialise_array = ZoStrap.serializeArrayFrom($('[form="js-buy-header-filters-form"]'), true); 527 var count_filter_active = Object.keys(serialise_array).length; 528 $('.js-buy-header-filters-dataprofile').find(date_filter_selector).each(function() { 529 var field_value = $(this).val(); 530 if ($(this).prop('type') == 'radio' && !$(this).prop('checked')) 531 { 532 field_value = ''; 533 } 534 if (field_value != '' && field_value != null) 535 { 536 count_filter_active++; 537 } 538 }); 539 if (count_filter_active > 0) { 540 $('.js-shoptab-filters-open_modal').addClass('filter-active'); 541 $('.js-shoptab-filters-open_modal').find('.js-shoptab-filters-open_modal-count_active').removeClass('js-hide').html('('+count_filter_active+')'); 542 $('.js-buy-content-empty_until_filtered').addClass('js-hide'); 543 } else { 544 $('.js-shoptab-filters-open_modal').removeClass('filter-active'); 545 $('.js-shoptab-filters-open_modal').find('.js-shoptab-filters-open_modal-count_active').addClass('js-hide'); 546 if (empty_until_filtered) { 547 $('.js-buy-content-filterable').addClass('js-hide'); 548 $('.js-buy-content-no_viewable_found').addClass('js-hide'); 549 $('.js-buy-content-empty_until_filtered').removeClass('js-hide'); 550 } else { 551 $('.js-buy-content-filterable').removeClass('js-hide'); 552 $('.js-buy-content-empty_until_filtered').addClass('js-hide'); 553 showNoViewableFound(); 554 } 555 } 556 } 557 558 function init_filter() { 559 init_multiselect_checkbox_filter(); 560 init_select_filter(); 561 init_date_filter(); 562 } 563 564 function initFilterDataFieldValue() { 565 var skugroup_id = "7103"; 566 var filter_values = App.loadFromStorage('skugroup_filter_' + skugroup_id, {}); 567 $('.js-buy-header-filters-dataprofile').find(date_filter_selector).each(function(idx, elem) { 568 var field_name = $(elem).attr('name'); 569 field_name = (field_name > '' ? field_name.replace('[]', '') : ''); 570 var field_value = filter_values ? filter_values[field_name] : null; 571 if (field_value != null) { 572 if ($(elem).prop('type').toLowerCase() === 'radio') { 573 $(elem).prop('checked', $(elem).val() == field_value); 574 } else if ($(elem).hasClass('js-zs-chosen-select')) { 575 if (Array.isArray(field_value)) { 576 $(elem).val(field_value); 577 } else { 578 $(elem).val([field_value]); 579 } 580 $(elem).trigger('chosen:updated'); 581 } else if ($(elem).hasClass('js-zs-multiselect-select')) { 582 if (Array.isArray(field_value)) { 583 $(elem).val(field_value); 584 } else { 585 $(elem).val([field_value]); 586 } 587 $(elem).multiselect_checkbox('reload'); 588 } else if ($(elem).prop('type').toLowerCase() === 'checkbox') { 589 if (Array.isArray(field_value)) { 590 $(elem).prop('checked', field_value.indexOf($(elem).val()) >= 0); 591 } else { 592 $(elem).prop('checked', $(elem).val() == field_value); 593 } 594 } else { 595 $(elem).val(field_value); 596 } 597 } 598 }); 599 } 600 601 function init_select_filter() { 602 const filter_container = $('.js-buy-header-filters-dataprofile'); 603 filter_container.find(".js-zs-chosen-select.select").each(function (index, elem) { 604 elem = $(elem); 605 if (elem.data('chosen')) { 606 return; 607 } 608 elem.chosen({ 609 disable_search_threshold: 100, 610 width: "100%", 611 }); 612 }); 613 } 614 615 function init_multiselect_checkbox_filter() { 616 const filter_container = $('.js-buy-header-filters-dataprofile'); 617 filter_container.find(".js-zs-chosen-select.multiselect").each(function (index, elem) { 618 elem = $(elem); 619 if (elem.data('plugin_multiselect')) { 620 return; 621 } 622 elem.multiselect_checkbox({ 623 texts: { 624 placeholder: elem.data('placeholder'), 625 }, 626 }); 627 }); 628 filter_container.find(".ms-options ul").append('<button type="button" class="button xs-width-full xs-hide" onclick="$(this).closest(\'.ms-options-wrap\').removeClass(\'ms-active\')">Close</button>'); 629 filter_container.find(".ms-options label").append('<span class="checkmark"></span>'); 630 } 631 632 function init_date_filter() { 633 const filter_container = $('.js-buy-header-filters-dataprofile'); 634 if (date_filter_type != 'no') { 635 var availDates = null; 636 var minDate = null; 637 availDates = (typeof availDates !== typeof undefined && availDates != null && availDates != 'all') ? Object.keys(availDates) : availDates; 638 var datePickerId = '#filter_date'; 639 var hasAvailDates = (typeof availDates !== typeof undefined && availDates != null && (availDates == 'all' || availDates.length > 0)); 640 var arrayOfValidDates = []; 641 642 if (hasAvailDates || minDate != null) { 643 var first_date = null; 644 if (availDates == 'all') { 645 first_date = new Date(); 646 first_date = first_date.setHours(0, 0, 0, 0); 647 } 648 if (hasAvailDates && availDates != 'all') { 649 for (var j = 0; j < availDates.length; j++) { 650 var date = new Date(availDates[j]); 651 date = date.setHours(0, 0, 0, 0); 652 if (j === 0 && first_date == null) 653 first_date = date; 654 655 var d = new Date(date); 656 arrayOfValidDates.push( 657 (1900 + d.getYear()) + "-" + 658 ((1 + d.getMonth()) < 10 ? '0' : '') + (1 + d.getMonth()) + "-" + 659 (d.getDate() < 10 ? '0' : '') + 660 d.getDate() 661 ); 662 } 663 } 664 var date_minDate = null; 665 if (minDate != null) { 666 date_minDate = new Date(minDate); 667 date_minDate = date_minDate.setHours(0, 0, 0, 0); 668 if (first_date == null || date_minDate < first_date) 669 first_date = date_minDate; 670 } 671 if (date_filter_type == 'start') { 672 filter_container.find(datePickerId).datepicker( "option", "beforeShowDay", function(date){ 673 var date_string = jQuery.datepicker.formatDate('yy-mm-dd', date); 674 var isValid = false;
675 if ((availDates == 'all' && date >= first_date) || (date_minDate != null && date >= date_minDate) || arrayOfValidDates.indexOf(date_string) !== -1) 676 isValid = true; 677 return [isValid] 678 }); 679 filter_container.find(datePickerId).datepicker( "option", "minDate", first_date ); 680 filter_container.find(datePickerId).datepicker('option', 'afterShow', function (inst) { 681 if (inst.input.data('optimizecalendardesign') === 'highlight_selected_date') { 682 inst.dpDiv.addClass('zs-ui-datepicker-theme-selected-date'); 683 inst.dpDiv.removeClass('zs-ui-datepicker-theme-purchasable-dates'); 684 } else { 685 inst.dpDiv.removeClass('zs-ui-datepicker-theme-selected-date'); 686 inst.dpDiv.addClass('zs-ui-datepicker-theme-purchasable-dates'); 687 } 688 }); 689 } else if (date_filter_type == 'range') { 690 $('.js-zostrap-daterangepicker').daterangepicker({ 691 showCustomRangeLabel: false, 692 autoUpdateInput: false, 693 firstDay: 1, 694 locale: { 695 format: $('.js-zostrap-daterangepicker').data('dateformat'), 696 cancelLabel: 'Cancel', 697 applyLabel: 'Apply', 698 }, 699 parentEl: ZoStrap.isMobile() ? '#js-filter-date-wrapper' : 'body', 700 isInvalidDate: function(date) { 701 var date_string = date.format('YYYY-MM-DD'); 702 var isValid = false; 703 if ((availDates == 'all' && date>=first_date) || (date_minDate != null && date >= date_minDate) || arrayOfValidDates.indexOf(date_string) != -1) 704 isValid = true; 705 return !isValid; 706 } 707 }); 708 709 $('.js-zostrap-daterangepicker').on('remove', function() { 710 if ($(this).data('daterangepicker')) { 711 $(this).data('daterangepicker').remove(); 712 } 713 }); 714 $('.js-zostrap-daterangepicker').on('show.daterangepicker', function(ev, picker) { 715 if (picker.element.data('optimizecalendardesign') === 'highlight_selected_date') { 716 picker.container.addClass('skp-daterangepicker-theme-selected-date'); 717 picker.container.removeClass('skp-daterangepicker-theme-purchasable-dates'); 718 } else { 719 picker.container.removeClass('skp-daterangepicker-theme-selected-date'); 720 picker.container.addClass('skp-daterangepicker-theme-purchasable-dates'); 721 } 722 }); 723 $('.js-zostrap-daterangepicker').on('apply.daterangepicker', function(ev, picker) { 724 $(this).val(picker.startDate.format($('.js-zostrap-daterangepicker').data('dateformat')) + ' - ' + picker.endDate.format($('.js-zostrap-daterangepicker').data('dateformat'))); 725 filterChange(this); 726 }); 727 $('.js-zostrap-daterangepicker').on('cancel.daterangepicker', function(ev, picker) { 728 $(this).val(''); 729 filterChange(this); 730 }); 731 } 732 } else if (typeof availDates != typeof undefined && availDates == null && minDate == null) { 733 if (date_filter_type == 'start') { 734 filter_container.find(datePickerId).datepicker( "option", "disabled", true ); 735 } else if (date_filter_type == 'range') { 736 $('.js-zostrap-daterangepicker').prop('disabled', true); 737 } 738 } 739 } 740 } 741 742 function filterChange(elem) { 743 if (elem.value != '') { 744 countFilterActive(); 745 } 746 load_tickets(); 747 } 748 749 function filter_position() { 750 var node_container; 751 if (ZoStrap.isMobile()) { 752 $('.js-shoptab-filters-open_modal').removeClass('js-hide'); 753 node_container = $('#js-shoptab-filters-modal .modal__body')[0]; 754 } else { 755 $('.js-shoptab-filters-open_modal').addClass('js-hide'); 756 node_container = $('#js-shoptab-filters-wrapper')[0]; 757 } 758 var node_elem = $('#js-shoptab-filters')[0]; 759 if (typeof node_container !== typeof undefined && typeof node_elem !== typeof undefined) { 760 node_container.appendChild(node_elem); 761 } 762 } 763 764 function cascadeFilterInit() { 765 if (!cascade_enabled) return; 766 767 data_fields_grouped = {}; 768 $('.js-data_field').each(function(index, elem) { 769 const field_name = $(elem).attr('name'); 770 if (!data_fields_grouped[field_name]) { 771 data_fields_grouped[field_name] = []; 772 } 773 const elem_type = $(elem).prop('type').toLowerCase(); 774 const elem_tag = elem.tagName.toLowerCase(); 775 776 if (elem_tag === 'select') { 777 data_fields_grouped[field_name].push($(elem).find('option').clone()); 778 } else if ((elem_type === 'radio' || elem_type === 'checkbox') || elem_tag === 'input') { 779 data_fields_grouped[field_name].push($(elem).clone()); 780 } else { 781 data_fields_grouped[field_name].push($(elem).clone()); 782 } 783 }); 784 } 785 786 function cascadeFilter(field) { 787 if (!cascade_enabled) { 788 return; 789 } 790 791 const field_names = Object.keys(data_fields_grouped); 792 if (field_names.length < 2) { 793 return; 794 } 795 796 // Determine from which index to start the cascade 797 let cascade_from = 0; 798 if (!field || field.length === 0) { 799 field = $('.js-data_field').addBack().find('[name="' + field_names[0] + '"]'); 800 } 801 802 const changed_index = field_names.indexOf(field.attr('name'));
803 if (changed_index === -1) { 804 return; 805 } 806 cascade_from = changed_index; 807 if (cascade_from >= field_names.length) { 808 return; 809 } 810 811 // Get the set of products filtered by the preceding fields in the cascade 812 let $products = $('.js-buy-content-filterable'); 813 814 // For each field from the first onwards, 815 // restrict the options based on the cumulative filters and update the cumulative product set 816 for (let j = 0; j < field_names.length; j++) { 817 const fname = field_names[j]; 818 const base_attr = 'data-' + fname.replace('[]', ''); 819 const originals = data_fields_grouped[fname]; 820 if (!originals || originals.length === 0) continue; 821 const $field = $('.js-data_field').addBack().find('[name="' + fname + '"]'); 822 823 // Collect distinct values available in the filtered products for the current field 824 const available = {}; 825 $products.each(function(index, product) { 826 const a = $(product).attr(base_attr); 827 if (a) { 828 try { 829 var arr = JSON.parse(a); 830 if (Array.isArray(arr)) { 831 for (var k = 0; k < arr.length; k++) { 832 available[arr[k]] = true; 833 } 834 } 835 } catch(e) {} 836 } 837 }); 838 839 // Update field options based on available values 840 if ($field.length === 0) { 841 continue; 842 } 843 const $el = $field.first(); 844 const tag = $el.prop('tagName').toLowerCase(); 845 846 if (tag === 'select') { 847 const currentVal = $el.val(); 848 849 // Remove all options and re-add only those that are still available, preserving the original order 850 $el.find('option').remove(); 851 originals[0].clone().each(function(index, elem) { 852 if ($(elem).attr('value') == '' || available.hasOwnProperty($(elem).attr('value'))) { 853 $el.append($(elem)); 854 } 855 }); 856 857 // Re-apply the current value if it's still valid, otherwise reset to null 858 if (Array.isArray(currentVal)) { 859 var newVal = currentVal.filter(function(v) { return available.hasOwnProperty(v); }); 860 $el.val(newVal.length > 0 ? newVal : null); 861 } else if (currentVal && available.hasOwnProperty(currentVal)) { 862 $el.val(currentVal); 863 } else { 864 $el.val(null); 865 } 866 867 // Update UI widgets 868 if ($el.hasClass('multiselect')) { 869 try { 870 $el.multiselect_checkbox('reload'); 871 $el.next().find(".ms-options ul").append('<button type="button" class="button xs-width-full xs-hide" onclick="$(this).closest(\'.ms-options-wrap\').removeClass(\'ms-active\')">Close</button>'); 872 $el.next().find(".ms-options label").append('<span class="checkmark"></span>'); 873 } catch(e) {} 874 } else if ($el.hasClass('select')) { 875 $el.trigger('chosen:updated'); 876 } 877 } else if ($el.is(':radio')) { 878 const $checked = $field.filter(':checked'); 879 const currentRadioVal = $checked.length > 0 ? $checked.val() : null; 880 881 // Show/hide radio groups 882 $field.each(function(index, elem) { 883 const radioVal = $(elem).val(); 884 const $group = $(elem).closest('.radio-group'); 885 if (radioVal !== '' && !available.hasOwnProperty(radioVal)) { 886 $group.addClass('js-hide'); 887 } else { 888 $group.removeClass('js-hide'); 889 } 890 }); 891 892 // Reset if the current selection is no longer valid 893 if (currentRadioVal && !available.hasOwnProperty(currentRadioVal)) { 894 $field.prop('checked', false); 895 } 896 } 897 898 // Filter products based on the current field's selected values 899 const $selected_values = $field.find(':checked, :selected').map(function() { 900 return $(this).val(); 901 }).get().filter(v => v !== ''); 902 if ($selected_values.length > 0) { 903 const filtered_products = []; 904 $products.each(function(index, product) { 905 const a = $(product).attr(base_attr); 906 if (a) { 907 try { 908 var arr = JSON.parse(a); 909 if (Array.isArray(arr)) { 910 for (var k = 0; k < arr.length; k++) { 911 if (Array.isArray(arr[k])) { 912 for (var m = 0; m < arr[k].length; m++) { 913 if ($selected_values.indexOf(arr[k][m]) !== -1) { 914 filtered_products.push(product); 915 return; 916 } 917 } 918 } else if (typeof arr[k] === 'string' || typeof arr[k] === 'number') { 919 if ($selected_values.indexOf(arr[k]) !== -1) { 920 filtered_products.push(product); 921 return; 922 } 923 } 924 } 925 } 926 } catch(e) {} 927 } 928 }); 929 $products = $(filtered_products); 930 } 931 } 932 } 933 934 App.pageSetUp(function () { 935 ZoStrap.binder(); 936 if ($('#js-shoptab-filters fieldset').length === 0) { 937 $('#js-buy-header-filters-form-reset-btn, #js-shoptab-filters-wrapper').addClass('js-hide'); 938 } else { 939 $('#js-buy-header-filters-form-reset-btn, #js-shoptab-filters-wrapper').removeClass('js-hide'); 940 } 941 let script_to_load = ['https://cloud.skiperformance.com/media/js/jquery-multiselect/jquery.multiselect.js']; 942 if (date_filter_type == 'range') { 943 script_to_load.push('https://cloud.skiperformance.com/media/js/daterangepicker/daterangepicker.js'); 944 } 945 App.loadScript( 946 script_to_load, 947 function() { 948 init_filter(); 949 initFilterDataFieldValue(); 950 cascadeFilterInit(); 951 cascadeFilter(); 952 filterDataField(); 953 countFilterActive(); 954 $('.js-buy-header-filters-dataprofile') 955 .find('input, select, .js-zs-chosen-select') 956 .not('[name="bookable_y_n_a"], [name="filter_date"], [name="pool_id"]') 957 .on('change', function(event) { 958 cascadeFilter($(event.target)); 959 filterDataField(); 960 countFilterActive(); 961 }); 962 } 963 ); 964 $('[name="bookable_y_n_a"], [name="pool_id"]') 965 .on('change', function (event) { 966 filterChange(event.target); 967 }); 968 969 $('#js-buy-header-filters-form-reset-btn').on('click', function (event) { 970 const filter_container = $('#js-shoptab-filters'); 971 if (date_filter_type == 'start') { 972 filter_container.find('#filter_date').datepicker('setDate', null); 973 } else if (date_filter_type == 'range') { 974 filter_container.find('.js-zostrap-daterangepicker').val(''); 975 } 976 filter_container.find('#pool_id').val(null); 977 filter_container.find(".js-zs-chosen-select.multiselect").multiselect_checkbox('reset'); 978 filter_container.find(".js-zs-chosen-select.select").val(null).trigger('chosen:updated');
979 filter_container.find(".radio").prop('checked',false); 980 cascadeFilter(); 981 countFilterActive(); 982 init_filter(); 983 load_tickets(); 984 }); 985 $(document).off('ZoStrap-resize', null, filter_position).on('ZoStrap-resize', null, null, filter_position); 986 filter_position(); 987 }); 988</script--> 989 990<div id="js-shoptab-filters" class="shoptab-filters lg-gray-f0f0f0-fill lg-pt3 lg-px3 lg-pb1"> 991 <h3 class="filter-description" style="margin-bottom: 20px;">Looking for something specific? Use the filters to narrow down your options</h3> 992 993 994 <div class="shoptab-filters-button js-shoptab-filters-button xs-text-right xs-gc12 lg-hide"> 995 <a href="javascript:void(0)" class="buy-button button xs-width-full js-zostrap-hide-modal">Filter</a> 996 </div> 997 998 <form method="POST" id="js-buy-header-filters-form"> 999 <input type="hidden" name="skugroup_id" value="7103"> 1000 </form> 1001</div></section> 1002 1003<!--script> 1004 App.pageSetUp(function() { 1005 if (ZoStrap.isMobile()) { 1006 $('body').addClass('mobile-product-list'); 1007 } 1008 }); 1009</script--> 1010 </div> 1011 </section> 1012 1013 <section class="shoptab-content container lg-py4 js-buy-content-binded_for_accordion js-buy-content" data-sg_id="7103"> 1014 <article class="product-detail-wrapper" itemscope="" itemtype="http://schema.org/Product"> 1015<div class="js-buy-content-grid-detail product-detail"> 1016 <span itemprop="brand">Suedtirol Skiarena</span> 1017 <h1 class="page-title product-name xs-px12 md-px0" itemprop="name">Südtirol Skipass 2027 Standard</h1> 1018 <div class="product-short-description xs-px12 md-px0" itemprop="description">For seniors, adults, youths and children â one ticket valid for the entire year.</div> 1019 1020 <div class="grid md-grid--g3 lg-grid--g6"> 1021 <div class="left-column gc xs-gc12 xs-order1 md-order0 md-gc7 lg-gc8"> 1022 1023 1024 <img itemprop="image" src="https://cloud.skiperformance.com/media/merchants/suedtirolskiarena.skiperformance.com/products-img/image-10003-large-5_3.jpg" class="product-image xs-width-full xs-width-fit xs-mb3"> 1025 1026 <section class="product-description xs-pt2 xs-mb3 xs-px12 md-pt0 md-px0 md-mb4"> 1027 <h2 class="xs-mb1">Description</h2> 1028 <p><b>Südtirol Skipass 2027<br>Standard</b></p><p><br></p><p>The Südtirol Skipass is valid 365 days a year in all 18 ski and hiking areas of the Südtirol Skiarena.</p><p> </p> </section> 1029 <section class="buy-products-link xs-p12 md-p0"> 1030 <button type="button" class="button md-hide xs-width-full js-btn-buy-tickets">Buy Products</button> 1031 </section> 1032 </div> 1033 </div> 1034</div></article> 1035 1036<!--script> 1037const newTitle = "Südtirol Skipass 2027 Standard"; 1038document.getElementsByTagName('title')[0].innerText = newTitle + ' | ' + document.getElementsByTagName('title')[0].innerText; 1039document.querySelector('meta[name="description"]').setAttribute("content", "For seniors, adults, youths and children â one ticket valid for the entire year."); 1040</script--> </section> 1041 1042<!-- BEGINNING OF PAGE CONTROLLER: Shop_Widget_Offer - ACTION: get_offer_skugroup - VIEW: shop/widgets/offer_widget --> 1043 1044<!-- END OF PAGE CONTROLLER: Shop_Widget_Offer - ACTION: get_offer_skugroup - VIEW: shop/widgets/offer_widget --> 1045<!-- END OF PAGE CONTROLLER: Shop_Widget_Buy - ACTION: wrapper - VIEW: shop/widgets/buy/wrapper --></div> 1046</div> 1047 1048<!--script> 1049 var getSkuIdsURL = '/en/ajax/json/Ajax_Product/getSkuIds'; 1050 var decorateCalendarDatesURL = '/en/ajax/json/Ajax_Product/dailyAvailabilityStatus'; 1051 var decorateCGCalendarDatesURL = '/en/ajax/json/Ajax_Booking/dailyAvailabilityStatus'; 1052 var decorateCalendarDatesActive = "1"; 1053 var skp_booking_ajax_hash = 'hHxjmU8Lp3tPx5A7V0cxtByAGfBrxOT%2BXG7u1Yrf1sBSDC6N7K75nbZU9iiPkJd%2By0NogxkxzvfI%2BpJW8E8OjyMDuCXzyZu41Bo%3D'; 1054 var manage_booking_url = '/en/bookings_with_keycard'; 1055 var userIsLogged = false; 1056 var preset_params = {}; 1057 var is_promo = false; 1058 var is_promo_offer = false; 1059 var active_tab_id = "7103"; 1060 var mobile_active_tab_id = null; 1061 var show_reminder_order_to_be_payed = false; 1062 var numItems = 0; 1063
1064 preset_params[active_tab_id] = 'skugroup_id=7103&_=1791505597827'; // Only to be used for the first time 1065 App.globals.has_more_than_one_tab = true 1066 function bookingKeycardAssociationTab() { 1067 if (userIsLogged) { 1068 App.goTo(manage_booking_url); 1069 } else { 1070 App.goTo(manage_booking_url, '#content'); 1071 } 1072 } 1073 1074 function promoTab(promo_connector_id, force) { 1075 if (typeof promo_connector_id === typeof undefined) { 1076 return; 1077 } 1078 App.tab_content_query = "#js-buy-shoptab-container"; 1079 var current_tab = $('#Tab_promo_' + promo_connector_id); 1080 current_tab.siblings().attr('data-active', 'false').removeClass('active'); 1081 if (force || current_tab.attr('data-active') != 'true') { 1082 current_tab.attr('data-active', 'true'); 1083 if (ZoStrap.isMobile()) { 1084 $('.js-buy-shoptab-wrapper').addClass('js-hide'); 1085 } else { 1086 current_tab.addClass('active'); 1087 } 1088 var loaderHtml = '<div class="xs-relative" style="height:' 1089 + App.globals.loader_height 1090 + 'px;"><div class="loader active"><span></span></div></div>'; 1091 $(App.tab_content_query).html(loaderHtml); 1092 var route = '/en/ajax/html/Shop_Widget_PromoCode/promo_wid'; 1093 if (typeof App.globals.switchTab != 'undefined') { 1094 App.globals.switchTab.abort(); 1095 } 1096 var gethtml_params = {}; 1097 // skpSlideshowBeahaviorOnTabSwitch('promo', promo_connector_id, gethtml_params); 1098 var data_query = 'is_promo=1&is_promo_offer=0&promo_connector_id=' + promo_connector_id + (typeof preset_params[promo_connector_id] != 'undefined' ? '&' + preset_params[promo_connector_id] : '') + '&has_more_than_one_tab=' + App.globals.has_more_than_one_tab; 1099 App.globals.switchTab = App.getHtml( 1100 route, 1101 data_query, 1102 App.tab_content_query, 1103 function() { 1104 delete App.globals.switchTab; 1105 var stateObj = { 1106 route: route, 1107 params: data_query, 1108 content: App.tab_content_query 1109 }; 1110 window.history.pushState( 1111 stateObj, 1112 document.title, 1113 'https://shop.suedtirolskiarena.com/en/store#/en/buy?is_promo=1&is_promo_offer=0&promo_connector_id=' + promo_connector_id, 1114 ); 1115 1116 skpWelcomeMessage(promo_connector_id, true, false); 1117 skpSlideshowShow('promo', promo_connector_id); 1118 }, 1119 gethtml_params 1120 ); 1121 App.scrollTo("#js-buy-shoptab-container"); 1122 preset_params[promo_connector_id] = ''; 1123 } else if (ZoStrap.isMobile()) { 1124 current_tab.attr('data-active', 'false').removeClass('active'); 1125 } 1126 } 1127 1128 function switchTab(id, force) { 1129 if (typeof id === typeof undefined) { 1130 return; 1131 } 1132 App.tab_content_query = "#js-buy-shoptab-container"; 1133 var current_tab = $('#Tab_'+id); 1134 current_tab.siblings().attr('data-active', 'false').removeClass('active'); 1135 if (current_tab.attr('data-active') != 'true' || force == true) { 1136 // handle slideshow video players on tab switch 1137 if (!!App.globals.jt_player) { 1138 $.each(App.globals.jt_player, function(index, element) { 1139 element.destroy(); 1140 }); 1141 App.globals.jt_player = {}; 1142 } 1143 1144 current_tab.attr('data-active', 'true').addClass('active'); 1145 if (ZoStrap.isMobile()) { 1146 $('.js-buy-shoptab-wrapper').addClass('js-hide'); 1147 } 1148 var loaderHtml = '<div class="xs-relative" style="height:' 1149 + App.globals.loader_height 1150 + 'px;"><div class="loader active"><span></span></div></div>'; 1151 $(App.tab_content_query).html(loaderHtml); 1152 var route = '/en/ajax/html/Shop_Widget_Buy/wrapper'; 1153 var params = 'skugroup_id=' + id + '&has_more_than_one_tab=' + App.globals.has_more_than_one_tab; 1154 if (current_tab.data('promo_id') != null) { 1155 params += '&is_promo=1&promo_id=' + current_tab.data('promo_id'); 1156 } 1157 if (current_tab.data('is_promo_offer') != null) { 1158 params += '&is_promo_offer=1'; 1159 } 1160 1161 if (typeof App.globals.switchTab != 'undefined') { 1162 App.globals.switchTab.abort(); 1163 } 1164 var gethtml_params = {}; 1165 skpSlideshowBeahaviorOnTabSwitch('skugroup', id, gethtml_params); 1166 var data_query = params + '&' + (typeof preset_params[id] != 'undefined' ? preset_params[id] : ''); 1167 App.globals.switchTab = App.getHtml( 1168 route, 1169 data_query, 1170 App.tab_content_query, 1171 function() { 1172 delete App.globals.switchTab; 1173 var stateObj = { 1174 route: history.state ? history.state.route : route, 1175 params: history.state ? history.state.params : data_query, 1176 content: history.state ? history.state.content : App.tab_content_query 1177 }; 1178 window.history.pushState( 1179 stateObj, 1180 document.title, 1181 'https://shop.suedtirolskiarena.com/en/store#/en/buy?skugroup_id=' + id, 1182 ); 1183 1184 if (ZoStrap.isMobile() && mobile_active_tab_id && mobile_active_tab_id == id) { 1185 $('.js-buy-content-header-back').remove(); 1186 } 1187 skpWelcomeMessage(id, false, current_tab.data('is_promo_offer') != null);
1188 skpSlideshowShow('skugroup', id); 1189 }, 1190 gethtml_params 1191 ); 1192 preset_params[id] = ''; 1193 } else if (ZoStrap.isMobile()) { 1194 current_tab.attr('data-active', 'false').removeClass('active'); 1195 } 1196 } 1197 1198 function tab_behavior() { 1199 if (ZoStrap.isMobile()) { 1200 $('.js-buy-shoptab-wrapper li').removeClass('active'); 1201 if ($('#js-buy-shoptab-container *').length > 0) { 1202 $('.js-buy-shoptab-wrapper').addClass('js-hide'); 1203 } else { 1204 $('.js-buy-shoptab-wrapper').removeClass('js-hide'); 1205 } 1206 } else { 1207 $('.js-buy-shoptab-wrapper').removeClass('js-hide'); 1208 } 1209 } 1210 1211 function onClickReloadOrderToBePayed() { 1212 $('#js-top-user_merchant_message').fadeOut(400); 1213 if ($numItems == 0) { 1214 App.action( 1215 '/en/ajax/json/Ajax_Order/use_order_as_basket', 1216 null, 1217 null 1218 ); 1219 } else { 1220 App.goTo( 1221 '/en/restore_order' 1222 ); 1223 } 1224 } 1225 1226 function onClickCloseOrderToBePayed() { 1227 $('#js-top-user_merchant_message').fadeOut(400); 1228 } 1229 1230 function skpSlideshowBeahaviorOnTabSwitch(tab_type, tab_id, gethtml_params) { 1231 if (ZoStrap.isMobile()) { 1232 if ( 1233 typeof skpslideshows != typeof undefined 1234 && skpslideshows 1235 ) { 1236 for(var position in skpslideshows) { 1237 if (skpslideshows[position]?.config?.[tab_type]?.[tab_id]?.['show_in_mobile'] == '1') { 1238 gethtml_params.noscroll = true; 1239 } 1240 } 1241 } 1242 } 1243 } 1244 1245 function skpSlideshowShow(tab_type, tab_id) { 1246 var has_only_one_object = JSON.parse($('[name="has_only_one_object"]').val() || 'true'); 1247 var is_layout_grid_and_one_object = typeof layoutFamily != 'undefined' && (has_only_one_object && layoutFamily == 'grid_list'); 1248 // Check if skpslideshows is present 1249 if ( 1250 (( 1251 tab_type == 'skugroup' && !is_layout_grid_and_one_object 1252 ) || ( 1253 tab_type == 'promo' 1254 )) 1255 && typeof skpslideshows != typeof undefined 1256 && skpslideshows 1257 ) { 1258 // for each load the wanted slideshow 1259 for(var position in skpslideshows) { 1260 skpslideshows[position].show(tab_type, tab_id); 1261 } 1262 } 1263 } 1264 1265 function skpSlideshowHide() { 1266 // Check if skpslideshows is present 1267 if (typeof skpslideshows != typeof undefined && skpslideshows) { 1268 // for each remove/stop/destroy/whatever skpslideshows because in promoTab we doesn't want slideshow 1269 for(var position in skpslideshows) { 1270 skpslideshows[position].hide(); 1271 } 1272 } 1273 } 1274 1275 function skpWelcomeMessage(id = null, is_promo = false, is_promo_offer = false) { 1276 // if slideshow is present, exit. We delegate this to slideshow function 1277 if (typeof skpslideshows != typeof undefined) { 1278 return; 1279 } 1280 1281 var welcomeScreen = $('#home-message'); 1282 1283 // Mobile behavior 1284 if (ZoStrap.isMobile()) { 1285 if (id == null) { 1286 // Show welcome message on mobile if we are in the list of shop tabs 1287 welcomeScreen.removeClass('js-hide'); 1288 } else { 1289 // Hide welcome message on mobile otherwise 1290 welcomeScreen.addClass('js-hide'); 1291 } 1292 return; 1293 } 1294 1295 // Desktop behavior 1296 if (is_promo && !is_promo_offer) { 1297 // Hide welcome message if we are in a promo tab 1298 welcomeScreen.addClass('js-hide'); 1299 } else { 1300 // Show welcome message if we are in shop tab, offer tab 1301 welcomeScreen.removeClass('js-hide'); 1302 } 1303 } 1304 1305 App.pageSetUp(function() { 1306 App.tab_content_query = "#js-buy-shoptab-container"; 1307 App.switchHtmlClass('shop-page-buy'); 1308 $('body').addClass('mobile-shoptab-list'); 1309 remove_configure_b2b_storage(); 1310 if (!is_promo && !is_promo_offer) { 1311 $('.tab-group').removeClass('active'); 1312 $('#Tab_' + active_tab_id).addClass('active'); 1313 } 1314 if (history.state != null && Object.keys(history.state).length > 0) { 1315 var oS = history.state; 1316 var current_tab, params; 1317 try { 1318 params = JSON.parse('{"' + decodeURI(oS.params).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"') + '"}'); 1319 } catch (err) { 1320 params = ''; 1321 } 1322 if (params.is_promo == '1' && params.is_promo_offer == '0') { 1323 current_tab = $('#Tab_promo_' + params.promo_connector_id); 1324 } else { 1325 current_tab = $('#Tab_' + params.skugroup_id); 1326 } 1327 if (current_tab.length > 0) { 1328 current_tab.siblings().attr('data-active', 'false').removeClass('active'); 1329 current_tab.attr('data-active', 'true').addClass('active'); 1330 1331 if (typeof App.globals.switchTab != 'undefined') { 1332 App.globals.switchTab.abort(); 1333 } 1334 var loaderHtml = '<div class="xs-relative" style="height:' 1335 + App.globals.loader_height 1336 + 'px;"><div class="loader active"><span></span></div></div>'; 1337 $(App.tab_content_query).html(loaderHtml); 1338 App.globals.switchTab = App.getHtml( 1339 oS.route, 1340 oS.params, 1341 App.tab_content_query, 1342 function() { 1343 delete App.globals.switchTab; 1344 if (params.is_promo == '1' && params.is_promo_offer == '0') { 1345 var id = params.promo_connector_id; 1346 } else { 1347 var id = params.skugroup_id; 1348 } 1349 if (ZoStrap.isMobile() && mobile_active_tab_id && mobile_active_tab_id == id) { 1350 $('.js-buy-content-header-back').remove(); 1351 } 1352 skpWelcomeMessage(id, params.is_promo == '1', params.is_promo_offer == '1'); 1353 if (params.is_promo == '0') {
1354 skpSlideshowShow('skugroup', params.skugroup_id); 1355 } else { 1356 skpSlideshowShow('promo', params.promo_connector_id); 1357 } 1358 } 1359 ); 1360 } else { 1361 var first_tab = $('.tab-group:first'); 1362 first_tab.addClass('active'); 1363 var first_tab_id = first_tab.data('id'); 1364 var first_tab_is_promo = first_tab.data('is_promo'); 1365 if (first_tab_is_promo) { 1366 if (typeof first_tab_id === 'string' || first_tab_id instanceof String) { 1367 first_tab_id = first_tab_id.replace('promo_', ''); 1368 } 1369 promoTab(first_tab_id); 1370 } else { 1371 switchTab(first_tab_id, true); 1372 } 1373 } 1374 } else { 1375 if (is_promo && !is_promo_offer) { 1376 promoTab(active_tab_id); 1377 } else if (is_promo_offer) { 1378 switchTab(active_tab_id, true); 1379 } else if (active_tab_id) { 1380 switchTab(active_tab_id, true); 1381 } else if (!ZoStrap.isMobile()) { 1382 var first_tab = $('.tab-group:first'); 1383 first_tab.addClass('active'); 1384 var first_tab_id = first_tab.data('id'); 1385 var first_tab_is_promo = first_tab.data('is_promo'); 1386 if (first_tab_is_promo) { 1387 if (typeof first_tab_id === 'string' || first_tab_id instanceof String) { 1388 first_tab_id = first_tab_id.replace('promo_', ''); 1389 } 1390 promoTab(first_tab_id); 1391 } else { 1392 switchTab(first_tab_id, true); 1393 } 1394 } else { 1395 if (mobile_active_tab_id) { 1396 switchTab(mobile_active_tab_id, true); 1397 } else { 1398 // For developers: Here I'm in the context where I don't have a skugroups. id = null 1399 skpWelcomeMessage(); 1400 skpSlideshowShow(); 1401 } 1402 } 1403 } 1404 tab_behavior(); 1405 1406 if (show_reminder_order_to_be_payed) { 1407 var top_message = '<div class="container xs-mb3 xs-z6" style="position: initial"><div class="page-message__text">' + 1408 'We see that you have a pending order.<ul><li>If you\'ve already completed the purchase on the payment website your payment is being processed and no action is needed</li><li>If you didn\'t complete the purchase on the payment website you can retrieve your order by clicking on the link below</li></ul>' + 1409 '<a href="javascript:void(0)" class="page-message__action" onclick="onClickReloadOrderToBePayed();">Re-add to cart<b></b></a>' + 1410 '</div>' + 1411 '<span class="page-message__close" data-dismiss="modal" type="button" onclick="onClickCloseOrderToBePayed();"></span></div>'; 1412 if ($('#js-top-user_merchant_message').is(':hidden')) 1413 { 1414 $('#js-top-user_merchant_message').html(top_message).fadeIn(400); 1415 } 1416 } 1417 var current_tab_id = $('.tab-group[data-active="true"]').data('id'); 1418 }); 1419</script--> 1420<!--script src="https://cloud.skiperformance.com/media/js/shop/widget/buy/booking_options.js"></script--> 1421 1422<!-- END OF PAGE CONTROLLER: Shop_Page_Buy - ACTION: home - VIEW: shop/pages/buy --></div> 1423 </div> 1424 1425 <div id="js-page-footer" class="page-footer-wrapper xs-z1 xs-text-center lg-text-left"> 1426 </div> 1427 1428 <!-- necessary for site to work --> 1429 <nav style="display:none;"> 1430 <ul> 1431<!-- NOTE: Notice the gaps after each icon usage <i></i>.. 1432Please note that these links work a bit different than 1433traditional href="" links. See documentation for details. 1434--> 1435 <li> 1436 <a href="/en/buy"><span class="menu-item-parent">Buy</span></a> 1437 </li> 1438 1439 <li> 1440 <a href="/en/basket"><span class="menu-item-parent">Cart</span><b class="collapse-sign"><em class="fa fa-plus-square-o"></em></b></a> 1441 <ul> 1442 <li> 1443 <a href="/en/buy/user_info?force=1"><span class="menu-item-parent">User Info</span><b class="collapse-sign"><em class="fa fa-plus-square-o"></em></b></a> 1444 <ul> 1445 <li> 1446 <a href="/en/buy/configure"><span class="menu-item-parent">Configure</span><b class="collapse-sign"><em class="fa fa-plus-square-o"></em></b></a> 1447 <ul> 1448 <li> 1449 <a href="/en/buy/review_and_pay"><span class="menu-item-parent">Review and Pay</span><b class="collapse-sign"><em class="fa fa-plus-square-o"></em></b></a> 1450 <ul> 1451 <li> 1452 <a href="/en/buy/confirm_purchase/OK"><span class="menu-item-parent">Confirm</span></a> 1453 </li> 1454 <li> 1455 <a href="/en/buy/confirm_purchase/OK"><span class="menu-item-parent">Confirm</span></a> 1456 </li> 1457 <li> 1458 <a href="/en/buy/confirm_purchase"><span class="menu-item-parent">Confirm</span></a> 1459 </li> 1460 <li> 1461 <a href="/en/buy/confirm_purchase"><span class="menu-item-parent">Confirm</span></a> 1462 </li> 1463 </ul> 1464 </li> 1465 </ul> 1466 </li> 1467 </ul> 1468 </li> 1469 <li> 1470 <a href="/en/buy/user_info"><span class="menu-item-parent">User Info</span><b class="collapse-sign"><em class="fa fa-plus-square-o"></em></b></a> 1471 <ul> 1472 <li> 1473 <a href="configure"><span class="menu-item-parent">Configure</span><b class="collapse-sign"><em class="fa fa-plus-square-o"></em></b></a> 1474 <ul> 1475 <li> 1476 <a href="review_and_pay"><span class="menu-item-parent">Review and Pay</span><b class="collapse-sign"><em class="fa fa-plus-square-o"></em></b></a> 1477 <ul> 1478 <li> 1479 <a href="confirm_ok"><span class="menu-item-parent">Confirm</span></a> 1480 </li> 1481 <li> 1482 <a href="confirm"><span class="menu-item-parent">Confirm</span></a> 1483 </li> 1484 </ul> 1485 </li> 1486 </ul> 1487 </li> 1488 </ul> 1489 </li> 1490 </ul> 1491 </li> 1492 1493 <li> 1494 <a href="/en/account"><span class="menu-item-parent">My Account</span><b class="collapse-sign"><em class="fa fa-plus-square-o"></em></b></a> 1495 <ul> 1496 <li> 1497 <a href="/en/personal_info"><span class="menu-item-parent">Manage profile</span></a> 1498 </li> 1499 <li> 1500 <a href="/en/manage_invoice"><span class="menu-item-parent">Company Profiles</span></a> 1501 </li> 1502 <li> 1503 <a href="/en/communication_preferences"><span class="menu-item-parent">Manage newsletters</span></a> 1504 </li> 1505 <li> 1506 <a href="/en/manage_password"><span class="menu-item-parent">Manage Password</span></a> 1507 </li> 1508 <li> 1509 <a href="/en/manage_Skicards"><span class="menu-item-parent">Manage Skicards</span></a> 1510 </li> 1511 <li> 1512 <a href="/en/manage_team"><span class="menu-item-parent">Manage team</span></a> 1513 </li> 1514 <li> 1515 <a href="/en/order_history"><span class="menu-item-parent">Order history</span><b class="collapse-sign"><em class="fa fa-plus-square-o"></em></b></a> 1516 <ul> 1517 <li> 1518 <a class="js-skp-breadcrumbs_fix" href="/en/order_details/:id?buy?skugroup_id=7103" data-href="/en/order_details/:id"><span class="menu-item-parent">Order Details</span><b class="collapse-sign"><em class="fa fa-plus-square-o"></em></b></a> 1519 <ul> 1520 <li> 1521 <a class="js-skp-breadcrumbs_fix" href="/en/order_details/:order_id/refund_request/:id?buy?skugroup_id=7103" data-href="/en/order_details/:order_id/refund_request/:id"><span class="menu-item-parent">Cancellation request</span></a> 1522 </li> 1523 <li> 1524 <a class="js-skp-breadcrumbs_fix" href="/en/order_details/:order_id/refund_request?buy?skugroup_id=7103" data-href="/en/order_details/:order_id/refund_request"><span class="menu-item-parent">Cancellation request</span></a> 1525 </li> 1526 </ul> 1527 </li> 1528 </ul> 1529 </li> 1530 <li> 1531 <a href="/en/manage_tickets"><span class="menu-item-parent">Tickets</span><b class="collapse-sign"><em class="fa fa-plus-square-o"></em></b></a> 1532 <ul> 1533 <li> 1534 <a class="js-skp-breadcrumbs_fix" href="/en/ticket_details?buy?skugroup_id=7103" data-href="/en/ticket_details"><span class="menu-item-parent">Ticket details</span></a> 1535 </li> 1536 </ul> 1537 </li> 1538 <li> 1539 <a href="/en/wallet"><span class="menu-item-parent">Wallet</span></a> 1540 </li> 1541 <li> 1542 <a href="/en/manage_account"><span class="menu-item-parent">Manage personal data</span></a> 1543 </li> 1544 <li> 1545 <a href="/en/b2b_manage_virtualcard"><span class="menu-item-parent">Manage Virtual Cards</span></a> 1546 </li> 1547 <li> 1548 <a href="/en/b2b_report"><span class="menu-item-parent">
1548Agent admin report</span></a> 1549 </li> 1550 </ul> 1551 </li> 1552 1553 <li> 1554 <a class="js-skp-breadcrumbs_fix" href="/en/guest/order_details/:id/:ref_num?buy?skugroup_id=7103" data-href="/en/guest/order_details/:id/:ref_num"><span class="menu-item-parent">Order Details</span><b class="collapse-sign"><em class="fa fa-plus-square-o"></em></b></a> 1555 <ul> 1556 <li> 1557 <a class="js-skp-breadcrumbs_fix" href="/en/guest/order_details/:order_id/:ref_num/refund_request/:id?buy?skugroup_id=7103" data-href="/en/guest/order_details/:order_id/:ref_num/refund_request/:id"><span class="menu-item-parent">Cancellation request</span></a> 1558 </li> 1559 <li> 1560 <a class="js-skp-breadcrumbs_fix" href="/en/guest/order_details/:order_id/:ref_num/refund_request?buy?skugroup_id=7103" data-href="/en/guest/order_details/:order_id/:ref_num/refund_request"><span class="menu-item-parent">Cancellation request</span></a> 1561 </li> 1562 </ul> 1563 </li> 1564 1565 <li> 1566 <a href="/en/support"><span class="menu-item-parent">Information</span><b class="collapse-sign"><em class="fa fa-plus-square-o"></em></b></a> 1567 <ul> 1568 <li> 1569 <a href="/en/support/service"><span class="menu-item-parent">Opening hours</span></a> 1570 </li> 1571 <li> 1572 <a href="/en/support/faq"><span class="menu-item-parent">FAQ</span></a> 1573 </li> 1574 1575 <li> 1576 <a href="/en/support/prices"><span class="menu-item-parent">Ticket prices</span></a> 1577 </li> 1578 </ul> 1579 </li> 1580 1581 <li> 1582 <ul> 1583 <li> 1584 <a href="/en/support/terms"><span class="menu-item-parent">Terms & Conditions</span><b class="collapse-sign"><em class="fa fa-plus-square-o"></em></b></a> 1585 </li> 1586 <li> 1587 <a href="/en/support/privacy"><span class="menu-item-parent">Privacy Policy</span></a> 1588 </li> 1589 <li> 1590 <a href="/en/support/cookie"><span class="menu-item-parent">Cookie Policy</span></a> 1591 </li> 1592 <li> 1593 <a href="/en/support/european_accessibility_act"><span class="menu-item-parent">Accessibility</span></a> 1594 </li> 1595 </ul> 1596 </li> 1597</ul> 1598 </nav> 1599 1600 <div id="no-browser-support" class="modal"> 1601 <div class="modal-dialog"> 1602 <header class="modal-header"> 1603 <!-- language menu --> 1604 <div id="js-modal_no_ie-header-lang_menu" class="zs-navbar xs-mt1-" style="display:none;"> 1605 <ul class="zs-dropdown-menu xs-float-right"> 1606 <li class="language-menu has-children"> 1607 <input type="checkbox" name="language_selector" id="language_selector_modal-ie8"> 1608 <label class="current-language top-level has-arrow pointer" for="language_selector_modal-ie8"> 1609 <img alt="en" src="https://cloud.skiperformance.com/media/img/flags/en.png" class="flag-icon"> 1610 EN </label> 1611 <ul class="dropdown-level-one caps"> 1612 <li> 1613 <a href="javascript:void(0)" onclick="App.goTo('https://shop.suedtirolskiarena.com/en/store#/en/buy');return false;" class="xs-nowrap"> 1614 <img alt="en" src="https://cloud.skiperformance.com/media/img/flags/en.png" class="flag-icon"> 1615 EN </a> 1616 </li> 1617 <li> 1618 <a href="javascript:void(0)" onclick="App.goTo('https://shop.suedtirolskiarena.com/it/negozio#/it/acquista');return false;" class="xs-nowrap"> 1619 <img alt="it" src="https://cloud.skiperformance.com/media/img/flags/it.png" class="flag-icon"> 1620 IT </a> 1621 </li> 1622 <li> 1623 <a href="javascript:void(0)" onclick="App.goTo('https://shop.suedtirolskiarena.com/de/store#/de/buy');return false;" class="xs-nowrap"> 1624 <img alt="de" src="https://cloud.skiperformance.com/media/img/flags/de.png" class="flag-icon"> 1625 DE </a> 1626 </li> 1627 </ul> 1628</li> 1629 </ul> 1630 </div> 1631 <!-- end language menu --> 1632 </header> 1633 <div class="modal-content"> 1634 <div style="margin-bottom: 16px;"><b>We're sorry, but this website does not support this browser.</b><br><br>Please upgrade to a modern browser.</div> 1635 <div> 1636 <a href="https://www.google.com/chrome/browser/desktop/index.html" target="_blank">Download the latest version of Google Chrome</a> </div> 1637 </div> 1638 </div> 1639 </div> 1640 1641 <!-- LOADING SPINNER --> 1642 <div class="modal fade modal-loader js-modal-z_order" id="ajax_loading" tabindex="-1" role="dialog" style="z-index: 1050; display: none;" aria-hidden="true"> 1643 <div class="modal-dialog" style="display: none;"> 1644 <div class="modal-content alert-info xs-text-center"> 1645 <div class="xs-relative xs-my1 xs-mx3" style="height: 60px;"> 1646 <div class="loader active"><span></span></div>
1647 </div> 1648 <h2 id="ajax_loading_text" class="xs-pt1">Loading...</h2> 1649 </div> 1650 </div> 1651 </div> 1652 <!-- END LOADING SPINNER --> 1653 1654 <!-- DIALOG BOX --> 1655 <div class="modal fade js-modal-z_order" id="message_box" tabindex="-1" role="dialog" style="display: none;"> 1656 <div class="modal-dialog"> 1657 <div class="modal-content"> 1658 <button type="button" class="modal__close close" data-dismiss="modal"><div class="zs-icon-close-thin main-color xs-text-24 js-zostrap-hide-modal"></div></button> 1659 <div class="modal__body xs-text-center"> 1660 <div id="message_text" class="message-text xs-mb0 bold"></div> 1661 <div id="message_text_extra"></div> 1662 </div> 1663 </div> 1664 </div> 1665 </div> 1666 <!-- END DIALOG BOX --> 1667 1668 1669 <!-- MODAL CONTAINER --> 1670 <div id="js-multi_modal_container" class="multi-modal2"> 1671 <!-- MODAL CONTENT - used on review page for update profile and language menu --> 1672 <div id="modal_content" class="modal fade" style="display:none"> 1673 <div id="modal-layout" class="modal-dialog"> 1674 <div class="modal__content"> 1675 <header class="modal__header"> 1676 <!-- language menu --> 1677 <div id="js-modal_content-header-lang_menu" class="modal-language-menu zs-navbar xs-pt1" style="display:none;"> 1678 <ul class="zs-dropdown-menu xs-float-right"> 1679 <li class="language-menu has-children"> 1680 <input type="checkbox" name="language_selector" id="language_selector_modal-content"> 1681 <label class="current-language top-level has-arrow pointer" for="language_selector_modal-content"> 1682 <img alt="en" src="https://cloud.skiperformance.com/media/img/flags/en.png" class="flag-icon"> 1683 EN </label> 1684 <ul class="dropdown-level-one caps"> 1685 <li> 1686 <a href="javascript:void(0)" onclick="App.goTo('https://shop.suedtirolskiarena.com/en/store#/en/buy');return false;" class="xs-nowrap"> 1687 <img alt="en" src="https://cloud.skiperformance.com/media/img/flags/en.png" class="flag-icon"> 1688 EN </a> 1689 </li> 1690 <li> 1691 <a href="javascript:void(0)" onclick="App.goTo('https://shop.suedtirolskiarena.com/it/negozio#/it/acquista');return false;" class="xs-nowrap"> 1692 <img alt="it" src="https://cloud.skiperformance.com/media/img/flags/it.png" class="flag-icon"> 1693 IT </a> 1694 </li> 1695 <li> 1696 <a href="javascript:void(0)" onclick="App.goTo('https://shop.suedtirolskiarena.com/de/store#/de/buy');return false;" class="xs-nowrap"> 1697 <img alt="de" src="https://cloud.skiperformance.com/media/img/flags/de.png" class="flag-icon"> 1698 DE </a> 1699 </li> 1700 </ul> 1701</li> 1702 </ul> 1703 </div> 1704 <!-- end language menu --> 1705 <a id="js-modal-close" class="modal__close" data-dismiss="modal"> 1706 <i class="zs-icon-close-thin main-color xs-text-24 js-zostrap-hide-modal"></i> 1707 </a> 1708 </header> 1709 <div id="modal_content_html" class="modal__body"></div> 1710 </div> 1711 </div> 1712 </div> 1713 <!-- END MODAL CONTENT --> 1714 <!-- DIALOG CONFIRM - used for yes or no questions --> 1715 <div class="modal fade js-modal-z_order zs" id="confirm_box" tabindex="-1" role="dialog" style="display: none;"> 1716 <div class="modal-dialog modal-dialog-sm"> 1717 <div class="modal-content alert-info delete-confirm"> 1718 <div id="confirm_message_text" class="bold xs-mb2"></div> 1719 <div class="xs-p1"> 1720 <button id="btn_NO" type="button" class="button button--secondary">No</button> 1721 <button id="btn_YES" type="button" class="button">Yes</button> 1722 </div> 1723 </div> 1724 </div> 1725 </div> 1726 <!-- END DIALOG CONFIRM --> 1727 </div> 1728 <!-- END MODAL CONTAINER --> 1729 1730 <!-- mobile menu links --> 1731 <!-- BEGINNING OF PAGE CONTROLLER: Shop_Widget_Mobile - ACTION: header_menu - VIEW: shop/widgets/menu/mobile_header_menu --> 1732<div id="js-zs-nav-mobile" class="mobile-menu zs-navbar xs-w4 js-zs-navbar xs-text-20"> 1733 <!-- close --> 1734 <div class="zs-accordion-menu-mobile-close pointer xs-text-right xs-p12 js-zs-accordion-menu-mobile-close" data-nav_id="js-zs-nav-mobile"> 1735 <i class="zs-icon-close-thin xs-text-28"></i> 1736 </div> 1737 <!-- menu --> 1738 <ul class="zs-accordion-menu animated js-zs-accordion-menu"> 1739 <li class="login-links xs-border-bottom xs-border-top"> 1740 <a href="#" onclick="App.openLoginModal();return false;" class="xs-nowrap">Sign in</a> 1741 <span class="xs-mx1-">/</span> 1742 <a href="#" onclick="App.openLoginModal('registration');return false;" class="xs-nowrap">Register</a> 1743 </li> 1744 <!--FRAGMENT returned: FRAG$shop.suedtirolskiarena.com$en$568$Controller_Shop$getSeasonMenu$mobile$1-->
1744 <!-- product menu --> 1745 <li class="product-menu has-children"> 1746 <input type="checkbox" name="mobile-menu-buy_tickets" id="mobile-menu-buy_tickets"> 1747 <label class="bold" for="mobile-menu-buy_tickets">Buy Tickets</label> 1748 <ul> 1749 <li><a href="#/en/buy?skugroup_id=7103">Südtirol Skipass 2027</a></li> 1750 <li><a href="#/en/buy?is_promo=1&promo_connector_id=356">Promo</a></li> 1751 </ul> 1752 </li> 1753 <!--FRAGMENT returned: FRAG$shop.suedtirolskiarena.com$en$568$Controller_Shop_Widget_Mobile$getProductMenuMobile--> <li class="has-children"> 1754 <input type="checkbox" name="nav-support" id="nav-support"> 1755 <label for="nav-support">Information</label> 1756 <ul> 1757 <li onclick="handleMenuItemClick()"><a href="#/en/support/prices">Ticket prices</a></li> 1758<li onclick="handleMenuItemClick()"><a href="#/en/support/service">Opening hours</a></li> 1759<li onclick="handleMenuItemClick()"><a href="#/en/support/faq">FAQ</a></li> 1760 1761<!--script> 1762 function handleMenuItemClick() { 1763 closeFooterMenuInformation(); 1764 } 1765</script--> 1766 </ul> 1767 </li> 1768 <li class="language-menu has-children"> 1769 <input type="checkbox" name="language_selector" id="language_selector_mobile"> 1770 <label class="current-language top-level has-arrow pointer" for="language_selector_mobile"> 1771 <img alt="en" src="https://cloud.skiperformance.com/media/img/flags/en.png" class="flag-icon"> 1772 Choose a language </label> 1773 <ul class="dropdown-level-one caps"> 1774 <li> 1775 <a href="javascript:void(0)" onclick="App.goTo('https://shop.suedtirolskiarena.com/en/store#/en/buy');return false;" class="xs-nowrap"> 1776 <img alt="en" src="https://cloud.skiperformance.com/media/img/flags/en.png" class="flag-icon"> 1777 EN </a> 1778 </li> 1779 <li> 1780 <a href="javascript:void(0)" onclick="App.goTo('https://shop.suedtirolskiarena.com/it/negozio#/it/acquista');return false;" class="xs-nowrap"> 1781 <img alt="it" src="https://cloud.skiperformance.com/media/img/flags/it.png" class="flag-icon"> 1782 IT </a> 1783 </li> 1784 <li> 1785 <a href="javascript:void(0)" onclick="App.goTo('https://shop.suedtirolskiarena.com/de/store#/de/buy');return false;" class="xs-nowrap"> 1786 <img alt="de" src="https://cloud.skiperformance.com/media/img/flags/de.png" class="flag-icon"> 1787 DE </a> 1788 </li> 1789 </ul> 1790</li> 1791 </ul> 1792</div> 1793 1794<!-- END OF PAGE CONTROLLER: Shop_Widget_Mobile - ACTION: header_menu - VIEW: shop/widgets/menu/mobile_header_menu --> 1795<!--================================================== --> 1796 1797<!--script src="https://cloud.skiperformance.com/media/js/bootstrap-modal.js"></script--> 1798<!--script src="https://cloud.skiperformance.com/media/js/jquery-validation/jquery.validate.min.js"></script--> 1799<!--script src="https://cloud.skiperformance.com/media/js/jquery-validation/localization/messages_en.min.js"></script--> 1800<!--script src="https://cloud.skiperformance.com/media/js/skp/jquery.validate.step.js"></script--> 1801<!--script src="https://cloud.skiperformance.com/media/js/skp/skpmenu.js"></script--> 1802 <!--FRAGMENT echoed: FRAG$shop.suedtirolskiarena.com$en$568$js_17_outer_page_scripts--> 1803<!--script type="text/javascript"> 1804 // global settings to disable the new gtag tracking system 1805 window.skp_gtag_enabled = true; 1806 1807 // this disables only the customer tracking codes 1808 window.skp_gtag_customer_tracking_enabled = true; 1809</script--> 1810 1811<!--script> 1812 function Skp_Tracking_Event(name, params, type) { 1813 this._name = name; 1814 this._params = params; 1815 this._type = type; 1816 /** 1817 * @descr we can prevent the event from firing 1818 * @param {Skp_TrackingCode} tracking_code 1819 * @return {boolean} 1820 */ 1821 this.canBeFired = function(tracking_code) { 1822 return !!tracking_code.shouldAllowClientSideEvent(this); 1823 }; 1824 1825 this.getParams = function() { 1826 return this._params; 1827 }; 1828 1829 this.setParams = function(params) { 1830 this._params = params; 1831 }; 1832 1833 this.setType = function(type) { 1834 this._type = type; 1835 }; 1836 1837 this.getType = function() { 1838 return this._type; 1839 }; 1840 1841 this.getName = function() { 1842 return this._name; 1843 }; 1844 1845 /** 1846 * This needs to be implemented on specific events. 1847 * 1848 * @param {Skp_TrackingCode} tracking_code 1849 * @param {Skp_Tracker_Abstract} tracker 1850 * 1851 * @return {boolean} 1852 */ 1853 this.shouldFire = function(tracking_code, tracker) { 1854 // get the tracking system
1855 var tracking_system = Skp_TrackingSystem.getInstance(); 1856 return true; 1857 }; 1858 } 1859</script--> 1860<!--script> 1861 function Skp_Tracking_Event_Pageview(name, params, type) { 1862 Skp_Tracking_Event.call(this, name); 1863 this._name = 'page_view'; 1864 1865 /** 1866 * 1867 * @param {Skp_TrackingCode} tracking_code 1868 * @param {Skp_Tracker_Gtag} tracker 1869 * @return {boolean} 1870 */ 1871 this.shouldFire = function(tracking_code, tracker) { 1872 return true; 1873 }; 1874 } 1875 1876 Skp_Tracking_Event_Pageview.prototype = Object.create(Skp_Tracking_Event.prototype); 1877 Skp_Tracking_Event_Pageview.prototype.constructor = Skp_Tracking_Event; 1878</script--> 1879<!--script> 1880 function Skp_Tracking_Event_AddToCart(name, params, type) { 1881 Skp_Tracking_Event.call(this, name); 1882 this._name = 'add_to_cart'; 1883 1884 /** 1885 * @param {Skp_TrackingCode} tracking_code 1886 * @param {Skp_Tracker_Gtag} tracker 1887 * 1888 * @return {boolean} 1889 */ 1890 this.shouldFire = function(tracking_code, tracker) { 1891 return true; 1892 }; 1893 } 1894 1895 Skp_Tracking_Event_AddToCart.prototype = Object.create(Skp_Tracking_Event.prototype); 1896 Skp_Tracking_Event_AddToCart.prototype.constructor = Skp_Tracking_Event; 1897 1898 Skp_Tracking_Event_AddToCart.buildGa4Params = function(item) { 1899 return { 1900 items: [ 1901 { 1902 item_id: item['sku_id'], 1903 item_name: item['sku_name'], 1904 item_category: item['category'], 1905 currency: item['currency'], 1906 price: parseFloat(item['price']), 1907 quantity: parseFloat(item['qty']), 1908 custom_params: { 1909 order_id: item['order_id'], 1910 }, 1911 } 1912 ], 1913 }; 1914 }; 1915 1916 Skp_Tracking_Event_AddToCart.buildGa4Event = function(item) { 1917 var gtag_params = Skp_Tracking_Event_AddToCart.buildGa4Params(item); 1918 var event = new Skp_Tracking_Event_AddToCart(); 1919 event.setParams(gtag_params); 1920 event.setType('ga4'); 1921 return event; 1922 }; 1923</script--> 1924<!--script> 1925 function Skp_Tracking_Event_RemoveFromCart(name, params, type) { 1926 Skp_Tracking_Event.call(this, name); 1927 this._name = 'remove_from_cart'; 1928 1929 /** 1930 * @param {Skp_TrackingCode} tracking_code 1931 * @param {Skp_Tracker_Gtag} tracker 1932 * 1933 * @return {boolean} 1934 */ 1935 this.shouldFire = function(tracking_code, tracker) { 1936 return true; 1937 }; 1938 } 1939 1940 Skp_Tracking_Event_RemoveFromCart.prototype = Object.create(Skp_Tracking_Event.prototype); 1941 Skp_Tracking_Event_RemoveFromCart.prototype.constructor = Skp_Tracking_Event; 1942 1943 Skp_Tracking_Event_RemoveFromCart.buildGa4Params = function(item) { 1944 return { 1945 items: [ 1946 { 1947 item_id: item['sku_id'], 1948 item_name: item['sku_name'], 1949 item_category: item['category'], 1950 currency: item['currency'], 1951 price: parseFloat(item['price']), 1952 quantity: parseFloat(item['qty']), 1953 custom_params: { 1954 order_id: item['order_id'], 1955 }, 1956 } 1957 ], 1958 }; 1959 }; 1960 1961 Skp_Tracking_Event_RemoveFromCart.buildGa4Event = function(item) { 1962 var gtag_params = Skp_Tracking_Event_RemoveFromCart.buildGa4Params(item); 1963 var event = new Skp_Tracking_Event_RemoveFromCart(); 1964 event.setParams(gtag_params); 1965 event.setType('ga4'); 1966 return event; 1967 }; 1968</script--> 1969<!--script> 1970 function Skp_Tracking_Event_Purchase(name, params, type) { 1971 Skp_Tracking_Event.call(this, name); 1972 this._name = 'purchase'; 1973 1974 this.shouldFire = function(tracking_code, tracker) { 1975 //var tracking_system=Skp_TrackingSystem.getInstance(); 1976 1977 return true; 1978 }; 1979 1980 } 1981 1982 Skp_Tracking_Event_Purchase.prototype = Object.create(Skp_Tracking_Event.prototype); 1983 Skp_Tracking_Event_Purchase.prototype.constructor = Skp_Tracking_Event; 1984 1985 Skp_Tracking_Event_Purchase.buildGa4Params = function(items, transaction) { 1986 return { 1987 'transaction_id': transaction['order_id'], 1988 'value': parseFloat(transaction['amount']), 1989 'tax': parseFloat(transaction['vat']), 1990 'affiliation': transaction['merchant_name'], 1991 'currency': transaction['currency'], 1992 'shipping': 0, 1993 'items': items, 1994 }; 1995 }; 1996 1997 Skp_Tracking_Event_Purchase.buildGa4Event = function(items, transaction) { 1998 var gtag_params = Skp_Tracking_Event_Purchase.buildGa4Params(items, transaction); 1999 var event = new Skp_Tracking_Event_Purchase(); 2000 event.setParams(gtag_params); 2001 event.setType('ga4'); 2002 return event; 2003 }; 2004</script--> 2005<!--script> 2006 function Skp_Tracking_Event_Refund(name, params, type) { 2007 Skp_Tracking_Event.call(this, name); 2008 this._name = 'refund'; 2009 2010 this.shouldFire = function(tracking_code, tracker) { 2011 //var tracking_system=Skp_TrackingSystem.getInstance(); 2012 2013 return true; 2014 }; 2015 2016 } 2017 2018 Skp_Tracking_Event_Refund.prototype = Object.create(Skp_Tracking_Event.prototype); 2019 Skp_Tracking_Event_Refund.prototype.constructor = Skp_Tracking_Event_Refund; 2020
2021 Skp_Tracking_Event_Refund.buildGa4Params = function(items, transaction) { 2022 return { 2023 'transaction_id': transaction['order_id'], 2024 'value': parseFloat(transaction['amount']), 2025 'tax': parseFloat(transaction['vat']), 2026 'affiliation': transaction['merchant_name'], 2027 'currency': transaction['currency'], 2028 'shipping': 0, 2029 'items': items, 2030 }; 2031 }; 2032 2033 Skp_Tracking_Event_Refund.buildGa4Event = function(items, transaction) { 2034 var gtag_params = Skp_Tracking_Event_Refund.buildGa4Params(items, transaction); 2035 var event = new Skp_Tracking_Event_Refund(); 2036 event.setParams(gtag_params); 2037 event.setType('ga4'); 2038 return event; 2039 }; 2040</script--> 2041<!--script> 2042 function Skp_Tracking_Event_ViewItem(name, params, type) { 2043 Skp_Tracking_Event.call(this, name); 2044 this._name = 'view_item'; 2045 2046 /** 2047 * @param {Skp_TrackingCode} tracking_code 2048 * @param {Skp_Tracker_Gtag} tracker 2049 * 2050 * @return {boolean} 2051 */ 2052 this.shouldFire = function(tracking_code, tracker) { 2053 return true; 2054 }; 2055 } 2056 2057 Skp_Tracking_Event_ViewItem.prototype = Object.create(Skp_Tracking_Event.prototype); 2058 Skp_Tracking_Event_ViewItem.prototype.constructor = Skp_Tracking_Event; 2059</script--> 2060<!--script> 2061 function Skp_Tracking_Event_ViewItemList(name, params, type) { 2062 Skp_Tracking_Event.call(this, name); 2063 this._name = 'view_item_list'; 2064 2065 /** 2066 * @param {Skp_TrackingCode} tracking_code 2067 * @param {Skp_Tracker_Gtag} tracker 2068 * 2069 * @return {boolean} 2070 */ 2071 this.shouldFire = function(tracking_code, tracker) { 2072 return true; 2073 }; 2074 } 2075 2076 Skp_Tracking_Event_ViewItemList.prototype = Object.create(Skp_Tracking_Event.prototype); 2077 Skp_Tracking_Event_ViewItemList.prototype.constructor = Skp_Tracking_Event; 2078</script--> 2079<!--script> 2080 function Skp_Tracking_Event_BeginCheckout(name, params, type) { 2081 Skp_Tracking_Event.call(this, name); 2082 this._name = 'begin_checkout'; 2083 2084 /** 2085 * @param {Skp_TrackingCode} tracking_code 2086 * @param {Skp_Tracker_Gtag} tracker 2087 * 2088 * @return {boolean} 2089 */ 2090 this.shouldFire = function(tracking_code, tracker) { 2091 return true; 2092 }; 2093 } 2094 2095 Skp_Tracking_Event_BeginCheckout.prototype = Object.create(Skp_Tracking_Event.prototype); 2096 Skp_Tracking_Event_BeginCheckout.prototype.constructor = Skp_Tracking_Event; 2097</script--> 2098 2099<!--script type="text/javascript"> 2100 function Skp_UserProperties(properties) { 2101 this._properties = properties; 2102 this.getProperties = function() { 2103 return this._properties; 2104 }; 2105 2106 this.getAgeRange = function() { 2107 return this._properties['age_range']; 2108 }; 2109 2110 this.getUserId = function() { 2111 return this._properties['user_id']; 2112 }; 2113 2114 } 2115 2116 function Skp_Shop_Item(item, transaction) { 2117 this._item = item; 2118 this._transaction = transaction; 2119 2120 this.getItem = function() { 2121 return this._item; 2122 }; 2123 2124 this.getTransaction = function() { 2125 return this._transaction; 2126 }; 2127 2128 this.setTransaction = function(transaction) { 2129 this._transaction = transaction; 2130 }; 2131 } 2132 2133 function Skp_Shop_Items_Purchase(transaction, items, tracker_items) { 2134 this._items = items; 2135 this._transaction = transaction; 2136 2137 this._tracker_items = tracker_items; 2138 2139 this.getItems = function() { 2140 return this._items; 2141 }; 2142 2143 this.getTrackerItems = function() { 2144 return this._tracker_items; 2145 }; 2146 2147 this.getTransaction = function() { 2148 return this._transaction; 2149 }; 2150 2151 this.setTransaction = function(transaction) { 2152 this._transaction = transaction; 2153 }; 2154 2155 this.setOrderId = function(id) { 2156 this._transaction['order_id'] = id; 2157 for (var i in this._items) { 2158 this._items[i]['_item']['order_id'] = id; 2159 } 2160 }; 2161 } 2162 2163 function Skp_Shop_Items_Refund(transaction, items, tracker_items) { 2164 this._items = items; 2165 this._transaction = transaction; 2166 2167 this._tracker_items = tracker_items; 2168 2169 this.getItems = function() { 2170 return this._items; 2171 }; 2172 2173 this.getTrackerItems = function() { 2174 return this._tracker_items; 2175 }; 2176 2177 this.getTransaction = function() { 2178 return this._transaction; 2179 }; 2180 2181 this.setTransaction = function(transaction) { 2182 this._transaction = transaction; 2183 }; 2184 2185 this.setOrderId = function(id) { 2186 this._transaction['order_id'] = id; 2187 for (var i in this._items) { 2188 this._items[i]['_item']['order_id'] = id; 2189 } 2190 }; 2191 } 2192 2193 function Skp_TrackingCode(code, type) { 2194 this._code = code; 2195 this._type = type; 2196 this._active = true; 2197 this._events_config = {}; 2198 this._server_enabled = false;
2199 this._debug_mode = false; 2200 2201 this._descr = null; 2202 this._owner = null; 2203 this._partners = Array(); 2204 this._groups = Array(); 2205 2206 this.enableServerSide = function(enable) { 2207 this._server_enabled = enable; 2208 }; 2209 2210 this.enableDebugMode = function(enable) { 2211 this._debug_mode = enable; 2212 }; 2213 2214 this.isDebugModeEnabled = function() { 2215 return this._debug_mode; 2216 }; 2217 2218 this.isServerSideEnabled = function() { 2219 return this._server_enabled; 2220 }; 2221 2222 this.setEventsConfig = function(config) { 2223 this._events_config = config; 2224 }; 2225 2226 this.shouldAllowClientSideEvent = function(event) { 2227 return this.hasClientSideEvent(event); 2228 }; 2229 2230 this.hasClientSideEvent = function (event) { 2231 if (Skp_TrackingSystem.getInstance().shouldAlwaysFireClientSide()) { 2232 return true; 2233 } 2234 2235 var event_name = event.getName(); 2236 2237 if (this._events_config.hasOwnProperty(event_name)) { 2238 return this._events_config[event_name] === 'c'; 2239 } 2240 var events_config = Skp_TrackingSystem.getInstance().getEventsConfig(); 2241 if (!events_config.hasOwnProperty(event_name)) { 2242 // no specific rules so consider allowed 2243 return true; 2244 } 2245 if (events_config[event_name] === 'c') { 2246 return true; 2247 } 2248 2249 return !this.isServerSideEnabled(); 2250 }; 2251 2252 this.setOwner = function(owner) { 2253 this._owner = owner; 2254 }; 2255 2256 this.getOwner = function() { 2257 return this._owner; 2258 }; 2259 2260 this.addGroup = function(name) { 2261 return this._groups.push(name); 2262 }; 2263 2264 this.hasGroup = function(name) { 2265 for (var i = 0; i < this._groups.length; i++) { 2266 if (this._groups[i] === name) { 2267 return true; 2268 } 2269 } 2270 return false; 2271 }; 2272 2273 this.addPartner = function(partner) { 2274 this._partners.push(partner); 2275 }; 2276 2277 this.getPartners = function() { 2278 return this._partners; 2279 }; 2280 2281 this.getGroups = function() { 2282 return this._groups; 2283 }; 2284 2285 this._type = Skp_TrackingCode.getTypeCode(type); 2286 2287 this.getCode = function() { 2288 return this._code; 2289 }; 2290 2291 this.setCode = function(code) { 2292 this._code = code; 2293 }; 2294 2295 this.getType = function() { 2296 return this._type; 2297 }; 2298 2299 this.activate = function(activ) { 2300 this._active = activ; 2301 }; 2302 2303 this.enable = function(activ) { 2304 2305 this._active = activ; 2306 }; 2307 } 2308 2309 2310 Skp_TrackingCode.getTypeCode = function(descr) { 2311 var code = descr; 2312 if (descr === 'Google Analytics (gtag)' || descr === 'Google Analytics (gtag) - DEBUG ONLY') { 2313 code = 'ga4'; 2314 } else if (descr === 'Google Tag Manager' || descr === 'Google Tag Manager - DEBUG ONLY') { 2315 code = 'tagmanager'; 2316 } 2317 return code; 2318 }; 2319 2320 function Skp_TrackingCode_Gtag(code, type) { 2321 Skp_TrackingCode.call(this, code); 2322 } 2323 2324 Skp_TrackingCode_Gtag.prototype = Object.create(Skp_TrackingCode.prototype); 2325 Skp_TrackingCode_Gtag.prototype.constructor = Skp_TrackingCode; 2326 2327 function Skp_TrackingCode_Gtag_Tagmanager(code) { 2328 this._fullcode = code; 2329 var splitted_code = code.split('/'); 2330 code = splitted_code[0]; 2331 2332 Skp_TrackingCode.call(this, code, 'tagmanager'); 2333 this.getFullCode = function() { 2334 return this._fullcode; 2335 }; 2336 } 2337 2338 Skp_TrackingCode_Gtag_Tagmanager.prototype = Object.create(Skp_TrackingCode_Gtag.prototype); 2339 Skp_TrackingCode_Gtag_Tagmanager.prototype.constructor = Skp_TrackingCode_Gtag; 2340 2341 function Skp_TrackingSystem() { 2342 this._always_fire_client_side = true; 2343 2344 this._trace_enabled = true; 2345 2346 this._simulate_new_order = false; 2347 2348 this._fake_order = 0; 2349 2350 this._trackings_added = false; 2351 this._skp_ga_4 = null; 2352 this._events_config = null; 2353 2354 this._trackers = Array(); 2355 this._tracking_codes = null; 2356 this._tracking_codes_remove = null; 2357 2358 this._handlers = new Object(); 2359 this._handlers_id_counter = 0; 2360 2361 this._on_ready_status = 0; 2362 2363 this._items = Array(); 2364 2365 this._user_properties = null; 2366 2367 this.shouldAlwaysFireClientSide = function () { 2368 return this._always_fire_client_side; 2369 } 2370 2371 this.setUserProperties = function(user_properties) { 2372 this._user_properties = new Skp_UserProperties(user_properties); 2373 return this._user_properties; 2374 }; 2375 2376 this.handleEvent = function(evtname, params) { 2377 for (var i in params.addItem) { 2378 if (evtname === 'add_to_cart') { 2379 this._execTrackersFunction('sendAddToCartEvent', params.addItem[i]); 2380 } 2381 } 2382 for (var i in params.removeItem) { 2383 if (evtname === 'remove_from_cart') { 2384 this._execTrackersFunction('sendRemoveFromCartEvent', params.removeItem[i]); 2385 } 2386 } 2387 if (evtname === 'view_item') { 2388 this._execTrackersFunction('sendViewItemEvent', params); 2389 } 2390 if (evtname === 'view_item_list') { 2391 this._execTrackersFunction('sendViewItemListEvent', params); 2392 } 2393 if (evtname === 'begin_checkout') { 2394 this._execTrackersFunction('sendBeginCheckoutEvent', params); 2395 } 2396 if (evtname === 'purchase') { 2397 this._execTrackersFunction('sendPurchaseEvent', params); 2398 } 2399 if (evtname === 'refund') { 2400 this._execTrackersFunction('sendRefundEvent', params); 2401 } 2402 }; 2403 2404 /** 2405 * @return {Skp_UserProperties} 2406 */ 2407 this.getUserProperties = function() { 2408 return this._user_properties; 2409 }; 2410 2411 this.getNewTestOrder = function() { 2412 return Math.floor(Math.random() * 9999999999); 2413 }; 2414 2415 if (this._simulate_new_order) { 2416 this._fake_order = this.getNewTestOrder(); 2417 } 2418 2419 this.enableSimulateNewOrder = function() { 2420 this._simulate_new_order = true; 2421 this._fake_order = this.getNewTestOrder(); 2422 }; 2423 2424 /** 2425 * 2426 * @return {Skp_Tracker_Abstract[]} 2427 */ 2428 this.getTrackers = function() { 2429 return this._trackers; 2430 }; 2431 2432 /** 2433 * @param {function} callback 2434 */ 2435 this.whenReady = function(callback) { 2436 var self = this; 2437 if (this._on_ready_status != 5) { 2438 setTimeout( 2439 function() { 2440 self.whenReady(callback); 2441 }, 10 2442 ); 2443 return; 2444 } 2445 callback(); 2446 }; 2447 2448 this.handleEvent = function(evtname, params) { 2449 if (evtname === 'view_item') { 2450 this.sendViewItemEvent(params); 2451 } 2452 if (evtname === 'view_item_list') { 2453 this.sendViewItemListEvent(params.items, params.list_id, params.list_name); 2454 } 2455 if (evtname === 'begin_checkout') { 2456 this.sendBeginCheckoutEvent(params.items, params.value, params.currency); 2457 } 2458 if (evtname === 'add_to_cart') { 2459 if ( 2460 typeof params.addItem !== 'undefined' && 2461 (Array.isArray(params.addItem) || typeof params.addItem === 'object') 2462 ) { 2463 if (typeof params.addItem === 'object') { 2464 var order_items = Object.values(params.addItem); 2465 } else { 2466 var order_items = params.addItem; 2467 } 2468 this.sendAddToCartEvent(order_items); 2469 } 2470 } 2471 if (evtname === 'remove_from_cart') { 2472 if ( 2473 typeof params.removeItem !== 'undefined' && 2474 (Array.isArray(params.removeItem) || typeof params.removeItem === 'object') 2475 ) { 2476 if (typeof params.removeItem === 'object') { 2477 var order_items = Object.values(params.removeItem); 2478 } else { 2479 var order_items = params.removeItem; 2480 } 2481 this.sendRemoveFromCartEvent(order_items); 2482 } 2483 } 2484 }; 2485 2486 /** 2487 * @param {function} handler 2488 * @param id 2489 */ 2490 this.onReady = function(handler, id) { 2491 if (!id) { 2492 id = 'id_' + this._handlers_id_counter; 2493 this._handlers_id_counter++; 2494 } 2495 this.addHandler('onReady', id, handler); 2496 }; 2497 2498 this.addHandler = function(when, id, funct) { 2499 if (!this._handlers.hasOwnProperty(when)) { 2500 this._handlers[when] = {}; 2501 } 2502 2503 this._handlers[when][id] = funct; 2504 return this; 2505 }; 2506 2507 this.log = function(msg) { 2508 App.log(msg); 2509 }; 2510 2511 this.trace = function(msg) { 2512 var prefix = 'TrackingSystem -> '; 2513 if (!this._trace_enabled) { 2514 return; 2515 } 2516 typeof msg === 'object' || Array.isArray(msg) ? 2517 (this.log(prefix + JSON.stringify(msg)), this.log(msg)) : 2518 this.log(prefix + msg); 2519 }; 2520 2521 this._execHandlers = function(hdl_type, evt) { 2522 var on_ready_check = false;
2523 if (hdl_type === 'onReady') { 2524 this.trace('firing onReady'); 2525 on_ready_check = true; 2526 } 2527 2528 if (this._handlers[hdl_type]) { 2529 var keys = Object.keys(this._handlers[hdl_type]); 2530 2531 if (on_ready_check) { 2532 this.trace('handling onReady'); 2533 } 2534 for (var key in this._handlers[hdl_type]) { 2535 this._handlers[hdl_type][key](evt, this); 2536 } 2537 } 2538 }; 2539 2540 /** 2541 * 2542 * @return {Skp_Tracker_Abstract[]} 2543 */ 2544 this.getTrackersIds = function() { 2545 var ids = []; 2546 for (var i in this._trackers) { 2547 ids.push(this._trackers[i].getId()); 2548 } 2549 return ids; 2550 }; 2551 2552 this.isReady = function() { 2553 for (var i in this._trackers) { 2554 if (!this._trackers[i].isReady()) { 2555 return false; 2556 } 2557 } 2558 return true; 2559 }; 2560 2561 /** 2562 * 2563 * @param id 2564 * @return {Skp_Tracker_Abstract} 2565 */ 2566 this.getTrackerById = function(id) { 2567 for (i in this._trackers) { 2568 if (this._trackers[i].getId() === id) { 2569 return this._trackers[i]; 2570 } 2571 } 2572 return null; 2573 }; 2574 2575 /** 2576 * @param id 2577 * @return {Skp_Tracker_Gtag} 2578 */ 2579 this.getTrackerGtag = function(id) { 2580 return this.getTrackerById('gtag'); 2581 }; 2582 2583 this.resetItems = function() { 2584 this.trace('Resetting Items'); 2585 for (var i in this._trackers) { 2586 this._trackers[i].resetItems(); 2587 } 2588 this._items = Array(); 2589 }; 2590 2591 this.addNewItem = function(item, transaction) { 2592 this.trace('Adding new Item'); 2593 var item_instance = new Skp_Shop_Item(item, transaction); 2594 for (var i in this._trackers) { 2595 this._trackers[i].addItem(item_instance); 2596 } 2597 this.addItem(item_instance); 2598 }; 2599 2600 this.isObject = function(val) { 2601 return typeof val === 'object' 2602 && !Array.isArray(val) 2603 && val !== null; 2604 }; 2605 2606 this.addItem = function(item) { 2607 this._items.push(item); 2608 }; 2609 2610 this._execTrackersFunction = function(fname, params) { 2611 for (var i in this._trackers) { 2612 var built_event = null; 2613 var tracker = this._trackers[i]; 2614 if (fname === 'sendPurchaseEvent') { 2615 var shop_purchase = this.buildShopItemsPurchase(params, this._items, tracker.getTrackerItems()); 2616 if (this._simulate_new_order) { 2617 this._trackers[i]._simulate_new_order = this._simulate_new_order; 2618 this._trackers[i]._fake_order = this._fake_order; 2619 shop_purchase.setOrderId(this._fake_order); 2620 } 2621 built_event = this._trackers[i][fname](shop_purchase); 2622 } else if (fname === 'sendAddToCartEvent') { 2623 var shop_items = this.buildShopItems(params); 2624 built_event = this._trackers[i][fname](shop_items); 2625 } else if (fname === 'sendRemoveFromCartEvent') { 2626 var shop_items = this.buildShopItems(params); 2627 built_event = this._trackers[i][fname](shop_items); 2628 } else { 2629 if (this._trackers[i][fname]) { 2630 built_event = this._trackers[i][fname](params); 2631 } 2632 } 2633 2634 if (this.isObject(built_event)) { 2635 if (this._trackers[i]._fireEvent) { 2636 this._trackers[i]._fireEvent(built_event); 2637 } 2638 } 2639 } 2640 2641 }; 2642 2643 this.setDimensions = function(dimensions) { 2644 this._execTrackersFunction('setDimensions', dimensions); 2645 }; 2646 2647 this.sendUserPropertiesEvent = function(user_properties) { 2648 var userprops = this.setUserProperties(user_properties); 2649 this._execTrackersFunction('sendUserPropertiesEvent', userprops); 2650 }; 2651 2652 this.sendNavigationEvent = function(params) { 2653 this._execTrackersFunction('sendNavigationEvent', params); 2654 }; 2655 2656 this.sendPageViewEvent = function(params) { 2657 this._execTrackersFunction('sendPageViewEvent', params); 2658 }; 2659 2660 this.sendAddToCartEvent = function(items) { 2661 this._execTrackersFunction('sendAddToCartEvent', items); 2662 }; 2663 2664 this.sendRemoveFromCartEvent = function(items) { 2665 this._execTrackersFunction('sendRemoveFromCartEvent', items); 2666 }; 2667 2668 this.sendViewItemEvent = function(item_data) { 2669 this._execTrackersFunction('sendViewItemEvent', item_data); 2670 }; 2671 2672 this.sendViewItemListEvent = function(items_data) { 2673 this._execTrackersFunction('sendViewItemListEvent', { items: items_data.items, list_id: items_data.list_id, list_name: items_data.list_name }); 2674 }; 2675 2676 this.sendBeginCheckoutEvent = function(items_data) { 2677 this._execTrackersFunction('sendBeginCheckoutEvent', { items: items_data.items, value: items_data.value, currency: items_data.currency }); 2678 }; 2679 2680 /** 2681 * @param transaction 2682 * @return {Skp_Shop_Items_Purchase} 2683 */ 2684 this.buildShopItemsPurchase = function(transaction, items, tracker_items) { 2685 return new Skp_Shop_Items_Purchase(transaction, items, tracker_items); 2686 }; 2687 2688 /** 2689 * @param transaction 2690 * @return {Skp_Shop_Items_Refund} 2691 */ 2692 this.buildShopItemsRefund = function(transaction, items, tracker_items) { 2693 return new Skp_Shop_Items_Refund(transaction, items, tracker_items); 2694 }; 2695 2696 /** 2697 * @param item 2698 * @return {Skp_Shop_Item} 2699 */ 2700 this.buildShopItem = function(item) { 2701 return new Skp_Shop_Item(item); 2702 }; 2703 2704 /** 2705 * @param items 2706 * @return {Skp_Shop_Item[]} 2707 */ 2708 this.buildShopItems = function(items) { 2709 var shop_items = Array(); 2710 for (var i in items) { 2711 shop_items.push(this.buildShopItem(items[i])); 2712 } 2713 return shop_items; 2714 }; 2715 2716 this.sendPurchaseEvent = function(transaction) { 2717 this._execTrackersFunction('sendPurchaseEvent', transaction); 2718 }; 2719 2720 this.isGa4Enabled = function(enab) { 2721 return true; 2722 }; 2723
2724 this.getSkpGa4Code = function() { 2725 return this._skp_ga_4; 2726 }; 2727 2728 this.isSkpGa4ServerEnabled = function() { 2729 return this._skp_ga_4_server; 2730 }; 2731 2732 /** 2733 * 2734 * @param {Skp_Tracker_Abstract} tracker 2735 */ 2736 this.addTracker = function(tracker, id) { 2737 id = typeof id !== 'undefined' ? id : tracker.getId(); 2738 tracker._id = id; 2739 this._trackers.push(tracker); 2740 }; 2741 2742 this.getEventsConfig = function () { 2743 return this._events_config; 2744 }; 2745 2746 this.getDomainAndSubdomains = function () { 2747 var hostname = window.location.hostname; 2748 var parts = hostname.split('.'); 2749 var result = []; 2750 2751 for (var i = 0; i < parts.length; i++) { 2752 if (parts.slice(i).length > 1) { 2753 var domain = parts.slice(i).join('.'); 2754 result.push(domain); 2755 } 2756 } 2757 return result; 2758 } 2759 2760 this.stopTracking=function (tracking_code) 2761 { 2762 var cookie_name= tracking_code.replace('G-','_ga_'); 2763 var domains = this.getDomainAndSubdomains(); 2764 for(var i in domains) { 2765 document.cookie = cookie_name + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;domain=."+domains[i]; 2766 } 2767 } 2768 2769 /** 2770 * 2771 * @param callback 2772 * @param App 2773 */ 2774 this.setup = function(callback, App) { 2775 //ensure we are adding tracking only once 2776 if (this._trackings_added) { 2777 return; 2778 } 2779 this.app= App; 2780 var self = this; 2781 2782 this._trackings_added = true; 2783 App._trackings_added = true; 2784 this._events_config = App.events_config; 2785 2786 this._skp_ga_4 = App.skp_ga_4; 2787 this._skp_ga_4_server = App.skp_ga_4_main_tc_server; 2788 this._tracking_codes = App.tracking_codes; 2789 this._tracking_codes_remove = App.tracking_codes_remove; 2790 2791 for (var i = 0; i < this._tracking_codes_remove.length; i++) { 2792 var tc = this._tracking_codes_remove[i]; 2793 if (tc.type === 'Google Analytics (gtag)') { 2794 this.stopTracking(tc.code); 2795 } 2796 } 2797 this.trace('Setting up Trackers'); 2798 2799 this._on_ready_status = 4; 2800 var self = this; 2801 2802 this._setupTrackers(this._tracking_codes, 2803 function() { 2804 self._execHandlers('onReady', new Skp_Tracking_Event('ready', self)); 2805 self.trace('Trackers All set'); 2806 self._on_ready_status = 5; 2807 callback(); 2808 } 2809 ); 2810 // Next we will set up Fb pixel and Tagmanager and any other 2811 }; 2812 2813 this._current_tracker_idx = 0; 2814 2815 this._setupTrackers = function(tracking_codes, callback) { 2816 this._current_tracker_idx = 0; 2817 var self = this; 2818 this._setupTracker(this._current_tracker_idx, tracking_codes, self, function() {}, callback); 2819 }; 2820 2821 /** 2822 * 2823 * @param {Skp_Tracker_Abstract_Base} tracker 2824 * @private 2825 */ 2826 this._getTrackerTrackingCodes = function(tracker) { 2827 var tcode_instances = Array(); 2828 for (var i in this._tracking_codes) { 2829 if (tracker.canHandleTrackingCode(this._tracking_codes[i])) { 2830 tcode_instance = tracker.buildNewTrackingCodeInstance(); 2831 tcode_instance.setCode(this._tracking_codes[i].code); 2832 if (this._tracking_codes[i].hasOwnProperty('events_cfg')) { 2833 tcode_instance.setEventsConfig(this._tracking_codes[i].events_cfg); 2834 } 2835 2836 if (this._tracking_codes[i].hasOwnProperty('server_enabled') && this._tracking_codes[i].server_enabled === 'Y') { 2837 tcode_instance.enableServerSide(true); 2838 } 2839 if (this._tracking_codes[i].hasOwnProperty('debug_mode') && this._tracking_codes[i].debug_mode) { 2840 tcode_instance.enableDebugMode(true); 2841 } 2842 tcode_instances.push(tcode_instance); 2843 } else { 2844 } 2845 } 2846 return tcode_instances; 2847 }; 2848 2849 this._setupTracker = function(idx, tracking_codes, skp_tracking, callback, callback_end) { 2850 var self = skp_tracking; 2851 skp_tracking._current_tracker_idx++; 2852 2853 if (skp_tracking._trackers.length == 0 || idx >= skp_tracking._trackers.length) { 2854 callback_end(); 2855 return; 2856 } 2857 var tcodes = this._getTrackerTrackingCodes(skp_tracking._trackers[idx]); 2858 2859 skp_tracking._trackers[idx].setup(tcodes, skp_tracking, 2860 function() { 2861 if (!skp_tracking._trackers[skp_tracking._current_tracker_idx]) { 2862 2863 callback_end(); 2864 } else { 2865 2866 skp_tracking._setupTracker(self._current_tracker_idx, tracking_codes, skp_tracking, function() { 2867 2868 } 2869 , callback_end 2870 ); 2871 } 2872 } 2873 ); 2874 }; 2875 2876 } 2877
2878 /** 2879 * @return {Skp_TrackingSystem} 2880 */ 2881 Skp_TrackingSystem.getInstance = function() { 2882 if (!Skp_TrackingSystem._instance) { 2883 Skp_TrackingSystem._instance = new Skp_TrackingSystem(); 2884 } 2885 return Skp_TrackingSystem._instance; 2886 }; 2887</script--> 2888<!--script type="text/javascript"> 2889 function Skp_Tracker_Abstract_Base() { 2890 this._id = ''; 2891 // event handler 2892 this.onBeforeConfigure = null; 2893 2894 /** 2895 * @param {function} handler 2896 */ 2897 this.onReady = function(handler) { 2898 this.addHandler('onReady', handler); 2899 }; 2900 2901 this._fake_order = 0; 2902 2903 this._trace_enabled = true; 2904 2905 this._simulate_new_order = false; 2906 2907 this._tracking_codes = Array(); 2908 this._tracking_codes_remove = Array(); 2909 this._enable_universal = false; 2910 this._customer_tracking_enabled = true; 2911 this._tracking_enabled = true; 2912 this._handlers = {}; 2913 this._last_sent_event = null; 2914 2915 this._managed_tcodes_types = {}; 2916 2917 this._items = Array(); 2918 this._items_tracker = Array(); 2919 2920 this.getId = function() { 2921 return this._id; 2922 }; 2923 2924 this.addItem = function(item) { 2925 this._items_tracker.push(item); 2926 }; 2927 2928 this.enableOrderSimulation = function() { 2929 this._simulate_new_order = trueM; 2930 }; 2931 2932 /** 2933 * 2934 * @return {Skp_TrackingCode} 2935 */ 2936 this.buildNewTrackingCodeInstance = function() { 2937 return new Skp_TrackingCode(); 2938 }; 2939 2940 this.addManagedTrackingCodeType = function(type, used_alias) { 2941 if (!used_alias) { 2942 used_alias = type; 2943 } 2944 this._managed_tcodes_types[type] = used_alias; 2945 }; 2946 2947 this.getLastSentEvent = function() { 2948 return this._last_sent_event; 2949 }; 2950 2951 // run an init function if defined 2952 if (this.init) { 2953 this.init(); 2954 } 2955 2956 this._fireEvent = function(evt) { 2957 this._execHandlers('onBeforeSend', evt); 2958 var excluded_tcodes = this._geteEventExcludedTrackingCodes(evt); 2959 this.addSendToParams(evt.getParams(), evt.getType(), excluded_tcodes); 2960 2961 this.fireEvent(evt); 2962 this._execHandlers('onAfterSend', evt); 2963 this._last_sent_event = evt; 2964 return evt; 2965 }; 2966 2967 this.addHandler = function(when, id, funct) { 2968 if (!this._handlers.hasOwnProperty(when)) { 2969 this._handlers[when] = {}; 2970 } 2971 this._handlers[when][id] = funct; 2972 return this; 2973 }; 2974 2975 this.enableCustomerTracking = function(enable) { 2976 this._customer_tracking_enabled = enable ?? true;; 2977 }; 2978 2979 /** 2980 * 2981 * @param id 2982 * @return {Skp_TrackingCode_Gtag} 2983 */ 2984 this.getTrackingCode = function(id) { 2985 for (var i in this._tracking_codes) { 2986 if (this._tracking_codes[i].getCode() === id) { 2987 return this._tracking_codes[i]; 2988 } 2989 } 2990 }; 2991 2992 /** 2993 * 2994 * @param owner 2995 * @return {Skp_TrackingCode_Gtag[]} 2996 */ 2997 this.getTrackingCodesByOwner = function(owner) { 2998 var tcodes = Array(); 2999 for (var i in this._tracking_codes) { 3000 if (this._tracking_codes[i].getOwner() === owner) { 3001 tcodes.push(this._tracking_codes[i]); 3002 } 3003 } 3004 return tcodes; 3005 }; 3006 3007 this.enableTrackingCodesOf = function(owner, enab) { 3008 enab = typeof enab !== 'undefined' ? enab : true; 3009 var tcodes = this.getTrackingCodesByOwner(owner); 3010 for (var key in tcodes) { 3011 enab ? tcodes[key].activate(true) : tcodes[key].activate(false); 3012 } 3013 return tcodes; 3014 }; 3015 3016 this.disableTrackingCodesOf = function(owner, enab) { 3017 this.enableTrackingCodesOf(owner, false); 3018 }; 3019 3020 this.enableTracking = function(enable) { 3021 this._tracking_enabled = enable ?? true;; 3022 }; 3023 3024 this.log = function(msg) { 3025 App.log(msg); 3026 }; 3027 3028 this.trace = function(msg) { 3029 var prefix = 'tracking_system (tracker): '; 3030 if (!this._trace_enabled) { 3031 return; 3032 } 3033 typeof msg === 'object' || Array.isArray(msg) ? 3034 (this.log(prefix + JSON.stringify(msg)), this.log(msg)) : 3035 this.log(prefix + msg); 3036 }; 3037 3038 this.getTargetTrackingCodeInstances = function(type) { 3039 var tcodes = []; 3040 for (var i in this._tracking_codes) { 3041 var code = this._tracking_codes[i]; 3042 if (code.hasOwnProperty('getType') && code.getType() === type && code._active) { 3043 tcodes.push(code); 3044 } 3045 } 3046 return tcodes; 3047 }; 3048 3049 this.getTrackingCodes = function(type, active_only) { 3050 type = typeof type !== 'undefined' ? type : 'all'; 3051 active_only = typeof active_only !== 'undefined' ? active_only : true; 3052 3053 var tcodes = []; 3054 for (var i in this._tracking_codes) { 3055 if ((type === 'all' || type === this._tracking_codes[i].getType()) 3056 && 3057 (!active_only || this._tracking_codes[i]._active)) { 3058 tcodes.push(this._tracking_codes[i].getCode()); 3059 } 3060 } 3061 return tcodes; 3062 }; 3063 3064 this.getActiveTrackingCodes = function(type) { 3065 type = typeof type !== 'undefined' ? type : 'all'; 3066 return this.getTrackingCodes(type, true); 3067 }; 3068 3069 this.canHandleTrackingCode = function(tcode) { 3070 return !!this._managed_tcodes_types[tcode.type]; 3071 }; 3072 3073 this.getTrackerItems = function() { 3074 return this._items_tracker; 3075 }; 3076 } 3077 3078 Skp_Tracker_Abstract_Base.prototype.resetItems = function() { 3079 this._items = Array(); 3080 this._items_tracker = Array(); 3081 }; 3082 3083 Skp_Tracker_Abstract_Base.prototype.addNewItem = function(item_generic) { 3084 this._items_tracker = QA; 3085 if (this._simulate_new_order) { 3086 if (transaction) { 3087 transaction['order_id'] = this._fake_order; 3088 } 3089 } 3090 3091 var item = this.buildItem(item_generic); 3092 this._items.push(item_generic); 3093 this._items_tracker.push(item); 3094 }; 3095 3096 function Skp_Tracker_Abstract() { 3097 // invoke this constructor in extended objects 3098 Skp_Tracker_Abstract_Base.call(this); 3099 // you must implement this methods 3100 3101 /** 3102 * 3103 * @param tracking_codes 3104 * @param {Skp_TrackingSystem} skp_object 3105 * @param callback 3106 */ 3107 this.setup = function(tracking_codes, skp_object, callback) { 3108 callback(); 3109 }; 3110 3111 this.isReady = function() { 3112 return true; 3113 }; 3114 3115 // you can override these function just remember to call supper super class if you need standard handling 3116 this.resetItems = function() { 3117 Skp_Tracker_Abstract_Base.prototype.resetItems(this); 3118 }; 3119 3120 this.addNewItem = function(item, transaction) { 3121 Skp_Tracker_Abstract_Base.prototype.addNewItem.call(this, item, transaction); 3122 }; 3123 3124 // you can implement any method you need of these in extended object 3125 /** 3126 * 3127 * @param {Skp_Shop_Items_Purchase} shop_purchase 3128 * @return {Skp_Tracking_Event} 3129 */ 3130 this.sendPurchaseEvent = function(shop_purchase) { 3131 }; 3132 3133 /** 3134 * 3135 * @param {Skp_Shop_Items_Refund} shop_items_refund 3136 * @return {Skp_Tracking_Event} 3137 */ 3138 this.sendRefundEvent = function(shop_items_refund) { 3139 }; 3140 3141 /** 3142 * @param {Skp_Shop_Item} items 3143 * @return {Skp_Tracking_Event} 3144 */ 3145 this.sendAddToCartEvent = function(items) { 3146 }; 3147 3148 /** 3149 * @param {Skp_Shop_Item} items 3150 * @return {Skp_Tracking_Event} 3151 */ 3152 this.sendRemoveFromCartEvent = function(items) { 3153 }; 3154 3155 /** 3156 * @param {Object} params 3157 * @return {Skp_Tracking_Event} 3158 */ 3159 this.sendSetEvent = function(params) { 3160 }; 3161 3162 /** 3163 * @param {Object} params 3164 * @return {Skp_Tracking_Event} 3165 */ 3166 this.sendNavigationEvent = function(params) { 3167 }; 3168 3169 /** 3170 * @param {Object} params 3171 * @return {Skp_Tracking_Event} 3172 */ 3173 this.sendPageViewEvent = function(params) { 3174 }; 3175 3176 /** 3177 * @param {Object} params 3178 * @return {Skp_Tracking_Event} 3179 */ 3180 this.setDimensions = function(params) { 3181 }; 3182 } 3183 3184 Skp_Tracker_Abstract.prototype = Object.create(Skp_Tracker_Abstract_Base.prototype); 3185 Skp_Tracker_Abstract.prototype.constructor = Skp_Tracker_Abstract_Base; 3186</script--> 3187 3188<!--script type="text/javascript"> 3189 function Skp_Tracker_Gtag() { 3190 Skp_Tracker_Abstract.call(this); 3191 this._id = 'gtag'; 3192 3193 this.fillServerContainerUrl = function(configpars) { 3194 if (configpars.hasOwnProperty('server_container_url')) { 3195 configpars['server_container_url'] = configpars.server_container_url; 3196 } 3197 return configpars; 3198 }; 3199 3200 this.setupDefaultTrackingCodes = function() { 3201 }; 3202 3203 this.setup = function(tracking_codes, skp_tracking, callback) { 3204 this.setupDefaultTrackingCodes(); 3205 3206 this.addTrackingCodes(tracking_codes, 'customer'); 3207 this.configureTrackings( 3208 function() { 3209 callback(); 3210 } 3211 ); 3212 }; 3213 3214 Skp_Tracker_Gtag._instance = this; 3215 window.skp_gtag_customer_tracking_enabled === false ? this._customer_tracking_enabled = false : true; 3216 3217 this.canAddToTheDataLayer = function(argument) { 3218 // eventually change this default based on the argument 3219 return true; 3220 }; 3221 3222 this.configureTrackings = function(callback) { 3223 if (window.skp_gtag_enabled === false) { 3224 this.enableTracking(false); 3225 } 3226 3227 if (!this._tracking_enabled) { 3228 window.gtag = function() { 3229 this.trace('GTAG tracking disabled'); 3230 }; 3231 return; 3232 } 3233 3234 var self = this; 3235 if (typeof self.onBeforeConfigure === 'function') { 3236 self.onBeforeConfigure(self); 3237 } 3238 3239 // importing gtag and configuring it for rhe properties 3240 var script = document.createElement('script'); 3241 // relying only on send_to to select default tracking code 3242 script.src = 'https://www.googletagmanager.com/gtag/js'; 3243 3244 script.async = true; 3245 3246 script.onload = function() { 3247 window.dataLayer = window.dataLayer || []; 3248 3249 window.dataLayer._push = window.dataLayer.push; 3250 window.dataLayer.push = function() { 3251 var allarguments = []; 3252 for (var idx in arguments) { 3253 try { 3254 if (self.canAddToTheDataLayer(arguments[idx])) { 3255 allarguments[idx] = arguments[idx]; 3256 } 3257 } catch (e) { 3258 } 3259 } 3260 return window.dataLayer._push.apply(window.dataLayer, allarguments); 3261 }; 3262 window.gtag = function() { 3263 dataLayer.push(arguments); 3264 }; 3265 gtag('js', new Date()); 3266 3267 for (var i in self._tracking_codes) { 3268 var tcode_groups = 'default'; 3269 if (self._tracking_codes[i].getGroups().length > 0) { 3270 tcode_groups = self._tracking_codes[i].getGroups(); 3271 } 3272 var configpars = { 3273 'enable_ads': true, 3274 'enhanced_conversions': true, 3275 'groups': tcode_groups, 3276 'send_page_view': false, 3277 }; 3278 if (Skp_Tracker_Gtag._debug_mode || self._tracking_codes[i]._debug_mode) { 3279 configpars.debug_mode = true; 3280 } 3281 if (!App.cookie_is_accepted_statistic && self._tracking_codes[i].getType() === 'tagmanager') { 3282 configpars['anonymize_ip'] = true; 3283 } 3284 3285 self.fillServerContainerUrl(configpars); 3286 gtag('config', self._tracking_codes[i].getCode(), 3287 configpars 3288 ); 3289 3290 self._tracking_codes[i]._active = true; 3291 3292 // we may want to skip cutstomer trackings 3293 if (!self._customer_tracking_enabled) { 3294 break; 3295 } 3296 } 3297 3298 window.skp_ga4_ready = true; 3299 3300 self._execHandlers('onReady', new Skp_Tracking_Event('ready', self)); 3301 3302 if (callback) { 3303 callback(); 3304 } 3305 3306 }; 3307 3308 document.head.appendChild(script); 3309 }; 3310 3311 /** 3312 * 3313 * @param {Skp_Tracking_Event} evt 3314 */ 3315 this.fireEvent = function(evt) { 3316 gtag('event', evt.getName(), evt.getParams()); 3317 return true; 3318 }; 3319
3320 this.getSendToParam = function(type, removeCodes) { 3321 var tcodes = []; 3322 for (var i in this._tracking_codes) { 3323 var code = this._tracking_codes[i]; 3324 if (code.hasOwnProperty('getType') && code.getType() === type && code._active) { 3325 var skip = false; 3326 if (removeCodes) { 3327 for (var n in removeCodes) { 3328 if (removeCodes[n].getCode() === this._tracking_codes[i].getCode()) { 3329 skip = true; 3330 } 3331 } 3332 } 3333 if (!skip) { 3334 tcodes.push(code.getCode()); 3335 } 3336 } 3337 } 3338 return tcodes; 3339 }; 3340 3341 3342 this.getTagType = function(orig_type) { 3343 if (this._managed_tcodes_types.hasOwnProperty(orig_type)) { 3344 return this._managed_tcodes_types[orig_type]; 3345 } 3346 return 'unknown'; 3347 }; 3348 3349 /** 3350 * @param tracking_code 3351 * @param type 3352 * 3353 * @return {Skp_TrackingCode_Ga4} 3354 */ 3355 this.buildTrackingCode = function(tracking_code, type, owner) { 3356 var track_code = null; 3357 var tagtype = this.getTagType(type); 3358 3359 if (tagtype === 'ga4') { 3360 track_code = new Skp_TrackingCode_Gtag_Ga4(tracking_code); 3361 } else if (tagtype === 'tagmanager') { 3362 track_code = new Skp_TrackingCode_Gtag_Tagmanager(tracking_code); 3363 } else if (this.getTagType(type) === 'unknown') { 3364 throw new Error('Cannot handle tracking code of type:' + type); 3365 } 3366 3367 if (track_code !== null) { 3368 track_code.setOwner(owner); 3369 } 3370 return track_code; 3371 }; 3372 3373 this.canHandleTrackingType = function(type) { 3374 return this._managed_tcodes_types.hasOwnProperty(type); 3375 }; 3376 3377 this.addNewTrackingCode = function(code, type, owner) { 3378 owner = typeof owner !== 'undefined' ? owner : 'skiperformance'; 3379 if (!this.canHandleTrackingType(type)) { 3380 return false; 3381 } 3382 var track_code = this.buildTrackingCode(code, type, owner); 3383 this._tracking_codes.push(track_code); 3384 return track_code; 3385 }; 3386 3387 this.addTrackingCode = function(tracking_object) { 3388 this._tracking_codes.push(tracking_object); 3389 }; 3390 3391 this.addTrackingCodes = function(track_codes, owner) { 3392 owner = typeof owner !== 'undefined' ? owner : 'customer'; 3393 3394 for (var i in track_codes) { 3395 this.addTrackingCode(track_codes[i]); 3396 } 3397 }; 3398 3399 this.sendNavigationEvent = function(pars) { 3400 // automatic in ga4 3401 }; 3402 3403 this.sendPageViewEvent = function(pars) { 3404 // automatic in ga4 3405 }; 3406 3407 this.addSendToParams = function(params, type, excluded_tcodes) { 3408 params.send_to = this.getSendToParam(type, excluded_tcodes); 3409 return params; 3410 }; 3411 3412 this._execHandlers = function(hdl_type, evt) { 3413 if (this._handlers[hdl_type]) { 3414 var keys = Object.keys(this._handlers[hdl_type]); 3415 for (var key in this._handlers[hdl_type]) { 3416 this._handlers[hdl_type][key](evt, this); 3417 } 3418 } 3419 }; 3420 3421 /** 3422 * @private 3423 * @param {Skp_Tracking_Event} evt 3424 */ 3425 this._geteEventExcludedTrackingCodes = function(evt) { 3426 var tcodes = this.getTargetTrackingCodeInstances('ga4'); 3427 var excluded = Array(); 3428 for (var i in tcodes) { 3429 if (!tcodes[i].hasClientSideEvent(evt) 3430 || !evt.shouldFire(tcodes[i], this) 3431 ) { 3432 excluded.push(tcodes[i]); 3433 } 3434 } 3435 return excluded; 3436 }; 3437 3438 this.sendNewEvent = function(event_name, params, type) { 3439 type = type || 'ga4'; 3440 3441 if (event_name === 'add_to_cart') { 3442 var evt = new Skp_Tracking_Event_AddToCart(); 3443 evt.setParams(params); 3444 evt.setType(type); 3445 } else if (event_name === 'remove_to_cart') { 3446 var evt = new Skp_Tracking_Event_RemoveFromCart(); 3447 evt.setParams(params); 3448 evt.setType(type); 3449 } else { 3450 var evt = new Skp_Tracking_Event(event_name, params, 'ga4'); 3451 } 3452 3453 this._fireEvent(evt); 3454 this._last_sent_event = evt; 3455 3456 return evt; 3457 }; 3458 3459 this.sendSetEvent = function(params) { 3460 return this.sendNewEvent('set', params); 3461 }; 3462 3463 this.isReady = function() { 3464 return window.skp_ga4_ready; 3465 }; 3466 3467 this.setDimensions = function(params) { 3468 var self = this; 3469 if (!this.isReady()) { 3470 setTimeout(function() { 3471 self.setDimensions(params); 3472 }, 100); 3473 } else { 3474 this.sendSetEvent(params); 3475 } 3476 }; 3477 } 3478 3479 Skp_Tracker_Gtag.prototype = Object.create(Skp_Tracker_Abstract.prototype); 3480 Skp_Tracker_Gtag.prototype.constructor = Skp_Tracker_Abstract; 3481 Skp_Tracker_Gtag._instance = null; 3482 3483 /** 3484 * @return {Skp_Tracker_Gtag} 3485 */ 3486 Skp_Tracker_Gtag.getInstance = function() { 3487 if (!Skp_Tracker_Gtag._instance) { 3488 Skp_Tracker_Gtag._instance = new Skp_Tracker_Gtag(); 3489 } 3490 return Skp_Tracker_Gtag._instance; 3491 }; 3492 3493 Skp_Tracker_Gtag._debug_mode = false;
3494 Skp_Tracker_Gtag.enableDebugMode = function() { 3495 Skp_Tracker_Gtag._debug_mode = true; 3496 }; 3497 3498 Skp_Tracker_Gtag.getInstance().addHandler('onBeforeSend', 3499 'exclude', function(evt, taginstance) { 3500 var tagi = Skp_Tracker_Gtag.getInstance(); 3501 if (evt.getName() === 'purchase') { 3502 /* 3503 var tcodes = tagi.enableTrackingCodesOf("skiperformance",false); 3504 var tcodes = tagi.enableTrackingCodesOf("customer",false); 3505 */ 3506 } 3507 3508 } 3509 ); 3510 3511</script--> 3512<!--script type="text/javascript"> 3513 function Skp_TrackingCode_Gtag_Ga4(code) { 3514 Skp_TrackingCode.call(this, code,"ga4"); 3515 } 3516 Skp_TrackingCode_Gtag_Ga4.prototype = Object.create(Skp_TrackingCode_Gtag.prototype); 3517 Skp_TrackingCode_Gtag_Ga4.prototype.constructor = Skp_TrackingCode_Gtag; 3518</script--> 3519<!--script> 3520 // EVENT ADD TO CART ------------------------------------------------------------------- 3521 function Skp_Tracking_Event_AddToCart_Ga4() { 3522 Skp_Tracking_Event.call(this, 'add_to_cart'); 3523 this._type = 'ga4'; 3524 3525 /** 3526 * @descr we can prevent the event from firing 3527 * @param {Skp_TrackingCode} tracking_code 3528 * @param {Skp_Tracker_Gtag} tracker 3529 * @return {boolean} 3530 */ 3531 this.shouldFire = function (tracking_code, tracker) { 3532 // get the tracking system 3533 var tracking_system = Skp_TrackingSystem.getInstance(); 3534 // sample filtering on tracker 3535 if (tracker.getId() === "gtag") { 3536 if (tracking_code.getOwner() === "skiperformance") { 3537 return true; 3538 } 3539 } 3540 return true; 3541 } 3542 } 3543 3544 Skp_Tracking_Event_AddToCart_Ga4.prototype = Object.create(Skp_Tracking_Event_AddToCart.prototype); 3545 Skp_Tracking_Event_AddToCart_Ga4.prototype.constructor = Skp_Tracking_Event_AddToCart; 3546 3547 /** 3548 * 3549 * @param {Skp_Shop_Item} shop_items 3550 * @return {Object} 3551 */ 3552 Skp_Tracking_Event_AddToCart_Ga4.buildParams = function (shop_items) { 3553 var items = Array(); 3554 3555 for(var i in shop_items) { 3556 var item = shop_items[i].getItem(); 3557 3558 items.push( 3559 { 3560 item_id: item['sku_id'], 3561 item_name: item['sku_name'], 3562 item_category: item['category'], 3563 currency: item['currency'], 3564 price: parseFloat(item['price']), 3565 quantity: parseFloat(item['qty']), 3566 custom_params: { 3567 order_id: item['order_id'] 3568 } 3569 } 3570 ); 3571 } 3572 3573 return { 3574 items: items 3575 }; 3576 } 3577 3578 /** 3579 * @param {Skp_Shop_Item[]} shop_items 3580 * @return {Skp_Tracking_Event_AddToCart_Ga4} 3581 */ 3582 Skp_Tracking_Event_AddToCart_Ga4.buildEvent = function (shop_items) { 3583 var gtag_params = Skp_Tracking_Event_AddToCart_Ga4.buildParams(shop_items); 3584 3585 var event = new Skp_Tracking_Event_AddToCart_Ga4(); 3586 event.setParams(gtag_params); 3587 3588 return event; 3589 } 3590</script--> 3591<!--script> 3592 function Skp_Tracking_Event_Pageview_Ga4() { 3593 Skp_Tracking_Event.call(this, "page_view"); 3594 this._type = "ga4" 3595 3596 /** 3597 * @param {Skp_TrackingCode_Gtag_Ga4} tracking_code 3598 * @param {Skp_Tracker} tracker 3599 * @return {boolean} 3600 */ 3601 this.shouldFire = function (tracking_code, tracker) { 3602 return true; 3603 } 3604 } 3605 Skp_Tracking_Event_Pageview.prototype = Object.create(Skp_Tracking_Event_Pageview.prototype); 3606 Skp_Tracking_Event_Pageview.prototype.constructor = Skp_Tracking_Event_Pageview; 3607</script--> 3608<!--script> 3609 function Skp_Tracking_Event_RemoveFromCart_Ga4() { 3610 Skp_Tracking_Event.call(this, 'remove_from_cart'); 3611 this._type = 'ga4'; 3612 3613 /** 3614 * @descr we can prevent the event from firing 3615 * @param {Skp_TrackingCode} tracking_code 3616 * @param {Skp_Tracker_Gtag} tracker 3617 * @return {boolean} 3618 */ 3619 this.shouldFire = function (tracking_code, tracker) { 3620 return true; 3621 } 3622 } 3623 3624 Skp_Tracking_Event_RemoveFromCart_Ga4.prototype = Object.create(Skp_Tracking_Event_RemoveFromCart.prototype); 3625 Skp_Tracking_Event_RemoveFromCart_Ga4.prototype.constructor = Skp_Tracking_Event_RemoveFromCart; 3626 3627 /** 3628 * @param {Skp_Shop_Item[]} shop_items 3629 * @return {Object} 3630 */ 3631 Skp_Tracking_Event_RemoveFromCart_Ga4.buildParams = function (shop_items) { 3632 var items = Array(); 3633 for(var i in shop_items) { 3634 var item = shop_items[i].getItem(); 3635 items.push( 3636 { 3637 item_id: item['sku_id'], 3638 item_name: item['sku_name'], 3639 item_category: item['category'], 3640 currency: item['currency'], 3641 price: parseFloat(item['price']), 3642 quantity: parseFloat(item['qty']), 3643 custom_params: { 3644 order_id: item['order_id'] 3645 } 3646 } 3647 ); 3648 } 3649 3650 return { 3651 items: items 3652 }; 3653 } 3654 3655 /** 3656 * @param {Skp_Shop_Item} shop_items 3657 * @return {Skp_Tracking_Event_RemoveFromCart_Ga4} 3658 */ 3659 Skp_Tracking_Event_RemoveFromCart_Ga4.buildEvent = function (shop_items) { 3660 var gtag_params = Skp_Tracking_Event_RemoveFromCart_Ga4.buildParams(shop_items); 3661 var event = new Skp_Tracking_Event_RemoveFromCart_Ga4(); 3662 event.setParams(gtag_params); 3663 return event; 3664 } 3665</script--> 3666<!--script> 3667 function Skp_Tracking_Event_Purchase_Ga4() { 3668 Skp_Tracking_Event.call(this, "purchase"); 3669 this._type = "ga4" 3670 3671 /** 3672 * @param {Skp_TrackingCode_Gtag_Ga4} tracking_code 3673 * @param {Skp_Tracker} tracker 3674 * @return {boolean} 3675 */ 3676 this.shouldFire = function (tracking_code, tracker) { 3677 return true; 3678 } 3679 } 3680 3681 Skp_Tracking_Event_Purchase_Ga4.prototype = Object.create(Skp_Tracking_Event_Purchase.prototype); 3682 Skp_Tracking_Event_Purchase_Ga4.prototype.constructor = Skp_Tracking_Event_Purchase; 3683 3684 /** 3685 * 3686 * @param {Skp_Shop_Item} shop_item 3687 * @return {Object} 3688 */ 3689 Skp_Tracking_Event_Purchase_Ga4.buildItemParam = function (shop_item) { 3690 var item = shop_item.getItem(); 3691 3692 var gtag_param = { 3693 item_id: item['sku_id'], 3694 item_name: item['sku_name'], 3695 item_category: item['category'], 3696 currency: item['currency'], 3697 price: parseFloat(item['price']), 3698 quantity: parseFloat(item['qty']), 3699 itm_order_id: item['order_id'] 3700 }; 3701 3702 if (App.cookie_is_accepted_marketing) { 3703 var up = Skp_TrackingSystem.getInstance().getUserProperties(); 3704 gtag_param.itm_user_id = up.getProperties().user_id; 3705 gtag_param.itm_age_range = up.getProperties().age_range; 3706 } 3707 3708 return gtag_param; 3709 } 3710 3711 /** 3712 * @descr this build the params as required by ga4 3713 * @param {Skp_Shop_Items_Purchase} shop_items_purchase 3714 * @return {Object} 3715 */ 3716 Skp_Tracking_Event_Purchase_Ga4.buildParams = function (shop_items_purchase) { 3717 // we are converting transaction to the information required by ga4 3718 var t_items = shop_items_purchase.getTrackerItems(); 3719 var items = Array(); 3720 for (var i in t_items) { 3721 var item = Skp_Tracking_Event_Purchase_Ga4.buildItemParam(t_items[i]); 3722 items.push(item); 3723 } 3724 3725 var transaction = shop_items_purchase.getTransaction(); 3726 var up = Skp_TrackingSystem.getInstance().getUserProperties(); 3727 var purchaseEventPars = { 3728 'event_id': transaction['event_id'], 3729 'transaction_id': transaction['order_id'], 3730 'value': parseFloat(transaction['price']), 3731 'tax': parseFloat(transaction['vat']), 3732 'affiliation': transaction['merchant_name'], 3733 'currency': transaction['currency'], 3734 'shipping': 0, 3735 'items': items 3736 }; 3737 3738 if (App.cookie_is_accepted_marketing) { 3739 purchaseEventPars.evt_user_id = up.getProperties().evt_user_id; 3740 purchaseEventPars.evt_age_range = up.getProperties().age_range; 3741 } 3742 return purchaseEventPars; 3743 } 3744 3745 /** 3746 * @descr 3747 * @param {Skp_Shop_Items_Purchase} shop_items_purchase 3748 * @return {Skp_Tracking_Event_Purchase_Ga4} 3749 */ 3750 Skp_Tracking_Event_Purchase_Ga4.buildEvent = function (shop_items_purchase) { 3751 var gtag_params = Skp_Tracking_Event_Purchase_Ga4.buildParams(shop_items_purchase); 3752 3753 var event = new Skp_Tracking_Event_Purchase_Ga4(); 3754 event.setParams(gtag_params); 3755 event.setType("ga4"); 3756 3757 return event; 3758 } 3759</script--> 3760<!--script> 3761 function Skp_Tracking_Event_ViewItem_Ga4() { 3762 Skp_Tracking_Event.call(this, 'view_item'); 3763 this._type = 'ga4'; 3764 3765 /** 3766 * @param {Skp_TrackingCode} tracking_code 3767 * @param {Skp_Tracker_Gtag} tracker 3768 * @return {boolean} 3769 */ 3770 this.shouldFire = function (tracking_code, tracker) { 3771 return true; 3772 } 3773 } 3774 3775 Skp_Tracking_Event_ViewItem_Ga4.prototype = Object.create(Skp_Tracking_Event_ViewItem.prototype); 3776 Skp_Tracking_Event_ViewItem_Ga4.prototype.constructor = Skp_Tracking_Event_ViewItem; 3777 3778 /** 3779 * @param {Object} item_data - { item_id, item_type, item_name, item_category, currency, price } 3780 * @return {Object} 3781 */ 3782 Skp_Tracking_Event_ViewItem_Ga4.buildParams = function (item_data) { 3783 var item = { 3784 item_id: item_data.item_id, 3785 item_type: item_data.item_type, 3786 item_name: item_data.item_name, 3787 item_category: item_data.item_category || '', 3788 currency: item_data.currency || '', 3789 price: parseFloat(item_data.price) || 0 3790 }; 3791 3792 return { 3793 currency: item_data.currency || '', 3794 value: item.price, 3795 items: [item] 3796 }; 3797 } 3798 3799 /** 3800 * @param {Object} item_data 3801 * @return {Skp_Tracking_Event_ViewItem_Ga4} 3802 */ 3803 Skp_Tracking_Event_ViewItem_Ga4.buildEvent = function (item_data) { 3804 var gtag_params = Skp_Tracking_Event_ViewItem_Ga4.buildParams(item_data); 3805 var event = new Skp_Tracking_Event_ViewItem_Ga4(); 3806 event.setParams(gtag_params); 3807 return event; 3808 } 3809</script--> 3810<!--script> 3811 function Skp_Tracking_Event_ViewItemList_Ga4() { 3812 Skp_Tracking_Event.call(this, 'view_item_list'); 3813 this._type = 'ga4'; 3814 3815 /** 3816 * @param {Skp_TrackingCode} tracking_code 3817 * @param {Skp_Tracker_Gtag} tracker 3818 * @return {boolean} 3819 */ 3820 this.shouldFire = function (tracking_code, tracker) { 3821 return true; 3822 } 3823 } 3824 3825 Skp_Tracking_Event_ViewItemList_Ga4.prototype = Object.create(Skp_Tracking_Event_ViewItemList.prototype); 3826 Skp_Tracking_Event_ViewItemList_Ga4.prototype.constructor = Skp_Tracking_Event_ViewItemList; 3827 3828 /** 3829 * @param {Array} items_data - array of { item_id, item_name, item_category, currency, price } 3830 * @param {String} list_id 3831 * @param {String} list_name 3832 * @return {Object} 3833 */ 3834 Skp_Tracking_Event_ViewItemList_Ga4.buildParams = function (items_data, list_id, list_name) { 3835 var items = []; 3836 for (var i = 0; i < items_data.length; i++) { 3837 items.push({ 3838 item_id: items_data[i].item_id, 3839 item_name: items_data[i].item_name, 3840 item_category: items_data[i].item_category || '', 3841 currency: items_data[i].currency || '', 3842 price: parseFloat(items_data[i].price) || 0, 3843 index: i 3844 }); 3845 } 3846 3847 return { 3848 item_list_id: list_id || '', 3849 item_list_name: list_name || '', 3850 items: items 3851 }; 3852 } 3853 3854 /** 3855 * @param {Array} items_data 3856 * @param {String} list_id 3857 * @param {String} list_name 3858 * @return {Skp_Tracking_Event_ViewItemList_Ga4} 3859 */ 3860 Skp_Tracking_Event_ViewItemList_Ga4.buildEvent = function (items_data, list_id, list_name) { 3861 var gtag_params = Skp_Tracking_Event_ViewItemList_Ga4.buildParams(items_data, list_id, list_name); 3862 var event = new Skp_Tracking_Event_ViewItemList_Ga4(); 3863 event.setParams(gtag_params); 3864 return event; 3865 } 3866</script--> 3867<!--script> 3868 function Skp_Tracking_Event_BeginCheckout_Ga4() { 3869 Skp_Tracking_Event.call(this, 'begin_checkout'); 3870 this._type = 'ga4'; 3871 3872 /** 3873 * @param {Skp_TrackingCode} tracking_code 3874 * @param {Skp_Tracker_Gtag} tracker 3875 * @return {boolean} 3876 */ 3877 this.shouldFire = function (tracking_code, tracker) { 3878 return true; 3879 } 3880 } 3881 3882 Skp_Tracking_Event_BeginCheckout_Ga4.prototype = Object.create(Skp_Tracking_Event_BeginCheckout.prototype); 3883 Skp_Tracking_Event_BeginCheckout_Ga4.prototype.constructor = Skp_Tracking_Event_BeginCheckout; 3884 3885 /** 3886 * @param {Array} items - array of { item_id, item_name, item_category, currency, price, quantity } 3887 * @param {Number} value - total cart value 3888 * @param {String} currency 3889 * @return {Object} 3890 */ 3891 Skp_Tracking_Event_BeginCheckout_Ga4.buildParams = function (items, value, currency) { 3892 var ga4_items = []; 3893 for (var i = 0; i < items.length; i++) { 3894 ga4_items.push({ 3895 item_id: items[i].item_id, 3896 item_name: items[i].item_name, 3897 item_category: items[i].item_category || '', 3898 currency: items[i].currency || currency || '', 3899 price: parseFloat(items[i].price) || 0, 3900 quantity: parseFloat(items[i].quantity) || 1 3901 }); 3902 } 3903 3904 return { 3905 currency: currency || '', 3906 value: parseFloat(value) || 0, 3907 items: ga4_items 3908 }; 3909 } 3910 3911 /** 3912 * @param {Array} items 3913 * @param {Number} value 3914 * @param {String} currency 3915 * @return {Skp_Tracking_Event_BeginCheckout_Ga4} 3916 */ 3917 Skp_Tracking_Event_BeginCheckout_Ga4.buildEvent = function (items, value, currency) { 3918 var gtag_params = Skp_Tracking_Event_BeginCheckout_Ga4.buildParams(items, value, currency); 3919 var event = new Skp_Tracking_Event_BeginCheckout_Ga4(); 3920 event.setParams(gtag_params); 3921 return event; 3922 } 3923</script--> 3924<!--script type="text/javascript"> 3925 function Skp_Tracker_Gtag_Ga4() { 3926 this.init = function() { 3927 this.addManagedTrackingCodeType('Google Analytics (gtag)', 'ga4'); 3928 this.addManagedTrackingCodeType('Google Analytics (gtag) - DEBUG ONLY', 'ga4'); 3929 this.addManagedTrackingCodeType('ga4', 'ga4'); 3930 }; 3931 3932 Skp_Tracker_Gtag.call(this); 3933 this._id = 'gtag_ga4'; 3934 3935 // this allows to specify a specific tracking code class if necessary 3936 /** 3937 * 3938 * @return {Skp_TrackingCode_Gtag_Ga4} 3939 */ 3940 this.buildNewTrackingCodeInstance = function() { 3941 return new Skp_TrackingCode_Gtag_Ga4(); 3942 }; 3943 3944 this.setupDefaultTrackingCodes = function() { 3945 // setting up default tracking codes 3946 var tc = this.buildNewTrackingCodeInstance(); 3947 tc.setCode(Skp_TrackingSystem.getInstance().getSkpGa4Code()); 3948 tc.enableServerSide(Skp_TrackingSystem.getInstance().isSkpGa4ServerEnabled()); 3949 tc.setOwner('skiperformance'); 3950 this.addTrackingCode(tc); 3951 }; 3952 3953 /** 3954 * 3955 * @param {Skp_UserProperties}user_properties 3956 */ 3957 this.sendUserPropertiesEvent = function(user_properties) { 3958 return new Skp_Tracking_Event('set', { user_properties: user_properties.getProperties() }, 'ga4'); 3959 }; 3960 3961 /** 3962 * @param {Skp_Shop_Item} shop_items 3963 * @return {Skp_Tracking_Event} 3964 */ 3965 this.sendAddToCartEvent = function(shop_items) { 3966 return Skp_Tracking_Event_AddToCart_Ga4.buildEvent(shop_items); 3967 }; 3968 3969 /** 3970 * @param {Skp_Shop_Item} shop_items 3971 * @return {Skp_Tracking_Event} 3972 */ 3973 this.sendRemoveFromCartEvent = function(shop_items) { 3974 return Skp_Tracking_Event_RemoveFromCart_Ga4.buildEvent(shop_items); 3975 }; 3976 3977 /** 3978 * @param {Skp_Shop_Items_Purchase} shop_items_purchase 3979 * @return {Skp_Tracking_Event} 3980 */ 3981 this.sendPurchaseEvent = function(shop_items_purchase) { 3982 var transaction = shop_items_purchase.getTransaction(); 3983 return Skp_Tracking_Event_Purchase_Ga4.buildEvent(shop_items_purchase); 3984 }; 3985 3986 /** 3987 * @param {Skp_Shop_Items_Refund} shop_items_refund 3988 * @return {Skp_Tracking_Event} 3989 */ 3990 this.sendRefundEvent = function(shop_items_refund) { 3991 var transaction = shop_items_refund.getTransaction(); 3992 return Skp_Tracking_Event_Refund_Ga4.buildEvent(shop_items_refund); 3993 }; 3994 3995 /** 3996 * @param {Object} params 3997 * @return {Skp_Tracking_Event_Pageview_Ga4} 3998 */ 3999 this.sendPageViewEvent = function(params) { 4000 const ga4_params = { 4001 page_location: params.page_location, 4002 page_path: params.page_location, 4003 client_id: params.client_id, 4004 language: params.language, 4005 page_encoding: params.page_encoding, 4006 page_title: params.page_title, 4007 user_agent: params.user_agent, 4008 page_referrer: document.referrer 4009 }; 4010 4011 var evt = new Skp_Tracking_Event_Pageview_Ga4(); 4012 evt.setParams(ga4_params); 4013 4014 return evt; 4015 }; 4016 4017 /** 4018 * @param {Object} item_data - { item_id, item_name, item_category, currency, price } 4019 * @return {Skp_Tracking_Event_ViewItem_Ga4} 4020 */ 4021 this.sendViewItemEvent = function(item_data) { 4022 return Skp_Tracking_Event_ViewItem_Ga4.buildEvent(item_data); 4023 }; 4024 4025 /** 4026 * @param {Object} params - { items, list_id, list_name } 4027 * @return {Skp_Tracking_Event_ViewItemList_Ga4} 4028 */ 4029 this.sendViewItemListEvent = function(params) { 4030 return Skp_Tracking_Event_ViewItemList_Ga4.buildEvent(params.items, params.list_id, params.list_name); 4031 }; 4032 4033 /** 4034 * @param {Object} params - { items, value, currency } 4035 * @return {Skp_Tracking_Event_BeginCheckout_Ga4} 4036 */ 4037 this.sendBeginCheckoutEvent = function(params) { 4038 return Skp_Tracking_Event_BeginCheckout_Ga4.buildEvent(params.items, params.value, params.currency); 4039 }; 4040 } 4041 4042 Skp_Tracker_Gtag_Ga4.prototype = Object.create(Skp_Tracker_Gtag.prototype); 4043 Skp_Tracker_Gtag_Ga4.prototype.constructor = Skp_Tracker_Gtag; 4044 Skp_Tracker_Gtag_Ga4._instance = null; 4045 4046 /** 4047 * @return {Skp_Tracker_Gtag} 4048 */ 4049 Skp_Tracker_Gtag_Ga4.getInstance = function() { 4050 if (!Skp_Tracker_Gtag_Ga4._instance) { 4051 Skp_Tracker_Gtag_Ga4._instance = new Skp_Tracker_Gtag_Ga4(); 4052 } 4053 return Skp_Tracker_Gtag_Ga4._instance
4053; 4054 }; 4055</script--> 4056<!--script> 4057 const skpAppConfig = { 4058 version: 41, 4059 baseUrl: 'https://shop.suedtirolskiarena.com/en/store', 4060 currentDomain: 'shop.suedtirolskiarena.com', 4061 dateFormat: 'd/m/Y', 4062 isProduction: true, 4063 environment: '10', 4064 messageInDialog: true, 4065 messageLifetime: 1500, 4066 is_backoffice: false, 4067 language: 'en', 4068 locale: 'en-US', 4069 events_config: {"purchase":"s","refund":"s"}, 4070 jsVersionHeader: 'x-skp-app-version', 4071 tokenHeader: 'x-csrf-token', 4072 csrfToken: 'f5590ceb571ccf63c61d46a2d823b72b971508ed.01m4f0w15vf66n0j9895hmn0bz.206276599', 4073 flashMessage: null, 4074 lb_header: 'awselb/2.0', 4075 4076 g_key: 'AIzaSyDpe6vOtmyNDvhiUcGH_pi5uTYYEJgtHBE', 4077 // these are the Google Analytics of skiperformance 4078 skp_ga_4: 'G-16DXPC6HWK', 4079 skp_ga_4_main_tc_server: true, 4080 consents: {"ad_storage":"denied","ad_user_data":"denied","ad_personalization":"denied","analytics_storage":"denied","functionality_storage":"granted","personalization_storage":"denied","security_storage":"granted","wait_for_update":500}, 4081 consent_configs: {"default":{"ad_storage":"denied","ad_user_data":"denied","ad_personalization":"denied","analytics_storage":"denied","functionality_storage":"denied","personalization_storage":"denied","security_storage":"denied","wait_for_update":500},"technical":{"functionality_storage":"granted","security_storage":"granted"},"statistic":{"analytics_storage":"granted"},"marketing":{"ad_storage":"granted","ad_user_data":"granted","ad_personalization":"granted","personalization_storage":"granted"}}, 4082 4083 enable_tracking: true, 4084 analyticsDebug: false, 4085 tracking_codes: [{"type":"Google Tag Manager","code":"GTM-P4XF7THD","server_enabled":"N","proxy_url":"","debug_mode":false}], 4086 tracking_codes_remove: [{"type":"Google Analytics (gtag)","code":"G-J883E4M4HN","server_enabled":"N","proxy_url":"","debug_mode":false}], 4087 // Tracking code types 4088 tracking_code_type_ga4: "Google Analytics (gtag)", 4089 tracking_code_type_ga4_debug: "Google Analytics (gtag) - DEBUG ONLY", 4090 tracking_code_type_gtm: "Google Tag Manager", 4091 tracking_code_type_gtm_debug: "Google Tag Manager - DEBUG ONLY", 4092 tracking_code_type_facebook_pixel: "Facebook Pixel", 4093 // Standard GA4 events 4094 tracking_code_gtag_command_event: "event", 4095 tracking_code_event_pageview: "page_view", 4096 tracking_code_event_add_to_cart: "add_to_cart", 4097 tracking_code_event_begin_checkout: "begin_checkout", 4098 tracking_code_event_purchase: "purchase", 4099 tracking_code_event_refund: "refund", 4100 tracking_code_event_remove_from_cart: "remove_from_cart", 4101 tracking_code_event_view_item: "view_item", 4102 tracking_code_event_view_item_list: "view_item_list", 4103 // User and cookie info 4104 cookie_is_accepted_statistic: false, 4105 cookie_is_accepted_marketing: false, 4106 user_age_range: "unknown", 4107 user_id: null, 4108 4109 globals: { 4110 html_classes: ["shop-page-buy","support-page-account","shop-page-basket","shop-page-booking","shop-page-config","shop-page-review-and-pay","shop-page-personal-info","shop-page-user-verifier","shop-page-confirm","shop-page-support","shop-page-account","shop-page-guest-account","shop-page-help","shop-page-maintenance","shop-page-replan","shop-page-booking-keycard-association","shop-page-wallet"], 4111 }, 4112 4113 sendPositionUrl: '/en/ajax/json/Ajax_User/get_position', 4114 4115 breadCrumb: { 4116 homeUrl: '/en/buy', 4117 }, 4118 4119 text: { 4120 basket: 'Cart', 4121 bookingChooseAvailabilityRequired: 'Please choose an availability', 4122 bookingChooseTimeRequired: 'Please select a time slot with available products', 4123 buy: 'Buy', 4124 copyToClipboardError: 'Error copying link', 4125 copyToClipboardSuccess: 'Link copied', 4126 copyToClipboardNotSupported: 'copy_to_clipboard.not_supported', 4127 clientError: 'Something went wrong with the request.', 4128 wafError: 'This file was blocked by our security filter. Please try resaving the file and uploading it again, or use a different file.', 4129 notFound: 'Error 404! Page not found', 4130 serverError: 'We\'re having some trouble on our end. Please try again later.', 4131 genericError: 'An error has occurred', 4132 showErrorDetails: 'Show technical details', 4133 home: 'Home', 4134 homeBuy: 'Buy your lift tickets and skipasses online', 4135 loading: 'Loading', 4136 title: "Online Ticketshop", 4137 }, 4138
4139 cookie: { 4140 cleanUpUrl: '/en/ajax/json/Ajax_User/cleanup_cookies', 4141 prefix: 'js_', 4142 sameSite: 'Lax', 4143 }, 4144 4145 login: { 4146 loginUrl: '/en/login', 4147 registrationUrl: '/en/create_account', 4148 guestRegistrationUrl: '/en/create_account_guest', 4149 }, 4150 4151 promoCodeUrl: '/en/ajax/html/Shop_Widget_PromoCode/promo_wid', 4152 shopChooseUrl: '/en/buy', 4153 shopChooseCompleteUrl: 'https://shop.suedtirolskiarena.com/en/store#/en/buy', 4154 navUrl: '/en/ajax/html/Ajax_Backoffice/nav', 4155 multilangTrkey: 'The fields are required in all languages<br />' 4156 }; 4157</script--> 4158<!--script src="https://cloud.skiperformance.com/media/js/app.js"></script--> 4159<!--script> 4160 url_elements = location.href.split("#"); 4161 if (url_elements.length == 1) 4162 { 4163 var querystring = ''; 4164 var default_shop_url = '/en/store'; 4165 var default_subpage = '/en/buy?bookable_y_n_a=a'; 4166 var full_url = default_shop_url; 4167 if (querystring != '') { 4168 full_url += '?' + querystring; 4169 } 4170 full_url += '#' + default_subpage; 4171 window.history.replaceState({}, null, full_url); 4172 } 4173</script--> 4174<section id="site-cookies" class="site-cookies xs-fixed xs-b0 xs-l0 xs-r0 xs-p3 xs-z4 lg-px5" style="display:none;"> 4175 <div class="grid xs-grid--g0 xs-grid--center"> 4176 <div class="gc xs-gc--auto"> 4177 <h3 class="cookie__title">This website uses cookies</h3> 4178 </div> 4179 <div class="gc xs-gc--none"> 4180 <a class="cookie__close xs-relative xs-t1- xs-r1-"> 4181 <i class="zs-icon-close-thin pointer main-color xs-text-24 js-cookie-form-submit" value="cookie.accept_close"></i> 4182 </a> 4183 </div> 4184 </div> 4185 <div class="xs-mb3"> 4186 We and our third-party partners use cookies for technical purposes and, with your consent, for statistical and marketing purposes as specified in the cookie policy. You can consent to the use of such technologies by using the "Accept all" button or set your preferences by using the "Accept selected" button. By closing this banner you continue to navigate using only necessary cookies. </div> 4187 <form class="js-cookie-form"> 4188 <div class="grid xs-grid--g2 md-grid--g0 xs-grid--center lg-grid--top lg-grid--center"> 4189 <div class="gc xs-gc12 xs-relative lg-gc--auto"> 4190 <fieldset class="xs-mb2 md-mb0 md-inline-block md-mr3"> 4191 <div class="grid xs-grid--center"> 4192 <div class="gc"> 4193 <span class="xs-gray-ccc-text bold xs-mr1">Necessary</span> 4194 </div> 4195 <div class="gc xs-text-right"> 4196 <label class="zs-switch xs-align-middle xs-text-right"> 4197 <input type="checkbox" class="js-cookie-form-checkbox" name="technical" value="1" checked="" disabled="" autocomplete="off"> 4198 <span class="zs-switch-slider"></span> 4199 </label> 4200 </div> 4201 </div> 4202 </fieldset> 4203 <fieldset class="xs-mb2 md-mb0 md-inline-block md-mr3"> 4204 <div class="grid xs-grid--center"> 4205 <div class="gc"> 4206 <span class=" bold xs-mr1">Statistics <span style="font-size: 10px;">(including US providers)</span></span> 4207 </div> 4208 <div class="gc xs-text-right"> 4209 <label class="zs-switch xs-align-middle xs-text-right"> 4210 <input type="checkbox" class="js-cookie-form-checkbox" name="statistic" value="1" autocomplete="off"> 4211 <span class="zs-switch-slider"></span> 4212 </label> 4213 </div> 4214 </div> 4215 </fieldset> 4216 <fieldset class="xs-mb2 md-mb0 md-inline-block md-mr3"> 4217 <div class="grid xs-grid--center"> 4218 <div class="gc"> 4219 <span class=" bold xs-mr1">Marketing <span style="font-size: 10px;">(including US providers)</span></span> 4220 </div> 4221 <div class="gc xs-text-right"> 4222 <label class="zs-switch xs-align-middle xs-text-right"> 4223 <input type="checkbox" class="js-cookie-form-checkbox" name="marketing" value="1" autocomplete="off"> 4224 <span class="zs-switch-slider"></span> 4225 </label> 4226 </div> 4227 </div> 4228 </fieldset> 4229 <div class="xs-mb2 xs-mt3 md-my0 md-inline md-center-y lg-block lg-no-center-y lg-mb0 lg-inline-block lg-center-y"> 4230 <a href="#" onclick="App.goTo('/en/support/cookie');return false;"> 4231 View details <i class="zs-icon-caret-right xs-align-middle"></i> 4232 </a> 4233 </div> 4234 </div> 4235 <div class="gc xs-gc12 lg-gc--none"> 4236 <fieldset class="xs-text-center md-mt2 lg-text-right lg-mt0"> 4237 <input type="button" class="button xs-mr04 xs-w40p xs-button--sm lg-w4 js-cookie-form-submit" value="Accept all"> 4238 <input type="button" class="button xs-ml04 xs-w40p xs-button--sm lg-w4 js-cookie-form-submit" value="Accept selected"> 4239 </fieldset> 4240 </div> 4241 </div> 4242 </form> 4243</section> 4244 4245<!--script> 4246 var isPrerender = true; 4247 var cookie_lifetime_days = 180; 4248 4249 function cookieAcceptEvent(event) { 4250 cookieAccept($(event.target).attr('value')); 4251 } 4252 4253 function cookieAccept(value) { 4254 const cookie_consent = {}; 4255 $('.js-cookie-form-checkbox').each(function(index, elem) { 4256 if (value == "Accept all") { 4257 cookie_consent[elem.name] = true; 4258 } else if (value == "cookie.accept_close") { 4259 cookie_consent[elem.name] = elem.name === 'technical'; 4260 } else { 4261 cookie_consent[elem.name] = elem.checked; 4262 } 4263 });
4264 App.setCookie('cookie_consent', JSON.stringify(cookie_consent), cookie_lifetime_days, window.location.hostname); 4265 App.deleteCookieNotTechnical(applyQueryParameters); 4266 $('#site-cookies').fadeOut(400); 4267 } 4268 4269 function cookieBannerShow() { 4270 $('#site-cookies').fadeIn(400); 4271 } 4272 4273 function saveQueryParameters() { 4274 const query_params = getQueryParameters(); 4275 sessionStorage.setItem('cookie_query_parameters', new URLSearchParams(query_params).toString()); 4276 } 4277 4278 function getQueryParameters() { 4279 const full_url = new URL(window.location.href); 4280 const hash_query_params = full_url.hash.split('?')[1] || ''; 4281 const session_query_params = sessionStorage.getItem('cookie_query_parameters') ?? ''; 4282 4283 return { 4284 ...Object.fromEntries(new URLSearchParams(session_query_params)), 4285 ...Object.fromEntries(new URLSearchParams(window.location.search)), 4286 ...Object.fromEntries(new URLSearchParams(hash_query_params)), 4287 }; 4288 } 4289 4290 function applyQueryParameters() { 4291 const query_params = getQueryParameters(); 4292 if (Object.keys(query_params).length) { 4293 // take the current url, remove any existing query parameters, and append the saved query parameters to it. 4294 // If there is a hash in the URL, preserve it as well. 4295 const current_url = new URL(window.location.href); 4296 const new_url = current_url.origin 4297 + current_url.pathname 4298 + '?' + new URLSearchParams(query_params).toString() 4299 + current_url.hash; 4300 if (new_url !== window.location.href) { 4301 window.location.href = new_url; 4302 return; 4303 } 4304 } 4305 location.reload(); 4306 } 4307 4308 App.pageSetUp(function() { 4309 saveQueryParameters(); 4310 if (!isPrerender) { 4311 if (App.getCookie('cookie_consent') === '') { 4312 cookieBannerShow(); 4313 } 4314 } 4315 // Consent defaults are now set in outer_page.php before any tag loads. 4316 // Only the update call is needed here, based on stored user preferences. 4317 App.applyConsents(); 4318 4319 $('.js-cookie-form-submit').off('click', null, cookieAcceptEvent).on('click', null, null, cookieAcceptEvent); 4320 }); 4321</script--> 4322 4323<!--script> 4324 var is_prerender = true; 4325 4326 App.pageSetUp(function() { 4327 if (!is_prerender) { 4328 4329 var targetNode = document.getElementById('content'); 4330 var config = { attributes: true, childList: true, subtree: true }; 4331 var callback = function(mutationsList, observer) { 4332 mutationsList.forEach(function(mutation) { 4333 if (mutation.type == 'childList' && mutation.addedNodes.length > 0) { 4334 if ($('.js-buy-promocode').length > 0) { 4335 $('body').addClass('promotab-selected'); 4336 } else { 4337 $('body').removeClass('promotab-selected'); 4338 } 4339 if ($('.js-buy-shoptab-wrapper li.tab-group').length == 1) { 4340 $('body').addClass('only-one-shoptab'); 4341 } else { 4342 $('body').removeClass('only-one-shoptab'); 4343 } 4344 } 4345 }); 4346 }; 4347 var observer = new MutationObserver(callback); 4348 observer.observe(targetNode, config); 4349 4350 $(document).off('ZoStrap-scroll', null, scrollOuterPage).on('ZoStrap-scroll', null, null, scrollOuterPage); 4351 $(document).off('ZoStrap-resize', null, resizeOuterPage).on('ZoStrap-resize', null, null, resizeOuterPage); 4352 } 4353 }); 4354 4355 function loadSnowFall() { 4356 var show_snow = false; 4357 if (show_snow) { 4358 var snowfall_today = new Date(); 4359 var snowfall_from = new Date(snowfall_today.getFullYear(), 11, 8, 0, 0, 0); 4360 var snowfall_to = new Date(snowfall_today.getFullYear() + 1, 0, 6, 23, 59, 59); 4361 if (snowfall_today.getTime() >= snowfall_from.getTime() && snowfall_today.getTime() <= snowfall_to.getTime()) { 4362 App.loadScript('https://cloud.skiperformance.com/media/js/snowfall.jquery.min.js', function() { 4363 $('#home-message:visible:not(:empty), #slideshow_above:visible:not(:empty), #slideshow_below:visible:not(:empty)').each(function (indx, elem) { 4364 $(elem).snowfall(); 4365 }); 4366 }); 4367 } 4368 } 4369 } 4370 4371 function scrollOuterPage(event) { 4372 var buy_datepickers = $('[id^="js-validity_start-"]:not([id$="-mobile"]):visible'); 4373 if (buy_datepickers.datepicker( "widget" ).is(":visible")) { 4374 ZoStrap.datepicker_recalculatePosition(buy_datepickers); 4375 // buy_datepickers.blur().datepicker('hide'); 4376 } 4377 if (typeof grid_details_buynow == 'function') { 4378 grid_details_buynow(); 4379 } 4380 $header = $("#js-page-header"); 4381 if ($(window).scrollTop() > $header.height()) 4382 { 4383 $header.addClass('header-small'); 4384 } else 4385 { 4386 $header.removeClass('header-small'); 4387 } 4388 } 4389 4390 function resizeOuterPage(event) { 4391 if (typeof tab_behavior == 'function') { 4392 tab_behavior(); 4393 } 4394 if (typeof promoTab_behavior == 'function') { 4395 promoTab_behavior(); 4396 } 4397 if (typeof grid_details_behavior == 'function') { 4398 grid_details_behavior(); 4399 } 4400 if (typeof numberGroupBehaviour == 'function') { 4401 numberGroupBehaviour(); 4402 } 4403 if (typeof backetBehaviour == 'function') { 4404 backetBehaviour(); 4405 } 4406 $('.js-buy-options-wrapper').css({ 4407 marginTop: 0 4408 }); 4409 } 4410 4411 function numberGroupBehaviour() { 4412 var ngi = $('.js-zostrap-ng-number'); 4413 ngi.each(function (index, elem) { 4414 elem = $(elem); 4415 var ng = elem.closest('.number-group'); 4416 if (ZoStrap.isMobile()) { 4417 ng.removeClass('number-group--small'); 4418 } else { 4419 ng.addClass('number-group--small'); 4420 } 4421 ZoStrap.numberGroupSize(elem); 4422 }); 4423 } 4424 4425 function getDatefromString(date, separator) { 4426 // var tz = new Date(date).toString().match(/([-\+][0-9]+)\s/)[1]; 4427 var arr_date = date.split(separator).map(function (x) { 4428 return parseInt(x, 10); 4429 }); 4430 return new Date(arr_date[0], arr_date[1] - 1, arr_date[2], 0, 0, 0) 4431 } 4432 4433 App.loadScript('https://cloud.skiperformance.com/media/js/datatables/datatables.min.js', function () { 4434 notifyDatatableScriptsLoaded(); 4435 }); 4436</script--> 4437 4438<!-- END OF PAGE CONTROLLER: Shop - ACTION: init - VIEW: shop/pages/outer_page --> 4439 4440<div><div class="grecaptcha-badge" data-style="bottomright" style="width: 256px; height: 60px; display: block; transition: right 0.3s; position: fixed; bottom: 14px; right: -186px; box-shadow: gray 0px 0px 5px; border-radius: 2px; overflow: hidden;"><div class="grecaptcha-logo"><iframe title="reCAPTCHA" width="256" height="60" role="presentation" name="a-p5cn0bgc41ya" frameborder="0" scrolling="no" sandbox="allow-forms allow-popups allow-same-origin allow-scripts allow-top-navigation allow-modals allow-popups-to-escape-sandbox allow-storage-access-by-user-activation" src="https://www.google.com/recaptcha/enterprise/anchor?ar=1&k=6LeX30kpAAAAAIZ-HrmlHKwbyirY6T1HDYl3Wnqs&co=aHR0cHM6Ly9zaG9wLnN1ZWR0aXJvbHNraWFyZW5hLmNvbTo0NDM.&hl=en&v=nY0xPItgwtlvjEjk2TqdwOQz&size=invisible&anchor-ms=20000&execute-ms=30000&cb=4i0rla8v8fsm"></iframe></div><div class="grecaptcha-error"></div><textarea id="g-recaptcha-response-100000" name="g-recaptcha-response" class="g-recaptcha-response" style="width: 250px; height: 40px; border: 1px solid rgb(193, 193, 193); margin: 10px 25px; padding: 0px; resize: none; display: none;"></textarea></div><iframe style="display: none;"></iframe></div><div id="zs-ui-main_container" class="zs zs-ui js-zs-ui-main_container"></div></body></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.