1<!doctype html> 2<html lang="de"> 3<head > 4 <meta charset="utf-8"/> 5<meta name="title" content="Blog â Knirps Regenschirme und Sonnenschirme"/> 6<meta name="description" content="Im Knirps Blog erhalten Sie alle Informationen und News zur Marke Knirps, den Produkten Regenschirme und Sonnenschirme und neuen Innovationen."/> 7<meta name="keywords" content="Blog, News, News-Blog, Info, Information, Neuigkeiten"/> 8<meta name="robots" content="INDEX,FOLLOW"/> 9<meta name="viewport" content="width=device-width, initial-scale=1"/> 10<meta name="msapplication-square70x70logo" content="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/images/touch-icons/logo-70.png"/> 11<meta name="msapplication-square150x150logo" content="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/images/touch-icons/logo-150.png"/> 12<meta name="msapplication-wide310x150logo" content="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/images/touch-icons/logo-310x150.png"/> 13<meta name="msapplication-square310x310logo" content="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/images/touch-icons/logo-310.png"/> 14<title>Blog â Knirps Regenschirme und Sonnenschirme</title> 15 <link rel="stylesheet" type="text/css" media="all" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Anowave_Ec/css/ec.css" /> 16<link rel="stylesheet" type="text/css" media="all" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/css/styles.css" /> 17<link rel="stylesheet" type="text/css" media="all" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Magezon_Core/css/styles.css" /> 18<link rel="stylesheet" type="text/css" media="all" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Magezon_Core/css/owlcarousel/owl.carousel.min.css" /> 19<link rel="stylesheet" type="text/css" media="all" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Magezon_Core/css/animate.css" /> 20<link rel="stylesheet" type="text/css" media="all" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Magezon_Core/css/fontawesome5.css" /> 21<link rel="stylesheet" type="text/css" media="all" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Magezon_Core/css/mgz_font.css" /> 22<link rel="stylesheet" type="text/css" media="all" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Magezon_Core/css/mgz_bootstrap.css" /> 23<link rel="stylesheet" type="text/css" media="all" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Magezon_Builder/css/openiconic.min.css" /> 24<link rel="stylesheet" type="text/css" media="all" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Magezon_Builder/css/styles.css" /> 25<link rel="stylesheet" type="text/css" media="all" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Magezon_Builder/css/common.css" /> 26<link rel="stylesheet" type="text/css" media="all" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Magezon_Core/css/magnific.css" /> 27<link rel="stylesheet" type="text/css" media="all" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Magezon_PageBuilder/css/styles.css" /> 28<link rel="stylesheet" type="text/css" media="all" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Magezon_PageBuilder/vendor/photoswipe/photoswipe.css" /> 29<link rel="stylesheet" type="text/css" media="all" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Magezon_PageBuilder/vendor/photoswipe/default-skin/default-skin.css" /> 30<link rel="stylesheet" type="text/css" media="all" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Magezon_PageBuilder/vendor/blueimp/css/blueimp-gallery.min.css" /> 31<link rel="stylesheet" type="text/css" media="all" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Magezon_PageBuilderIconBox/css/styles.css" />
32<script type="text/javascript" src="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Hyva_MagezonBuilder/js/load-script.js"></script>
32 33<link rel="preload" as="font" crossorigin="anonymous" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/fonts/FuturaStdBook.woff2" /> 34<link rel="preload" as="font" crossorigin="anonymous" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/fonts/FuturaStdMedium.woff2" /> 35<link rel="preload" as="font" crossorigin="anonymous" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/fonts/FuturaStdBold.woff2" /> 36<link rel="preload" as="font" crossorigin="anonymous" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/fonts/FuturaStdLight.woff2" /> 37<link rel="preload" as="font" crossorigin="anonymous" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/fonts/FuturaPTBook.woff2" /> 38<link rel="preload" as="font" crossorigin="anonymous" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/fonts/FuturaPTBold.woff2" /> 39<link rel="preload" as="font" crossorigin="anonymous" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/fonts/FuturaPTMedium.woff2" /> 40<link rel="preload" as="font" crossorigin="anonymous" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/fonts/FuturaPTLight.woff2" /> 41<link rel="preload" as="font" crossorigin="anonymous" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/fonts/helvetica-neue-lt-pro-400-normal.woff2" /> 42<link rel="preload" as="font" crossorigin="anonymous" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/fonts/helvetica-neue-lt-pro-400-italic.woff2" /> 43<link rel="preload" as="font" crossorigin="anonymous" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/fonts/helvetica-neue-lt-pro-700-normal.woff2" /> 44<link rel="preload" as="font" crossorigin="anonymous" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/fonts/helvetica-neue-lt-pro-700-italic.woff2" /> 45<link rel="preload" as="font" crossorigin="anonymous" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/fonts/helvetica-neue-lt-pro-cond-700.woff2" /> 46<link rel="preload" as="font" crossorigin="anonymous" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/fonts/helvetica-neue-lt-pro-100-normal.woff2" /> 47<link rel="preload" as="font" crossorigin="anonymous" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/fonts/helvetica-neue-lt-pro-200-normal.woff2" /> 48<link rel="preload" as="font" crossorigin="anonymous" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/fonts/helvetica-neue-lt-pro-300-normal.woff2" /> 49<link rel="canonical" href="https://knirps.de/blog" /> 50<link rel="alternate" hreflang="de" href="https://knirps.de/blog" /> 51<link rel="alternate" hreflang="x-default" href="https://knirps.de/blog" /> 52<link rel="alternate" hreflang="en" href="https://knirps.com/blog" /> 53<link rel="alternate" hreflang="nl" href="https://knirps.nl/blog" /> 54<link rel="alternate" hreflang="fr" href="https://knirps.fr/blog" /> 55<link rel="alternate" hreflang="de-CH" href="https://knirps.ch/blog" /> 56<link rel="apple-touch-icon" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/images/touch-icons/logo-180.png" /> 57<link rel="shortcut icon" href="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/images/touch-icons/logo-196.png" /> 58<link rel="icon" type="image/x-icon" href="https://knirps.de/media/favicon/default/knirps.svg" /> 59<link rel="shortcut icon" type="image/x-icon" href="https://knirps.de/media/favicon/default/knirps.svg" />
60<script async src="https://scripts.luigisbox.tech/LBX-770525.js"></script>
60 61<link rel="preconnect" href="https://www.googletagmanager.com"> 62<meta name="p:domain_verify" content="c8044b0028600c4390e40e1c7d436e63"> 63 64
64<script data-ommit="true" nonce="MW8zbHFodjIwMXlkMHZyNXk1Z2htd2p6a2FwNHo5a24=">var AEC = (function() 65{ 66 return { 67 add: function(context, dataLayer) 68 { 69 let element = context, qty = 1, variants = [], variant = [], variant_attribute_option = [], items = []; 70 71 document.querySelectorAll('input[name=qty]:checked, [name=qty]').forEach(element => 72 { 73 qty = element.value; 74 }); 75 76 qty = Math.abs(qty); 77 78 if (isNaN(qty)) 79 { 80 qty = 1; 81 } 82 83 function closestForm(element) 84 { 85 while (element) 86 { 87 if (element.tagName === 'FORM') 88 { 89 return element; 90 } 91 element = element.parentElement; 92 } 93 return null; 94 } 95 96 const form = closestForm(context); 97 98 if (form && typeof form.checkValidity === 'function') 99 { 100 if (!form.checkValidity()) 101 { 102 return true; 103 } 104 } 105 106 if (!AEC.gtm()) 107 { 108 if (element.dataset?.click) 109 { 110 AEC.Time.track(dataLayer, AEC.Const.TIMING_CATEGORY_ADD_TO_CART, element.dataset?.name, element.dataset?.category); 111 112 (click => 113 { 114 new Function(click)(); 115 }) 116 (element.dataset?.click); 117 } 118 119 return true; 120 } 121 122 if(element.dataset?.configurable) 123 { 124 document.querySelectorAll('[name^="super_attribute"]').forEach(attribute => 125 { 126 if (attribute.matches('select')) 127 { 128 var name = attribute.getAttribute('name'), id = name.substring(name.indexOf('[') + 1, name.lastIndexOf(']')); 129 130 if (attribute.selectedIndex) 131 { 132 var option = attribute.options[attribute.selectedIndex]; 133 134 if (option) 135 { 136 variants.push( 137 { 138 id: id, 139 option: option.label, 140 text: option.text 141 }); 142 } 143 } 144 } 145 146 if (attribute.matches('input') && -1 != attribute.type.indexOf('radio')) 147 { 148 if (attribute.parentNode.classList.contains('swatch-option-selected') || attribute.checked) 149 { 150 Object.entries(AEC.SUPER).forEach(([key, super_attribute]) => 151 { 152 if (-1 != attribute.name.indexOf("super_attribute[" + super_attribute.id + "]")) 153 { 154 let variant = 155 { 156 id: super_attribute.id, 157 /* START OF MODIFICATIONS */ 158 text: attribute.ariaLabel, 159 sku: element.dataset?.simpleId, 160 /* END OF MODIFICATIONS */ 161 option: attribute.value 162 }; 163 164 variants.push(variant); 165 } 166 }); 167 } 168 } 169 }); 170 171 /** 172 * Colour Swatch support 173 */ 174 if (!variants.length) 175 { 176 Object.entries(AEC.SUPER).forEach(([key, attribute]) => 177 { 178 var swatch = document.querySelectorAll('div[attribute-code="' + attribute.code + '"], div[data-attribute-code="' + attribute.code + '"]'); 179 180 swatch.forEach(element => 181 { 182 let variant = 183 { 184 id: attribute.id, 185 text: '', 186 option: null 187 }; 188 189 var select = element.querySelector('select'); 190 191 if (select) 192 { 193 if (select.selectedIndex) 194 { 195 var option = select.options[select.selectedIndex]; 196 197 if (option) 198 { 199 variant.text = option.text; 200 variant.option = option.value; 201 } 202 } 203 } 204 else 205 { 206 var span = element.querySelector('span.swatch-attribute-selected-option'); 207 208 if (span) 209 { 210 variant.text = span.innerHTML; 211 variant.option = span.parentNode.dataset.optionSelected; 212 } 213 } 214 215 variants.push(variant); 216 }); 217 }); 218 } 219 220 if (!variants.length) 221 { 222 AEC.EventDispatcher.trigger('ec.variants', variants); 223 } 224 225 var SUPER_SELECTED = []; 226 227 for (var i = 0, l = variants.length; i < l; i++) 228 { 229 for (var a = 0, b = AEC.SUPER.length; a < b; a++) 230 { 231 if (AEC.SUPER[a].id == variants[i].id) 232 { 233 var text = variants[i].text; 234 235 if (AEC.useDefaultValues) 236 { 237 AEC.SUPER[a].options.forEach(option => 238 { 239 if (parseInt(option.value_index) == parseInt(variants[i].option)) 240 { 241 if (option.hasOwnProperty('admin_label')) 242 { 243 text = option.admin_label; 244 } 245 else if (option.hasOwnProperty('store_label')) 246 { 247 text = option.store_label; 248 } 249 } 250 }); 251 } 252 253 variant.push([AEC.SUPER[a].label,text].join(AEC.Const.VARIANT_DELIMITER_ATT)); 254 255 let tier_price = Number.parseFloat(element.dataset?.price).toFixed(2); 256
257 Object.entries(AEC.CONFIGURABLE_SIMPLES).forEach(([key, simple]) => 258 { 259 if (simple.hasOwnProperty('configurations')) 260 { 261 Object.entries(simple.configurations).forEach(([key, configuration]) => 262 { 263 if (configuration.label === variants[i].option) 264 { 265 let prices = []; 266 267 Object.entries(simple.price_tier).forEach(([key, tier]) => 268 { 269 if (parseInt(qty) >= parseInt(tier.price_qty)) 270 { 271 prices.push(Number.parseFloat(tier.price)); 272 } 273 }); 274 275 if (prices.length) 276 { 277 tier_price = prices.sort(function(a,b) { return a < b; }).pop(); 278 } 279 } 280 }); 281 } 282 }); 283 284 variant_attribute_option.push( 285 { 286 attribute: variants[i].id, 287 option: variants[i].option, 288 price: tier_price 289 }); 290 } 291 } 292 } 293 294 if (!variant.length) 295 { 296 if (element.dataset?.click) 297 { 298 AEC.Time.track(dataLayer, AEC.Const.TIMING_CATEGORY_ADD_TO_CART, element.dataset?.name, element.dataset?.category); 299 300 (click => 301 { 302 new Function(click)(); 303 }) 304 (element.dataset?.click); 305 } 306 307 return true; 308 } 309 } 310 311 if (element.dataset?.grouped) 312 { 313 for (var u = 0, y = window.G.length; u < y; u++) 314 { 315 let field = document.querySelector('[name="super_group[' + window.G[u].id + ']"]'); 316 317 if (field) 318 { 319 (qty => 320 { 321 if (qty) 322 { 323 let item = 324 { 325 'item_name': window.G[u].item_name, 326 'item_id': window.G[u].item_id, 327 'price': window.G[u].price, 328 'category': window.G[u].category, 329 'item_brand': window.G[u].item_brand, 330 'quantity': qty 331 }; 332 333 Object.assign(item, item, AEC.GA4.transformCategories(element.dataset?.category)); 334 335 items.push(item); 336 } 337 })(Math.abs(field.value)); 338 } 339 } 340 } 341 else 342 { 343 let price = Number.parseFloat(element.dataset?.price); 344 345 if (element.dataset?.hasOwnProperty('selection')) 346 { 347 let selection = parseInt(element.dataset?.selection); 348 349 Object.entries(AEC.CONFIGURABLE_SIMPLES).forEach(([key, simple]) => 350 { 351 if (key == selection) 352 { 353 if (simple.hasOwnProperty('price_tier')) 354 { 355 Object.entries(simple.configurations).forEach(([key, configuration]) => 356 { 357 let prices = []; 358 359 Object.entries(simple.price_tier).forEach(([key, tier]) => 360 { 361 if (parseInt(qty) >= parseInt(tier.price_qty)) 362 { 363 prices.push(Number.parseFloat(tier.price)); 364 } 365 }); 366 367 if (prices.length) 368 { 369 price = prices.sort(function(a,b) { return a < b; }).pop(); 370 } 371 }); 372 } 373 } 374 }); 375 } 376 /* START OF MODIFICATIONS */ 377 let item = 378 { 379 category: element.dataset?.category, 380 google_business_vertical: element.dataset?.googleBusinessVertical ?? 'retail', 381 index: 0, 382 item_brand: element.dataset?.brand, 383 item_id: 1 === parseInt(element.dataset?.useSimple) ? element.dataset?.simpleId : element.dataset?.id, 384 /*item_id_numeric: parseInt(element.dataset?.numeric),*/ 385 item_name: element.dataset?.name, 386 item_variant: variant.join(AEC.Const.VARIANT_DELIMITER), 387 /*variants: variants,*/ 388 price: price, 389 quantity: qty, 390 /*currency: AEC.currencyCode,*/ 391 /*remarketingAdwordsId: element.dataset?.remarketingAdwordsId,*/ 392 /*remarketingFacebookId: element.dataset?.remarketingFacebookId,*/ 393 variant_id: variants[0]?.sku 394 }; 395 /* END OF MODIFICATIONS */ 396 Object.assign(item, item, AEC.GA4.transformCategories(element.dataset?.category)); 397 398 items.push(item); 399 } 400 401 let value_combined = 0; 402 403 for (var i = 0, l = items.length; i < l; i++) 404 { 405 value_combined += (Number.parseFloat(items[i].price) * Number.parseInt(items[i].quantity)); 406 407 (function(item) 408 { 409 Object.entries(AEC.parseJSON(element.dataset?.attributes)).forEac
409h(([key, value]) => 410 { 411 item[key] = value; 412 }); 413 414 let options = []; 415 416 Object.entries(AEC.parseJSON(element.dataset?.options)).forEach(([key, name]) => 417 { 418 let option = document.querySelector('[name="options[' + key + ']"]'), value = null; 419 420 if (!option) 421 { 422 option = document.querySelector('[name="options[' + key + '][]"]'); 423 } 424 425 switch(true) 426 { 427 case option instanceof HTMLInputElement: 428 case option instanceof HTMLTextAreaElement: value = option.value; 429 break; 430 case option instanceof HTMLSelectElement: value = option.options[option.selectedIndex].text; 431 break; 432 } 433 434 if (value) 435 { 436 options.push({ name: name, value: value }); 437 } 438 439 }); 440 441 if (options.length) 442 { 443 item['options'] = options; 444 } 445 446 /* START OF MODIFICATIONS */ 447 items[i] = Object.fromEntries(Object.entries(item).sort(([a], [b]) => a.localeCompare(b))); 448 /* END OF MODIFICATIONS */ 449 450 })(items[i]); 451 } 452 453 var data = 454 { 455 'event':'add_to_cart', 456 'ecommerce': 457 { 458 'currency': AEC.currencyCode, 459 'value': value_combined, 460 'item_list_id': element.dataset?.list, 461 'item_list_name': element.dataset?.list, 462 'items': items, 463 /* START OF MODIFICATIONS 464 'options': variant_attribute_option 465 END OF MODIFICATIONS */ 466 }, 467 'currentStore': element.dataset?.store 468 }; 469 470 if (AEC.useDefaultValues) 471 { 472 data['currentStore'] = AEC.storeName; 473 } 474 475 /** 476 * Notify listeners 477 */ 478 this.EventDispatcher.trigger('ec.add.data', data); 479 480 /** 481 * Track event 482 */ 483 AEC.CookieConsent.queue(() => 484 { 485 AEC.Cookie.add(data).push(dataLayer); 486 487 /** 488 * Track time 489 */ 490 AEC.Time.track(dataLayer, AEC.Const.TIMING_CATEGORY_ADD_TO_CART, element.dataset?.name, element.dataset?.category); 491 492 }).process(); 493 494 /** 495 * Save backreference 496 */ 497 if (AEC.localStorage) 498 { 499 (function(items) 500 { 501 for (var i = 0, l = items.length; i < l; i++) 502 { 503 AEC.Storage.reference().set( 504 { 505 id: items[i].item_id, 506 category: items[i].category 507 }); 508 } 509 })(items); 510 } 511 512 if (AEC.facebook) 513 { 514 if ("function" === typeof fbq) 515 { 516 (function(product, items, fbq) 517 { 518 var content_ids = [], price = 0; 519 520 for (var i = 0, l = items.length; i < l; i++) 521 { 522 content_ids.push(items[i].remarketingFacebookId ?? items[i].item_id); 523 524 price += parseFloat(items[i].price); 525 } 526 527 (function(callback) 528 { 529 if (AEC.Const.COOKIE_DIRECTIVE) 530 { 531 AEC.CookieConsent.queue(callback).process(); 532 } 533 else 534 { 535 callback.apply(window,[]); 536 } 537 }) 538 ( 539 (function(product, content_ids, price) 540 { 541 return function() 542 { 543 if ('undefined' === typeof variants) 544 { 545 variants = []; 546 } 547 548 fbq('track', 'AddToCart', 549 { 550 content_name: product, 551 content_ids: content_ids, 552 content_type: !variants.length ? 'product' : 'product_group', 553 value: price, 554 currency: AEC.currencyCode 555 }, 556 { 557 eventID: AEC.UUID.generate({ event: 'AddToCart'}) 558 }); 559 }; 560 561 })(product, content_ids, price) 562 ); 563 564 })(element.dataset?.name, items, fbq); 565 } 566 } 567 568 if (AEC.tiktok) 569 { 570 if ('undefined' !== typeof ttq) 571 { 572 (function(product, items, ttq) 573 { 574 var contents = [], price = 0; 575 576 for (var i = 0, l = items.length; i < l; i++) 577 { 578 contents.push 579 ( 580 { 581 content_id: items[i].item_id, 582 content_name: items[i].item_name, 583 quantity: items[i].quantity, 584 brand: items[i].item_brand, 585 price: items[i].price 586 } 587 ); 588 589 price += parseFloat(items[i].price); 590 } 591 592 (function(callback) 593 { 594 if (AEC.Const.COOKIE_DIRECTIVE) 595 { 596 AEC.CookieConsent.queue(callback).process(); 597 } 598 else 599 { 600 callback.apply(window,[]); 601 } 602 }) 603 ( 604 (function(product, content_ids, price) 605 { 606 return function() 607 { 608 AEC.TikTok.event('AddToCart', { 609 contents: contents, 610 content_type:'product', 611 value: price, 612 currency: AEC.currencyCode, 613 }, 614 { 615 event_id: AEC.UUID.generate({ event: 'AddToCart'}) 616 }); 617 }; 618 619 })(product, contents, price) 620 ); 621 622 })(element.dataset?.name, items, ttq); 623 } 624 } 625 626 if (element.dataset?.click) 627 { 628 (click => 629 { 630 new Function(click)(); 631 }) 632 (element.dataset?.click); 633 } 634 635 return true; 636 }, 637 addSwatch: function(context,dataLayer) 638 { 639 var element = context; 640 641 if (window.jQuery) 642 { 643 jQuery(document).on('ajax:addToCart', function() 644 { 645 var attributes = []; 646 647 Object.entries(AEC.parseJSON(element.dataset?.swatch)).forEac
647h(([key, value]) => 648 { 649 attributes.push(value); 650 }); 651 652 var option = document.querySelector('.swatch-option.selected'); 653 654 if (!option) 655 { 656 let form = jQuery(element).parents('form:first'); 657 658 if (form) 659 { 660 let selected = []; 661 662 Object.entries(attributes).forEach(([key, value]) => 663 { 664 let e = form.find('input[name="super_attribute[' + value.attribute_id + ']"]'); 665 666 if (e.length > 0) 667 { 668 if (e.get(0).dataset.hasOwnProperty('label')) 669 { 670 let a = e.get(0).dataset.label; 671 let b = value.attribute_label; 672 673 selected.push([b,a].join(AEC.Const.VARIANT_DELIMITER_ATT)); 674 } 675 else if(e.get(0).dataset.hasOwnProperty('attrName')) 676 { 677 let a = e.get(0).value; 678 let b = value.attribute_label; 679 680 selected.push([b,a].join(AEC.Const.VARIANT_DELIMITER_ATT)); 681 } 682 } 683 }); 684 685 variant = [selected].join(AEC.Const.VARIANT_DELIMITER); 686 } 687 } 688 else 689 { 690 variant = [[attributes[0].attribute_label, option.getAttribute('aria-label')].join(AEC.Const.VARIANT_DELIMITER_ATT)].join(AEC.Const.VARIANT_DELIMITER); 691 } 692 693 let item = 694 { 695 category: element.dataset?.category, 696 index: element.dataset?.position, 697 item_brand: element.dataset?.brand, 698 item_id: element.dataset?.id, 699 item_id_numeric:parseInt(element.dataset?.numeric), 700 item_list_id: element.dataset?.list, 701 item_list_name: element.dataset?.list, 702 item_name: element.dataset?.name, 703 item_variant: variant, 704 price: element.dataset?.price, 705 quantity: 1 706 }; 707 708 Object.assign(item, item, AEC.GA4.transformCategories(element.dataset?.category)); 709 710 /* START OF MODIFICATIONS */ 711 item = Object.fromEntries(Object.entries(item).sort(([a], [b]) => a.localeCompare(b))); 712 /* END OF MODIFICATIONS */ 713 714 /** 715 * Track event 716 */ 717 AEC.Cookie.add( 718 { 719 event: 'add_to_cart', 720 currency: AEC.currencyCode, 721 item_list_id: element.dataset?.list, 722 item_list_name: element.dataset?.list, 723 ecommerce: 724 { 725 items: [item] 726 }, 727 currentStore: element.dataset?.store 728 }).push(dataLayer); 729 730 /** 731 * Track time 732 */ 733 AEC.Time.track(dataLayer, AEC.Const.TIMING_CATEGORY_ADD_TO_CART, element.dataset?.name, element.dataset?.category); 734 }); 735 } 736 737 return true; 738 }, 739 click: function(context,dataLayer) 740 { 741 var element = context; 742
743 if (!AEC.gtm()) 744 { 745 AEC.Time.track(dataLayer, AEC.Const.TIMING_CATEGORY_PRODUCT_CLICK, element.dataset?.name, element.dataset?.category); 746 747 return true; 748 } 749 /* START OF MODIFICATIONS */ 750 var item = 751 { 752 category: element.dataset?.category, 753 google_business_vertical: 'retail', 754 index: element.dataset?.position, 755 item_brand: element.dataset?.brand, 756 item_id: element.dataset?.id, 757 item_list_id: element.dataset?.list, 758 item_list_name: element.dataset?.list, 759 item_name: element.dataset?.name, 760 /*item_id_numeric:parseInt(element.dataset?.numeric),*/ 761 price: element.dataset?.price, 762 quantity: element.dataset?.quantity, 763 variant_id: element.dataset.simpleId, 764 /*currency: AEC.currencyCode*/ 765 }; 766 767 Object.entries(AEC.parseJSON(element.dataset?.attributes)).forEach(([key, value]) => 768 { 769 item[key] = value; 770 }); 771 772 /* START OF MODIFICATIONS */ 773 Object.assign(item, item, AEC.GA4.transformCategories(item.category)); 774 item = Object.fromEntries(Object.entries(item).sort(([a], [b]) => a.localeCompare(b))); 775 /* END OF MODIFICATIONS */ 776 777 var data = 778 { 779 event: 'select_item', 780 currentStore: element.dataset?.store, 781 /*item_list_id: element.dataset?.list, 782 item_list_name: element.dataset?.list,*/ 783 ecommerce: 784 { 785 item_list_id: element.dataset?.list, 786 item_list_name: element.dataset?.list, 787 items: 788 [ 789 item 790 ] 791 }, 792 }; 793 /* END OF MODIFICATIONS */ 794 795 /** 796 * Push data 797 */ 798 AEC.CookieConsent.queue(() => 799 { 800 AEC.Cookie.click(data).push(dataLayer); 801 802 }).process(); 803 804 /** 805 * Track time 806 */ 807 AEC.Time.track(dataLayer, AEC.Const.TIMING_CATEGORY_PRODUCT_CLICK, element.dataset?.name, element.dataset?.category); 808 809 if (element.dataset?.click) 810 { 811 (click => 812 { 813 new Function(click)(); 814 }) 815 (element.dataset?.click); 816 } 817 818 return true; 819 }, 820 remove: function(context, dataLayer, event) 821 { 822 var element = context; 823
824 if (!AEC.gtm()) 825 { 826 AEC.Time.track(dataLayer, AEC.Const.TIMING_CATEGORY_REMOVE_FROM_CART, element.dataset?.name, element.dataset?.category); 827 } 828 829 /* START OF MODIFICATIONS */ 830 var item = 831 { 832 item_name: element.dataset?.name, 833 item_id: element.dataset?.id, 834 price: parseFloat(element.dataset?.price), 835 category: element.dataset?.category, 836 item_brand: element.dataset?.brand, 837 quantity: element.dataset?.quantity, 838 currency: AEC.currencyCode 839 }; 840 /* END OF MODIFICATIONS */ 841 842 Object.entries(AEC.parseJSON(element.dataset?.attributes)).forEach(([key, value]) => 843 { 844 item[key] = value; 845 }); 846 847 Object.assign(item, item, AEC.GA4.augmentCategories(item)); 848 849 /* START OF MODIFICATIONS */ 850 item = Object.fromEntries(Object.entries(item).sort(([a], [b]) => a.localeCompare(b))); 851 /* END OF MODIFICATIONS */ 852 853 var data = 854 { 855 event: 'remove_from_cart', 856 /* START OF MODIFICATIONS */ 857 currentStore: element.dataset?.store, 858 /*eventLabel: element.dataset?.name,*/ 859 /* END OF MODIFICATIONS */ 860 ecommerce: 861 { 862 item_list_id: element.dataset?.list, 863 item_list_name: element.dataset?.list, 864 items: 865 [ 866 item 867 ] 868 } 869 }; 870 871 AEC.EventDispatcher.trigger('ec.remove.data', data); 872 873 let executor = element => 874 { 875 let params = 876 { 877 action:null 878 }; 879 880 if (element.dataset?.hasOwnProperty('postreaction')) 881 { 882 params = AEC.parseJSON(element.dataset?.postreaction); 883 } 884 else if (element.dataset?.hasOwnProperty('post')) 885 { 886 params = AEC.parseJSON(element.dataset?.post); 887 } 888 else if (element.dataset?.hasOwnProperty('postAction')) 889 { 890 params = AEC.parseJSON(element.dataset?.postAction); 891 } 892 893 async function getFormKey() 894 { 895 if ('cookieStore' in window) 896 { 897 const cookie = await cookieStore.get('form_key'); 898 899 return cookie?.value || null; 900 } 901 902 const cookies = Object.fromEntries(document.cookie.split('; ').map(cookie => 903 { 904 const [name, value] = cookie.split('='); 905 return [decodeURIComponent(name), decodeURIComponent(value)]; 906 })); 907 908 return cookies['form_key'] || null; 909 } 910 911 getFormKey().then(formKey => 912 { 913 let form = document.createElement("form"); 914 915 form.setAttribute('method', 'post'); 916 form.setAttribute('action', params.action); 917 918 if (params.hasOwnProperty('data')) 919 { 920 params.data['form_key'] = formKey; 921 922 Object.entries(params.data).forEach(([name, value]) => 923 { 924 let input = document.createElement('input'); 925 926 input.setAttribute('type', 'text'); 927 input.setAttribute('name', name); 928 input.setAttribute('value', value); 929 930 form.append(input); 931 }); 932 } 933 934 document.querySelector("body").appendChild(form); 935 936 form.submit(); 937 }); 938 }; 939 940 if (AEC.Message.confirm) 941 { 942 if (typeof require !== "undefined" && typeof require === "function") 943 { 944 require(['Magento_Ui/js/modal/confirm'], function(confirmation) 945 { 946 confirmation( 947 { 948 title: AEC.Message.confirmRemoveTitle, 949 content: AEC.Message.confirmRemove, 950 actions: 951 { 952 confirm: function() 953 { 954 /** 955 * Track event 956 */ 957 AEC.Cookie.remove(data).push(dataLayer); 958 959 /** 960 * Track time 961 */ 962 AEC.Time.track(dataLayer, AEC.Const.TIMING_CATEGORY_REMOVE_FROM_CART, element.dataset?.name); 963 964 /** 965 * Execute standard data-post 966 */ 967 executor(element); 968 }, 969 cancel: function() 970 { 971 return false; 972 }, 973 always: function() 974 { 975 return false; 976 } 977 } 978 }); 979 }); 980 } 981 else 982 { 983 if (typeof Alpine !== "undefined") 984 { 985 return true; 986 } 987 } 988 } 989 else 990 { 991 /** 992 * Track event 993 */ 994 AEC.Cookie.remove(data).push(dataLayer); 995 996 /** 997 * Track time 998 */ 999 AEC.Time.track(dataLayer, AEC.Const.TIMING_CATEGORY_REMOVE_FROM_CART, element.dataset?.name); 1000 1001 executor(element); 1002 } 1003 1004 return false;
1005 }, 1006 wishlist: function(context, dataLayer) 1007 { 1008 var element = context; 1009 1010 if (!AEC.gtm()) 1011 { 1012 /** 1013 * Track time 1014 */ 1015 AEC.Time.track(dataLayer, AEC.Const.TIMING_CATEGORY_PRODUCT_WISHLIST, element.dataset?.name,'Wishlist'); 1016 1017 return true; 1018 } 1019 1020 let attributes = JSON.parse(element.dataset?.eventAttributes); 1021 1022 /** 1023 * Track event 1024 */ 1025 AEC.Cookie.wishlist( 1026 { 1027 event: element.dataset?.event, 1028 eventLabel: element.dataset?.eventLabel, 1029 ecommerce: 1030 { 1031 items: attributes.items 1032 } 1033 }).push(dataLayer); 1034 1035 return true; 1036 }, 1037 wishlistRemove: function(context, dataLayer) 1038 { 1039 var element = context; 1040 1041 if (!AEC.gtm()) 1042 { 1043 /** 1044 * Track time 1045 */ 1046 AEC.Time.track(dataLayer, AEC.Const.TIMING_CATEGORY_PRODUCT_WISHLIST, element.dataset?.name,'Wishlist'); 1047 1048 return true; 1049 } 1050 1051 let attributes = JSON.parse(element.dataset?.eventAttributes); 1052 1053 /** 1054 * Track event 1055 */ 1056 AEC.Cookie.wishlistRemove( 1057 { 1058 event: element.dataset?.event, 1059 eventLabel: element.dataset?.eventLabel, 1060 ecommerce: 1061 { 1062 items: attributes.items 1063 } 1064 }).push(dataLayer); 1065 1066 return true; 1067 }, 1068 compare: function(context, dataLayer) 1069 { 1070 var element = context; 1071 1072 if (!AEC.gtm()) 1073 { 1074 /** 1075 * Track time 1076 */ 1077 AEC.Time.track(dataLayer, AEC.Const.TIMING_CATEGORY_PRODUCT_COMPARE, element.dataset?.name,'Compare'); 1078 1079 return true; 1080 } 1081 1082 let attributes = JSON.parse(element.dataset?.eventAttributes); 1083 1084 AEC.Cookie.compare( 1085 { 1086 event: element.dataset?.event, 1087 eventLabel: element.dataset?.eventLabel, 1088 ecommerce: 1089 { 1090 items: attributes.items 1091 } 1092 }).push(dataLayer); 1093 1094 return true; 1095 }, 1096 Bind: (function() 1097 { 1098 return { 1099 apply: function(parameters) 1100 { 1101 /** 1102 * Merge persistent storage 1103 */ 1104 AEC.Persist.merge(); 1105 1106 /** 1107 * Push private data 1108 */ 1109 AEC.Cookie.pushPrivate(); 1110 1111 document.addEventListener('DOMContentLoaded',() => 1112 { 1113 document.body.addEventListener('catalogCategoryAddToCartRedirect', () => 1114 { 1115 dataLayer.push( 1116 { 1117 event: AEC.Const.CATALOG_CATEGORY_ADD_TO_CART_REDIRECT_EVENT 1118 }); 1119 }); 1120 }); 1121 1122 if (parameters) 1123 { 1124 if (parameters.performance) 1125 { 1126 if (window.performance) 1127 { 1128 window.onload = function() 1129 { 1130 setTimeout(function() 1131 { 1132 var time = performance.timing.loadEventEnd - performance.timing.responseEnd; 1133 1134 var timePayload = 1135 { 1136 'event':'performance', 1137 'performance': 1138 { 1139 'timingCategory': 'Load times', 1140 'timingVar': 'load', 1141 'timingValue': (time % 60000) 1142 } 1143 }; 1144 1145 switch(window.google_tag_params.ecomm_pagetype) 1146 { 1147 case 'home': 1148 1149 timePayload.performance.timingLabel = 'Home'; 1150 1151 AEC.CookieConsent.queue(() => 1152 { 1153 dataLayer.push(timePayload); 1154 }).process(); 1155 1156 break; 1157 case 'product': 1158 1159 timePayload.performance.timingLabel = 'Product'; 1160 1161 AEC.CookieConsent.queue(() => 1162 { 1163 dataLayer.push(timePayload); 1164 }).process(); 1165 1166 break; 1167 1168 case 'category': 1169 1170 timePayload.performance.timingLabel = 'Category'; 1171 1172 AEC.CookieConsent.queue(() => 1173 { 1174 dataLayer.push(timePayload); 1175 }).process(); 1176 1177 break; 1178 } 1179 1180 }, 0); 1181 }; 1182 } 1183 } 1184 } 1185 1186 return this; 1187 } 1188 }; 1189 1190 })(), 1191 Time: (function() 1192 { 1193 var T = 1194 { 1195 event: 'trackTime', 1196 timingCategory: '', 1197 timingVar: '', 1198 timingValue: -1, 1199 timingLabel: '' 1200 }; 1201 1202 var time = new Date().getTime(); 1203 1204 return { 1205 track: function(dataLayer, category, variable, label) 1206 { 1207 T.timingValue = (new Date().getTime()) - time; 1208 1209 if (category) 1210 { 1211 T.timingCategory = category; 1212 } 1213 1214 if (variable) 1215 { 1216 T.timingVar = variable; 1217 } 1218 1219 if (label) 1220 { 1221 T.timingLabel = label; 1222 } 1223 1224 dataLayer.push(T); 1225 1226 }, 1227 trackContinue: function(dataLayer, category, variable, label) 1228 { 1229 this.track(dataLayer, category, variable, label); 1230 1231 time = new Date().getTime(); 1232 } 1233 }; 1234 1235 })(), 1236 Persist:(function() 1237 { 1238 var DATA_KEY = 'persist'; 1239 1240 var proto = 'undefined' != typeof Storage ? 1241 { 1242 push: function(key, entity) 1243 { 1244 /** 1245 * Get data 1246 */ 1247 var data = this.data(); 1248 1249 /** 1250 * Push data 1251 */ 1252 data[key] = entity; 1253 1254 /** 1255 * Save to local storage 1256 */ 1257 localStorage.setItem(DATA_KEY, JSON.stringify(data)); 1258 1259 return this; 1260 }, 1261 data: function() 1262 { 1263 var data = localStorage.getItem(DATA_KEY); 1264 1265 if (null !== data) 1266 { 1267 return JSON.parse(data); 1268 } 1269 1270 return {}; 1271 }, 1272 merge: function() 1273 { 1274 var data = this.data(); 1275 var push = 1276 { 1277 persist: {} 1278 }; 1279 1280 for (var i in data) 1281 { 1282 push.persist[i] = data[i]; 1283 } 1284 1285 dataLayer.push(push); 1286 1287 return this; 1288 }, 1289 clear: function() 1290 { 1291 /** 1292 * Reset private local storage 1293 */ 1294 localStorage.setItem(DATA_KEY,JSON.stringify({})); 1295 1296 return this; 1297 } 1298 } : { 1299 push: function(){}, 1300 merge: function(){}, 1301 clear: function(){} 1302 }; 1303 1304 /** 1305 * Constants 1306 */ 1307 proto.CONST_KEY_PROMOTION = 'persist_promotion'; 1308 1309 return proto; 1310 1311 })(), 1312 Checkout: (function() 1313 { 1314 return { 1315 init: false, 1316 data: {}, 1317 tracked: {}, 1318 getData: function() 1319 { 1320 return this.data; 1321 }, 1322 getPayload: function() 1323 { 1324 if (this.data && this.data.hasOwnProperty('payload')) 1325 { 1326 return this.data.payload; 1327 } 1328 1329 return { 1330 error: 'Missing checkout payload data' 1331 }; 1332 }, 1333 step: function(previous, current, currentCode) 1334 { 1335 if (!this.init) 1336 { 1337 return this.fail('Step tracking requires a checkout page.'); 1338 } 1339 1340 if (this.data && this.data.hasOwnProperty('ecommerce')) 1341 { 1342 this.data.ecommerce['step'] = ++current; 1343 1344 /** 1345 * Notify listeners 1346 */ 1347 AEC.EventDispatcher.trigger('ec.checkout.step.data', this.data); 1348 1349 /** 1350 * Track checkout step 1351 */ 1352 AEC.Cookie.checkout(this.data).push(dataLayer); 1353 } 1354 1355 return this; 1356 }, 1357 stepOption: function(step, option) 1358 { 1359 if (!option) 1360 { 1361 return this; 1362 } 1363 1364 if (!this.init) 1365 { 1366 return this.fail('Step option tracking requires a checkout page.'); 1367 } 1368 1369 1370 if (!option.toString().length) 1371 { 1372 return this; 1373 } 1374 1375 var data = 1376 { 1377 'event': 'checkoutOption', 1378 'ecommerce': 1379 { 1380 'checkout_option': 1381 { 1382 'actionField': 1383 { 1384 'step': step, 1385 'option': option 1386 } 1387 } 1388 } 1389 }; 1390 1391 /** 1392 * Notify listeners 1393 */ 1394 AEC.EventDispatcher.trigger('ec.checkout.step.option.data', data); 1395 1396 /** 1397 * Track checkout option 1398 */ 1399 AEC.CookieConsent.queue(() => 1400 { 1401 AEC.Cookie.checkoutOption(data).push(dataLayer); 1402 1403 }).process(); 1404 1405 1406 return this; 1407 }, 1408 fail: function(message) 1409 { 1410 console.log(message); 1411 1412 return this; 1413 } 1414 }; 1415 1416 })(), 1417 Cookie: (function() 1418 { 1419 return { 1420 data: null, 1421 privateData: null, 1422 reset: function() 1423 { 1424 if (AEC.reset) 1425 { 1426 dataLayer.push({ ecommerce: null }); 1427 } 1428 1429 return dataLayer; 1430 }, 1431 push: function(dataLayer, consent) 1432 { 1433 consent = typeof consent !== 'undefined' ? consent : true; 1434 1435 if (this.data) 1436 { 1437 this.reset().push(this.data); 1438 1439 /** 1440 * Reset data to prevent further push 1441 */ 1442 this.data = null; 1443 } 1444 1445 return this; 1446 }, 1447 pushPrivate: function() 1448 { 1449 var data = this.getPrivateData(); 1450 1451 if (data) 1452 { 1453 dataLayer.push( 1454 { 1455 privateData: data 1456 }); 1457 } 1458 1459 return this; 1460 }, 1461 augment: function(products) 1462 { 1463 /** 1464 * Parse data & apply local reference 1465 */ 1466 var reference = AEC.Storage.reference().get(); 1467 1468 if (reference) 1469 { 1470 for (var i = 0, l = products.length; i < l; i++) 1471 { 1472 for (var a = 0, b = reference.length; a < b; a++) 1473 { 1474 if (products[i].item_id.toString().toLowerCase() === reference[a].id.toString().toLowerCase()) 1475 { 1476 products[i].category = reference[a].category; 1477 } 1478 } 1479 } 1480 } 1481
1482 products.forEach(product => 1483 { 1484 if (product.hasOwnProperty('category')) 1485 { 1486 let categories = product.category.split(/\//); 1487 1488 if (categories.length) 1489 { 1490 let index = 2; 1491 1492 categories.forEach(category => 1493 { 1494 product['item_category' + index] = category; 1495 }); 1496 } 1497 } 1498 }); 1499 1500 return products; 1501 }, 1502 click: function(data) 1503 { 1504 AEC.EventDispatcher.trigger('ec.cookie.click.data', data); 1505 1506 this.data = data; 1507 1508 return this; 1509 }, 1510 add: function(data) 1511 { 1512 AEC.EventDispatcher.trigger('ec.cookie.add.data', data); 1513 1514 this.data = data; 1515 1516 return this; 1517 }, 1518 remove: function(data) 1519 { 1520 AEC.EventDispatcher.trigger('ec.cookie.remove.item.data', data); 1521 1522 this.data = data; 1523 1524 if (AEC.localStorage) 1525 { 1526 this.data.ecommerce.items = this.augment(this.data.ecommerce.items); 1527 } 1528 1529 return this; 1530 }, 1531 compare: function(data) 1532 { 1533 AEC.EventDispatcher.trigger('ec.cookie.compare.data', data); 1534 1535 this.data = data; 1536 1537 return this; 1538 }, 1539 wishlist: function(data) 1540 { 1541 AEC.EventDispatcher.trigger('ec.cookie.wishlist.data', data); 1542 1543 this.data = data; 1544 1545 return this; 1546 }, 1547 wishlistRemove: function(data) 1548 { 1549 AEC.EventDispatcher.trigger('ec.cookie.wishlist.remove.data', data); 1550 1551 this.data = data; 1552 1553 return this; 1554 }, 1555 update: function(data) 1556 { 1557 AEC.EventDispatcher.trigger('ec.cookie.update.item.data', data); 1558 1559 this.data = data; 1560 1561 return this; 1562 }, 1563 visitor: function(data) 1564 { 1565 AEC.EventDispatcher.trigger('ec.cookie.visitor.data', data); 1566 1567 this.data = (function(data, privateData) 1568 { 1569 if (privateData) 1570 { 1571 if (privateData.hasOwnProperty('visitor')) 1572 { 1573 data.visitorId = privateData.visitor.visitorId; 1574 data.visitorLoginState = privateData.visitor.visitorLoginState; 1575 } 1576 } 1577 1578 return data; 1579 1580 })(data, AEC.Cookie.getPrivateData()); 1581 1582 return this; 1583 }, 1584 detail: function(data) 1585 { 1586 AEC.EventDispatcher.trigger('ec.cookie.detail.data', data); 1587 1588 this.data = data; 1589 1590 return this; 1591 }, 1592 purchase: function(data) 1593 { 1594 AEC.EventDispatcher.trigger('ec.cookie.purchase.data', data); 1595 1596 this.data = data; 1597 1598 if (AEC.localStorage) 1599 { 1600 this.data.ecommerce.purchase.items = this.augment(this.data.ecommerce.purchase.items); 1601 } 1602 1603 return this; 1604 }, 1605 impressions: function(data) 1606 { 1607 AEC.EventDispatcher.trigger('ec.cookie.impression.data', data); 1608 1609 this.data = data; 1610 1611 return this; 1612 }, 1613 checkout: function(data) 1614 { 1615 AEC.EventDispatcher.trigger('ec.cookie.checkout.step.data', data); 1616 1617 this.data = data; 1618 1619 if (AEC.localStorage) 1620 { 1621 this.data.ecommerce.items = this.augment(this.data.ecommerce.items); 1622 } 1623 1624 return this; 1625 }, 1626 checkoutOption: function(data) 1627 { 1628 AEC.EventDispatcher.trigger('ec.cookie.checkout.step.option.data', data); 1629 1630 this.data = data; 1631 1632 return this; 1633 }, 1634 promotion: function(data) 1635 { 1636 AEC.EventDispatcher.trigger('ec.cookie.promotion.data', data); 1637 1638 this.data = data; 1639 1640 return this; 1641 }, 1642 promotionClick: function(data, element) 1643 { 1644 AEC.EventDispatcher.trigger('ec.cookie.promotion.click', data, 1645 { 1646 element: element 1647 }); 1648 1649 this.data = data; 1650 1651 return this; 1652 }, 1653 remarketing: function(data) 1654 { 1655 AEC.EventDispatcher.trigger('ec.cookie.remarketing.data', data); 1656 1657 this.data = data; 1658 1659 return this; 1660 }, 1661 getPrivateData: function() 1662 { 1663 if (!this.privateData) 1664 { 1665 var cookie = this.get('privateData'); 1666 1667 if (cookie) 1668 { 1669 this.privateData = this.parse(cookie); 1670 } 1671 } 1672 1673 return this.privateData; 1674 }, 1675 set: function(name, value, days) 1676 { 1677 if (!days) 1678 { 1679 days = 30; 1680 } 1681 1682 let date = new Date(); 1683 1684 date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); 1685 1686 document.cookie = name + "=" + encodeURIComponent(value) + "; expires=" + date.toGMTString() + "; path=/; domain=" + AEC.Const.COOKIE_DOMAIN; 1687 1688 return this; 1689 }, 1690 get: function(name) 1691 { 1692 var start = document.cookie.indexOf(name + "="), len = start + name.length + 1; 1693 1694 if ((!start) && (name != document.cookie.substring(0, name.length))) 1695 { 1696 return null; 1697 } 1698 1699 if (start == -1) 1700 { 1701 return null; 1702 } 1703 1704 var end = document.cookie.indexOf(String.fromCharCode(59), len); 1705 1706 if (end == -1) 1707 { 1708 end = document.cookie.length; 1709 } 1710 1711 return decodeURIComponent(document.cookie.substring(len, end)); 1712 }, 1713 unset: function(name) 1714 { 1715 document.cookie = name + "=" + "; path=/; expires=" + (new Date(0)).toUTCString(); 1716 1717 return this; 1718 }, 1719 parse: function(json) 1720 { 1721 var json = decodeURIComponent(json.replace(/\+/g, ' ')); 1722 1723 return JSON.parse(json); 1724 } 1725 }; 1726 })(), 1727 CookieConsent: (function() 1728 { 1729 return { 1730 scripts: [], 1731 chain: {}, 1732 endpoints:{}, 1733 cookies: {}, 1734 consent: [], 1735 config: {}, 1736 nonce: {}, 1737 widget: 1738 { 1739 display: false, 1740 color: 'rgba(0,0,0,1)', 1741 colorEnd: 'rgba(0,0,0,1)' 1742 }, 1743 queue: function(callback, event) 1744 { 1745 event = typeof event !== 'undefined' ? event : AEC.Const.COOKIE_DIRECTIVE_CONSENT_GRANTED_EVENT; 1746 1747 if (!this.chain.hasOwnProperty(event)) 1748 { 1749 this.chain[event] = []; 1750 } 1751 1752 switch(AEC.Const.COOKIE_DIRECTIVE_ENGINE) 1753 { 1754 case 4: 1755 1756 callback = (callback => 1757 { 1758 return function() 1759 { 1760 /** 1761 * Chnage to dispatch event only when Onetrust is loaded 1762 */ 1763 if (false) 1764 { 1765 if ('undefined' !== typeof OneTrust) 1766 { 1767 OneTrust.OnConsentChanged(() => 1768 { 1769 callback.apply(this); 1770 }); 1771 1772 if (window.OnetrustActiveGroups) 1773 { 1774 let groups = window.OptanonActiveGroups.split(',').filter(String); 1775
1776 if (groups.includes('C0001','C0002','C0003','C0004','C0005')) 1777 { 1778 callback.apply(this); 1779 } 1780 } 1781 } 1782 } 1783 else 1784 { 1785 callback.apply(this); 1786 } 1787 } 1788 1789 })(callback); 1790 1791 break; 1792 } 1793 1794 this.chain[event].push(callback); 1795 1796 return this; 1797 }, 1798 dispatch: function(consent) 1799 { 1800 /** 1801 * Essential cookies 1802 */ 1803 AEC.Const.COOKIE_DIRECTIVE_CONSENT_GRANTED = true; 1804 1805 /** 1806 * Push consent to dataLayer 1807 */ 1808 dataLayer.push(consent); 1809 1810 return this.process(consent.event); 1811 }, 1812 process: function(event) 1813 { 1814 event = typeof event !== 'undefined' ? event : AEC.Const.COOKIE_DIRECTIVE_CONSENT_GRANTED_EVENT; 1815 1816 if (this.getConsent(event)) 1817 { 1818 this.dequeue(event); 1819 } 1820 else if (AEC.Const.COOKIE_DIRECTIVE_OVERRIDE_DECLINE) 1821 { 1822 this.dequeue(event); 1823 } 1824 else 1825 { 1826 if (4 === AEC.Const.COOKIE_DIRECTIVE_ENGINE) 1827 { 1828 /** 1829 * Chnage to dispatch event only when Onetrust is loaded 1830 */ 1831 if (false) 1832 { 1833 (event => 1834 { 1835 window.addEventListener('onetrust_loaded', e => 1836 { 1837 if (this.getConsent(event)) 1838 { 1839 this.dequeue(event); 1840 } 1841 }); 1842 })(event); 1843 } 1844 else 1845 { 1846 this.dequeue(event); 1847 } 1848 } 1849 1850 } 1851 1852 return this; 1853 }, 1854 dequeue: function(event) 1855 { 1856 if (this.chain.hasOwnProperty(event)) 1857 { 1858 try 1859 { 1860 let response; 1861 1862 this.chain[event].forEach(fn => 1863 { 1864 response = fn.apply(this,[]); 1865 }); 1866 } 1867 catch (e) 1868 { 1869 console.debug(e); 1870 } 1871 1872 this.chain[event] = []; 1873 } 1874 1875 return this; 1876 }, 1877 getConsent: function(event) 1878 { 1879 switch(AEC.Const.COOKIE_DIRECTIVE_ENGINE) 1880 { 1881 case 0: 1882 1883 if (!AEC.Const.COOKIE_DIRECTIVE) 1884 { 1885 return true; 1886 } 1887 1888 break; 1889 1890 case 1: 1891 1892 if (1 == AEC.Cookie.get(event)) 1893 { 1894 return true; 1895 } 1896 1897 if (this.consent.includes(event)) 1898 { 1899 return true; 1900 } 1901 1902 break; 1903 1904 case 4: 1905 1906 if (window.OnetrustActiveGroups) 1907 { 1908 let groups = window.OptanonActiveGroups.split(',').filter(String); 1909 1910 if (groups.includes('C0001','C0002','C0003','C0004','C0005')) 1911 { 1912 return true; 1913 } 1914 } 1915 1916 break; 1917 1918 default: return true; 1919 } 1920 1921 return false; 1922 }, 1923 updateConsent: function() 1924 { 1925 (segments => 1926 { 1927 let grant = []; 1928 1929 for (var i = 0, l = segments.length; i < l;i++) 1930 { 1931 if (1 == AEC.Cookie.get(segments[i])) 1932 { 1933 grant.push(segments[i]); 1934 } 1935 } 1936 1937 if (grant.length) 1938 { 1939 AEC.CookieConsent.acceptGoogleConsent(grant).getWidget(); 1940 1941 grant.forEach(segment => 1942 { 1943 AEC.CookieConsent.acceptConsent(segment); 1944 }); 1945 } 1946 1947 })(AEC.Const.COOKIE_DIRECTIVE_SEGMENT_MODE_EVENTS); 1948 1949 return this; 1950 }, 1951 acceptGoogleConsent: function(segments) 1952 { 1953 if ('function' === typeof gtag) 1954 { 1955 const consentMode = true === AEC.Const.COOKIE_DIRECTIVE_SEGMENT_MODE ? 1956 { 1957 ad_storage: -1 !== segments.indexOf('cookieConsentMarketingGranted') ? 'granted' : 'denied', 1958 security_storage: -1 !== segments.indexOf('cookieConsentGranted') ? 'granted' : 'denied', 1959 functionality_storage: -1 !== segments.indexOf('cookieConsentGranted') ? 'granted' : 'denied', 1960 personalization_storage: -1 !== segments.indexOf('cookieConsentPreferencesGranted') ? 'granted' : 'denied', 1961 analytics_storage: -1 !== segments.indexOf('cookieConsentAnalyticsGranted') ? 'granted' : 'denied', 1962 ad_user_data: -1 !== segments.indexOf('cookieConsentUserdata') ? 'granted' : 'denied', 1963 ad_personalization: -1 !== segments.indexOf('cookieConsentPersonalization') ? 'granted' : 'denied' 1964 } : 1965 { 1966 ad_storage: 'granted', 1967 security_storage: 'granted', 1968 functionality_storage: 'granted', 1969 personalization_storage: 'granted', 1970 analytics_storage: 'granted', 1971 ad_user_data: 'granted', 1972 ad_personalization: 'granted' 1973 }; 1974 1975 /** 1976 * Update consent 1977 */ 1978 gtag('consent','update',consentMode); 1979 1980 /** 1981 * Update localStorage 1982 */ 1983 localStorage.setItem('consentMode', JSON.stringify(consentMode)); 1984 1985 /**
1986 * Dispatch custom event 1987 */ 1988 window.dispatchEvent(new CustomEvent("consent_accept", { detail: { consentMode: consentMode, segments: segments } })); 1989 } 1990 1991 return this; 1992 }, 1993 finish: function() 1994 { 1995 let segments = []; 1996 1997 AEC.Const.COOKIE_DIRECTIVE_SEGMENT_MODE_EVENTS.forEach(segment => 1998 { 1999 if (this.getConsent(segment)) 2000 { 2001 segments.push(segment); 2002 } 2003 }); 2004 2005 this.pickup( 2006 { 2007 detail: 2008 { 2009 segments: segments 2010 } 2011 }); 2012 }, 2013 acceptConsent: function(event) 2014 { 2015 return this.dispatch({ event:event }); 2016 }, 2017 declineConsent: function(event) 2018 { 2019 return this.dispatch({ event:event }); 2020 }, 2021 declineGoogleConsent: function() 2022 { 2023 if ('function' === typeof gtag) 2024 { 2025 const consentMode = 2026 { 2027 ad_storage: 'denied', 2028 security_storage: 'denied', 2029 functionality_storage: 'denied', 2030 personalization_storage: 'denied', 2031 analytics_storage: 'denied', 2032 ad_user_data: 'denied', 2033 ad_personalization: 'denied' 2034 }; 2035 2036 /** 2037 * Update consent 2038 */ 2039 gtag('consent','update',consentMode); 2040 2041 /** 2042 * Update localStorage 2043 */ 2044 localStorage.setItem('consentMode', JSON.stringify(consentMode)); 2045 2046 /** 2047 * Dispatch custom event 2048 */ 2049 window.dispatchEvent(new CustomEvent("consent_decline",{ detail: { consentMode: consentMode } })); 2050 } 2051 2052 return this; 2053 }, 2054 setEndpoints: function(endpoints) 2055 { 2056 this.endpoints = endpoints; 2057 2058 return this; 2059 }, 2060 getConsentDialog: function(dataLayer) 2061 { 2062 if (1 == AEC.Cookie.get(AEC.Const.COOKIE_DIRECTIVE_CONSENT_DECLINE_EVENT)) 2063 { 2064 AEC.CookieConsent.declineGoogleConsent([AEC.Const.COOKIE_DIRECTIVE_CONSENT_DECLINE_EVEN]).getWidget(); 2065 2066 return this; 2067 } 2068 2069 if (1 != AEC.Cookie.get(AEC.Const.COOKIE_DIRECTIVE_CONSENT_GRANTED_EVENT)) 2070 { 2071 this.renderConsentDialog(dataLayer); 2072 } 2073 else 2074 { 2075 AEC.CookieConsent.getWidget(); 2076 } 2077 2078 return this; 2079 }, 2080 closeConsentDialog: function(directive) 2081 { 2082 directive.remove(); 2083 2084 this.getWidget(); 2085 2086 return this; 2087 }, 2088 renderConsentDialog: function(dataLayer) 2089 { 2090 let template = document.querySelector('template[data-consent]'); 2091 2092 (endpoints => 2093 { 2094 var directive = (body => 2095 { 2096 body.insertAdjacentHTML('beforeend', template.innerHTML); 2097 2098 return body.lastElementChild; 2099 2100 })(document.body); 2101 2102 let uuid = AEC.Cookie.get('cookieUuid'); 2103 2104 if (uuid) 2105 { 2106 directive.querySelector('[data-consent-uuid').innerHTML = uuid; 2107 } 2108 2109 let check_default = Number(directive.dataset.check); 2110 2111 directive.querySelectorAll('input[type=checkbox][data-consent]').forEach(checkbox => 2112 { 2113 checkbox.checked = AEC.CookieConsent.getConsent(checkbox.dataset.consent) ? true : (!uuid && check_default ? true : false); 2114 }); 2115 2116 directive.querySelector('[data-consent-uuid-wrapper]').style.display = uuid ? 'block' : 'none'; 2117 2118 (directive => 2119 { 2120 let listener = event => 2121 { 2122 if (event.key === 'Escape') 2123 { 2124 AEC.CookieConsent.closeConsentDialog(directive).acquireProxyCookies(); 2125 } 2126 }; 2127 2128 document.addEventListener('keydown', event => 2129 { 2130 listener(event); 2131 2132 document.removeEventListener('keydown', listener); 2133 }); 2134 2135 })(directive); 2136 2137 directive.querySelectorAll('a.customize').forEach(element => 2138 { 2139 let customize = directive.querySelector('.ec-gtm-cookie-directive-customize'); 2140 2141 element.addEventListener('click', event => 2142 { 2143 if ('block' === customize.style.display) 2144 { 2145 directive.querySelector('a.action.accept').style.display = 'none'; 2146 2147 customize.style.display = 'none'; 2148 } 2149 else 2150 { 2151 directive.querySelector('a.action.accept').style.display = 'block'; 2152 2153 customize.style.display = 'block'; 2154 } 2155 2156 event.target.innerHTML = 'block' === customize.style.display ? event.target.dataset.hide : event.target.dataset.show; 2157 }); 2158 }); 2159 2160 directive.querySelectorAll('a.ec-gtm-cookie-directive-note-toggle').forEach(element => 2161 { 2162 element.addEventListener('click', event => 2163 { 2164 if ('block' === event.target.nextElementSibling.style.display) 2165 { 2166 event.target.nextElementSibling.style.display = 'none'; 2167 } 2168 else 2169 { 2170 directive.querySelectorAll('.ec-gtm-cookie-directive-note').forEach(note => 2171 { 2172 note.previousElementSibling.innerHTML = note.previousElementSibling.dataset.show; 2173 2174 note.style.display = 'none'; 2175 }); 2176 2177 event.target.nextElementSibling.style.display = 'block'; 2178 } 2179 2180 event.target.innerHTML = 'block' === event.target.nextElementSibling.style.display ? event.target.dataset.hide : event.target.dataset.show; 2181 2182 }); 2183 }); 2184 2185 directive.querySelectorAll('a.accept').forEach(element => 2186 { 2187 element.addEventListener('click', event => 2188 { 2189 event.target.text = event.target.dataset.confirm; 2190 2191 var grant = [...directive.querySelectorAll('[name="cookie[]"]:checked')].map(element => { return element.value }); 2192 2193 grant.unshift('cookieConsentGranted'); 2194 2195 AEC.CookieConsent.acceptGoogleConsent(grant); 2196 2197 AEC.Request.post(endpoints.cookie, { cookie: grant }, response => 2198 { 2199 Object.keys(response).forEach(event => 2200 { 2201 AEC.CookieConsent.acceptConsent(event); 2202 }); 2203 2204 AEC.CookieConsent.closeConsentDialog(directive).acquireProxyCookies(); 2205 }); 2206 }); 2207 }); 2208 2209 directive.querySelectorAll('a.accept-all').forEach(element => 2210 { 2211 element.addEventListener('click', event => 2212 { 2213 event.target.text = event.target.dataset.confirm; 2214 2215 [...directive.querySelectorAll('[name="cookie[]"]')].forEac
2215h(element => 2216 { 2217 element.checked = true; 2218 }); 2219 2220 var grant = [...directive.querySelectorAll('[name="cookie[]"]:checked')].map(element => { return element.value }); 2221 2222 grant.unshift('cookieConsentGranted'); 2223 2224 AEC.CookieConsent.acceptGoogleConsent(grant); 2225 2226 AEC.Request.post(endpoints.cookie, { cookie: grant }, response => 2227 { 2228 Object.keys(response).forEach(event => 2229 { 2230 AEC.CookieConsent.acceptConsent(event); 2231 }); 2232 2233 AEC.CookieConsent.closeConsentDialog(directive).acquireProxyCookies(); 2234 }); 2235 }); 2236 }); 2237 2238 directive.querySelectorAll('a.decline').forEach(element => 2239 { 2240 element.addEventListener('click', event => 2241 { 2242 [...directive.querySelectorAll('[name="cookie[]"]')].forEach(element => 2243 { 2244 element.checked = false; 2245 }); 2246 2247 AEC.CookieConsent.declineGoogleConsent(); 2248 2249 AEC.Request.post(endpoints.cookie, { decline: true }, response => 2250 { 2251 Object.keys(response).forEach(event => 2252 { 2253 AEC.CookieConsent.declineConsent(event); 2254 }); 2255 2256 AEC.CookieConsent.closeConsentDialog(directive).acquireProxyCookies(); 2257 }); 2258 }); 2259 }); 2260 2261 directive.querySelectorAll('a.close').forEach(element => 2262 { 2263 element.style.display = AEC.Const.COOKIE_DIRECTIVE_CONSENT_GRANTED ? 'block' : 'none'; 2264 2265 element.addEventListener('click', event => 2266 { 2267 AEC.CookieConsent.closeConsentDialog(directive).acquireProxyCookies(); 2268 }); 2269 }); 2270 })(this.endpoints); 2271 2272 return this; 2273 }, 2274 acquireProxyCookies: function() 2275 { 2276 if (!this.config.acquire) 2277 { 2278 return this; 2279 } 2280 2281 const acquire = localStorage.getItem("acquire"); 2282 2283 if (!acquire) 2284 { 2285 (context => 2286 { 2287 setTimeout(() => 2288 { 2289 const cookies = Object.fromEntries(document.cookie.split(';').map(s => s.trim()).filter(Boolean).map(pair => {const i = pair.indexOf('=');const k = i > -1 ? pair.slice(0, i) : pair;const v = i > -1 ? pair.slice(i + 1) : '';try { return [decodeURIComponent(k), decodeURIComponent(v)]; }catch { return [k, v]; }})); 2290 2291 Object.entries(cookies).forEach(([name, value]) => 2292 { 2293 if (!context.cookies.hasOwnProperty(name)) 2294 { 2295 context.cookies[name] = true; 2296 } 2297 }); 2298 2299 AEC.Request.post(context.endpoints.cookieConsent, { cookies: context.cookies }, response => 2300 { 2301 return true; 2302 }); 2303 2304 },1000); 2305 2306 })(this); 2307 2308 localStorage.setItem("acquire", true); 2309 } 2310 2311 return this; 2312 }, 2313 setProxy: function() 2314 { 2315 (context => 2316 { 2317 new MutationObserver((mutations) => 2318 { 2319 mutations.forEach((mutation) => 2320 { 2321 [...mutation.addedNodes].forEach(node => 2322 { 2323 if (node.nodeType !== 1) 2324 { 2325 return; 2326 } 2327 2328 if (node.matches('script') && node.dataset && node.dataset.hasOwnProperty('consent')) 2329 { 2330 context.scripts.push( 2331 { 2332 script: node, 2333 parent: node.parentNode ? node.parentNode : document.head, 2334 segment: node.dataset.consent 2335 }); 2336 2337 [...node.attributes].forEach((attr) => 2338 { 2339 if (attr.name.startsWith('defer')) 2340 { 2341 node.removeAttribute(attr.name); 2342 } 2343 }); 2344 2345 node.remove(); 2346 } 2347 }); 2348 }); 2349 }).observe(document.documentElement, { childList: true, subtree: true }); 2350 2351 })(this); 2352 2353 return this; 2354 }, 2355 setReflect: function(fn, strategy, whitelist) 2356 { 2357 2358 whitelist.push(BASE_URL); 2359 2360 (function() 2361 { 2362 const proto = Document.prototype; 2363 2364 const descriptor = Object.getOwnPropertyDescriptor(proto, "cookie"); 2365 2366 if (!descriptor || !descriptor.set) 2367 { 2368 return; 2369 } 2370 2371 Object.defineProperty(proto, "cookie", 2372 { 2373 configurable: true, 2374 enumerable: descriptor.enumerable, 2375 get: function() 2376 { 2377 return descriptor.get.call(this); 2378 }, 2379 set: function(value) 2380 { 2381 try 2382 { 2383 const name = value.split("=")[0]; 2384 2385 window.dispatchEvent(new CustomEvent("captured_cookie", 2386 { 2387 detail: { cookie: { name, value } } 2388 })); 2389 } 2390 catch (e) 2391 { 2392 console.warn("Cookie observer error:", e); 2393 } 2394 return descriptor.set.call(this, value); 2395 } 2396 }); 2397 })(); 2398 2399 if (1 == strategy) 2400 { 2401 const originalSetAttribute = HTMLScriptElement.prototype.setAttribute; 2402 2403 Object.defineProperties(HTMLScriptElement.prototype, 2404 { 2405 src: 2406 { 2407 set: function(value) 2408 { 2409 const source = value?.toString?.() ?? value; 2410
2411 if (!AEC.CookieConsent.getConsent(AEC.Const.COOKIE_DIRECTIVE_CONSENT_GRANTED_EVENT) && !this.dataset.hasOwnProperty('materialize')) 2412 { 2413 const skip = whitelist?.some(n => source.includes(n)); 2414 2415 if (!skip) 2416 { 2417 this.setAttribute('type', 'text/template'); 2418 this.setAttribute('data-consent', AEC.Const.COOKIE_DIRECTIVE_CONSENT_GRANTED_EVENT); 2419 } 2420 } 2421 2422 this.setAttribute('src', value); 2423 }, 2424 get: function() 2425 { 2426 return this.getAttribute('src'); 2427 } 2428 }, 2429 setAttribute: 2430 { 2431 value: function(name, value) 2432 { 2433 if (name === 'src') 2434 { 2435 const source = value?.toString?.() ?? value; 2436 2437 if (!AEC.CookieConsent.getConsent(AEC.Const.COOKIE_DIRECTIVE_CONSENT_GRANTED_EVENT) && !this.dataset.hasOwnProperty('materialize')) 2438 { 2439 const skip = whitelist?.some(n => source.includes(n)); 2440 2441 if (!skip) 2442 { 2443 this.setAttribute('type', 'text/template'); 2444 this.setAttribute('data-consent', AEC.Const.COOKIE_DIRECTIVE_CONSENT_GRANTED_EVENT); 2445 } 2446 } 2447 } 2448 2449 return originalSetAttribute.call(this, name, value); 2450 }, 2451 writable: true, 2452 configurable: true 2453 } 2454 }); 2455 } 2456 2457 window.addEventListener('captured_cookie', event => 2458 { 2459 this.cookies[event.detail.cookie.name] = event.detail.cookie.value; 2460 }); 2461 2462 fn.apply(this,[this]); 2463 }, 2464 setAsses: function(asses) 2465 { 2466 asses = asses || []; 2467 2468 if (asses.length) 2469 { 2470 setTimeout(() => 2471 { 2472 let cookies = Object.fromEntries(document.cookie.split('; ').map(c => c.split('='))); 2473 2474 let result = []; 2475 2476 Object.entries(cookies).forEach(([name, value]) => 2477 { 2478 if(!asses.includes(name)) 2479 { 2480 result.push(name); 2481 } 2482 }); 2483 2484 let debug = document.createElement('div'); 2485 2486 Object.assign(debug.style, 2487 { 2488 position: 'fixed', 2489 width: '85%', 2490 maxWidth: '600px', 2491 bottom: '30px', 2492 left: '20px', 2493 padding: '20px', 2494 borderRadius: '2px', 2495 color: 'rgba(0,0,0,1)', 2496 background: 'rgba(255, 198, 75, 0.95)', 2497 dropShadow: '0px 0px 2px', 2498 zIndex: 9999 2499 }); 2500 2501 if (result.length) 2502 { 2503 result.unshift(''); 2504 result.unshift('We have identified the following cookies that might be set prior to consent.'); 2505 } 2506 else 2507 { 2508 result.push('No NON-ESSENTIAL cookies found.'); 2509 } 2510 2511 result.push(''); 2512 result.push('<small>Once done, remember to disable Test mode in Stores -> Configuration -> Anowave -> Cookie Consent Mode V2 -> Test Mode OR delete <strong>asses</strong> cookie manually.</small>'); 2513 2514 debug.innerHTML = result.join('<br />'); 2515 2516 document.body.appendChild(debug); 2517 }, 2518 1000); 2519 } 2520 2521 return this; 2522 }, 2523 pickup: function(event) 2524 { 2525 document.querySelectorAll('script[data-consent]').forEach(script => 2526 { 2527 let segment = script.dataset.consent; 2528 2529 if (-1 != event.detail.segments.indexOf(segment)) 2530 { 2531 delete script.dataset.consent; 2532 2533 this.materialize(script, this.nonce, event.detail.segments); 2534 } 2535 }); 2536 2537 this.scripts.forEach(script => 2538 { 2539 if (-1 != event.detail.segments.indexOf(script.segment)) 2540 { 2541 this.materialize(script.script, this.nonce, event.detail.segments); 2542 } 2543 }); 2544 2545 return this; 2546 }, 2547 materialize: function(script, nonce, segments) 2548 { 2549 let tag = document.createElement('script'); 2550 2551 tag.type = "text/javascript"; 2552 tag.innerHTML = script.innerHTML; 2553 2554 tag.dataset.materialize = true; 2555 2556 if (script.getAttribute('src')) 2557 { 2558 tag.src = script.src; 2559 } 2560 2561 tag.setAttribute('nonce', nonce); 2562 2563 if (script.parentNode) 2564 { 2565 script.parentNode.appendChild(tag); 2566 script.parentNode.removeChild(script); 2567 } 2568 else 2569 { 2570 document.body.appendChild(tag); 2571 } 2572 }, 2573 setNonce: function(nonce) 2574 { 2575 this.nonce = nonce; 2576 2577 return this; 2578 }, 2579 setWidget: function(config) 2580 { 2581 config = config || {}; 2582 2583 this.config = config; 2584 2585 this.setAsses(config.asses).setProxy().setNonce(config.nonce).setEndpoints(config.endpoints); 2586 2587 (context => 2588 { 2589 let block = {}; 2590 2591 window.addEventListener('consent_accept', event => 2592 { 2593 context.consent = event.detail.segments; 2594 2595 context.pickup(event); 2596 2597 new MutationObserver((mutations) => 2598 { 2599 mutations.forEach((mutation) => 2600 {
2601 [...mutation.addedNodes].forEach(node => 2602 { 2603 if (node.nodeType !== 1) 2604 { 2605 return; 2606 } 2607 2608 if (node.matches('script') && -1 != node.type.indexOf('text/template')) 2609 { 2610 let segment = node.dataset.consent; 2611 2612 if (-1 != event.detail.segments.indexOf(segment)) 2613 { 2614 delete node.dataset.consent; 2615 2616 context.materialize(node, this.nonce. event.detail.segments); 2617 } 2618 } 2619 }); 2620 }); 2621 }).observe(document.documentElement, { childList: true, subtree: true }); 2622 }); 2623 })(this); 2624 2625 this.widget = {...this.widget, ...config.options }; 2626 2627 return this; 2628 }, 2629 getWidget: function() 2630 { 2631 if (this.widget.display) 2632 { 2633 let svg = (node => 2634 { 2635 return (text => 2636 { 2637 let styles = 2638 { 2639 position: 'fixed', 2640 bottom: '10px', 2641 left: '10px', 2642 'z-index': '9999', 2643 cursor: 'pointer' 2644 }; 2645 2646 let style = Object.entries(styles).map(([key, value]) => 2647 { 2648 return [key,value].join(':'); 2649 }); 2650 2651 let svg = node('svg', { id: 'consentWidget', width:52, height: 50, style: style.join(';') }); 2652 2653 let gradient = node('linearGradient', { id: 'gradient', gradientTransform: 'rotate(90)'}); 2654 2655 let filter = node('filter', { id: 'shadow' }); 2656 2657 [ 2658 node('feDropShadow', { dx: '0', dy: '0', stdDeviation: '0.7','flood-opacity': 0.5 }), 2659 2660 ].forEach(element => 2661 { 2662 filter.appendChild(element); 2663 }); 2664 2665 let count = parseInt(text); 2666 2667 [ 2668 node('stop', { offset: '0%', 'stop-color': this.widget.color }), 2669 node('stop', { offset: '100%', 'stop-color': this.widget.colorEnd }) 2670 2671 ].forEach(element => 2672 { 2673 gradient.appendChild(element); 2674 }); 2675 2676 2677 if (0) 2678 { 2679 svg.appendChild(filter); 2680 } 2681 2682 svg.appendChild(gradient); 2683 2684 let transform = 'scale(1.5 1.5) translate(0 10)'; 2685 2686 [ 2687 node('path', { id: 'a', d: 'M22.6004 0H7.40039C3.50039 0 0.400391 3.1 0.400391 7C0.400391 10.9 3.50039 14 7.40039 14H22.6004C26.5004 14 29.6004 10.9 29.6004 7C29.6004 3.1 26.4004 0 22.6004 0ZM1.60039 7C1.60039 3.8 4.20039 1.2 7.40039 1.2H17.3004L14.2004 12.8H7.40039C4.20039 12.8 1.60039 10.2 1.60039 7Z', filter: 'url(#shadow)', fill: 'url(#gradient)', transform: transform }), 2688 node('path', { id: 'b', d: 'M24.6012 4.0001C24.8012 4.2001 24.8012 4.6001 24.6012 4.8001L22.5012 7.0001L24.7012 9.2001C24.9012 9.4001 24.9012 9.8001 24.7012 10.0001C24.5012 10.2001 24.1012 10.2001 23.9012 10.0001L21.7012 7.8001L19.5012 10.0001C19.3012 10.2001 18.9012 10.2001 18.7012 10.0001C18.5012 9.8001 18.5012 9.4001 18.7012 9.2001L20.8012 7.0001L18.6012 4.8001C18.4012 4.6001 18.4012 4.2001 18.6012 4.0001C18.8012 3.8001 19.2012 3.8001 19.4012 4.0001L21.6012 6.2001L23.8012 4.0001C24.0012 3.8001 24.4012 3.8001 24.6012 4.0001Z', fill: 'rgba(255,255,255,1)', transform: transform }), 2689 node('path', { id: 'c', d: 'M12.7 4.1002C12.9 4.3002 13 4.7002 12.8 4.9002L8.6 9.8002C8.5 9.9002 8.4 10.0002 8.3 10.0002C8.1 10.1002 7.8 10.1002 7.6 9.9002L5.4 7.7002C5.2 7.5002 5.2 7.
26891002 5.4 6.9002C5.6 6.7002 6 6.7002 6.2 6.9002L8 8.6002L11.8 4.1002C12 3.9002 12.4 3.9002 12.7 4.1002Z', fill: 'url(#gradient)', transform: transform }) 2690 2691 ].forEach(element => 2692 { 2693 svg.appendChild(element); 2694 }); 2695 2696 let loader = node('circle', { id: 'd', cx: 13, cy:25.5, r: 6, fill:'transparent', stroke:'url(#gradient)', 'stroke-width':2, 'stroke-dasharray':'60 40', 'stroke-dashoffset': 40, filter: 'url(#shadow)', style: 'display:none' }); 2697 2698 [ 2699 node('animateTransform', 2700 { 2701 attributeName: "transform", 2702 attributeType: "XML", 2703 type: "rotate", 2704 dur: "1s", 2705 from: "0 13 25.5", 2706 to: "360 13 25.5", 2707 repeatCount: "indefinite" 2708 }) 2709 2710 ].forEach(element => 2711 { 2712 loader.appendChild(element); 2713 }); 2714 2715 svg.appendChild(loader); 2716 2717 return svg; 2718 }); 2719 2720 })((n, v) => 2721 { 2722 n = document.createElementNS("http://www.w3.org/2000/svg", n); 2723 2724 for (var p in v) 2725 { 2726 n.setAttributeNS(null, p, v[p]); 2727 } 2728 2729 return n; 2730 }); 2731 2732 let widget = svg(); 2733 2734 /** 2735 * Remove widget 2736 */ 2737 this.deleteWidget(); 2738 2739 /** 2740 * Add widget 2741 */ 2742 document.body.appendChild(widget); 2743 2744 /** 2745 * Render widget 2746 */ 2747 document.body.querySelectorAll('[id=consentWidget]').forEach(element => 2748 { 2749 element.addEventListener('click', event => 2750 { 2751 AEC.CookieConsent.renderConsentDialog(dataLayer); 2752 }); 2753 }); 2754 2755 return widget; 2756 } 2757 2758 return null; 2759 }, 2760 deleteWidget: function() 2761 { 2762 document.body.querySelectorAll('[id=consentWidget]').forEach(element => 2763 { 2764 element.parentNode.removeChild(element); 2765 }); 2766 2767 return this; 2768 }, 2769 loader: (function() 2770 { 2771 return { 2772 show: function() 2773 { 2774 document.querySelectorAll('[id=c]').forEach(e => { e.style.display = 'none' }); 2775 document.querySelectorAll('[id=d]').forEach(e => { e.style.display = 'block' }); 2776 }, 2777 hide: function() 2778 { 2779 document.querySelectorAll('[id=c]').forEach(e => { e.style.display = 'block' }); 2780 document.querySelectorAll('[id=d]').forEach(e => { e.style.display = 'none' }); 2781 } 2782 } 2783 })() 2784 } 2785 })(), 2786 Storage: (function() 2787 { 2788 return { 2789 set: function(property, value) 2790 { 2791 if ('undefined' !== typeof(Storage)) 2792 { 2793 localStorage.setItem(property, JSON.stringify(value)); 2794 } 2795 2796 return this; 2797 2798 }, 2799 get: function(property) 2800 { 2801 if ('undefined' !== typeof(Storage)) 2802 { 2803 return JSON.parse(localStorage.getItem(property)); 2804 } 2805 2806 return null; 2807 }, 2808 reference: function() 2809 { 2810 return (function(storage) 2811 { 2812 return { 2813 set: function(reference) 2814 { 2815 var current = storage.get('category.add') || []; 2816 2817 var exists = (function(current, reference) 2818 { 2819 for (var i = 0, l = current.length; i < l; i++) 2820 { 2821 if (current[i].id.toString().toLowerCase() === reference.id.toString().toLowerCase()) 2822 { 2823 /** 2824 * Update category 2825 */ 2826 current[i].category = reference.category; 2827 2828 return true; 2829 } 2830 } 2831 2832 return false; 2833 2834 })(current, reference); 2835 2836 if (!exists) 2837 { 2838 current.push(reference); 2839 } 2840 2841 storage.set('category.add', current); 2842 2843 return this; 2844 }, 2845 get: function() 2846 { 2847 return storage.get('category.add'); 2848 } 2849 } 2850 })(this); 2851 } 2852 } 2853 })(), 2854 gtm: function() 2855 { 2856 if ("undefined" === typeof google_tag_manager) 2857 { 2858 /** 2859 * Log error to console 2860 */ 2861 console.log('Unable to detect Google Tag Manager. Please verify if GTM install snippet is available.'); 2862 2863 return false;
2864 } 2865 2866 return true; 2867 }, 2868 parseJSON: function(content) 2869 { 2870 if ('object' === typeof content) 2871 { 2872 return content; 2873 } 2874 2875 if ('string' === typeof content) 2876 { 2877 try 2878 { 2879 return JSON.parse(content); 2880 } 2881 catch (e){} 2882 } 2883 2884 return {}; 2885 }, 2886 getPayloadSize: function(object) 2887 { 2888 var objects = [object], size = 0; 2889 2890 for (var index = 0; index < objects.length; index++) 2891 { 2892 switch (typeof objects[index]) 2893 { 2894 case 'boolean': 2895 size += 4; 2896 break; 2897 case 'number': 2898 size += 8; 2899 break; 2900 case 'string': 2901 size += 2 * objects[index].length; 2902 break; 2903 case 'object': 2904 if (Object.prototype.toString.call(objects[index]) != '[object Array]') 2905 { 2906 for (var key in objects[index]) size += 2 * key.length; 2907 } 2908 for (var key in objects[index]) 2909 { 2910 var processed = false; 2911 2912 for (var search = 0; search < objects.length; search++) 2913 { 2914 if (objects[search] === objects[index][key]) { 2915 processed = true; 2916 break; 2917 } 2918 } 2919 if (!processed) objects.push(objects[index][key]); 2920 } 2921 } 2922 } 2923 return size; 2924 }, 2925 getPayloadChunks: function(arr, len) 2926 { 2927 var chunks = [],i = 0, n = arr.length; 2928 2929 while (i < n) 2930 { 2931 chunks.push(arr.slice(i, i += len)); 2932 }; 2933 2934 return chunks; 2935 }, 2936 url: function(url) 2937 { 2938 return [AEC.Const.URL, url].join(''); 2939 }, 2940 EventDispatcher: (function() 2941 { 2942 return { 2943 events: {}, 2944 on: function(event, callback) 2945 { 2946 var handlers = this.events[event] || []; 2947 2948 handlers.push(callback); 2949 2950 this.events[event] = handlers; 2951 }, 2952 trigger: function() 2953 { 2954 /** 2955 * Cast arguments to array 2956 */ 2957 let args = [...arguments]; 2958 2959 /** 2960 * Get event 2961 */ 2962 let event = args ? args.shift() : null; 2963 2964 /** 2965 * Get handlers 2966 */ 2967 let handlers = this.events[event] || []; 2968 2969 /** 2970 * Get data 2971 */ 2972 let data = args ? args.shift() : {}; 2973 2974 /** 2975 * Get options 2976 */ 2977 let options = args ? args.shift() : {}; 2978 2979 /** 2980 * Quit if no handler 2981 */ 2982 if (!handlers || handlers.length < 1) 2983 { 2984 return; 2985 } 2986 2987 console.log(event + '(' + handlers.length + ' listeners)'); 2988 2989 handlers.forEach(function(handler) 2990 { 2991 handler(data, options); 2992 }); 2993 } 2994 } 2995 })(), 2996 Request: (function() 2997 { 2998 return { 2999 get: function(url, params, callback) 3000 { 3001 this.execute('GET', [url,this.serialize(params)].join('?'), callback).send(null); 3002 }, 3003 post: function(url, params, callback) 3004 { 3005 this.execute('POST', url, callback).send(this.serialize(params)); 3006 }, 3007 execute: function(method, url, callback) 3008 { 3009 try 3010 { 3011 var request = new XMLHttpRequest(); 3012 3013 request.open(method, url, true); 3014 3015 request.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); 3016 request.setRequestHeader('X-Requested-With','XMLHttpRequest'); 3017 3018 request.addEventListener('load', () => 3019 { 3020 let response; 3021 3022 if ('application/json' === request.getResponseHeader("Content-Type")) 3023 { 3024 response = JSON.parse(request.responseText); 3025 } 3026 else 3027 { 3028 response = request.responseText; 3029 } 3030 3031 if ('function' === typeof callback) 3032 { 3033 callback(response); 3034 } 3035 }); 3036 } 3037 catch (e) 3038 { 3039 console.log(e.message); 3040 3041 return null; 3042 } 3043 3044 3045 return request; 3046 }, 3047 serialize: function(entity, prefix) 3048 { 3049 var query = []; 3050 3051 Object.keys(entity).map(key => 3052 { 3053 var k = prefix ? prefix + "[" + key + "]" : key, value = entity[key]; 3054 3055 query.push((value !== null && typeof value === "object") ? this.serialize(value, k) : encodeURIComponent(k) + "=" + encodeURIComponent(value)); 3056 }); 3057 3058 return query.join("&"); 3059 } 3060 } 3061 })(), 3062 UUID: (() => 3063 { 3064 return { 3065 generate: event => 3066 { 3067 event = event || {}; 3068 3069 let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) 3070 { 3071 var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); 3072 return v.toString(16); 3073 }); 3074 3075 if (-1 == ['AddToCart'].indexOf(event)) 3076 { 3077 try 3078 {
3079 let current = AEC.Cookie.get('facebook_latest_uuid'); 3080 3081 if (current) 3082 { 3083 current = JSON.parse(current); 3084 3085 if (current.hasOwnProperty('uuid') && current.hasOwnProperty('event')) 3086 { 3087 if (event.event === current.event) 3088 { 3089 uuid = current.uuid; 3090 } 3091 } 3092 } 3093 } 3094 catch (e){} 3095 } 3096 3097 event['uuid'] = uuid; 3098 3099 /** 3100 * Set facebook uuid cookie 3101 */ 3102 if (AEC.Const.COOKIE_DIRECTIVE) 3103 { 3104 if (AEC.Const.COOKIE_DIRECTIVE_CONSENT_GRANTED) 3105 { 3106 AEC.Cookie.set('facebook_latest_uuid', JSON.stringify(event)); 3107 } 3108 } 3109 else 3110 { 3111 AEC.Cookie.set('facebook_latest_uuid', JSON.stringify(event)); 3112 } 3113 3114 return uuid; 3115 } 3116 } 3117 })(), 3118 Proxy: (() => 3119 { 3120 function proxyFactory(worker) 3121 { 3122 const handler = 3123 { 3124 get(target, method) 3125 { 3126 return function (...args) 3127 { 3128 return new Promise((resolve, reject) => 3129 { 3130 const id = Date.now() + Math.random().toString(36).substr(2); 3131 3132 worker.onmessage = function (event) 3133 { 3134 const { id: responseId, result, error } = event.data; 3135 3136 if (responseId === id) 3137 { 3138 if (error) 3139 { 3140 reject(new Error(error)); 3141 } 3142 else 3143 { 3144 resolve(result); 3145 } 3146 } 3147 }; 3148 3149 worker.postMessage({ id, method, args }); 3150 }); 3151 }; 3152 } 3153 }; 3154 3155 return new Proxy({}, handler); 3156 }; 3157 3158 return { 3159 get: worker => 3160 { 3161 return proxyFactory 3162 ( 3163 new Worker(worker) 3164 ) 3165 } 3166 } 3167 })(), 3168 TikTok: (() => 3169 { 3170 return { 3171 event: (event, dataset, event_identifier) => 3172 { 3173 if ('undefined' !== typeof ttq) 3174 { 3175 ttq.track(event, dataset, event_identifier); 3176 } 3177 } 3178 } 3179 })() 3180 } 3181})(); 3182if ('undefined' !== typeof AEC && 'undefined' !== typeof AEC.EventDispatcher) 3183{ 3184 AEC.GA4 = (() => 3185 { 3186 return { 3187 enabled: false, 3188 transformCategories: function(category) 3189 { 3190 if (null === category) 3191 { 3192 return {}; 3193 } 3194 3195 let map = {}, categories = category.toString().split('/'); 3196 3197 if (categories) 3198 { 3199 map['item_category'] = categories.shift(); 3200 3201 if (categories.length) 3202 { 3203 let index = 1; 3204 3205 categories.forEach(category => 3206 { 3207 map['item_category' + (++index)] = category; 3208 }); 3209 } 3210 } 3211 3212 return map; 3213 }, 3214 augmentCategories: function(product) 3215 { 3216 if (product.hasOwnProperty('category')) 3217 { 3218 AEC.Cookie.augment([product]); 3219 } 3220 3221 return this.transformCategories(product.category); 3222 }, 3223 augmentItem: function(product) 3224 { 3225 let map = {}; 3226 3227 map['google_business_vertical'] = 'retail'; 3228 3229 Object.entries(product).forEach(([key, value]) => 3230 { 3231 if (-1 === ['id','name','price','category','currency','variant','brand'].indexOf(key)) 3232 { 3233 map[key] = value; 3234 } 3235 }); 3236 3237 return map; 3238 } 3239 3240 } 3241 })(); 3242 3243 /** 3244 * Modify checkout step option payloasd 3245 */ 3246 AEC.EventDispatcher.on('ec.checkout.step.option.data', data => 3247 { 3248 if (!AEC.GA4.enabled) 3249 { 3250 return true; 3251 } 3252
3253 switch(parseInt(data.ecommerce.checkout_option.actionField.step)) 3254 { 3255 case AEC.Const.CHECKOUT_STEP_SHIPPING: 3256 3257 data['event'] = 'add_shipping_info'; 3258 3259 if (AEC.GA4.quote.hasOwnProperty('coupon')) 3260 { 3261 data.ecommerce['coupon'] = AEC.GA4.quote.coupon; 3262 } 3263 3264 data.ecommerce['currency'] = AEC.GA4.currency; 3265 3266 data.ecommerce['items'] = AEC.Checkout.getPayload().ecommerce.items; 3267 3268 data.ecommerce['shipping_tier'] = data.ecommerce.checkout_option.actionField.option; 3269 3270 (data => 3271 { 3272 let value = 0; 3273 3274 data.ecommerce['items'].forEach(item => 3275 { 3276 value += Number(item.price) * Number(item.quantity); 3277 }); 3278 3279 data.ecommerce['value'] = value; 3280 3281 })(data); 3282 3283 3284 3285 3286 delete data.ecommerce.checkout_option; 3287 3288 break; 3289 3290 case AEC.Const.CHECKOUT_STEP_PAYMENT: 3291 3292 data['event'] = 'add_payment_info'; 3293 3294 if (AEC.GA4.quote.hasOwnProperty('coupon')) 3295 { 3296 data.ecommerce['coupon'] = AEC.GA4.quote.coupon; 3297 } 3298 3299 data.ecommerce['currency'] = AEC.GA4.currency; 3300 3301 data.ecommerce['items'] = AEC.Checkout.getPayload().ecommerce.items; 3302 3303 data.ecommerce['payment_type'] = data.ecommerce.checkout_option.actionField.option; 3304 3305 (data => 3306 { 3307 let value = 0; 3308 3309 data.ecommerce['items'].forEach(item => 3310 { 3311 value += Number(item.price) * Number(item.quantity); 3312 }); 3313 3314 data.ecommerce['value'] = value; 3315 3316 })(data); 3317 3318 3319 3320 delete data.ecommerce.checkout_option; 3321 3322 break; 3323 } 3324 }); 3325}</script>
3325<script data-ommit="true" nonce="MW8zbHFodjIwMXlkMHZyNXk1Z2htd2p6a2FwNHo5a24="> 3326 window.DopplerEc = window.DopplerEc || (function () { 3327 /** 3328 * Map stamped DOM nodes to GA4 items. 3329 * 3330 * Each product tile carries TWO stamped anchors (image link + title link, see 3331 * ec/selectors/click), so results are de-duplicated by item_id â one entry per product. 3332 * 3333 * @param {NodeList|Array} nodes elements carrying data-event="select_item" 3334 * @param {Object} listContext { item_list_id, item_list_name } for item-level attribution 3335 * @returns {Array} GA4 items 3336 */ 3337 var collectItems = function (nodes, listContext) { 3338 var items = [], trace = {}; 3339 3340 listContext = listContext || {}; 3341 3342 Array.prototype.forEach.call(nodes || [], function (element) { 3343 var entity = { 3344 google_business_vertical: 'retail', 3345 index: parseFloat(element.dataset.position), 3346 item_brand: element.dataset.brand, 3347 item_id: element.dataset.id, 3348 item_name: element.dataset.name, 3349 price: parseFloat(element.dataset.price), 3350 variant_id: element.dataset.simpleId, 3351 dimension5: element.dataset['dimension5'] 3352 }; 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 Object.assign(entity, entity, AEC.GA4.transformCategories(element.dataset.category)); 3363 3364 var attributes = element.dataset.attributes; 3365 3366 if (attributes) { 3367 Object.entries(JSON.parse(attributes)).forEach(function (pair) { 3368 entity[pair[0]] = pair[1]; 3369 }); 3370 } 3371 3372 entity = Object.fromEntries(Object.entries(entity).sort(function (a, b) { 3373 return a[0].localeCompare(b[0]); 3374 })); 3375 3376 if (!trace.hasOwnProperty(entity.item_id)) { 3377 trace[entity.item_id] = true; 3378 3379 items.push(entity); 3380 } 3381 }); 3382 3383 return items; 3384 }; 3385 3386 /** 3387 * Push a view_item_list for an already-mapped set of items. 3388 * 3389 * Used by the dynamic-listing path only; the server-rendered templates keep their own push 3390 * (which additionally handles payload chunking). Appended pages are one page worth of 3391 * products, comfortably below the payload size limit, so no chunking is needed here. 3392 */ 3393 var pushItemList = function (items, listContext) { 3394 if (!items || !items.length) { 3395 return; 3396 } 3397 3398 listContext = listContext || {}; 3399 3400 var payload = { 3401 event: 'view_item_list', 3402 ecommerce: { 3403 item_list_id: listContext['item_list_id'], 3404 item_list_name: listContext['item_list_name'], 3405 currency: AEC.currencyCode, 3406 items: items 3407 } 3408 }; 3409 3410 AEC.CookieConsent.queue(function () { 3411 AEC.Cookie.impressions(payload).push(dataLayer); 3412 }).process(); 3413 }; 3414 3415 /** 3416 * Bind Anowave's interaction handlers to freshly injected nodes. 3417 * 3418 * Anowave binds these once on DOMContentLoaded (Anowave_Ec::events.phtml) and re-binds only 3419 * from a PerformanceObserver filtered to initiatorType === "xmlhttprequest". Endless scroll 3420 * loads pages with fetch(), whose initiatorType is "fetch", so appended tiles would never 3421 * get handlers and clicks on them would go untracked. 3422 * 3423 * The map mirrors events.phtml and is keyed off the same Anowave constants, so event names 3424 * cannot drift. Listing tiles currently carry select_item and add_to_wishlist; the rest are 3425 * included so a tile gaining, say, an add-to-cart button keeps working. 3426 * 3427 * Matches Anowave's own guard: only nodes not already marked data-bound are bound, making 3428 * this safe to call repeatedly over overlapping node sets. 3429 */ 3430 var bindEvents = function (nodes) { 3431 var handlers = { 3432 'add_to_cart': function (event) { 3433 AEC.add(event.currentTarget, dataLayer, event); 3434 }, 3435 'remove_from_cart': function (event) { 3436 AEC.remove(event.currentTarget, dataLayer, event); 3437 }, 3438 'select_item': function (event) { 3439 AEC.click(event.currentTarget, dataLayer, event); 3440 }, 3441 'add_to_wishlist': function (event) { 3442 AEC.wishlist(event.currentTarget, dataLayer, event); 3443 }, 3444 'remove_from_wishlist': function (event) { 3445 AEC.wishlistRemove(event.currentTarget, dataLayer, event); 3446 }, 3447 'add_to_compare': function (event) { 3448 AEC.compare(event.currentTarget, dataLayer, event); 3449 }, 3450 'add_to_cart_swatch': function (event) { 3451 AEC.addSwatch(event.currentTarget, dataLayer, event); 3452 } 3453 }; 3454 3455 Array.prototype.forEach.call(nodes || [], function (node) { 3456 if (!node.querySelectorAll) { 3457 return; 3458 } 3459 3460 // The dispatched nodes are the appended <li> wrappers; the stamped elements are
3461 // the anchors/buttons inside them (and, defensively, the node itself). 3462 var candidates = [].concat( 3463 node.dataset && node.dataset.event ? [node] : [], 3464 Array.prototype.slice.call( 3465 node.querySelectorAll('[data-event]:not([data-bound])') 3466 ) 3467 ); 3468 3469 candidates.forEach(function (element) { 3470 var handler = handlers[element.dataset.event]; 3471 3472 if (!handler || element.dataset.bound) { 3473 return; 3474 } 3475 3476 element.addEventListener('click', handler); 3477 element.dataset.bound = true; 3478 }); 3479 }); 3480 }; 3481 3482 return { 3483 collectItems: collectItems, 3484 pushItemList: pushItemList, 3485 bindEvents: bindEvents 3486 }; 3487 })(); 3488</script>
3488 3489 3490 <link rel="preconnect" href="//privacy-proxy.usercentrics.eu"> 3491
3491<script 3492 id="usercentrics-cmp" 3493 src="https://web.cmp.usercentrics.eu/ui/loader.js" 3494 data-settings-id="YH_VWr8ayWE6dy" 3495 async 3496 ></script>
3496 3497 3498 <link rel="preload" href="//privacy-proxy.usercentrics.eu/latest/uc-block.bundle.js" as="script" nonce="NHE0MDFpZGpwN2psNDVrN3B5b3YyemVpcTkxcW5pdnI="> 3499
3499<script type="application/javascript" src="https://privacy-proxy.usercentrics.eu/latest/uc-block.bundle.js" nonce="NHE0MDFpZGpwN2psNDVrN3B5b3YyemVpcTkxcW5pdnI="></script>
3499 3500
3500<script nonce="NHE0MDFpZGpwN2psNDVrN3B5b3YyemVpcTkxcW5pdnI="> 3501 uc.blockOnly(['BJ59EidsWQ','BJz7qNsdj-7','S1pcEj_jZX','uJyv6-Nm']); </script>
3501 3502
3502<script data-ommit="true" nonce="MW8zbHFodjIwMXlkMHZyNXk1Z2htd2p6a2FwNHo5a24="> 3503 3504 window.dataLayer = window.dataLayer || []; 3505 3506 window.AEC = window.AEC || {}; 3507 3508 AEC.Const = {"URL":"https://knirps.de/","TIMING_CATEGORY_ADD_TO_CART":"Add To Cart Time","TIMING_CATEGORY_REMOVE_FROM_CART":"Remove From Cart Time","TIMING_CATEGORY_PRODUCT_CLICK":"Product Detail Click Time","TIMING_CATEGORY_CHECKOUT":"Checkout Time","TIMING_CATEGORY_CHECKOUT_STEP":"Checkout Step Tim","TIMING_CATEGORY_PRODUCT_WISHLIST":"Add to Wishlist Time","TIMING_CATEGORY_PRODUCT_COMPARE":"Add to Compare Time","VARIANT_DELIMITER":"-","VARIANT_DELIMITER_ATT":":","CHECKOUT_STEP_SHIPPING":1,"CHECKOUT_STEP_PAYMENT":2,"CHECKOUT_STEP_ORDER":3,"DIMENSION_SEARCH":18,"COOKIE_DIRECTIVE":false,"COOKIE_DIRECTIVE_ENGINE":0,"COOKIE_DIRECTIVE_SEGMENT_MODE":false,"COOKIE_DIRECTIVE_SEGMENT_MODE_EVENTS":["cookieConsentGranted"],"COOKIE_DIRECTIVE_CONSENT_GRANTED_EVENT":"cookieConsentGranted","COOKIE_DIRECTIVE_CONSENT_DECLINE_EVENT":"cookieConsentDeclined","COOKIE_DIRECTIVE_OVERRIDE_DECLINE":false,"COOKIE_DOMAIN":"knirps.de","CATALOG_CATEGORY_ADD_TO_CART_REDIRECT_EVENT":"catalogCategoryAddToCartRedirect","META_CONVERSIONS_API_EVENTS":["NONE","AddToCart","ViewCategory","ViewContent","Purchase","InitiateCheckout","AddPaymentInfo","AddToWishlist","CustomizeProduct","Search"]}; 3509 3510 AEC.Const.COOKIE_DIRECTIVE_CONSENT_GRANTED = AEC.CookieConsent.getConsent("cookieConsentGranted"); 3511 3512 Object.entries({"Message":{"confirm":false,"confirmRemoveTitle":"Sind Sie sicher?","confirmRemove":"Soll dieser Artikel wirklich aus Ihrem Warenkorb entfernt werden?"},"storeName":"Deutsch","currencyCode":"EUR","useDefaultValues":true,"facebook":false,"tiktok":false,"SUPER":[],"CONFIGURABLE_SIMPLES":[],"BUNDLE":{"bundles":[],"options":[]},"localStorage":"true","summary":false,"reset":false,"tax":1,"simples":false}).forEach(([key,value]) => { AEC[key] = value; }); 3513 3514</script>
3514 3515
3516<script data-ommit="true" nonce="MW8zbHFodjIwMXlkMHZyNXk1Z2htd2p6a2FwNHo5a24="> 3517 3518 (summary => 3519 { 3520 if (summary) 3521 { 3522 let getSummary = (event) => 3523 { 3524 AEC.Request.post("https:\/\/knirps.de\/datalayer\/index\/cart\/",{ event:event }, (response) => 3525 { 3526 dataLayer.push(response); 3527 }); 3528 }; 3529 3530 ['ec.cookie.remove.item.data','ec.cookie.update.item.data','ec.cookie.add.data'].forEach(event => 3531 { 3532 AEC.EventDispatcher.on(event, (event => 3533 { 3534 return () => 3535 { 3536 setTimeout(() => { getSummary(event); }, 2000); 3537 }; 3538 })(event)); 3539 }); 3540 } 3541 })(AEC.summary); 3542 3543</script>
3543<script data-ommit="true" nonce="MW8zbHFodjIwMXlkMHZyNXk1Z2htd2p6a2FwNHo5a24="> 3544 3545 if ('undefined' !== typeof AEC && AEC.GA4) 3546 { 3547 AEC.GA4.enabled = true; 3548 3549 3550 AEC.GA4.conversion_event = "purchase"; 3551 3552 3553 AEC.GA4.currency = "EUR"; 3554 3555 3556 AEC.GA4.quote = []; 3557 } 3558 3559</script>
3559<script data-ommit="true" nonce="MW8zbHFodjIwMXlkMHZyNXk1Z2htd2p6a2FwNHo5a24="> 3560 3561 3562 window.dataLayer = window.dataLayer || []; 3563 3564 dataLayer.push({'gtm.nonce': 'MW8zbHFodjIwMXlkMHZyNXk1Z2htd2p6a2FwNHo5a24='}); 3565 3566 3567 3568 3569 var dataLayerTransport = (function() 3570 { 3571 var data = []; 3572 3573 return { 3574 data:[], 3575 push: function(data) 3576 { 3577 this.data.push(data); 3578 3579 return this; 3580 }, 3581 serialize: function() 3582 { 3583 return this.data; 3584 } 3585 } 3586 })(); 3587 3588</script>
3588 3589 3590
3590<script data-ommit="true" nonce="MW8zbHFodjIwMXlkMHZyNXk1Z2htd2p6a2FwNHo5a24="> 3591 3592 (endpoints => 3593 { 3594 let engines = 3595 { 3596 0: () => {}, 3597 1: () => {}, 3598 2: () => 3599 { 3600 window.addEventListener('CookiebotOnAccept', event => 3601 { 3602 return true; 3603 }, 3604 false); 3605 }, 3606 3: () => {}, 3607 4: () => 3608 { 3609 (() => 3610 { 3611 let wait = 0, interval = 100; 3612 3613 let otc = () => 3614 { 3615 return 'undefined' !== typeof window.OneTrust; 3616 }; 3617 3618 window.ot = setInterval(end => 3619 { 3620 wait += interval; 3621 3622 if (wait > end) 3623 { 3624 if (window.ot) 3625 { 3626 clearInterval(window.ot); 3627 } 3628 } 3629 3630 if (otc()) 3631 { 3632 window.dispatchEvent(new CustomEvent("onetrust_loaded", 3633 { 3634 detail: 3635 { 3636 groups: window.OptanonActiveGroups 3637 } 3638 })); 3639 3640 clearInterval(window.ot); 3641 3642 let uuid = AEC.Cookie.get('cookieUuid'); 3643 3644 let map = []; 3645 3646 OneTrust.OnConsentChanged(() => 3647 { 3648 let groups = window.OptanonActiveGroups.split(',').filter(String); 3649 3650 let grant = [], consent = {}; 3651 3652 groups.forEach(group => 3653 { 3654 if (map.hasOwnProperty(group)) 3655 { 3656 map[group].forEach(signal => 3657 { 3658 consent[signal] = true; 3659 }); 3660 } 3661 }); 3662 3663 Object.keys(consent).forEach(key => 3664 { 3665 grant.push(key); 3666 }); 3667 3668 let params = 3669 { 3670 cookie: grant 3671 }; 3672 3673 if (!grant.length) 3674 { 3675 params['decline'] = true; 3676 } 3677 3678 AEC.Request.post(endpoints.cookie, params , response => 3679 { 3680 return true; 3681 }); 3682 3683 return true; 3684 }); 3685 } 3686 }, 3687 interval); 3688 3689 })(2000); 3690 }, 3691 5: () => 3692 { 3693 let grant = []; 3694 3695 grant.push("cookieConsentGranted"); 3696 3697 let uuid = AEC.Cookie.get('cookieUuid'); 3698 3699 if (!uuid) 3700 { 3701 AEC.Request.post(endpoints.cookie, { cookie: grant }, response => 3702 { 3703 return true; 3704 }); 3705 } 3706 return true; 3707 }, 3708 6: () => 3709 { 3710 return true; 3711 } 3712 }; 3713 3714 engines[AEC.Const.COOKIE_DIRECTIVE_ENGINE].apply(this,[]); 3715 3716 })({"type":"json","cookie":"https:\/\/knirps.de\/datalayer\/index\/cookie\/","cookieContent":"https:\/\/knirps.de\/datalayer\/index\/cookieContent\/","cookieConsent":"https:\/\/knirps.de\/datalayer\/index\/cookieConsent\/"}); 3717 3718 </script>
3718 3719
3720<script data-ommit="true" nonce="MW8zbHFodjIwMXlkMHZyNXk1Z2htd2p6a2FwNHo5a24="> 3721 3722 /* Dynamic remarketing */ 3723 window.google_tag_params = window.google_tag_params || {}; 3724 3725 /* Default pagetype */ 3726 window.google_tag_params.ecomm_pagetype = "other"; 3727 3728 /* Grouped products collection */ 3729 window.G = []; 3730 3731 /** 3732 * Global revenue 3733 */ 3734 window.revenue = 0; 3735 3736 /** 3737 * DoubleClick 3738 */ 3739 window.DoubleClick = 3740 { 3741 DoubleClickRevenue: 0, 3742 DoubleClickTransaction: 0, 3743 DoubleClickQuantity: 0 3744 }; 3745 3746 3747 AEC.Cookie.visitor({"pageType":"other","pageName":"Blog \u2013 Knirps Regenschirme und Sonnenschirme","websiteCountry":"DE","websiteLanguage":"de_DE","visitorLoginState":"Logged out","visitorLifetimeValue":0,"visitorExistingCustomer":"Nein","clientStatus":"Not client","visitorType":"NOT LOGGED IN","currentStore":"Deutsch"}).push(dataLayer, false); 3748 3749</script>
3749 3750<meta name="facebook-domain-verification" content="dcc94td1st6fbpgl4jzt12meguj470"> 3751<!-- Google Tag Manager -->
3752<script nonce="MW8zbHFodjIwMXlkMHZyNXk1Z2htd2p6a2FwNHo5a24=">(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': 3753new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], 3754j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.nonce='MW8zbHFodjIwMXlkMHZyNXk1Z2htd2p6a2FwNHo5a24=';j.src= 3755'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); 3756})(window,document,'script','dataLayer','GTM-TFDQGJV');</script>
3756 3757<!-- End Google Tag Manager --> 3758
3759<script data-ommit="true" nonce="MW8zbHFodjIwMXlkMHZyNXk1Z2htd2p6a2FwNHo5a24="> 3760 3761 3762</script>
vendor: 1 bytes, line 3762
3762
3763<script data-ommit="true" nonce="MW8zbHFodjIwMXlkMHZyNXk1Z2htd2p6a2FwNHo5a24=">AEC.Bind.apply({"performance":false})</script>
3763 3764 3765<!--Custom Style--> 3766<style> 3767 .magezon-builder { 3768 z-index: unset; 3769 } 3770 @media (min-width: 1260px) { 3771 .magezon-builder .mgz-container {width: 1260px;} 3772 } 3773 </style> 3774 3775
3775<script type="text/javascript">var script = document.createElement('script'); 3776script.src = 'https://integrations.etrusted.com/applications/widget.js/v2'; 3777script.async = true; 3778script.defer = true; 3779document.head.appendChild(script);</script>
3779<script> 3780 var BASE_URL = 'https://knirps.de/'; 3781 var THEME_PATH = 'https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE'; 3782 var COOKIE_CONFIG = { 3783 "expires": null, 3784 "path": "\u002F", 3785 "domain": ".knirps.de", 3786 "secure": false, 3787 "lifetime": "7884000", 3788 "cookie_restriction_enabled": false }; 3789 var CURRENT_STORE_CODE = 'default'; 3790 var CURRENT_WEBSITE_ID = '1'; 3791 3792 window.hyva = window.hyva || {} 3793 3794 window.cookie_consent_groups = window.cookie_consent_groups || {} 3795 window.cookie_consent_groups['necessary'] = true; 3796 3797 window.cookie_consent_config = window.cookie_consent_config || {}; 3798 window.cookie_consent_config['necessary'] = [].concat( 3799 window.cookie_consent_config['necessary'] || [], 3800 [ 3801 'user_allowed_save_cookie', 3802 'form_key', 3803 'mage-messages', 3804 'private_content_version', 3805 'mage-cache-sessid', 3806 'last_visited_store', 3807 'section_data_ids' 3808 ] 3809 ); 3810 //# sourceURL=hyva-variables.js 3811</script>
vendor: 1 bytes, line 3811
3811
3812<script> 3813 (function( hyva, undefined ) { 3814 3815 function lifetimeToExpires(options, defaults) { 3816 3817 const lifetime = options.lifetime || defaults.lifetime; 3818 3819 if (lifetime) { 3820 const date = new Date; 3821 date.setTime(date.getTime() + lifetime * 1000); 3822 return date; 3823 } 3824 3825 return null; 3826 } 3827 3828 function generateRandomString() { 3829 3830 const allowedCharacters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 3831 length = 16; 3832 3833 let formKey = '', 3834 charactersLength = allowedCharacters.length; 3835 3836 for (let i = 0; i < length; i++) { 3837 formKey += allowedCharacters[Math.round(Math.random() * (charactersLength - 1))] 3838 } 3839 3840 return formKey; 3841 } 3842 3843 const sessionCookieMarker = {noLifetime: true} 3844 3845 const cookieTempStorage = {}; 3846 3847 const internalCookie = { 3848 get(name) { 3849 const v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)'); 3850 return v ? v[2] : null; 3851 }, 3852 set(name, value, days, skipSetDomain) { 3853 let expires, 3854 path, 3855 domain, 3856 secure, 3857 samesite; 3858 3859 const defaultCookieConfig = { 3860 expires: null, 3861 path: '/', 3862 domain: null, 3863 secure: false, 3864 lifetime: null, 3865 samesite: 'lax' 3866 }; 3867 3868 const cookieConfig = window.COOKIE_CONFIG || {}; 3869 3870 expires = days && days !== sessionCookieMarker 3871 ? lifetimeToExpires({lifetime: 24 * 60 * 60 * days, expires: null}, defaultCookieConfig) 3872 : lifetimeToExpires(window.COOKIE_CONFIG, defaultCookieConfig) || defaultCookieConfig.expires; 3873 3874 path = cookieConfig.path || defaultCookieConfig.path; 3875 domain = !skipSetDomain && (cookieConfig.domain || defaultCookieConfig.domain); 3876 secure = cookieConfig.secure || defaultCookieConfig.secure; 3877 samesite = cookieConfig.samesite || defaultCookieConfig.samesite; 3878 3879 document.cookie = name + "=" + encodeURIComponent(value) + 3880 (expires && days !== sessionCookieMarker ? '; expires=' + expires.toGMTString() : '') + 3881 (path ? '; path=' + path : '') + 3882 (domain ? '; domain=' + domain : '') + 3883 (secure ? '; secure' : '') + 3884 (samesite ? '; samesite=' + samesite : 'lax'); 3885 }, 3886 isWebsiteAllowedToSaveCookie() { 3887 const allowedCookies = this.get('user_allowed_save_cookie'); 3888 if (allowedCookies) { 3889 const allowedWebsites = JSON.parse(unescape(allowedCookies)); 3890 3891 return allowedWebsites[CURRENT_WEBSITE_ID] === 1; 3892 } 3893 return false; 3894 }, 3895 getGroupByCookieName(name) { 3896 const cookieConsentConfig = window.cookie_consent_config || {}; 3897 let group = null; 3898 for (let prop in cookieConsentConfig) { 3899 if (!cookieConsentConfig.hasOwnProperty(prop)) continue; 3900 if (cookieConsentConfig[prop].includes(name)) { 3901 group = prop; 3902 break; 3903 } 3904 } 3905 return group; 3906 }, 3907 isCookieAllowed(name) { 3908 const cookieGroup = this.getGroupByCookieName(name); 3909 return cookieGroup 3910 ? window.cookie_consent_groups[cookieGroup] 3911 : this.isWebsiteAllowedToSaveCookie(); 3912 }, 3913 saveTempStorageCookies() { 3914 for (const [name, data] of Object.entries(cookieTempStorage)) { 3915 if (this.isCookieAllowed(name)) { 3916 this.set(name, data['value'], data['days'], data['skipSetDomain']); 3917 delete cookieTempStorage[name]; 3918 } 3919 } 3920 } 3921 }; 3922 3923 hyva.getCookie = (name) => { 3924 const cookieConfig = window.COOKIE_CONFIG || {}; 3925 3926 if (cookieConfig.cookie_restriction_enabled && ! internalCookie.isCookieAllowed(name)) { 3927 return cookieTempStorage[name] ? cookieTempStorage[name]['value'] : null; 3928 } 3929 3930 return internalCookie.get(name); 3931 } 3932 3933 hyva.setCookie = (name, value, days, skipSetDomain) => { 3934 const cookieConfig = window.COOKIE_CONFIG || {}; 3935 3936 if (cookieConfig.cookie_restriction_enabled && ! internalCookie.isCookieAllowed(name)) { 3937 cookieTempStorage[name] = {value, days, skipSetDomain}; 3938 return; 3939 } 3940 return internalCookie.set(name, value, days, skipSetDomain); 3941 } 3942 3943 3944 hyva.setSessionCookie = (name, value, skipSetDomain) => { 3945 return hyva.setCookie(name, value, sessionCookieMarker, skipSetDomain) 3946 } 3947 3948 hyva.getBrowserStorage = () => { 3949 const browserStorage = window.localStorage || window.sessionStorage; 3950 if (!browserStorage) { 3951 console.warn('Browser Storage is unavailable'); 3952 return false;
3953 } 3954 try { 3955 browserStorage.setItem('storage_test', '1'); 3956 browserStorage.removeItem('storage_test'); 3957 } catch (error) { 3958 console.warn('Browser Storage is not accessible', error); 3959 return false; 3960 } 3961 return browserStorage; 3962 } 3963 3964 hyva.postForm = (postParams) => { 3965 const form = document.createElement("form"); 3966 3967 let data = postParams.data; 3968 3969 if (! postParams.skipUenc && ! data.uenc) { 3970 data.uenc = btoa(window.location.href); 3971 } 3972 form.method = "POST"; 3973 form.action = postParams.action; 3974 3975 Object.keys(postParams.data).map(key => { 3976 const field = document.createElement("input"); 3977 field.type = 'hidden' 3978 field.value = postParams.data[key]; 3979 field.name = key; 3980 form.appendChild(field); 3981 }); 3982 3983 const form_key = document.createElement("input"); 3984 form_key.type = 'hidden'; 3985 form_key.value = hyva.getFormKey(); 3986 form_key.name="form_key"; 3987 form.appendChild(form_key); 3988 3989 document.body.appendChild(form); 3990 3991 form.submit(); 3992 } 3993 3994 hyva.getFormKey = function () { 3995 let formKey = hyva.getCookie('form_key'); 3996 3997 if (!formKey) { 3998 formKey = generateRandomString(); 3999 hyva.setCookie('form_key', formKey); 4000 } 4001 4002 return formKey; 4003 } 4004 4005 hyva.formatPrice = (value, showSign, options = {}) => { 4006 const groupSeparator = options.groupSeparator; 4007 const decimalSeparator = options.decimalSeparator 4008 delete options.groupSeparator; 4009 delete options.decimalSeparator; 4010 const formatter = new Intl.NumberFormat( 4011 'de\u002DDE', 4012 Object.assign({ 4013 style: 'currency', 4014 currency: 'EUR', 4015 signDisplay: showSign ? 'always' : 'auto' 4016 }, options) 4017 ); 4018 return (typeof Intl.NumberFormat.prototype.formatToParts === 'function') ? 4019 formatter.formatToParts(value).map(({type, value}) => { 4020 switch (type) { 4021 case 'currency': 4022 return '\u20AC' || value; 4023 case 'minusSign': 4024 return '- '; 4025 case 'plusSign': 4026 return '+ '; 4027 case 'group': 4028 return groupSeparator !== undefined ? groupSeparator : value; 4029 case 'decimal': 4030 return decimalSeparator !== undefined ? decimalSeparator : value; 4031 default : 4032 return value; 4033 } 4034 }).reduce((string, part) => string + part) : 4035 formatter.format(value); 4036 } 4037 4038 const formatStr = function (str, nStart) { 4039 const args = Array.from(arguments).slice(2); 4040 4041 return str.replace(/(%+)([0-9]+)/g, (m, p, n) => { 4042 const idx = parseInt(n) - nStart; 4043 4044 if (args[idx] === null || args[idx] === void 0) { 4045 return m; 4046 } 4047 return p.length % 2 4048 ? p.slice(0, -1).replace('%%', '%') + args[idx] 4049 : p.replace('%%', '%') + n; 4050 }) 4051 } 4052 4053 hyva.str = function (string) { 4054 const args = Array.from(arguments); 4055 args.splice(1, 0, 1); 4056 4057 return formatStr.apply(undefined, args); 4058 } 4059 4060 hyva.strf = function () { 4061 const args = Array.from(arguments); 4062 args.splice(1, 0, 0); 4063 4064 return formatStr.apply(undefined, args); 4065 } 4066 4067 /** 4068 * Take a html string as `content` parameter and 4069 * extract an element from the DOM to replace in 4070 * the current page under the same selector, 4071 * defined by `targetSelector` 4072 */ 4073 hyva.replaceDomElement = (targetSelector, content) => { 4074 // Parse the content and extract the DOM node using the `targetSelector` 4075 const parser = new DOMParser(); 4076 const doc = parser.parseFromString(content, 'text/html');
4077 const contentNode = doc.querySelector(targetSelector); 4078 4079 // Bail if content or target can't be found 4080 if (!contentNode || !document.querySelector(targetSelector)) { 4081 return; 4082 } 4083 4084 hyva.activateScripts(contentNode); 4085 4086 // Replace the old DOM node with the new content 4087 document.querySelector(targetSelector).replaceWith(contentNode); 4088 4089 // Reload customerSectionData and display cookie-messages if present 4090 window.dispatchEvent(new CustomEvent("reload-customer-section-data")); 4091 hyva.initMessages(); 4092 } 4093 4094 hyva.removeScripts = (contentNode) => { 4095 const scripts = contentNode.getElementsByTagName('script'); 4096 for (let i = 0; i < scripts.length; i++) { 4097 scripts[i].parentNode.removeChild(scripts[i]); 4098 } 4099 const templates = contentNode.getElementsByTagName('template'); 4100 for (let i = 0; i < templates.length; i++) { 4101 const container = document.createElement('div'); 4102 container.innerHTML = templates[i].innerHTML; 4103 hyva.removeScripts(container); 4104 templates[i].innerHTML = container.innerHTML; 4105 } 4106 } 4107 4108 hyva.activateScripts = (contentNode) => { 4109 // Create new array from HTMLCollection to avoid mutation of collection while manipulating the DOM. 4110 const scripts = Array.from(contentNode.getElementsByTagName('script')); 4111 4112 // Iterate over all script tags to duplicate+inject each into the head 4113 for (const original of scripts) { 4114 const script = document.createElement('script'); 4115 original.type && (script.type = original.type); 4116 script.innerHTML = original.innerHTML; 4117 4118 // Remove the original (non-executing) script from the contentNode 4119 original.parentNode.removeChild(original) 4120 4121 // Add script to head 4122 document.head.appendChild(script); 4123 } 4124 4125 return contentNode; 4126 } 4127 4128 const replace = {['+']: '-', ['/']: '_', ['=']: ','}; 4129 hyva.getUenc = () => btoa(window.location.href).replace(/[+/=]/g, match => replace[match]); 4130 4131 let currentTrap; 4132 4133 const focusableElements = (rootElement) => { 4134 const selector = 'button, [href], input, select, textarea, details, [tabindex]:not([tabindex="-1"]'; 4135 return Array.from(rootElement.querySelectorAll(selector)) 4136 .filter(el => { 4137 return el.style.display !== 'none' 4138 && !el.disabled 4139 && el.tabIndex !== -1 4140 && (el.offsetWidth || el.offsetHeight || el.getClientRects().length) 4141 }) 4142 } 4143 4144 const focusTrap = (e) => { 4145 const isTabPressed = e.key === 'Tab' || e.keyCode === 9; 4146 if (!isTabPressed) return; 4147 4148 const focusable = focusableElements(currentTrap) 4149 const firstFocusableElement = focusable[0] 4150 const lastFocusableElement = focusable[focusable.length - 1] 4151 4152 e.shiftKey 4153 ? document.activeElement === firstFocusableElement && (lastFocusableElement.focus(), e.preventDefault()) 4154 : document.activeElement === lastFocusableElement && (firstFocusableElement.focus(), e.preventDefault()) 4155 }; 4156 4157 hyva.releaseFocus = (rootElement) => { 4158 if (currentTrap && (!rootElement || rootElement === currentTrap)) { 4159 currentTrap.removeEventListener('keydown', focusTrap) 4160 currentTrap = null 4161 } 4162 } 4163 hyva.trapFocus = (rootElement) => { 4164 if (!rootElement) return; 4165 hyva.releaseFocus() 4166 currentTrap = rootElement 4167 rootElement.addEventListener('keydown', focusTrap) 4168 const firstElement = focusableElements(rootElement)[0] 4169 firstElement && firstElement.focus() 4170 } 4171 4172 hyva.safeParseNumber = (rawValue) => { 4173 const number = rawValue ? parseFloat(rawValue) : null; 4174 4175 return Array.isArray(number) || isNaN(number) ? rawValue : number; 4176 } 4177 4178 const toCamelCase = s => s.split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(''); 4179 hyva.createBooleanObject = (name, value = false, additionalMethods = {}) => { 4180 4181 const camelCase = toCamelCase(name);
4182 const key = '__hyva_bool_' + name 4183 4184 return new Proxy(Object.assign( 4185 additionalMethods, 4186 { 4187 [key]: !!value, 4188 [name]() {return !!this[key]}, 4189 ['!' + name]() {return !this[key]}, // @deprecated This does not work with non-CSP Alpine 4190 ['not' + camelCase]() {return !this[key]}, 4191 ['toggle' + camelCase]() {this[key] = !this[key]}, 4192 [`set${camelCase}True`]() {this[key] = true}, 4193 [`set${camelCase}False`]() {this[key] = false}, 4194 } 4195 ), { 4196 set(target, prop, value) { 4197 return prop === name 4198 ? (target[key] = !!value) 4199 : Reflect.set(...arguments); 4200 } 4201 }) 4202 } 4203 4204 hyva.alpineInitialized = (fn) => window.addEventListener('alpine:initialized', fn, {once: true}) 4205 window.addEventListener('alpine:init', () => Alpine.data('{}', () => ({})), {once: true}); 4206 window.addEventListener('user-allowed-save-cookie', () => internalCookie.saveTempStorageCookies()) 4207 4208 }( window.hyva = window.hyva || {} )); 4209 //# sourceURL=hyva.js 4210</script>
vendor: 1 bytes, line 4210
4210
4211<script type="speculationrules"> 4212{ 4213 "tag": "Hyva Theme", 4214 "prefetch": [{ 4215 "source": "document", 4216 "where": { 4217 "and": [ 4218 { "href_matches": "/*" }, 4219 { "not": { 4220 "href_matches": ["/customer/*","/search/*","/sales/*","/wishlist/*","/checkout/*","/paypal/*","/newsletter/*","/stores/store/redirect/*"] }}, 4221 { "not": { 4222 "selector_matches": [".no-preload", ".do-not-prerender", "[download]", "[rel~=nofollow]", "[target]"] 4223 }} 4224 ] 4225 }, 4226 "eagerness": "moderate" 4227 }] 4228} 4229</script>
4229 4230
4231<script> 4232 const viewTransitionToGalleryPageStorage = 'view-transition-to-gallery-page-type'; 4233 const setTransitionNameBetweenGallery = async (url, promise) => { 4234 if (window.matchMedia('(prefers-reduced-motion)').matches) return; 4235 4236 const productGallery = document.getElementById('gallery-main'); 4237 const productListItem = document.querySelector(`.product-item-photo[href="${url}"]`); 4238 const targetElement = productListItem || productGallery; 4239 4240 if (targetElement) { 4241 targetElement.style.viewTransitionName = 'view-transition-to-gallery'; 4242 4243 await promise; 4244 targetElement.style.viewTransitionName = ''; 4245 } 4246 }; 4247 4248 const getViewTransitionToGalleryPageIsProduct = () => { 4249 return document.body.classList.contains('catalog-product-view') ? 'product-page' : 'other' 4250 } 4251 4252 window.addEventListener('pageswap', async (e) => { 4253 if (!e.viewTransition) return; 4254 const pageType = getViewTransitionToGalleryPageIsProduct(); 4255 const target = new URL(e.activation.entry.url); 4256 4257 sessionStorage.setItem(viewTransitionToGalleryPageStorage, pageType); 4258 setTransitionNameBetweenGallery(target.href, e.viewTransition.finished); 4259 }); 4260 4261 window.addEventListener('pagereveal', async (e) => { 4262 if (!e.viewTransition || (window.navigation && !window.navigation.activation.from)) return; 4263 const previousPageType = sessionStorage.getItem(viewTransitionToGalleryPageStorage); 4264 const pageType = getViewTransitionToGalleryPageIsProduct(); 4265 sessionStorage.removeItem(viewTransitionToGalleryPageStorage); 4266 4267 if (previousPageType === pageType) return; 4268 const target = new URL(window.navigation.activation.from.url); 4269 setTransitionNameBetweenGallery(target.href, e.viewTransition.ready); 4270 }); 4271</script>
4271 4272 4273<meta property="og:type" content="article"/> 4274<meta property="og:title" content="Blog – Knirps Regenschirme und Sonnenschirme"/> 4275<meta property="og:description" content="Im Knirps Blog erhalten Sie alle Informationen und News zur Marke Knirps, den Produkten Regenschirme und Sonnenschirme und neuen Innovationen."/> 4276<meta property="og:url" content="https://knirps.de/blog"/> 4277<meta property="og:site_name" content="Knirps"/> 4278<meta property="og:image" content="https://knirps.de/media/og_image/websites/1/fb_logo.jpg"/> 4279<meta property="og:image:width" content="640"/> 4280<meta property="og:image:height" content="640"/>
4281<script type="application/ld+json">{"@context":"https:\/\/schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","item":{"@id":"https:\/\/knirps.de\/blog\/","name":"Blog"},"position":1}]}</script>
4281<style> 4282 .ec-gtm-cookie-directive > div { background: #ffffff; color: #000000; -webkit-border-radius: 8px; -moz-border-radius: 8px; -ms-border-radius: 8px; -o-border-radius: 8px; border-radius: 8px; } 4283 .ec-gtm-cookie-directive > div > div > div { padding-left: 0px; } 4284 .ec-gtm-cookie-directive > div > div > div a.action.accept, 4285 .ec-gtm-cookie-directive > div > div > div a.action.accept-all { color: #8bc53f; } 4286 .ec-gtm-cookie-directive > div > div > div a.action.refuse, 4287 .ec-gtm-cookie-directive > div > div > div a.action.customize { color: #000000; } 4288 .ec-gtm-cookie-directive > div > div > div .ec-gtm-cookie-directive-note-toggle { color: #8bc53f; } 4289 .ec-gtm-cookie-directive-segments { background: #ffffff; } 4290 .ec-gtm-cookie-directive-segments > div input[type="checkbox"] + label:before { border:1px solid #000000; } 4291 .ec-gtm-cookie-directive .consent-logo { width: 0px; } 4292 4293</style><style>.ha8y4pj{height:50px}.mgz-element.o24j7px .mgz-element-heading-text{font-weight:300}.x18o8oi{height:20px}.t2m7ek4-s{padding:0 10px 0 10px!important;margin:0!important}.imo5vs0-s{text-align:center}.mgz-element.imo5vs0 .mgz-cta-content{text-align:center;min-height:150px;padding:15px}.mgz-element.imo5vs0 .mgz-cta-title{font-size:18px;color:#ffffff}.mgz-element.imo5vs0 .mgz-cta-description{color:#ffffff}.mgz-element.imo5vs0 .mgz-cta-bg,.mgz-element.imo5vs0 .mgz-cta-bg-overlay{transition-duration:1500ms}.f60gsyk-s{text-align:center}.mgz-element.f60gsyk .mgz-cta-content{text-align:center;min-height:150px;padding:15px}.mgz-element.f60gsyk .mgz-cta-title{font-size:18px;color:#ffffff}.mgz-element.f60gsyk .mgz-cta-description{color:#ffffff}.mgz-element.f60gsyk .mgz-cta-bg,.mgz-element.f60gsyk .mgz-cta-bg-overlay{transition-duration:1500ms}.csk37y9-s{text-align:center}.mgz-element.csk37y9 .mgz-cta-content{text-align:center;min-height:150px;padding:15px;background-color:#ffffff}.mgz-element.csk37y9 .mgz-cta-title{font-size:18px;color:#ffffff}.mgz-element.csk37y9 .mgz-cta-description{color:#ffffff}.mgz-element.csk37y9 .mgz-cta-bg,.mgz-element.csk37y9 .mgz-cta-bg-overlay{transition-duration:1500ms}.mgz-element.csk37y9 .mgz-cta-bg-overlay{background-color:rgba(255,255,255,0)}.kbo0ou6-s{text-align:center}.mgz-element.kbo0ou6 .mgz-cta-content{text-align:center;min-height:150px;padding:15px}.mgz-element.kbo0ou6 .mgz-cta-title{font-size:18px;color:#ffffff}.mgz-element.kbo0ou6 .mgz-cta-description{color:#ffffff}.mgz-element.kbo0ou6 .mgz-cta-bg,.mgz-element.kbo0ou6 .mgz-cta-bg-overlay{transition-duration:1500ms}.jxqeaun-s{text-align:center}.mgz-element.jxqeaun .mgz-cta-content{text-align:center;min-height:150px;padding:15px}.mgz-element.jxqeaun .mgz-cta-title{font-size:18px;color:#ffffff}.mgz-element.jxqeaun .mgz-cta-description{color:#ffffff}.mgz-element.jxqeaun .mgz-cta-bg-wrapper{min-height:300px}.mgz-element.jxqeaun .mgz-cta-bg,.mgz-element.jxqeaun .mgz-cta-bg-overlay{transition-duration:1500ms}.xdb079v-s{text-align:center}.mgz-element.xdb079v .mgz-cta-content{text-align:center;min-height:150px;padding:15px}.mgz-element.xdb079v .mgz-cta-title{font-size:18px;color:#ffffff}.mgz-element.xdb079v .mgz-cta-description{color:#ffffff}.mgz-element.xdb079v .mgz-cta-bg,.mgz-element.xdb079v .mgz-cta-bg-overlay{transition-duration:1500ms}.aeelgq5-s{text-align:center}.mgz-element.aeelgq5 .mgz-cta-content{text-align:center;min-height:150px;padding:15px}.mgz-element.aeelgq5 .mgz-cta-title{font-size:18px;color:#ffffff}.mgz-element.aeelgq5 .mgz-cta-description{color:#ffffff}.mgz-element.aeelgq5 .mgz-cta-bg,.mgz-element.aeelgq5 .mgz-cta-bg-overlay{transition-duration:1500ms}.ocn0435-s{text-align:center}.mgz-element.ocn0435 .mgz-cta-content{text-align:center;min-height:150px;padding:15px}.mgz-element.ocn0435 .mgz-cta-title{font-size:18px;color:#ffffff}.mgz-element.ocn0435 .mgz-cta-description{color:#ffffff}.mgz-element.ocn0435 .mgz-cta-bg,.mgz-element.ocn0435 .mgz-cta-bg-overlay{transition-duration:1500ms}.n6jvc34-s{text-align:center}.mgz-element.n6jvc34 .mgz-cta-content{text-align:center;min-height:150px;padding:15px}.mgz-element.n6jvc34 .mgz-cta-title{font-size:18px;color:#ffffff}.mgz-element.n6jvc34 .mgz-cta-description{color:#ffffff}.mgz-element.n6jvc34 .mgz-cta-bg,.mgz-element.n6jvc34 .mgz-cta-bg-overlay{transition-duration:1500ms}.mev8wng-s{text-align:center}.mgz-element.mev8wng .mgz-cta-content{text-align:center;min-height:150px;padding:15px;background-color:#343434}.mgz-element.mev8wng .mgz-cta-title{font-size:18px;color:#ffffff}.mgz-element.mev8wng .mgz-cta-description{color:#ffffff}.mgz-element.mev8wng .mgz-cta-bg,.mgz-element.mev8wng .mgz-cta-bg-overlay{transition-duration:1500ms}.m807fig-s{padding:0!important;margin:0!important}.k0kbj28-s{text-align:center}.mgz-element.k0kbj28 .mgz-cta-content{text-align:center;min-height:150px;padding:15px}.mgz-element.k0kbj28 .mgz-cta-title{font-size:18px;color:#ffffff}.mgz-element.k0kbj28 .mgz-cta-description{color:#ffffff}.mgz-element.k0kbj28 .mgz-cta-bg,.mgz-element.k0kbj28 .mgz-cta-bg-overlay{transition-duration:1500ms}.qfi5h1i-s{padding:0!important;margin-top:0 !important;margin-bottom:0 !important;margin-left:0 !important}.kb7nebb-s{min-height:300px !important;padding:0!important;margin:0!important}.vbwld4e,.m807fig,.qfi5h1i{border:10px solid transparent}.vbwld4e>.mgz-element-inner,.m807fig>.mgz-element-inner,.qfi5h1i>.mgz-element-inner{padding:0;margin:0}.yctgn9o-s{text-align:center}.mgz-element.yctgn9o .mgz-cta-content{text-align:center;min-height:150px;padding:15px}.mgz-element.yctgn9o .mgz-cta-title{font-size:18px;color:#ffffff}.mgz-element.yctgn9o .mgz-cta-description{color:#ffffff}.mgz-element.yctgn9o .mgz-cta-bg,.mgz-element.yctgn9o .mgz-cta-bg-overlay{transition-duration:1500ms}.km3nqbp-s{text-align:center}.mgz-element.km3nqbp .mgz-cta-content{text-align:center;min-height:150px;padding:15px}.mgz-element.km3nqbp .mgz-cta-title{font-size:18px;color:#ffffff}.mgz-element.km3nqbp .mgz-cta-description{color:#ffffff}.mgz-element.km3nqbp .mgz-cta-bg,.mgz-element.km3nqbp .mgz-cta-bg-overlay{transition-duration:1500ms}.nfmswbq>.mgz-element-inner{padding:0}.peb9ipg-s{text-align:center}.mgz-element.peb9ipg .mgz-cta-content{text-align:center;min-height:150px;padding:5px}.mgz-element.peb9ipg .mgz-cta-title{font-size:18px;color:#ffffff}.mgz-element.peb9ipg .mgz-cta-description{color:#ffffff}.mgz-element.peb9ipg .mgz-cta-bg,.mgz-element.peb9ipg .mgz-cta-bg-overlay{transition-duration:1500ms}.tn4oym6-s{padding:0!important;margin:0!important}.sviof2x-s{padding:0!important;margin:0!important}.custom-background .mgz-cta-content{background-color:#343434 !important}a:link,a:visited{text-decoration:none}</style></head> 4294<body id="html-body" class="cms-blog- cms-page-view page-layout-1column-fullwidth"> 4295<!-- Google Tag Manager (noscript) -->
vendor: 69 bytes, lines 4295-4296
4295 4296<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=
4296GTM-TFDQGJV
vendor: 85 bytes, lines 4296-4297
4296" 4297height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
4298<!-- End Google Tag Manager (noscript) --><input name="form_key" type="hidden" value="8hdfTz3HiM3AEb3d" /> 4299 <noscript> 4300 <section 4301 class="message global noscript border-b-2 border-blue-500 bg-blue-50 shadow-none m-0 px-0 rounded-none font-normal" 4302 aria-labelledby="messageGlobalNoScriptMessage" 4303 > 4304 <div class="container text-center"> 4305 <p id="messageGlobalNoScriptMessage"> 4306 <strong>JavaScript scheint in Ihrem Browser deaktiviert zu sein.</strong> 4307 <span> 4308 Um unsere Website in bester Weise zu erfahren, aktivieren Sie Javascript in Ihrem Browser. </span> 4309 </p> 4310 </div> 4311 </section> 4312 </noscript> 4313 4314
4315<script> 4316 document.body.addEventListener('touchstart', () => {}, {passive: true}) 4317</script>
4317 4318
4319<script> 4320 (function(hyva) { 4321 const formValidationRules = { 4322 required(value, options, field, context) { 4323 const el = field.element.type === 'hidden' ? createTextInputFrom(field.element) : field.element, 4324 fieldName = getFieldName(field), 4325 msg = fieldName 4326 ? hyva.str('\u00251\u0020field\u0020is\u0020required.', fieldName) 4327 : 'Vervollst\u00E4ndigen\u0020Sie\u0020bitte\u0020die\u0020notwendigen\u0020Angaben.'; 4328 4329 if (el.type === 'radio' || el.type === 'checkbox') { 4330 return (value === undefined || value.length === 0) ? msg : true; 4331 } 4332 4333 el.setAttribute('required', ''); 4334 el.checkValidity(); 4335 4336 return el.validity.valueMissing ? msg : true; 4337 }, 4338 maxlength(value, options, field, context) { 4339 const n = Number(options) 4340 if (value.length > n) { 4341 const fieldName = getFieldName(field); 4342 return fieldName 4343 ? n === 1 4344 ? hyva.str('\u00251\u0020field\u0020cannot\u0020be\u0020longer\u0020than\u00201\u0020character.', fieldName) 4345 : hyva.str('\u00251\u0020field\u0020cannot\u0020be\u0020longer\u0020than\u0020\u00252\u0020characters.', fieldName, options) 4346 : n === 1 4347 ? 'Bitte\u0020geben\u0020Sie\u0020nicht\u0020mehr\u0020als\u00201\u0020Zeichen\u0020ein.' 4348 : hyva.strf('Bitte\u0020geben\u0020Sie\u0020nicht\u0020mehr\u0020als\u0020\u00250\u0020Zeichen\u0020ein.', options); 4349 } 4350 return true; 4351 }, 4352 minlength(value, options, field, context) { 4353 const n = Number(options) 4354 if (value.length > 0 && value.length < n) { 4355 const fieldName = getFieldName(field); 4356 return fieldName 4357 ? n === 1 4358 ? hyva.str('\u00251\u0020field\u0020must\u0020be\u0020at\u0020least\u00201\u0020character\u0020long.', fieldName) 4359 : hyva.str('\u00251\u0020field\u0020must\u0020be\u0020at\u0020least\u0020\u00252\u0020characters\u0020long.', fieldName, options) 4360 : n === 1 4361 ? 'Bitte\u0020geben\u0020Sie\u0020mindestens\u00201\u0020Zeichen\u0020ein.' 4362 : hyva.strf('Bitte\u0020geben\u0020Sie\u0020mindestens\u0020\u00250\u0020Zeichen\u0020ein.', options); 4363 } 4364 return true; 4365 }, 4366 max(value, options, field, context) { 4367 field.element.setAttribute('max', options); 4368 field.element.checkValidity(); 4369 if (field.element.validity.rangeOverflow) { 4370 const fieldName = getFieldName(field); 4371 return fieldName 4372 ? hyva.str('\u00251\u0020field\u0020must\u0020contain\u0020a\u0020value\u0020less\u0020than\u0020or\u0020equal\u0020to\u0020\u0022\u00252\u0022.', fieldName, options) 4373 : hyva.strf('Bitte\u0020geben\u0020Sie\u0020einen\u0020Wert\u0020ein,\u0020der\u0020kleiner\u0020oder\u0020gleich\u0020\u0022\u00250\u0022\u0020ist.', options); 4374 } 4375 return true; 4376 }, 4377 min(value, options, field, context) { 4378 field.element.setAttribute('min', options); 4379 field.element.checkValidity(); 4380 if (field.element.validity.rangeUnderflow) { 4381 const fieldName = getFieldName(field); 4382 return fieldName 4383 ? hyva.str('\u00251\u0020field\u0020must\u0020contain\u0020a\u0020value\u0020greater\u0020than\u0020or\u0020equal\u0020to\u0020\u0022\u00252\u0022.', fieldName, options) 4384 : hyva.strf('Bitte\u0020geben\u0020Sie\u0020einen\u0020Wert\u0020gr\u00F6\u00DFer\u0020oder\u0020gleich\u0020\u0022\u00250\u0022\u0020ein.', options); 4385 } 4386 return true; 4387 }, 4388 step(value, options, field, context) { 4389 field.element.setAttribute('step', options); 4390 field.element.checkValidity(); 4391 if (field.element.validity.stepMismatch) { 4392 const val = Number(value), 4393 step = Number(options), 4394 fieldName = getFieldName(field), 4395 nearestLowerValue = Math.floor(val / step) * step,
4396 nearestUpperValue = Math.ceil(val / step) * step; 4397 return fieldName 4398 ? hyva.str('\u00251\u0020field\u0020is\u0020invalid.\u0020The\u0020two\u0020nearest\u0020valid\u0020values\u0020are\u0020\u0022\u00252\u0022\u0020and\u0020\u0022\u00253\u0022.', fieldName, nearestLowerValue, nearestUpperValue) 4399 : hyva.strf('Bitte\u0020geben\u0020Sie\u0020einen\u0020g\u00FCltigen\u0020Wert\u0020ein.\u0020Die\u0020beiden\u0020n\u00E4chstliegenden\u0020g\u00FCltigen\u0020Werte\u0020sind\u0020\u0022\u00250\u0022\u0020und\u0020\u0022\u00251\u0022.', nearestLowerValue, nearestUpperValue); 4400 } 4401 return true; 4402 }, 4403 pattern(value, options, field, context) { 4404 field.element.setAttribute('pattern', options); 4405 field.element.checkValidity(); 4406 if (field.element.validity.patternMismatch) { 4407 const fieldName = getFieldName(field); 4408 return fieldName 4409 ? field.element.pattern 4410 ? hyva.str('\u00251\u0020field\u0020must\u0020match\u0020the\u0020requested\u0020format\u003A\u0020\u00252.', fieldName, field.element.pattern) 4411 : hyva.str('\u00251\u0020field\u0020must\u0020match\u0020the\u0020requested\u0020format.', fieldName) 4412 : field.element.pattern 4413 ? hyva.strf('Bitte\u0020entsprechen\u0020Sie\u0020dem\u0020gew\u00FCnschten\u0020Format\u003A\u0020\u00250.', field.element.pattern) 4414 : 'Bitte\u0020beachten\u0020Sie\u0020das\u0020gew\u00FCnschte\u0020Format.'; 4415 } 4416 return true; 4417 }, 4418 email(value, options, field, context) { 4419 const rule = /^([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*@([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*\.(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]){2,})$/i; 4420 if (value.length > 0 && !rule.test(value)) { 4421 const fieldName = getFieldName(field); 4422 return fieldName 4423 ? hyva.str('\u00251\u0020field\u0020must\u0020contain\u0020a\u0020valid\u0020email\u0020address\u0020\u0028Ex\u003A\u0020johndoe\u0040domain.com\u0029.', fieldName) 4424 : 'Bitte\u0020geben\u0020Sie\u0020eine\u0020g\u00FCltige\u0020E\u002DMail\u0020Adresse\u0020ein\u0020\u0028z.B.\u0020johndoe\u0040domain.com\u0029.'; 4425 } 4426 return true; 4427 }, 4428 password(value, options, field, context) { 4429 const rule = /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$/; 4430 if (value.length > 0 && !rule.test(value)) { 4431 const fieldName = getFieldName(field); 4432 return fieldName 4433 ? hyva.str('\u00251\u0020field\u0020must\u0020contain\u0020at\u0020least\u0020one\u0020upper\u0020case,\u0020one\u0020lower\u0020case,\u0020one\u0020digit\u0020and\u0020one\u0020special\u0020character\u0020\u0028\u0023\u003F\u0021\u0040\u0024\u0025\u005E\u0026\u002A\u002D\u0029', fieldName) 4434 : 'Bitte\u0020geben\u0020Sie\u0020mindestens\u0020einen\u0020Gro\u00DFbuchstaben,\u0020einen\u0020Kleinbuchstaben,\u0020eine\u0020Ziffer\u0020und\u0020ein\u0020Sonderzeichen\u0020\u0028\u0023\u003F\u0021\u0040\u0024\u0025\u005E\u0026amp\u003B\u002A\u002D\u0029\u0020an.'; 4435 } 4436 return true; 4437 }, 4438 equalTo(value, options, field, context) { 4439 const dependencyField = context.fields[options].element; 4440 if (value !== dependencyField.value) { 4441 const dependencyFieldName = 4442 dependencyField.label || 4443 dependencyField.title || 4444 (dependencyField.labels && dependencyField.labels[0] && dependencyField.labels[0].innerText) || 4445 dependencyField.name, 4446 fieldName = getFieldName(field); 4447 return fieldName
4448 ? hyva.str('\u00251\u0020field\u0020value\u0020must\u0020be\u0020the\u0020same\u0020as\u0020\u0022\u00252\u0022.', fieldName, dependencyFieldName) 4449 : hyva.strf('Der\u0020Wert\u0020dieses\u0020Feldes\u0020muss\u0020mit\u0020\u0022\u00250\u0022\u0020identisch\u0020sein.', dependencyFieldName); 4450 } 4451 return true; 4452 } 4453 }; 4454 4455 function raceSome(promises, pred) { 4456 return new Promise((resolve, reject) => { 4457 4458 if (promises.length === 0) { 4459 return resolve(); 4460 } 4461 4462 let settled = false, nDone = 0; 4463 4464 const resolveIf = v => { 4465 if (!settled && (pred(v) || ++nDone === promises.length)) { 4466 settled = true; 4467 resolve(v); 4468 } 4469 return v; 4470 } 4471 4472 promises.map(promise => { 4473 promise.then(resolveIf).catch(reason => { 4474 settled = true; 4475 reject(reason) 4476 }); 4477 return promise; 4478 }); 4479 }); 4480 } 4481 4482 const INPUT_ATTRIBUTE_RULES = {min: 'min', max: 'max', required: 'required', minlength: 'minlength', maxlength: 'maxlength', step: 'step', pattern: 'pattern'} 4483 const INPUT_TYPE_RULES = {email: 'email'} 4484 4485 function getRules(element) { 4486 let rules = {}; 4487 Object.keys(INPUT_ATTRIBUTE_RULES).forEach(attrName => { 4488 if (element.hasAttribute(attrName)) { 4489 rules[INPUT_ATTRIBUTE_RULES[attrName]] = element.getAttribute(attrName); 4490 } 4491 }) 4492 if (INPUT_TYPE_RULES[element.type]) { 4493 rules[INPUT_TYPE_RULES[element.type]] = true; 4494 } 4495 4496 if (element.dataset.validate) { 4497 try { 4498 Object.assign(rules, JSON.parse(element.dataset.validate)); 4499 } catch (error) { 4500 console.error('Validator error. Cannot parse data-validate attribute of element:\n', element); 4501 } 4502 } 4503 4504 return rules; 4505 } 4506 4507 function isInvalidRuleResult(ruleState) { 4508 return typeof ruleState === 'string' || !ruleState || (ruleState.type && ruleState.content); 4509 } 4510 4511 async function runValidateFn(rule, options, value, field) { 4512 return formValidationRules[rule](value, options, field, this); 4513 } 4514 4515 function generateId() { 4516 let id; 4517 do { 4518 id = `${this.idPrefix}-${++this.idSeq}`; 4519 } while (document.getElementById(id)); 4520 return id; 4521 } 4522 4523 function isVisible(element) { 4524 const el = element.type !== 'hidden' ? element : (element.parentElement || {}); 4525 return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length) 4526 } 4527 4528 function elementWillValidate(element) { 4529 return (element.willValidate || element.type === 'hidden') 4530 && element.tagName !== 'BUTTON' 4531 && element.disabled === false 4532 && !(element.tagName === 'INPUT' && element.type === 'submit') 4533 && (element.hasAttribute('data-validate-hidden') || isVisible(element)) 4534 } 4535 4536 function createMessageContainer(el, fieldWrapperClassName) { 4537 if (! el.parentElement) { 4538 return; 4539 } 4540 const refocus = document.activeElement === el; 4541 const wrapper = document.createElement('div'); 4542 wrapper.classList.add.apply(wrapper.classList, fieldWrapperClassName.split(' ')); 4543 el.parentElement.insertBefore(wrapper, el); 4544 wrapper.appendChild(el); 4545 refocus && document.activeElement !== el && el.focus(); 4546 return wrapper; 4547 } 4548 4549 function containerNotFound(selector, el) { 4550 const msg = `Cannot find message container element ${selector} of ${el.name}`; 4551 console.error(msg, el); 4552 throw msg; 4553 } 4554 4555 function createTextInputFrom(el) { 4556 const text = document.createElement('INPUT'); 4557 text.type = 'text'; 4558 text.value = el.value; 4559 return text; 4560 } 4561 4562 function classNamesToSelector(classNames) { 4563 return classNames.split(' ') 4564 .filter(className => className.length > 0) 4565 .map(className => `.${className}`) 4566 .join('') 4567 } 4568 4569 function hasMessagesWrapper(field, messagesWrapperClassName) { 4570 return this.getMessageContainer(field).querySelector(classNamesToSelector(messagesWrapperClassName)); 4571 } 4572
4573 function getMessagesWrapper(field, messagesWrapperClassName) { 4574 if (hasMessagesWrapper.call(this, field, messagesWrapperClassName)) { 4575 return this.getMessageContainer(field).querySelector(classNamesToSelector(messagesWrapperClassName)); 4576 } 4577 4578 const msgWrapper = document.createElement('ul'); 4579 const msgId = generateId.call(this); 4580 msgWrapper.id = msgId; 4581 field.element.setAttribute('aria-errormessage', msgId); 4582 field.element.setAttribute('aria-describedby', msgId); 4583 msgWrapper.classList.add.apply(msgWrapper.classList, messagesWrapperClassName.split(' ')); 4584 if (field.validateOnChange) { 4585 msgWrapper.setAttribute('aria-live', 'polite'); 4586 } 4587 this.getMessageContainer(field).appendChild(msgWrapper); 4588 4589 return msgWrapper; 4590 } 4591 4592 function getCheckedValues(field) { 4593 const name = field.element.name.replace(/([\\"])/g, '\\$1'); 4594 const elements = field.element.form.querySelectorAll('input[name="' + name + '"]:checked'); 4595 return Array.from(elements).map(el => el.value); 4596 } 4597 4598 function escapeHtml(s) { 4599 const div = document.createElement('div') 4600 div.innerText = s; 4601 return div.innerHTML; 4602 } 4603 4604 4605 function formValidation(form, options = {}) { 4606 const formElement = form || this.$el; 4607 4608 if (formElement.dataset && formElement.dataset.options) { 4609 try { 4610 options = Object.assign(options, JSON.parse(formElement.dataset.options || '{}')); 4611 } catch (e) { 4612 throw new Error('Cannot read the form options from the data-options attribute: not valid JSON'); 4613 } 4614 } 4615 4616 // Disable browser default validation 4617 if (formElement.tagName === 'FORM') { 4618 formElement.setAttribute('novalidate', ''); 4619 } else { 4620 console.error('formValidation can be initialized only on FORM element', formElement); 4621 return; 4622 } 4623 4624 options = Object.assign({ 4625 fieldWrapperClassName: 'field field-reserved', 4626 messagesWrapperClassName: 'messages', 4627 validClassName: 'field-success', 4628 invalidClassName: 'field-error', 4629 pageMessagesWrapperSelector: null, 4630 scrollToFirstError: true, 4631 }, options || {}); 4632 4633 return { 4634 state: { 4635 valid: false, 4636 }, 4637 fields: {}, 4638 idSeq: 0, 4639 idPrefix: formElement.id || 'vld-msg', 4640 setupFields(elements) { 4641 this.fields = {}; 4642 Array.from(elements).forEach(element => { 4643 if (elementWillValidate(element)) { 4644 this.setupField(element); 4645 } 4646 }); 4647 }, 4648 setupField(element) { 4649 if (! element) return; 4650 const onChange = !!element.dataset.onChange; 4651 if (elementWillValidate(element)) { 4652 const rules = getRules(element); 4653 if (Object.keys(rules).length > 0) { 4654 if (this.fields[element.name]) { 4655 Object.assign(this.fields[element.name].rules, rules); 4656 } else { 4657 this.fields[element.name] = { 4658 element, 4659 rules: rules, 4660 validateOnChange: onChange, 4661 state: { 4662 valid: null, 4663 rules: {} 4664 } 4665 } 4666 } 4667 } 4668 } else { 4669 console.error('Element will not validate', element); 4670 } 4671 }, 4672 onSubmit(event) { 4673 if (event.target.tagName === 'FORM') { 4674 event.preventDefault(); 4675 4676 this.validate() 4677 .then(() => event.target.submit()) 4678 .catch(invalidElements => {}); 4679 } 4680 }, 4681 onChange(event) {
4682 event.target.dataset.onChange = 'true'; 4683 if (!Object.keys(this.fields).length) { 4684 this.setupFields(formElement.elements); 4685 } 4686 if (!Object.keys(this.fields).includes(event.target.name)) { 4687 this.setupField(event.target); 4688 } 4689 const field = this.fields[event.target.name]; 4690 4691 this.validateField(field); 4692 field && field.element.removeAttribute('data-on-change') 4693 }, 4694 validateSafe() { 4695 return new Promise(resolve => this.validate().then(() => resolve(true)).catch(() => {})) 4696 }, 4697 validate() { 4698 if (!Object.keys(this.fields).length || !Object.keys(this.fields).length !== formElement.elements.length) { 4699 this.setupFields(formElement.elements); 4700 } 4701 return new Promise(async (resolve, reject) => { 4702 if (formElement.elements) { 4703 await raceSome(this.validateFields(), result => result !== true) 4704 const invalidFields = Object.values(this.fields).filter(field => !field.state.valid); 4705 this.state.valid = invalidFields.length === 0; 4706 if (this.state.valid) { 4707 resolve(); 4708 } else { 4709 if (options.scrollToFirstError && invalidFields.length > 0) { 4710 invalidFields[0].element.focus() 4711 invalidFields[0].element.select && invalidFields[0].element.select(); 4712 } 4713 reject(invalidFields.map(field => field.element)); 4714 } 4715 } 4716 }); 4717 }, 4718 validateFields() { 4719 const fields = Object.values(this.fields); 4720 4721 fields.forEach(field => { 4722 this.getMessageContainer(field).classList.remove(options.validClassName, options.invalidClassName) 4723 }); 4724 return fields.map(field => this.validateField(field)) 4725 }, 4726 validateField(field) { 4727 if (! field || ! elementWillValidate(field.element)) { 4728 return new Promise(resolve => resolve(true)) 4729 } 4730 4731 let value; 4732 if (field.element.type === 'checkbox') { 4733 value = getCheckedValues(field); 4734 } else if (field.element.type === 'radio') { 4735 value = getCheckedValues(field)[0] || undefined; 4736 } else if (field.element.tagName === 'SELECT' && field.element.multiple) { 4737 value = Array.from(field.element.selectedOptions).map(opt => opt.value); 4738 } else { 4739 value = field.element.value; 4740 } 4741 4742 const rules = field.rules || {}; 4743 4744 field.state.valid = true; 4745 this.showFieldState(field); 4746 4747 4748 const fieldValidations = Object.keys(rules).filter(rule => formValidationRules[rule]).map(async rule => { 4749 return runValidateFn.call(this, rule, rules[rule], value, field).then(result => { 4750 field.state.rules[rule] = result; 4751 return result; 4752 }) 4753 }); 4754 4755 return new Promise(resolve => { 4756 Promise.all(fieldValidations).then(results => { 4757 field.state.valid = !elementWillValidate(field.element) || rules.length === 0 || !results.some(isInvalidRuleResult)
4758 this.showFieldState(field); 4759 resolve(field.state.valid); 4760 }) 4761 }); 4762 }, 4763 getMessagesByField(field) { 4764 const messages = []; 4765 const invalidRules = Object.keys(field.state.rules).filter(rule => isInvalidRuleResult(field.state.rules[rule])); 4766 4767 field.rules && Object.keys(field.rules).forEach((rule) => { 4768 if (invalidRules.includes(rule)) { 4769 const customMessage = field.element.getAttribute('data-msg-' + rule); 4770 const message = customMessage ? customMessage : field.state.rules[rule]; 4771 const ruleOptions = JSON.parse(JSON.stringify(field.rules[rule])); 4772 4773 if (typeof message === 'undefined' || message === null || (typeof message !== 'string' && ! message.type)) { 4774 messages.push(hyva.strf('Validation rule "%0" failed.', rule)); 4775 } else if (Array.isArray(ruleOptions)) { 4776 ruleOptions.unshift(message.type ? message.content : message); 4777 const content = hyva.strf.apply(null, ruleOptions); 4778 messages.push(message.type ? {type: message.type, content} : content); 4779 } else { 4780 const content = hyva.strf(message.type ? message.content : message, ruleOptions) 4781 messages.push(message.type ? {type: message.type, content} : content); 4782 } 4783 } 4784 }); 4785 return messages; 4786 }, 4787 /** @deprecated */ 4788 getFieldWrapper(field) { 4789 return this.getMessageContainer(field) 4790 }, 4791 getMessageContainer(field) { 4792 let container; 4793 const pageSelector = field.element.getAttribute('data-validation-container') || options.pageMessagesContainerSelector; 4794 if (pageSelector) { 4795 container = document.querySelector(pageSelector) 4796 || containerNotFound(pageSelector, field.element) 4797 } else { 4798 const containerSelector = classNamesToSelector(options.fieldWrapperClassName); 4799 container = field.element.closest(containerSelector) 4800 || createMessageContainer(field.element, options.fieldWrapperClassName) 4801 || containerNotFound(containerSelector, field.element); 4802 } 4803 4804 return container; 4805 }, 4806 showFieldState(field) { 4807 const container = this.getMessageContainer(field), 4808 hasErrorMessages = hasMessagesWrapper.call(this, field, options.messagesWrapperClassName), 4809 messages = this.getMessagesByField(field).map(m => { 4810 return m.type !== 'html' ? escapeHtml(m.type ? m.content : m) : m.content; 4811 }); 4812 container.classList.toggle(options.validClassName, field.state.valid && ! hasErrorMessages); 4813 container.classList.toggle(options.invalidClassName, !field.state.valid || hasErrorMessages); 4814 this.createHtmlErrorMessage(field, messages); 4815 4816 if (field.state.valid) { 4817 field.element.removeAttribute('aria-invalid'); 4818 } else { 4819 field.element.setAttribute('aria-invalid', 'true'); 4820 if (! document.activeElement) { 4821 field.element.focus(); 4822 } 4823 } 4824 }, 4825 removeMessages(field, messagesClass) { 4826 if (! hasMessagesWrapper.call(this, field, messagesClass || options.messagesWrapperClassName)) { 4827 return; 4828 } 4829 4830 const msgWrapper = getMessagesWrapper.call(this, field, messagesClass || options.messagesWrapperClassName); 4831 const messages = msgWrapper.querySelectorAll(`[data-msg-field='${field.element.name}']`);
4832 Array.from(messages).forEach(msg => msg.remove()); 4833 if (msgWrapper && msgWrapper.childElementCount === 0) { 4834 field.element.removeAttribute('aria-errormessage'); 4835 field.element.removeAttribute('aria-describedby'); 4836 msgWrapper.remove(); 4837 } 4838 }, 4839 createErrorMessage(field, messages) { 4840 const htmlMessages = (Array.isArray(messages) ? messages : [messages]).map(escapeHtml) 4841 this.createHtmlErrorMessage(field, htmlMessages); 4842 }, 4843 createHtmlErrorMessage(field, messages) { 4844 this.removeMessages(field, options.messagesWrapperClassName); 4845 field.element.removeAttribute('aria-errormessage'); 4846 field.element.removeAttribute('aria-describedby'); 4847 4848 if (!field.state.valid) { 4849 const msgWrapper = this.addHtmlMessages(field, options.messagesWrapperClassName, messages); 4850 field.element.setAttribute('aria-errormessage', msgWrapper.id); 4851 field.element.setAttribute('aria-describedby', msgWrapper.id); 4852 } 4853 }, 4854 /** @deprecated */ 4855 createMessage(field, message) { 4856 return this.addMessages(field, options.messagesWrapperClassName, message); 4857 }, 4858 addMessages(field, messagesClass, messages) { 4859 const htmlMessages = (Array.isArray(messages) ? messages : [messages]).map(escapeHtml) 4860 return this.addHtmlMessages(field, messagesClass, htmlMessages); 4861 }, 4862 addHtmlMessages(field, messagesClass, htmlMessages) { 4863 const msgWrapper = getMessagesWrapper.call(this, field, messagesClass); 4864 4865 (Array.isArray(htmlMessages) ? htmlMessages : [htmlMessages]).forEach((htmlMessage) => { 4866 const li = document.createElement('li'); 4867 li.innerHTML = htmlMessage; 4868 li.setAttribute('data-msg-field', field.element.name); 4869 msgWrapper.appendChild(li); 4870 }); 4871 4872 return msgWrapper; 4873 }, 4874 setField(name, value) { 4875 this.fields[name].element.value = value; 4876 this.fields[name].element.dispatchEvent((new Event('input'))); 4877 this.validateField(this.fields[name]); 4878 } 4879 } 4880 } 4881 4882 function getFieldName(field) { 4883 const fieldName = field.element?.getAttribute('title') 4884 || document.querySelector(`label[for="${field.element?.id}"]`)?.innerText; 4885 4886 return fieldName 4887 ? fieldName.trim() 4888 : ''; 4889 } 4890 4891 hyva.formValidation = formValidation; 4892 hyva.formValidation.rules = formValidationRules; 4893 hyva.formValidation.setInputAttributeRuleName = (attrName, ruleName) => INPUT_ATTRIBUTE_RULES[attrName] = ruleName || attrName; 4894 hyva.formValidation.setInputTypeRuleName = (typeName, ruleName) => INPUT_TYPE_RULES[typeName] = ruleName || typeName; 4895 hyva.formValidation.addRule = (name, validator) => formValidationRules[name] = validator; 4896 hyva.formValidation.getFieldName = getFieldName; 4897 }(window.hyva = window.hyva || {})); 4898 4899 window.addEventListener('alpine:init', () => { 4900 Alpine.data('hyva.formValidation', hyva.formValidation); 4901 Alpine.data('hyva.formValidation($el)', hyva.formValidation); 4902 }, {once: true}); 4903 //# sourceURL=hyva-advanced-form-validation.js 4904</script>
4904 4905<div class="page-wrapper"><div class="page messages">
4905<script type="module"> 4906 window.defaultSuccessMessageTimeout = 10000; 4907 4908 import { 4909 initMessages 4910 } from 'https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/js/components/messages.js'; 4911 4912 window.addEventListener('alpine:init', () => { 4913 Alpine.data('initMessages', initMessages); 4914 }, { 4915 once: true 4916 }); 4917</script>
4917 4918<section 4919 id="messages" 4920 x-data="initMessages" 4921 x-bind="eventListeners" 4922 role="alert" 4923 aria-live="polite"> 4924 <template x-if="hasMessages"> 4925 <div class="w-full"> 4926 <div class="container py-3 mx-auto messages"> 4927 <template x-for="(message, index) in messages" :key="index"> 4928 <div> 4929 <template x-if="hasMessage"> 4930 <div 4931 class="message relative overflow-hidden" 4932 :class="message.type" 4933 :ui-id="getMessageUiId" 4934 :role="message.type === 'error' ? 'alert' : 'status'" 4935 :aria-label="message.type === 'error' ? 'Fehlermeldung' : 4936 message.type === 'success' ? 'Success Message' : 4937 message.type === 'notice' ? 'Hinweismeldung' : 4938 'Informationsmeldung'"> 4939 <template x-if="hasCountdown(index)"> 4940 <div class="absolute bottom-0 left-0 right-0 h-1 bg-bg-secondary-darker"> 4941 <div 4942 class="h-full transition-all duration-100 ease-linear" 4943 :class="{ 4944 'bg-green-600': message.type === 'success', 4945 'bg-red-600': message.type === 'error', 4946 'bg-yellow-600': message.type === 'warning', 4947 'bg-blue-600': message.type === 'notice' 4948 }" 4949 :style="`width: ${getProgress(index)}%`" 4950 role="progressbar" 4951 :aria-valuenow="getProgress(index)" 4952 aria-valuemin="0" 4953 aria-valuemax="100" 4954 :aria-label="'Time remaining'"></div> 4955 </div> 4956 </template> 4957 4958 <span x-html="message.text"></span> 4959 4960 <div class="flex items-center gap-2 ml-auto"> 4961 <template x-if="hasCountdown(index)"> 4962 <span 4963 class="text-xs font-medium px-2 py-1 rounded bg-white/20" 4964 x-text="getCountdown(index) + 's'" 4965 :aria-label="'SchlieÃt automatisch in ' + getCountdown(index) + ' Sekunden'"></span> 4966 </template> 4967 4968 <button 4969 type="button" 4970 class="p-1 transition-colors duration-200 focus:text-primary-darker hover:primary-darker close-btn" 4971 aria-label="Nachricht schlieÃen" 4972 @click.prevent="removeMessage"> 4973 <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 18 18" fill="none" aria-hidden="true"> 4974<path fill-rule="evenodd" clip-rule="evenodd" d="M0.43934 0.43934C1.02513 -0.146447 1.97487 -0.146447 2.56066 0.43934L9 6.87868L15.4393 0.43934C16.0251 -0.146447 16.9749 -0.146447 17.5607 0.43934C18.1464 1.02513 18.1464 1.97487 17.5607 2.56066L11.1213 9L17.5607 15.4393C18.1464 16.0251 18.1464 16.9749 17.5607 17.5607C16.9749 18.1464 16.0251 18.1464 15.4393 17.5607L9 11.1213L2.56066 17.5607C1.97487 18.1464 1.02513 18.1464 0.43934 17.5607C-0.146447 16.9749 -0.146447 16.0251 0.43934 15.4393L6.87868 9L0.43934 2.56066C-0.146447 1.97487 -0.146447 1.02513 0.43934 0.43934Z" fill="currentColor"/> 4975</svg> 4976 </button> 4977 </div> 4978 </div> 4979 </template> 4980 </div> 4981 </template> 4982 </div> 4983 </div> 4984 </template> 4985</section></div><header class="page-header">
4985<a class="action skip sr-only focus:not-sr-only focus:absolute focus:z-40 focus:bg-white 4986 contentarea" 4987 href="#contentarea"> 4988 <span> 4989 Zum Inhalt springen </span> 4990</a> 4991
4991<script type="application/javascript" async 4992 src="https://static.klaviyo.com/onsite/js/YyB7FJ/klaviyo.js"></script>
4992 4993 4994 <div x-data="initKlaviyoCustomerTracking()" 4995 @private-content-loaded.window="sendCustomerDataToKlaviyo(event.detail.data)"></div> 4996
4996<script> 4997 !function(){if(!window.klaviyo){window._klOnsite=window._klOnsite||[];try{window.klaviyo=new Proxy({},{get:function(n,i){return"push"===i?function(){var n;(n=window._klOnsite).push.apply(n,arguments)}:function(){for(var n=arguments.length,o=new Array(n),w=0;w<n;w++)o[w]=arguments[w];var t="function"==typeof o[o.length-1]?o.pop():void 0,e=new Promise((function(n){window._klOnsite.push([i].concat(o,[function(i){t&&t(i),n(i)}]))}));return e}}})}catch(n){window.klaviyo=window.klaviyo||[],window.klaviyo.push=function(){var n;(n=window._klOnsite).push.apply(n,arguments)}}}}(); 4998 4999 function initKlaviyoCustomerTracking() { 5000 return { 5001 sendCustomerDataToKlaviyo(data) { 5002 window.klaviyo = window.klaviyo || []; 5003 const customer = data.customer; 5004 5005 window.klaviyo.isIdentified().then((identified)=> { 5006 if(customer && customer.email && !identified) { 5007 window.klaviyo.identify({ 5008 '$email': customer.email, 5009 '$first_name': customer.firstname ? customer.firstname : '', 5010 '$last_name': customer.lastname ? customer.lastname : '' 5011 }); 5012 } 5013 }); 5014 } 5015 } 5016 } 5017 </script>
vendor: 1 bytes, line 5017
5017
5018<script> 5019 function initHeader() { 5020 return { 5021 searchOpen: false, 5022 cart: {}, 5023 isCartOpen: false, 5024 getData(data) { 5025 if (data.cart) { 5026 this.cart = data.cart; 5027 } 5028 }, 5029 isCartEmpty() { 5030 return !this.cart.summary_count; 5031 }, 5032 toggleCart(event) { 5033 if (event.detail && event.detail.isOpen !== undefined) { 5034 this.isCartOpen = event.detail.isOpen; 5035 if (!this.isCartOpen && this.$refs && this.$refs.cartButton) { 5036 this.$refs.cartButton.focus(); 5037 } 5038 } else { 5039 /* 5040 * The toggle-cart event was previously dispatched without parameter to open the drawer (not toggle). 5041 * Keeping this in here for backwards compatibility. 5042 */ 5043 this.isCartOpen = true; 5044 } 5045 }, 5046 }; 5047 } 5048 5049 function initCompareHeader() { 5050 return { 5051 compareProducts: null, 5052 itemCount: 0, 5053 receiveCompareData(data) { 5054 if (data['compare-products']) { 5055 this.compareProducts = data['compare-products']; 5056 this.itemCount = this.compareProducts.count; 5057 } 5058 }, 5059 }; 5060 } 5061</script>
5061 5062<div id="header" 5063 class="relative z-30 w-full" 5064 x-data="initHeader()" 5065 @private-content-loaded.window="getData(event.detail.data)"> 5066 <div class="bg-header-bg text-header-text"> 5067 <div class="container flex items-center justify-center w-full mx-auto mt-0 px-6 py-3 5068 lg:py-5"> 5069 <div class="menu lg:hidden flex-wrap lg:flex-nowrap lg:order-6 lg:w-full items-center justify-between w-auto mt-0 order-1 z-20 flex-1 "> 5070 5071<div 5072 class="navigation lg:hidden" 5073 x-data="initMobileMenu" 5074 x-init="checkIsMobileResolution()" 5075 @sub-menu-state-change.window="hasActiveSubMenu" 5076 @resize.window.debounce="updateMenuPosition(); checkIsMobileResolution();" 5077 data-testid="mobile-navigation" 5078 @keyup.escape="close"> 5079 <button 5080 type="button" 5081 class="align-middle p-2 toggle-menu-button" 5082 aria-label="Menü öffnen" 5083 aria-controls="mobileMenu" 5084 @click="toggleOpen" 5085 data-testid="mobile-menu-trigger"> 5086 <svg xmlns="http://www.w3.org/2000/svg" width="18" height="14" viewBox="0 0 18 14" fill="none" role="img"> 5087<path d="M1 1H17M1 7H17M1 13H17" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> 5088<title>hamburger</title></svg> 5089 </button> 5090 5091 <dialog 5092 id="mobileMenu" 5093 class="fixed w-full h-full m-0 open:flex flex-col transition ease-out duration-300 open:duration-500 max-w-full backdrop:hidden overflow-visible" 5094 x-show="isOpen" 5095 :style="{ top: menuTopPosition, maxHeight: menuHeight }" 5096 x-htmldialog.noscroll="close" 5097 x-transition:enter-start="-translate-x-full" 5098 x-transition:enter-end="translate-x-0" 5099 x-transition:leave-start="translate-x-0" 5100 x-transition:leave-end="-translate-x-full" 5101 role="dialog" 5102 aria-modal="true" 5103 aria-labelledby="mobile-menu-title" 5104 data-testid="mobile-menu-container" 5105 @keyup.escape="close"> 5106 <span id="mobile-menu-title" class="sr-only"> 5107 Hauptnavigationsmenü </span> 5108 <button 5109 type="button" 5110 @click="close" 5111 class=" 5112 transition-colors duration-300 w-11 h-11 inline-flex items-center justify-center 5113 absolute -top-14 right-0 5114 " 5115 aria-label="Menü schließen" 5116 x-cloak 5117 x-show="showLanguageSwitcher" 5118 data-testid="mobile-menu-close"> 5119 <svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 18 18" fill="none" aria-hidden="true"> 5120<path fill-rule="evenodd" clip-rule="evenodd" d="M0.43934 0.43934C1.02513 -0.146447 1.97487 -0.146447 2.56066 0.43934L9 6.87868L15.4393 0.43934C16.0251 -0.146447 16.9749 -0.146447 17.5607 0.43934C18.1464 1.02513 18.1464 1.97487 17.5607 2.56066L11.1213 9L17.5607 15.4393C18.1464 16.0251 18.1464 16.9749 17.5607 17.5607C16.9749 18.1464 16.0251 18.1464 15.4393 17.5607L9 11.1213L2.56066 17.5607C1.97487 18.1464 1.02513 18.1464 0.43934 17.5607C-0.146447 16.9749 -0.146447 16.0251 0.43934 15.4393L6.87868 9L0.43934 2.56066C-0.146447 1.97487 -0.146447 1.02513 0.43934 0.43934Z" fill="currentColor"/> 5121</svg> 5122 </button> 5123 <div 5124 class="grow relative overflow-y-auto overflow-x-hidden" 5125 data-testid="mobile-menu-content"> 5126 <nav 5127 aria-label="Mobiles Hauptmenü" 5128 data-testid="mobile-menu-nav"> 5129 <ul> 5130 <li 5131 class="" 5132 data-level="0" 5133 data-testid="mobile-menu-item"> 5134 <a 5135 href="/" 5136 class="border-b border-border-secondary font-medium text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary" 5137 data-testid="mobile-menu-link">Startseite</a> 5138 </li> 5139 5140 <li 5141 data-level="0" 5142 x-data="initMobileSubMenu" 5143 data-testid="mobile-menu-item"> 5144 <button 5145 type="button" 5146 class="w-full justify-between border-b border-border-secondary font-medium text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary" 5147 aria-controls="category-node-30-mobile-menu-panel" 5148 aria-expanded="false" 5149 x-ref="openSubMenuBtn" 5150 :aria-expanded="isOpen" 5151 :disabled="isOpen" 5152 @click="open" 5153 x-show="!isOpen" 5154 data-testid="mobile-menu-expand">
5155 <span class="flex items-center gap-3 ms-7"> 5156 Regenschirme </span> 5157 <span 5158 class=" 5159 text-text-secondary-darker rounded-6 border w-9 h-9 inline-flex items-center justify-center 5160 hover:border-border-secondary-darker focus:border-primary hover:text-primary focus:text-primary transition duration-300 5161 mobile-menu-arrow 5162 "> 5163 <svg xmlns="http://www.w3.org/2000/svg" width="6" height="10" viewBox="0 0 14 23" fill="none" aria-hidden="true"> 5164<path d="M2.5 2.00032L11.8333 11.3337L2.5 20.667" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> 5165</svg> 5166 </span> 5167 </button> 5168 <ul 5169 id="category-node-30-mobile-menu-panel" 5170 class="w-full overflow-y-auto overflow-x-hidden overscroll-y-contain transition duration-300" 5171 x-show="isOpen" 5172 x-transition:enter-start="opacity-0 translate-x-8" 5173 x-transition:enter-end="opacity-100 translate-x-0" 5174 x-transition:leave-start="opacity-100 translate-x-0" 5175 x-transition:leave-end="opacity-0 translate-x-8" 5176 @keydown.escape.stop.prevent="close" 5177 data-testid="mobile-submenu-container"> 5178 <li data-level="1"> 5179 <span class="sr-only"> 5180 Sie befinden sich derzeit in: Regenschirme </span> 5181 <button 5182 type="button" 5183 class="w-full bg-transparent text-primary gap-1 border-b border-border-secondary font-medium text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary" 5184 @click="close" 5185 x-ref="closeSubMenuBtn" 5186 data-testid="mobile-submenu-back"> 5187 <span class="text-text-secondary-darker px-2 pb-1 mobile-menu-arrow"> 5188 <svg xmlns="http://www.w3.org/2000/svg" width="6" height="10" viewBox="0 0 14 23" fill="none" class="rotate-180" aria-hidden="true"> 5189<path d="M2.5 2.00032L11.8333 11.3337L2.5 20.667" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> 5190</svg> 5191 </span> 5192 Regenschirme </button> 5193 <a 5194 href="https://knirps.de/regenschirme.html" 5195 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary border-b border-border-secondary font-medium" 5196 data-testid="mobile-menu-see-all"> 5197 <span class="ms-7"> 5198 Alle Regenschirme ansehen </span> 5199 </a> 5200 </li> 5201 5202 <li 5203 data-level="1" 5204 x-data="initMobileSubMenu" 5205 data-testid="mobile-menu-item"> 5206 <button 5207 type="button" 5208 class="w-full justify-between border-b border-border-secondary font-medium text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary" 5209 aria-controls="category-node-31-mobile-menu-panel" 5210 aria-expanded="false" 5211 x-ref="openSubMenuBtn" 5212 :aria-expanded="isOpen" 5213 :disabled="isOpen" 5214 @click="open" 5215 x-show="!isOpen" 5216 data-testid="mobile-menu-expand"> 5217 <span class="flex items-center gap-3 ms-7"> 5218 Taschenschirme </span> 5219 <span 5220 class=" 5221 text-text-secondary-darker rounded-6 border w-9 h-9 inline-flex items-center justify-center 5222 hover:border-border-secondary-darker focus:border-primary hover:text-primary focus:text-primary transition duration-300 5223 mobile-menu-arrow 5224 "> 5225 <svg xmlns="http://www.w3.org/2000/svg" width="6" height="10" viewB
5225ox="0 0 14 23" fill="none" aria-hidden="true"> 5226<path d="M2.5 2.00032L11.8333 11.3337L2.5 20.667" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> 5227</svg> 5228 </span> 5229 </button> 5230 <ul 5231 id="category-node-31-mobile-menu-panel" 5232 class="w-full overflow-y-auto overflow-x-hidden overscroll-y-contain transition duration-300" 5233 x-show="isOpen" 5234 x-transition:enter-start="opacity-0 translate-x-8" 5235 x-transition:enter-end="opacity-100 translate-x-0" 5236 x-transition:leave-start="opacity-100 translate-x-0" 5237 x-transition:leave-end="opacity-0 translate-x-8" 5238 @keydown.escape.stop.prevent="close" 5239 data-testid="mobile-submenu-container"> 5240 <li data-level="2"> 5241 <span class="sr-only"> 5242 Sie befinden sich derzeit in: Taschenschirme </span> 5243 <button 5244 type="button" 5245 class="w-full bg-transparent text-primary gap-1 border-b border-border-secondary font-medium text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary" 5246 @click="close" 5247 x-ref="closeSubMenuBtn" 5248 data-testid="mobile-submenu-back"> 5249 <span class="text-text-secondary-darker px-2 pb-1 mobile-menu-arrow"> 5250 <svg xmlns="http://www.w3.org/2000/svg" width="6" height="10" viewBox="0 0 14 23" fill="none" class="rotate-180" aria-hidden="true"> 5251<path d="M2.5 2.00032L11.8333 11.3337L2.5 20.667" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> 5252</svg> 5253 </span> 5254 Taschenschirme </button> 5255 <a 5256 href="https://knirps.de/regenschirme/taschenschirme.html" 5257 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary border-b border-border-secondary font-medium" 5258 data-testid="mobile-menu-see-all"> 5259 <span class="ms-7"> 5260 Alle Taschenschirme ansehen </span> 5261 </a> 5262 </li> 5263 5264 <li 5265 data-level="2" 5266 data-testid="mobile-menu-item"> 5267 <a 5268 href="https://knirps.de/regenschirme/taschenschirme/besondere-regenschirme.html" 5269 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary border-b border-border-secondary font-medium" 5270 data-testid="mobile-menu-link"> 5271 <span class="flex items-center gap-3 ms-7"> 5272 Specials </span> 5273 </a> 5274 </li> 5275 5276 <li 5277 data-level="2" 5278 data-testid="mobile-menu-item"> 5279 <a 5280 href="https://knirps.de/regenschirme/taschenschirme/taschenschirme-klein.html" 5281 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary border-b border-border-secondary font-medium" 5282 data-testid="mobile-menu-link"> 5283 <span class="flex items-center gap-3 ms-7"> 5284 Small </span> 5285 </a> 5286 </li> 5287 5288 <li 5289 data-level="2" 5290 data-testid="mobile-menu-item"> 5291 <a 5292 href="https://knirps.de/regenschirme/taschenschirme/taschenschirme-mittel.html" 5293 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary border-b border-border-secondary font-medium" 5294 data-testid="mobile-menu-link">
5295 <span class="flex items-center gap-3 ms-7"> 5296 Medium </span> 5297 </a> 5298 </li> 5299 5300 <li 5301 data-level="2" 5302 data-testid="mobile-menu-item"> 5303 <a 5304 href="https://knirps.de/regenschirme/taschenschirme/taschenschirme-gross.html" 5305 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary border-b border-border-secondary font-medium" 5306 data-testid="mobile-menu-link"> 5307 <span class="flex items-center gap-3 ms-7"> 5308 Large </span> 5309 </a> 5310 </li> 5311 5312 <li 5313 data-level="2" 5314 data-testid="mobile-menu-item"> 5315 <a 5316 href="https://knirps.de/regenschirme/taschenschirme/kinderschirm.html" 5317 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary border-b border-border-secondary font-medium" 5318 data-testid="mobile-menu-link"> 5319 <span class="flex items-center gap-3 ms-7"> 5320 Kinderschirm </span> 5321 </a> 5322 </li> 5323 </ul> 5324 </li> 5325 5326 <li 5327 data-level="1" 5328 x-data="initMobileSubMenu" 5329 data-testid="mobile-menu-item"> 5330 <button 5331 type="button" 5332 class="w-full justify-between border-b border-border-secondary font-medium text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary" 5333 aria-controls="category-node-38-mobile-menu-panel" 5334 aria-expanded="false" 5335 x-ref="openSubMenuBtn" 5336 :aria-expanded="isOpen" 5337 :disabled="isOpen" 5338 @click="open" 5339 x-show="!isOpen" 5340 data-testid="mobile-menu-expand"> 5341 <span class="flex items-center gap-3 ms-7"> 5342 Stockschirm </span> 5343 <span 5344 class=" 5345 text-text-secondary-darker rounded-6 border w-9 h-9 inline-flex items-center justify-center 5346 hover:border-border-secondary-darker focus:border-primary hover:text-primary focus:text-primary transition duration-300 5347 mobile-menu-arrow 5348 "> 5349 <svg xmlns="http://www.w3.org/2000/svg" width="6" height="10" viewBox="0 0 14 23" fill="none" aria-hidden="true"> 5350<path d="M2.5 2.00032L11.8333 11.3337L2.5 20.667" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> 5351</svg> 5352 </span> 5353 </button> 5354 <ul 5355 id="category-node-38-mobile-menu-panel" 5356 class="w-full overflow-y-auto overflow-x-hidden overscroll-y-contain transition duration-300" 5357 x-show="isOpen" 5358 x-transition:enter-start="opacity-0 translate-x-8" 5359 x-transition:enter-end="opacity-100 translate-x-0" 5360 x-transition:leave-start="opacity-100 translate-x-0" 5361 x-transition:leave-end="opacity-0 translate-x-8" 5362 @keydown.escape.stop.prevent="close" 5363 data-testid="mobile-submenu-container"> 5364 <li data-level="2"> 5365 <span class="sr-only"> 5366 Sie befinden sich derzeit in: Stockschirm </span> 5367 <button 5368 type="button" 5369 class="w-full bg-transparent text-primary gap-1 border-b border-border-secondary font-medium text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary" 5370 @click="close" 5371 x-ref="closeSubMenuBtn" 5372 data-testid="mobile-submenu-back">
5373 <span class="text-text-secondary-darker px-2 pb-1 mobile-menu-arrow"> 5374 <svg xmlns="http://www.w3.org/2000/svg" width="6" height="10" viewBox="0 0 14 23" fill="none" class="rotate-180" aria-hidden="true"> 5375<path d="M2.5 2.00032L11.8333 11.3337L2.5 20.667" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> 5376</svg> 5377 </span> 5378 Stockschirm </button> 5379 <a 5380 href="https://knirps.de/regenschirme/stockschirme.html" 5381 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary border-b border-border-secondary font-medium" 5382 data-testid="mobile-menu-see-all"> 5383 <span class="ms-7"> 5384 Alle Stockschirm ansehen </span> 5385 </a> 5386 </li> 5387 5388 <li 5389 data-level="2" 5390 data-testid="mobile-menu-item"> 5391 <a 5392 href="https://knirps.de/regenschirme/stockschirme/stockschirme-gross.html" 5393 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary border-b border-border-secondary font-medium" 5394 data-testid="mobile-menu-link"> 5395 <span class="flex items-center gap-3 ms-7"> 5396 Large </span> 5397 </a> 5398 </li> 5399 5400 <li 5401 data-level="2" 5402 data-testid="mobile-menu-item"> 5403 <a 5404 href="https://knirps.de/regenschirme/stockschirme/stockschirme-extra-large.html" 5405 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary border-b border-border-secondary font-medium" 5406 data-testid="mobile-menu-link"> 5407 <span class="flex items-center gap-3 ms-7"> 5408 Extra Large </span> 5409 </a> 5410 </li> 5411 </ul> 5412 </li> 5413 5414 <li 5415 data-level="1" 5416 data-testid="mobile-menu-item"> 5417 <a 5418 href="https://knirps.de/regenschirme/uv-schutz.html" 5419 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary border-b border-border-secondary font-medium" 5420 data-testid="mobile-menu-link"> 5421 <span class="flex items-center gap-3 ms-7"> 5422 Regenschirme mit UV-Schutz </span> 5423 </a> 5424 </li> 5425 5426 <li 5427 data-level="1" 5428 data-testid="mobile-menu-item"> 5429 <a 5430 href="https://knirps.de/regenschirme/leichte-regenschirme.html" 5431 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary border-b border-border-secondary font-medium" 5432 data-testid="mobile-menu-link"> 5433 <span class="flex items-center gap-3 ms-7"> 5434 Leichte Regenschirme </span> 5435 </a> 5436 </li> 5437 5438 <li 5439 data-level="1" 5440 data-testid="mobile-menu-item"> 5441 <a 5442 href="https://knirps.de/regenschirme/ersatzhuellen.html" 5443 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary border-b border-border-secondary font-medium" 5444 data-testid="mobile-menu-link">
5445 <span class="flex items-center gap-3 ms-7"> 5446 Ersatzhüllen </span> 5447 </a> 5448 </li> 5449 </ul> 5450 </li> 5451 5452 <li 5453 data-level="0" 5454 x-data="initMobileSubMenu" 5455 data-testid="mobile-menu-item"> 5456 <button 5457 type="button" 5458 class="w-full justify-between border-b border-border-secondary font-medium text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary" 5459 aria-controls="category-node-36-mobile-menu-panel" 5460 aria-expanded="false" 5461 x-ref="openSubMenuBtn" 5462 :aria-expanded="isOpen" 5463 :disabled="isOpen" 5464 @click="open" 5465 x-show="!isOpen" 5466 data-testid="mobile-menu-expand"> 5467 <span class="flex items-center gap-3 ms-7"> 5468 Sonnenschirme </span> 5469 <span 5470 class=" 5471 text-text-secondary-darker rounded-6 border w-9 h-9 inline-flex items-center justify-center 5472 hover:border-border-secondary-darker focus:border-primary hover:text-primary focus:text-primary transition duration-300 5473 mobile-menu-arrow 5474 "> 5475 <svg xmlns="http://www.w3.org/2000/svg" width="6" height="10" viewBox="0 0 14 23" fill="none" aria-hidden="true"> 5476<path d="M2.5 2.00032L11.8333 11.3337L2.5 20.667" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> 5477</svg> 5478 </span> 5479 </button> 5480 <ul 5481 id="category-node-36-mobile-menu-panel" 5482 class="w-full overflow-y-auto overflow-x-hidden overscroll-y-contain transition duration-300" 5483 x-show="isOpen" 5484 x-transition:enter-start="opacity-0 translate-x-8" 5485 x-transition:enter-end="opacity-100 translate-x-0" 5486 x-transition:leave-start="opacity-100 translate-x-0" 5487 x-transition:leave-end="opacity-0 translate-x-8" 5488 @keydown.escape.stop.prevent="close" 5489 data-testid="mobile-submenu-container"> 5490 <li data-level="1"> 5491 <span class="sr-only"> 5492 Sie befinden sich derzeit in: Sonnenschirme </span> 5493 <button 5494 type="button" 5495 class="w-full bg-transparent text-primary gap-1 border-b border-border-secondary font-medium text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary" 5496 @click="close" 5497 x-ref="closeSubMenuBtn" 5498 data-testid="mobile-submenu-back"> 5499 <span class="text-text-secondary-darker px-2 pb-1 mobile-menu-arrow"> 5500 <svg xmlns="http://www.w3.org/2000/svg" width="6" height="10" viewBox="0 0 14 23" fill="none" class="rotate-180" aria-hidden="true"> 5501<path d="M2.5 2.00032L11.8333 11.3337L2.5 20.667" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> 5502</svg> 5503 </span> 5504 Sonnenschirme </button> 5505 <a 5506 href="https://knirps.de/sonnenschirme.html" 5507 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary border-b border-border-secondary font-medium" 5508 data-testid="mobile-menu-see-all"> 5509 <span class="ms-7"> 5510 Alle Sonnenschirme ansehen </span> 5511 </a> 5512 </li> 5513 5514 <li 5515 data-level="1" 5516 data-testid="mobile-menu-item"> 5517 <a 5518 href="https://knirps.de/sonnenschirme/ampelschirme.html" 5519 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary border-b border-border-secondary font-medium" 5520 data-testid="mobile-menu-link">
5521 <span class="flex items-center gap-3 ms-7"> 5522 Ampelschirme </span> 5523 </a> 5524 </li> 5525 5526 <li 5527 data-level="1" 5528 data-testid="mobile-menu-item"> 5529 <a 5530 href="https://knirps.de/sonnenschirme/balkonschirme.html" 5531 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary border-b border-border-secondary font-medium" 5532 data-testid="mobile-menu-link"> 5533 <span class="flex items-center gap-3 ms-7"> 5534 Balkonschirme </span> 5535 </a> 5536 </li> 5537 5538 <li 5539 data-level="1" 5540 data-testid="mobile-menu-item"> 5541 <a 5542 href="https://knirps.de/sonnenschirme/mittelstockschirme.html" 5543 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary border-b border-border-secondary font-medium" 5544 data-testid="mobile-menu-link"> 5545 <span class="flex items-center gap-3 ms-7"> 5546 Mittelstockschirm </span> 5547 </a> 5548 </li> 5549 5550 <li 5551 data-level="1" 5552 x-data="initMobileSubMenu" 5553 data-testid="mobile-menu-item"> 5554 <button 5555 type="button" 5556 class="w-full justify-between border-b border-border-secondary font-medium text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary" 5557 aria-controls="category-node-48-mobile-menu-panel" 5558 aria-expanded="false" 5559 x-ref="openSubMenuBtn" 5560 :aria-expanded="isOpen" 5561 :disabled="isOpen" 5562 @click="open" 5563 x-show="!isOpen" 5564 data-testid="mobile-menu-expand"> 5565 <span class="flex items-center gap-3 ms-7"> 5566 Schirmständer </span> 5567 <span 5568 class=" 5569 text-text-secondary-darker rounded-6 border w-9 h-9 inline-flex items-center justify-center 5570 hover:border-border-secondary-darker focus:border-primary hover:text-primary focus:text-primary transition duration-300 5571 mobile-menu-arrow 5572 "> 5573 <svg xmlns="http://www.w3.org/2000/svg" width="6" height="10" viewBox="0 0 14 23" fill="none" aria-hidden="true"> 5574<path d="M2.5 2.00032L11.8333 11.3337L2.5 20.667" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> 5575</svg> 5576 </span> 5577 </button> 5578 <ul 5579 id="category-node-48-mobile-menu-panel" 5580 class="w-full overflow-y-auto overflow-x-hidden overscroll-y-contain transition duration-300" 5581 x-show="isOpen" 5582 x-transition:enter-start="opacity-0 translate-x-8" 5583 x-transition:enter-end="opacity-100 translate-x-0" 5584 x-transition:leave-start="opacity-100 translate-x-0" 5585 x-transition:leave-end="opacity-0 translate-x-8" 5586 @keydown.escape.stop.prevent="close" 5587 data-testid="mobile-submenu-container"> 5588 <li data-level="2"> 5589 <span class="sr-only"> 5590 Sie befinden sich derzeit in: Schirmständer </span> 5591 <button 5592 type="button" 5593 class="w-full bg-transparent text-primary gap-1 border-b border-border-secondary font-medium text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary" 5594 @click="close" 5595 x-ref="closeSubMenuBtn" 5596 data-testid="mobile-submenu-back">
5597 <span class="text-text-secondary-darker px-2 pb-1 mobile-menu-arrow"> 5598 <svg xmlns="http://www.w3.org/2000/svg" width="6" height="10" viewBox="0 0 14 23" fill="none" class="rotate-180" aria-hidden="true"> 5599<path d="M2.5 2.00032L11.8333 11.3337L2.5 20.667" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> 5600</svg> 5601 </span> 5602 Schirmständer </button> 5603 <a 5604 href="https://knirps.de/sonnenschirme/sonnenschirme-schirmstaender.html" 5605 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary border-b border-border-secondary font-medium" 5606 data-testid="mobile-menu-see-all"> 5607 <span class="ms-7"> 5608 Alle Schirmständer ansehen </span> 5609 </a> 5610 </li> 5611 5612 <li 5613 data-level="2" 5614 data-testid="mobile-menu-item"> 5615 <a 5616 href="https://knirps.de/sonnenschirme/sonnenschirme-schirmstaender/sonnenschirme-mittelstockschirmstaender.html" 5617 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary border-b border-border-secondary font-medium" 5618 data-testid="mobile-menu-link"> 5619 <span class="flex items-center gap-3 ms-7"> 5620 Für Mittelstockschirme </span> 5621 </a> 5622 </li> 5623 5624 <li 5625 data-level="2" 5626 data-testid="mobile-menu-item"> 5627 <a 5628 href="https://knirps.de/sonnenschirme/sonnenschirme-schirmstaender/ampelschirme-schirmstaender.html" 5629 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary border-b border-border-secondary font-medium" 5630 data-testid="mobile-menu-link"> 5631 <span class="flex items-center gap-3 ms-7"> 5632 Für Ampelschirme </span> 5633 </a> 5634 </li> 5635 </ul> 5636 </li> 5637 5638 <li 5639 data-level="1" 5640 data-testid="mobile-menu-item"> 5641 <a 5642 href="https://knirps.de/sonnenschirme/sonnenschirme-schutzhuellen.html" 5643 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary border-b border-border-secondary font-medium" 5644 data-testid="mobile-menu-link"> 5645 <span class="flex items-center gap-3 ms-7"> 5646 Schutzhülle </span> 5647 </a> 5648 </li> 5649 5650 <li 5651 data-level="1" 5652 data-testid="mobile-menu-item"> 5653 <a 5654 href="https://knirps.de/sonnenschirme/sonnenschirme-ersatzteile.html" 5655 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary border-b border-border-secondary font-medium" 5656 data-testid="mobile-menu-link"> 5657 <span class="flex items-center gap-3 ms-7"> 5658 Ersatzteile </span> 5659 </a> 5660 </li> 5661 5662 <li 5663 data-level="1" 5664 data-testid="mobile-menu-item"> 5665 <a 5666 href="https://knirps.de/sonnenschirme/sonnenschirme-bezuege.html" 5667 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary border-b border-border-secondary font-medium" 5668 data-testid="mobile-menu-link">
5669 <span class="flex items-center gap-3 ms-7"> 5670 Ersatzbezug </span> 5671 </a> 5672 </li> 5673 </ul> 5674 </li> 5675 5676 <li 5677 data-level="0" 5678 data-testid="mobile-menu-item"> 5679 <a 5680 href="https://knirps.de/bekleidung-accessoires.html" 5681 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary border-b border-border-secondary font-medium" 5682 data-testid="mobile-menu-link"> 5683 <span class="flex items-center gap-3 ms-7"> 5684 Accessoires </span> 5685 </a> 5686 </li> 5687 5688 <li 5689 data-level="0" 5690 data-testid="mobile-menu-item"> 5691 <a 5692 href="https://knirps.de/sale.html" 5693 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary border-b border-border-secondary font-medium" 5694 data-testid="mobile-menu-link"> 5695 <span class="flex items-center gap-3 ms-7"> 5696 Sale </span> 5697 </a> 5698 </li> 5699 <li data-level="0" data-testid="mobile-menu-item"> 5700 <a href="/blog/" 5701 title="konfigurator entwicklung" 5702 class="border-b border-border-secondary font-medium text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary" 5703 data-testid="mobile-menu-link" 5704 aria-current="page">Blog</a> 5705</li> 5706<li data-level="0" data-testid="mobile-menu-item"> 5707 <a href="/Kooperationen/" 5708 title="konfigurator entwicklung" 5709 class="border-b border-border-secondary font-medium text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary" 5710 data-testid="mobile-menu-link" 5711 aria-current="page">Kooperationen</a> 5712</li> </ul> 5713 </nav> 5714 <nav 5715 aria-label="Mobile Shop-Einstellungen" 5716 data-testid="mobile-menu-settings"> 5717 <p 5718 class="uppercase text-12 pt-6 pb-2 px-6 leading-130 font-medium" 5719 data-testid="mobile-menu-settings-title"> 5720 Einstellungen </p> 5721 <div x-data="initLanguageSwitcher" 5722 class="w-full" 5723 x-id="['language-switcher']" 5724 :data-testid="$id('language-switcher')"> 5725 <div x-id="['menu-options']" class="relative w-full"> 5726 <div class="flex items-center"> 5727 <button 5728 @click.prevent="toggleOpen" 5729 type="button" 5730 :id="$id('menu-options')" 5731 class="w-full py-4.5 px-6 flex items-center gap-3 text-16 font-light leading-4 justify-start hover:text-primary transition-colors duration-200 aria-expanded:underline" 5732 aria-haspopup="true" 5733 :aria-expanded="open"> 5734 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 19 19" fill="none" class="inline mr-1 transition-colors" aria-hidden="true"> 5735<path d="M0.554929 8.5H2.5C3.60457 8.5 4.5 9.39543 4.5 10.5V11.5C4.5 12.6046 5.39543 13.5 6.5 13.5C7.60457 13.5 8.5 14.3954 8.5 15.5V18.4451M5.5 1.43552V3C5.5 4.38071 6.61929 5.5 8 5.5H8.5C9.60457 5.5 10.5 6.39543 10.5 7.5C10.5 8.60457 11.3954 9.5 12.5 9.5C13.6046 9.5 14.5 8.60457 14.5 7.5C14.5 6.39543 15.3954 5.5 16.5 5.5L17.5645 5.5M12.5 17.9879V15.5C12.5 14.3954 13.3954 13.5 14.5 13.5H17.5645M18.5 9.5C18.5 14.4706 14.4706 18.5 9.5 18.5C4.52944 18.5 0.5 14.4706 0.5 9.5C0.5 4.52944 4.52944 0.5 9.5 0.5C14.4706 0.5 18.5 4.52944 18.5 9.5Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/> 5736</svg>
5737 Deutsch <span class="transition duration-300 ml-auto language-switcher-arrow" :class="{'rotate-180': open}"> 5738 <svg xmlns="http://www.w3.org/2000/svg" width="18" height="14" viewBox="0 0 20 20" fill="none" aria-hidden="true"> 5739<path fill-rule="evenodd" clip-rule="evenodd" d="M5.29289 7.29289C5.68342 6.90237 6.31658 6.90237 6.70711 7.29289L10 10.5858L13.2929 7.29289C13.6834 6.90237 14.3166 6.90237 14.7071 7.29289C15.0976 7.68342 15.0976 8.31658 14.7071 8.70711L10.7071 12.7071C10.3166 13.0976 9.68342 13.0976 9.29289 12.7071L5.29289 8.70711C4.90237 8.31658 4.90237 7.68342 5.29289 7.29289Z" fill="currentColor"/> 5740</svg> 5741 </span> 5742 </button> 5743 </div> 5744 <nav 5745 x-cloak 5746 x-show="open" 5747 x-transition 5748 class="z-20 pl-14 pr-6 pb-3"> 5749 <div class="flex flex-col gap-2" role="menu" aria-orientation="vertical" :aria-labelledby="$id('menu-options')"> 5750 <a 5751 href="https://knirps.de/stores/store/redirect/___store/knirps_en/___from_store/default/uenc/aHR0cHM6Ly9rbmlycHMuY29tL2Jsb2cv/" 5752 role="menuitem" 5753 tabindex="0" 5754 data-item-num="1" 5755 data-lang-code="en" 5756 class="font-light text-16 hover:text-primary focus:text-primary transition-colors duration-300"> 5757 Global </a> 5758 <a 5759 href="https://knirps.de/stores/store/redirect/___store/knirps_fr/___from_store/default/uenc/aHR0cHM6Ly9rbmlycHMuZnIvYmxvZy8~/" 5760 role="menuitem" 5761 tabindex="0" 5762 data-item-num="2" 5763 data-lang-code="fr" 5764 class="font-light text-16 hover:text-primary focus:text-primary transition-colors duration-300"> 5765 Français </a> 5766 <a 5767 href="https://knirps.de/stores/store/redirect/___store/knirps_nl/___from_store/default/uenc/aHR0cHM6Ly9rbmlycHMubmwvYmxvZy8~/" 5768 role="menuitem" 5769 tabindex="0" 5770 data-item-num="3" 5771 data-lang-code="nl" 5772 class="font-light text-16 hover:text-primary focus:text-primary transition-colors duration-300"> 5773 Nederlands </a> 5774 <a 5775 href="https://knirps.de/stores/store/redirect/___store/ch_de/___from_store/default/uenc/aHR0cHM6Ly9rbmlycHMuY2gvYmxvZy8~/" 5776 role="menuitem" 5777 tabindex="0" 5778 data-item-num="4" 5779 data-lang-code="ch-de" 5780 class="font-light text-16 hover:text-primary focus:text-primary transition-colors duration-300"> 5781 Schweiz </a> 5782 <a 5783 href="https://knirps.de/stores/store/redirect/___store/knirps_cz/___from_store/default/uenc/aHR0cHM6Ly9rbmlycHMuY3ovYmxvZy8~/" 5784 role="menuitem" 5785 tabindex="0" 5786 data-item-num="5" 5787 data-lang-code="cz" 5788 class="font-light text-16 hover:text-primary focus:text-primary transition-colors duration-300"> 5789 ÄeÅ¡tina </a> 5790 </div> 5791 </nav> 5792 </div> 5793 </div> 5794
5794<script> 5795 function initLanguageSwitcher() { 5796 return { 5797 open: false, 5798 toggleOpen() { 5799 this.open = !this.open; 5800 if (this.open) this.$nextTick(() => this.focusFirst()); 5801 }, 5802 setOpenFalse() { 5803 this.open = false; 5804 }, 5805 focusableElements() { 5806 return [...this.$root.querySelectorAll('[role="menuitem"]:not([tabindex="-1"])')]; 5807 }, 5808 focusFirst() { 5809 const items = this.focusableElements(); 5810 if (items.length) items[0].focus(); 5811 }, 5812 } 5813 } 5814 window.addEventListener('alpine:init', () => Alpine.data('initLanguageSwitcher', initLanguageSwitcher), { 5815 once: true 5816 }) 5817 </script>
5817 5818 <a 5819 href="https://knirps.de/customer/account/index/" 5820 class="text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary font-light" 5821 data-testid="mobile-menu-account-link"> 5822 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 19 19" fill="none" aria-hidden="true"> 5823<path d="M2.62104 15.3037C4.65267 14.1554 6.9998 13.5 9.5 13.5C12.0002 13.5 14.3473 14.1554 16.379 15.3037M12.5 7.5C12.5 9.15685 11.1569 10.5 9.5 10.5C7.84315 10.5 6.5 9.15685 6.5 7.5C6.5 5.84315 7.84315 4.5 9.5 4.5C11.1569 4.5 12.5 5.84315 12.5 7.5ZM18.5 9.5C18.5 14.4706 14.4706 18.5 9.5 18.5C4.52944 18.5 0.5 14.4706 0.5 9.5C0.5 4.52944 4.52944 0.5 9.5 0.5C14.4706 0.5 18.5 4.52944 18.5 9.5Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/> 5824</svg> 5825 Mein Konto </a> 5826 5827<a 5828 href="https://knirps.de/wishlist/" 5829 class="relative font-light text-16 flex items-center gap-3 leading-150 py-4.5 px-6 hover:text-primary aria-[current=page]:text-primary" 5830 x-data="initWishlistHeader" 5831 @private-content-loaded.window="receiveWishlistData" 5832 aria-label="Wunschliste" 5833 :aria-label="linkAriaLabel"> 5834 <span class="relative"> 5835 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 19 17" fill="none" aria-hidden="true"> 5836<path d="M1.81802 1.81802C0.0606601 3.57538 0.0606601 6.42462 1.81802 8.18198L9.50005 15.864L17.182 8.18198C18.9393 6.42462 18.9393 3.57538 17.182 1.81802C15.4246 0.0606601 12.5754 0.0606602 10.818 1.81802L9.50005 3.13609L8.18198 1.81802C6.42462 0.0606604 3.57538 0.0606604 1.81802 1.81802Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/> 5837</svg> 5838 <template x-if="itemCount"> 5839 <span 5840 x-text="itemCount" 5841 class="absolute -top-1/2 -right-1/2 px-1.5 py-1 rounded-full bg-primary text-white text-xs font-semibold leading-none text-center uppercase" 5842 aria-hidden="true"></span> 5843 </template> 5844 </span> 5845 <span class="inline-block lg:hidden"> 5846 Wunschliste </span> 5847</a> </nav> 5848 </div> 5849 </dialog> 5850</div> 5851
5852<script> 5853 document.addEventListener('alpine:init', () => { 5854 Alpine.data('initMobileMenu', () => ({ 5855 isOpen: false, 5856 isSubMenuOpen: false, 5857 isOverflowing: false, 5858 menuTopPosition: '0px', 5859 showLanguageSwitcher: false, 5860 menuHeight: '100dvh', 5861 isMobile: false, 5862 5863 init() { 5864 Array.from(this.$root.querySelectorAll('a')).forEach(link => { 5865 if (link.href === `${window.location.origin}${window.location.pathname}`) { 5866 link.setAttribute('aria-current', 'page'); 5867 } 5868 }); 5869 5870 this.updateMenuPosition(); 5871 }, 5872 5873 checkIsMobileResolution() { 5874 const matchMedia = window.matchMedia('(max-width: 1024px)'); 5875 5876 this.isMobile = matchMedia.matches; 5877 5878 if (typeof matchMedia.onchange !== 'object') { 5879 matchMedia.addListener((event) => { 5880 this.isMobile = event.matches; 5881 this.close() 5882 }); 5883 } else { 5884 matchMedia.addEventListener( 5885 "change", 5886 (event) => { 5887 this.close() 5888 return this.isMobile = event.matches 5889 } 5890 ) 5891 } 5892 }, 5893 5894 toggleOpen() { 5895 if (this.isOpen) { 5896 this.close(); 5897 } else { 5898 this.open(); 5899 } 5900 }, 5901 5902 open() { 5903 document.body.classList.add('mobile-menu-open'); 5904 window.scrollTo(0, 0); 5905 this.updateMenuPosition(); 5906 this.isOpen = true; 5907 5908 setTimeout(() => { 5909 this.showLanguageSwitcher = true; 5910 }, 500); 5911 }, 5912 close() { 5913 this.showLanguageSwitcher = false;
5914 document.body.classList.remove('mobile-menu-open'); 5915 this.isOpen = false; 5916 }, 5917 5918 updateMenuPosition() { 5919 const headerElement = document.getElementById('header'); 5920 if (headerElement) { 5921 const headerHeight = headerElement.offsetHeight; 5922 this.menuTopPosition = `${headerHeight}px`; 5923 this.menuHeight = `calc(100dvh - ${headerHeight}px)`; 5924 } 5925 }, 5926 5927 hasActiveSubMenu() { 5928 this.isSubMenuOpen = !!this.$root.querySelector('[data-open]'); 5929 }, 5930 })); 5931 5932 Alpine.data('initMobileSubMenu', () => ({ 5933 isOpen: false, 5934 hiddenElements: [], 5935 5936 init() { 5937 this.hiddenElements = []; 5938 }, 5939 5940 open() { 5941 this.isOpen = true; 5942 this.$root.setAttribute('data-open', ''); 5943 5944 this.hideOtherItems(); 5945 5946 this.$nextTick(() => { 5947 this.$dispatch('sub-menu-state-change'); 5948 this.$refs.closeSubMenuBtn?.focus(); 5949 }); 5950 }, 5951 5952 close() { 5953 this.isOpen = false; 5954 this.$root.removeAttribute('data-open'); 5955 5956 this.restoreHiddenItems(); 5957 5958 this.$nextTick(() => { 5959 this.$dispatch('sub-menu-state-change'); 5960 if (this.$refs.openSubMenuBtn) { 5961 this.$refs.openSubMenuBtn.focus(); 5962 } 5963 }); 5964 }, 5965 5966 hideOtherItems() { 5967 this.hiddenElements = []; 5968 5969 const parent = this.$root.parentElement; 5970 const siblings = Array.from(parent.children).filter(el => el !== this.$root); 5971 5972 siblings.forEach(sibling => { 5973 if (!sibling.hasAttribute('x-hidden')) { 5974 sibling.setAttribute('x-hidden', ''); 5975 sibling.style.display = 'none'; 5976 this.hiddenElements.push(sibling); 5977 } 5978 }); 5979 5980 if (parentLevel > 0) { 5981 const allItems = parent.querySelectorAll(`[data-level="${parentLevel-1}"]`); 5982 allItems.forEach(item => { 5983 if (!item.hasAttribute('data-open') && !item.hasAttribute('x-hidden')) { 5984 item.setAttribute('x-hidden', ''); 5985 item.style.display = 'none'; 5986 this.hiddenElements.push(item); 5987 } 5988 }); 5989 } 5990 }, 5991 5992 restoreHiddenItems() { 5993 this.hiddenElements.forEach(el => { 5994 el.removeAttribute('x-hidden'); 5995 el.style.display = ''; 5996 }); 5997 5998 this.hiddenElements = []; 5999 } 6000 })); 6001 Alpine.data('initWishlistHeader', () => { 6002 return { 6003 wishlistProducts: null, 6004 itemCount: 0, 6005 linkAriaLabel() { 6006 const countLabel = this.itemCount > 1 ? 6007 hyva.str('\u00251\u0020Artikel', this.itemCount) : 6008 hyva.str('\u00251\u0020Artikel', this.itemCount); 6009 return `Wunschlistenprodukte (${countLabel})`; 6010 }, 6011 receiveWishlistData() { 6012 const data = this.$event.detail.data; 6013 let counterPos = data.wishlist.counter ? data.wishlist.counter.split(" ")[0] : 0; 6014 this.itemCount = data.wishlist && data.wishlist.items ? 6015 parseInt(counterPos) : 6016 0; 6017 } 6018 } 6019 }) 6020 }); 6021</script>
6021 6022 </div> 6023 <div class="flex-1 order-2"> 6024 <div class="w-full pb-2 sm:pb-0 mx-auto md:mx-0 order-2 md:order-0 header-logo lg:relative lg:w-auto"> 6025 <a 6026 class="logo flex items-center justify-center text-xl font-medium tracking-wide 6027 no-underline hover:no-underline font-title lg:justify-start lg:pl-12 lg:w-fit" 6028 href="https://knirps.de/" 6029 aria-label="Zur Startseite gehen"> 6030 <img 6031 src="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/images/logo.svg" 6032 alt="Knirps" 6033 width="155" height="64" loading="eager" /> 6034 </a> 6035</div> </div> 6036 6037 <template x-if="!$store.isTablet.value"> 6038 <div class="hidden flex-1 order-2 lg:block"> 6039 <div 6040 x-ref="searchContainer" 6041 class="text-search-text-closed mx-auto search-container transition-[width,max-width] duration-300 bg-search-bg order-4 6042 md:pl-0 md:order-0 6043 max-lg:container max-lg:px-2 6044 lg:max-w-[360px] lg:w-[360px] lg:bg-transparent"
6045 :class="{'lg:w-[80vw]! lg:max-w-[768px]! xl:max-w-[960px]! 2xl:max-w-[1200px]! text-search-text!': isOpen, 'relative z-100': isOpen}" 6046 x-data="initMiniSearch" 6047 x-init="init()" 6048 @keydown.window.escape="closeSearch()"> 6049 <search role="search"> 6050 <form 6051 id="search_mini_form" 6052 class="form minisearch transition-colors duration-300 relative flex max-w-full mx-auto my-0 px-2 py-2 z-50" 6053 :class="{'bg-search-bg z-100!': isOpen, 'minisearch--no-results': isOpen && !hasDisplayResults() && !isLoadingTopItems }" 6054 action="https://knirps.de/catalogsearch/result/" 6055 method="get" 6056 @submit.prevent="search()" 6057 x-ref="form"> 6058 <div 6059 class="w-full border-b flex items-center z-50 transition-[width,background-color,border-color,border-radius] duration-300 lg:border-b-0 lg:w-[calc(100%-56px)]" 6060 :class="{'rounded-(--search-input-radius) bg-search-accent-bg border-b-transparent! w-[calc(100%-48px)]!': isOpen}"> 6061 <label class="sr-only" for="search"> 6062 Suche </label> 6063 <input 6064 id="search" 6065 x-ref="searchInput" 6066 type="search" 6067 autocomplete="off" 6068 name="q" 6069 value="" 6070 placeholder="Was suchen Sie?" 6071 maxlength="128" 6072 class="w-full text-lg lg:text-xl border-0 bg-transparent transition-[border-color] rounded-none duration-300 lg:border-b lg:border-inherit" 6073 :class="{'lg:border-b-transparent': isOpen}" 6074 @search-open.window.debounce.10="$el.focus(); $el.select()" 6075 @focus="openSearch()" 6076 @focusout="handleInputBlur()" 6077 @focus.once="suggest" 6078 @input.debounce.300="suggest" 6079 @keydown.arrow-down.prevent="focusElement()"> 6080 <button 6081 class="action search rounded-none p-3 hover:text-current/80 shadow-none" 6082 title="Suche" 6083 aria-label="Suche" 6084 @click.prevent="isOpen ? search() : $refs.searchInput.focus()"> 6085 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 25 24" fill="none" aria-hidden="true"> 6086<path fill-rule="evenodd" clip-rule="evenodd" d="M10.1003 4.80002C7.4493 4.80002 5.30027 6.94906 5.30027 9.60002C5.30027 12.251 7.4493 14.4 10.1003 14.4C12.7512 14.4 14.9003 12.251 14.9003 9.60002C14.9003 6.94906 12.7512 4.80002 10.1003 4.80002ZM2.90027 9.60002C2.90027 5.62357 6.12382 2.40002 10.1003 2.40002C14.0767 2.40002 17.3003 5.62357 17.3003 9.60002C17.3003 11.155 16.8073 12.5949 15.9692 13.7719L21.7488 19.5515C22.2174 20.0201 22.2174 20.7799 21.7488 21.2486C21.2802 21.7172 20.5204 21.7172 20.0517 21.2486L14.2721 15.4689C13.0951 16.3071 11.6553 16.8 10.1003 16.8C6.12382 16.8 2.90027 13.5765 2.90027 9.60002Z" fill="currentColor"/> 6087</svg> 6088 </button> 6089 </div> 6090 <button 6091 type="button" 6092 x-show="isOpen" 6093 x-cloak 6094 x-transition:enter="transition ease-out duration-300" 6095 x-transition:enter-start="opacity-0" 6096 x-transition:enter-end="opacity-100" 6097 x-transition:leave="transition ease-in duration-300" 6098 x-transition:leave-start="opacity-100" 6099 x-transition:leave-end="opacity-0" 6100 @click="closeSearch()" 6101 class="action close rounded-none hover:text-current/80 transition-colors p-4 absolute right-2 top-2" 6102 data-testid="search-close-button" 6103 title="Schließen" 6104 aria-label="Schließen"> 6105 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewB
6105ox="0 0 18 18" fill="none" aria-hidden="true"> 6106<path fill-rule="evenodd" clip-rule="evenodd" d="M0.43934 0.43934C1.02513 -0.146447 1.97487 -0.146447 2.56066 0.43934L9 6.87868L15.4393 0.43934C16.0251 -0.146447 16.9749 -0.146447 17.5607 0.43934C18.1464 1.02513 18.1464 1.97487 17.5607 2.56066L11.1213 9L17.5607 15.4393C18.1464 16.0251 18.1464 16.9749 17.5607 17.5607C16.9749 18.1464 16.0251 18.1464 15.4393 17.5607L9 11.1213L2.56066 17.5607C1.97487 18.1464 1.02513 18.1464 0.43934 17.5607C-0.146447 16.9749 -0.146447 16.0251 0.43934 15.4393L6.87868 9L0.43934 2.56066C-0.146447 1.97487 -0.146447 1.02513 0.43934 0.43934Z" fill="currentColor"/> 6107</svg> 6108 </button> 6109 <div 6110 x-cloak 6111 x-show="isOpen" 6112 x-transition:enter="transition ease-out duration-300" 6113 x-transition:enter-start="opacity-0" 6114 x-transition:enter-end="opacity-100" 6115 x-transition:leave="transition ease-in duration-300" 6116 x-transition:leave-start="opacity-100" 6117 x-transition:leave-end="opacity-0" 6118 x-ref="searchDropdown" 6119 role="region" 6120 aria-label="Search suggestions" 6121 aria-live="polite" 6122 aria-atomic="false" 6123 data-testid="search-dropdown" 6124 class="rounded-(--card-radius) rounded-t-none! absolute top-full w-full left-0 right-0 bg-search-bg shadow-lg max-h-[90vh] overflow-y-auto z-100"> 6125 <div 6126 x-cloak 6127 x-show="isLoadingAutocomplete" 6128 class="absolute inset-0 z-20 bg-search-bg/60 flex items-center justify-center pointer-events-auto"> 6129 <svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="2" stroke-linecap="round" class="w-7 h-7 animate-spin" aria-hidden="true"> 6130 <circle style="opacity: .3;" cx="12" cy="12" r="10"/> 6131 <path fill="none" stroke-width="2" d="M12,2 a10,10 0 0,1 10,10"/> 6132</svg> 6133 </div> 6134 <template x-if="isLoadingTopItems && !hasAutocompleteResults() && !topItemsLoaded"> 6135 <div class="container flex flex-col gap-3 mx-auto p-2 pb-3 overflow-hidden" data-testid="search-loading"> 6136 <div class="flex flex-col md:flex-row gap-3"> 6137 <div class="flex flex-row gap-3 md:hidden h-fit"> 6138 <div class="rounded-(--card-radius) p-3 bg-search-card-bg h-fit flex-1"> 6139 <div class="h-5 bg-search-skeleton rounded mb-3 w-1/3 animate-pulse"></div> 6140 <ul class="flex flex-col gap-2"> 6141 <template x-for="i in categoryCount" :key="i"> 6142 <li> 6143 <div class="h-4 bg-search-skeleton rounded animate-pulse"></div> 6144 </li> 6145 </template> 6146 </ul> 6147 </div> 6148 <div class="rounded-(--card-radius) p-3 bg-search-card-bg h-fit flex-1" x-show="trendingQueries.length > 0"> 6149 <div class="h-5 bg-search-skeleton rounded mb-3 w-1/2 animate-pulse"></div> 6150 <ul class="flex flex-col gap-2"> 6151 <template x-for="i in trendingQueries.length" :key="i"> 6152 <li> 6153 <div class="h-4 bg-search-skeleton rounded animate-pulse"></div> 6154 </li> 6155 </template> 6156 </ul> 6157 </div> 6158 </div> 6159 <div class="flex-1"> 6160 <div class="flex md:grid md:grid-cols-3 gap-3 overflow-x-auto md:overflow-x-visible pb-3 md:pb-0"> 6161 <template x-for="i in productC
6161ount" :key="i"> 6162 <div class="rounded-(--card-radius) bg-search-accent-bg p-4 min-w-[160px] md:min-w-0 flex flex-col"> 6163 <div class="aspect-square bg-search-skeleton rounded mb-3 animate-pulse"></div> 6164 <div class="h-4 bg-search-skeleton rounded mb-2 animate-pulse"></div> 6165 <div class="h-5 bg-search-skeleton rounded w-1/3 mt-auto animate-pulse"></div> 6166 </div> 6167 </template> 6168 </div> 6169 </div> 6170 <div class="min-w-64 hidden md:flex flex-col gap-3"> 6171 <div class="rounded-(--card-radius) p-3 flex-1 bg-search-card-bg"> 6172 <div class="h-5 bg-search-skeleton rounded mb-3 w-1/3 animate-pulse"></div> 6173 <ul class="flex flex-col gap-2"> 6174 <template x-for="i in categoryCount" :key="i"> 6175 <li> 6176 <div class="h-4 bg-search-skeleton rounded animate-pulse"></div> 6177 </li> 6178 </template> 6179 </ul> 6180 </div> 6181 <div class="rounded-(--card-radius) p-3 flex-1 bg-search-card-bg" x-show="trendingQueries.length > 0"> 6182 <div class="h-5 bg-search-skeleton rounded mb-3 w-1/2 animate-pulse"></div> 6183 <ul class="flex flex-col gap-2"> 6184 <template x-for="i in trendingQueries.length" :key="i"> 6185 <li> 6186 <div class="h-4 bg-search-skeleton rounded animate-pulse"></div> 6187 </li> 6188 </template> 6189 </ul> 6190 </div> 6191 </div> 6192 </div> 6193 </div> 6194 </template> 6195 <template x-if="!hasDisplayResults() && !isLoadingTopItems && $refs.searchInput.value.length >= minSearchLength"> 6196 <div class="container flex flex-col gap-3 mx-auto p-2 pb-3"> 6197 <div class="flex h-full w-full items-center justify-center py-8"> 6198 <p class="text-lg">Keine Ergebnisse gefunden</p> 6199 </div> 6200 </div> 6201 </template> 6202 <template x-if="hasDisplayResults()"> 6203 <div class="container flex flex-col gap-3 mx-auto p-2 pb-3 overflow-hidden"> 6204 <div class="flex flex-col md:flex-row-reverse gap-3"> 6205 <div class="flex flex-row md:flex-col gap-3 items-stretch md:min-w-64"> 6206 <div class="rounded-(--card-radius) p-3 bg-search-card-bg flex-1" x-show="getDisplayResults().categories.length > 0"> 6207 <span class="text-primary font-semibold mb-2">Kategorien</span> 6208 <ul class="flex flex-col gap-1"> 6209 <template x-for="category in getDisplayResults().categories" :key="category.url"> 6210 <li> 6211 <a :href="category.url" class="hover:text-primary transition-colors [&_>em]:text-primary" x-html="category.attributes?.title || category.attributes?.name || ''"></a> 6212 </li> 6213 </template> 6214 </ul> 6215 </div> 6216 <div class="rounded-(--card-radius) p-3 bg-search-card-bg flex-1" x-show="trendingQueries.length > 0 && !isLoadingTopItems">
6217 <span class="text-primary font-semibold mb-2">Vorschläge</span> 6218 <ul class="flex flex-col gap-1"> 6219 <template x-for="(query, index) in trendingQueries" :key="index"> 6220 <li> 6221 <button 6222 type="button" 6223 @click="search(query)" 6224 class="text-left hover:text-primary transition-colors w-full" 6225 x-text="query"> 6226 </button> 6227 </li> 6228 </template> 6229 </ul> 6230 </div> 6231 </div> 6232 <div class="flex-1"> 6233 <div x-show="getDisplayResults().products.length > 0" class="relative" x-data="horizontalScroll({ containerRef: 'productsScrollContainer' })"> 6234 <button 6235 type="button" 6236 aria-label="Scroll left" 6237 class="rounded-(--card-radius) w-fit h-fit absolute left-0 top-1/2 -translate-y-1/2 z-10 flex items-center p-1.5 bg-search-accent-bg/80 transition-opacity md:hidden" 6238 :class="{ 'opacity-0 pointer-events-none': !canScrollLeft, 'opacity-100': canScrollLeft }" 6239 @click="scrollNav(-1)" 6240 x-show="canScrollLeft" 6241 x-cloak> 6242 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-6 h-6" width="24" height="24" aria-hidden="true"> 6243 <path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd"/> 6244</svg> 6245 </button> 6246 <div 6247 x-ref="productsScrollContainer" 6248 @scroll="updateScrollState()" 6249 class="flex md:grid md:grid-cols-3 gap-3 overflow-x-auto md:overflow-x-visible pb-2 md:pb-0 w-full max-w-full min-w-0"> 6250 <template x-for="(product, productIndex) in getDisplayResults().products.slice(0, productC
6250ount)" :key="product.url"> 6251 <a :href="product.url" @click="trackAutocompleteClick(product, productIndex)" class="rounded-(--card-radius) bg-search-accent-bg p-4 hover:shadow-lg transition-shadow flex flex-col w-[calc(50%-6px)] [content-visibility:auto] contain-[paint] md:w-auto flex-shrink-0 md:shrink"> 6252 <div class="aspect-square bg-white rounded mb-3 flex items-center justify-center overflow-hidden"> 6253 <img 6254 x-show="product.attributes?.image_link" 6255 :src="product.attributes.image_link" 6256 :alt="product.attributes?.title?.untouched || product.attributes?.title || ''" 6257 loading="lazy" 6258 decoding="async" 6259 fetchpriority="low" 6260 class="w-full h-full object-contain" /> 6261 <span x-show="!product.attributes?.image_link" class="text-gray-400 text-sm">Kein Bild verfügbar</span> 6262 </div> 6263 <div class="text-lg font-bold [&_>em]:text-primary" x-html="product.attributes?.title || ''"></div> 6264 <div 6265 class="w-full overflow-x-hidden swatch-attribute-options pb-1 pt-2" 6266 x-data="{ swatches: getProductSwatchesMeta(product) }" 6267 x-show="swatches.visible.length"> 6268 <div class="flex flex-nowrap w-full overflow-auto snap items-center gap-0.5 lg:gap-1 relative swatches-container"> 6269 <template x-for="(color, index) in swatches.visible" :key="`${product.url}-swatch-${index}`"> 6270 <div 6271 class="swatch-option relative cursor-pointer select-none product-option-value-label p-0 w-[30px] h-4 rounded-3 bg-cover bg-size-[30px_20px] bg-center" 6272 :style="`background-color: ${color}`"> 6273 </div> 6274 </template> 6275 <span 6276 class="swatch-counter flex items-center w-[30px] h-4 justify-center bg-bg-primary text-14 rounded-3 leading-170 font-semibold" 6277 x-show="swatches.hiddenCount > 0"> 6278 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6" width="14" height="14" aria-hidden="true"> 6279 <path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15"/> 6280</svg> 6281 </span> 6282 </div> 6283 </div> 6284 <div class="flex flex-row-reverse justify-end items-end gap-1.5 mt-auto pt-3"> 6285 <div 6286 class="text-text-secondary old-price line-through text-sm" 6287 x-show="product.attributes?.price_old && product.attributes.price_old !== product.attributes?.price" 6288 x-text="product.attributes?.price_old"> 6289 </div> 6290 <div 6291 class="text-2xl leading-none font-regular" 6292 :class="{ 'text-price-discounted': product.attributes?.price_old && product.attributes.price_old !== product.attributes?.price }" 6293 x-show="product.attributes?.price" 6294 x-text="product.attributes.price"> 6295 </div> 6296 </div> 6297 </a> 6298 </template> 6299 </div> 6300 <button 6301 type="button" 6302 aria-label="Scroll right" 6303 class="w-fit h-fit roun
6303ded absolute right-0 top-1/2 -translate-y-1/2 z-10 flex items-center p-1.5 bg-search-accent-bg/80 transition-opacity md:hidden" 6304 :class="{ 'opacity-0 pointer-events-none': !canScrollRight, 'opacity-100': canScrollRight }" 6305 @click="scrollNav(1)" 6306 x-show="canScrollRight" 6307 x-cloak> 6308 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-6 h-6" width="24" height="24" aria-hidden="true"> 6309 <path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"/> 6310</svg> 6311 </button> 6312 </div> 6313 <div x-show="getDisplayResults().products.length === 0 && !isLoadingTopItems" class="flex h-full w-full items-center justify-center py-8"> 6314 <p class="text-lg text-text-secondary-darker">Keine Ergebnisse gefunden</p> 6315 </div> 6316 </div> 6317 </div> 6318 <button x-show="hasAutocompleteResults()" type="submit" class="w-full btn btn-primary text-center" data-testid="search-show-all-results"> 6319 Zeige alle Ergebnisse </button> 6320 </div> 6321 </template> 6322 </div> 6323 </form> 6324 </search> 6325 <div 6326 x-cloak 6327 x-show="isOpen" 6328 x-transition:enter="transition ease-out duration-300" 6329 x-transition:enter-start="opacity-0" 6330 x-transition:enter-end="opacity-100" 6331 x-transition:leave="transition ease-in duration-300" 6332 x-transition:leave-start="opacity-100" 6333 x-transition:leave-end="opacity-0" 6334 class="fixed inset-0 bg-black/30 backdrop-blur-sm z-20" 6335 data-testid="search-overlay" 6336 @click="closeSearch()"></div> 6337 </div> 6338 </div> 6339 </template> 6340 6341 <div class="flex w-full items-center justify-end flex-1 order-3"> 6342 6343 <div class="header-links-wrapper flex items-center gap-3 order-3 md:order-0 lg:py-5"> 6344 6345 <!-- Store Switcher --> 6346 <div class="flex items-center"> 6347 <div x-data="initLanguageSwitcher" 6348 class="language-switcher w-full" 6349 x-id="['language-switcher']" 6350 :data-testid="$id('language-switcher')"> 6351 <div x-id="['menu-options']" class="relative inline-block text-left"> 6352 <div class="flex items-center group"> 6353 <button @click.prevent="toggleOpen" 6354 @click.outside="setOpenFalse" 6355 @keydown.window.escape="setOpenFalse" 6356 type="button" 6357 :id="$id('menu-options')" 6358 class="w-full border-0 shadow-none uppercase text-12 font-medium leading-130 flex items-center 6359 transition-colors group-hover:text-current/80 group-aria-expanded:text-current/80" 6360 aria-haspopup="true" 6361 :aria-expanded="open" 6362 aria-label="Sprachauswahl" 6363 title="Sprachauswahl"> 6364 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 19 19" fill="none" class="inline mr-1 transition-colors" aria-hidden="true"> 6365<path d="M0.554929 8.5H2.5C3.60457 8.5 4.5 9.39543 4.5 10.5V11.5C4.5 12.6046 5.39543 13.5 6.5 13.5C7.60457 13.5 8.5 14.3954 8.5 15.5V18.4451M5.5 1.43552V3C5.5 4.38071 6.61929 5.5 8 5.5H8.5C9.60457 5.5 10.5 6.39543 10.5 7.5C10.5 8.60457 11.3954 9.5 12.5 9.5C13.6046 9.5 14.5 8.60457 14.5 7.5C14.5 6.39543 15.3954 5.5 16.5 5.5L17.5645 5.5M12.5 17.9879V15.5C12.5 14.3954 13.3954 13.5 14.5 13.5H17.5645M18.5 9.5C18.5 14.4706 14.4706 18.5 9.5 18.5C4.52944 18.5 0.5 14.4706 0.5 9.5C0.5 4.52944 4.52944 0.5 9.5 0.5C14.4706 0.5 18.5 4.52944 18.5 9.5Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/> 6366</svg>
6367 <span class="inline-block align-middle">de</span> 6368 6369 <span :class="{ 'rotate-180': open }" class="inline-block transform transition-all duration-200 align-middle"> 6370 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-5 h-5" width="18" height="18" aria-hidden="true"> 6371 <path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7"/> 6372</svg> 6373 </span> 6374 </button> 6375 </div> 6376 <nav x-cloak 6377 x-show="open" 6378 x-transition.origin.top.right 6379 @keydown.tab="trapFocus($event)" 6380 @keydown.shift.tab="trapFocus($event)" 6381 class="bg-white rounded-(--header-card-radius) [&>*:first-child]:rounded-t-(--header-card-radius) border-t-2 border-primary absolute left-0 top-full z-20 mt-3 origin-top-left overflow-visible shadow-lg" 6382 role="menu" 6383 aria-orientation="vertical" 6384 :aria-labelledby="$id('menu-options')"> 6385 <a href="https://knirps.de/stores/store/redirect/___store/knirps_en/___from_store/default/uenc/aHR0cHM6Ly9rbmlycHMuY29tL2Jsb2cv/" 6386 role="menuitem" 6387 tabindex="0" 6388 data-item-num="1" 6389 data-lang-code="en" 6390 class="text-text-secondary first:rounded-t-[5px] px-4 py-2 hover:bg-bg-secondary flex items-center justify-between gap-2"> 6391 6392 <span class="flex items-center gap-2 w-5 h-5"> 6393 <img src="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Doppler_StoreSwitcher/flags/4x3/gb.svg" 6394 alt="English" 6395 class="w-5 h-5 rounded-full object-cover" /> 6396 </span> 6397 6398 <span class="text-12 font-medium leading-130">Global</span> 6399 <span class="code text-8 font-medium leading-130 text-right">EN</span> 6400 </a> 6401 <a href="https://knirps.de/stores/store/redirect/___store/knirps_fr/___from_store/default/uenc/aHR0cHM6Ly9rbmlycHMuZnIvYmxvZy8~/" 6402 role="menuitem" 6403 tabindex="0" 6404 data-item-num="2" 6405 data-lang-code="fr" 6406 class="text-text-secondary first:rounded-t-[5px] px-4 py-2 hover:bg-bg-secondary flex items-center justify-between gap-2"> 6407 6408 <span class="flex items-center gap-2 w-5 h-5"> 6409 <img src="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Doppler_StoreSwitcher/flags/4x3/fr.svg" 6410 alt="Français" 6411 class="w-5 h-5 rounded-full object-cover" /> 6412 </span> 6413
6414 <span class="text-12 font-medium leading-130">Français</span> 6415 <span class="code text-8 font-medium leading-130 text-right">FR</span> 6416 </a> 6417 <a href="https://knirps.de/stores/store/redirect/___store/knirps_nl/___from_store/default/uenc/aHR0cHM6Ly9rbmlycHMubmwvYmxvZy8~/" 6418 role="menuitem" 6419 tabindex="0" 6420 data-item-num="3" 6421 data-lang-code="nl" 6422 class="text-text-secondary first:rounded-t-[5px] px-4 py-2 hover:bg-bg-secondary flex items-center justify-between gap-2"> 6423 6424 <span class="flex items-center gap-2 w-5 h-5"> 6425 <img src="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Doppler_StoreSwitcher/flags/4x3/nl.svg" 6426 alt="Nederlands" 6427 class="w-5 h-5 rounded-full object-cover" /> 6428 </span> 6429 6430 <span class="text-12 font-medium leading-130">Nederlands</span> 6431 <span class="code text-8 font-medium leading-130 text-right">NL</span> 6432 </a> 6433 <a href="https://knirps.de/stores/store/redirect/___store/ch_de/___from_store/default/uenc/aHR0cHM6Ly9rbmlycHMuY2gvYmxvZy8~/" 6434 role="menuitem" 6435 tabindex="0" 6436 data-item-num="4" 6437 data-lang-code="ch-de" 6438 class="text-text-secondary first:rounded-t-[5px] px-4 py-2 hover:bg-bg-secondary flex items-center justify-between gap-2"> 6439 6440 <span class="flex items-center gap-2 w-5 h-5"> 6441 <img src="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Doppler_StoreSwitcher/flags/4x3/ch.svg" 6442 alt="Deutsch" 6443 class="w-5 h-5 rounded-full object-cover" /> 6444 </span> 6445 6446 <span class="text-12 font-medium leading-130">Schweiz</span> 6447 <span class="code text-8 font-medium leading-130 text-right">CH-DE</span> 6448 </a> 6449 <a href="https://knirps.de/stores/store/redirect/___store/knirps_cz/___from_store/default/uenc/aHR0cHM6Ly9rbmlycHMuY3ovYmxvZy8~/" 6450 role="menuitem" 6451 tabindex="0" 6452 data-item-num="5" 6453 data-lang-code="cz" 6454 class="text-text-secondary first:rounded-t-[5px] px-4 py-2 hover:bg-bg-secondary flex items-center justify-between gap-2"> 6455 6456 <sp
6456an class="flex items-center gap-2 w-5 h-5"> 6457 <img src="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Doppler_StoreSwitcher/flags/4x3/cz.svg" 6458 alt="Czech" 6459 class="w-5 h-5 rounded-full object-cover" /> 6460 </span> 6461 6462 <span class="text-12 font-medium leading-130">ÄeÅ¡tina</span> 6463 <span class="code text-8 font-medium leading-130 text-right">CZ</span> 6464 </a> 6465 <div class="absolute left-1 -top-2 w-0 h-0 6466 border-l-8 border-l-transparent 6467 border-r-8 border-r-transparent 6468 border-b-8 border-primary language-arrow"> 6469 </div> 6470 </nav> 6471 </div> 6472 </div> 6473
6473<script> 6474 function initLanguageSwitcher() { 6475 return { 6476 open: false, 6477 toggleOpen() { 6478 this.open = !this.open; 6479 if (this.open) this.$nextTick(() => this.focusFirst()); 6480 }, 6481 setOpenFalse() { 6482 this.open = false; 6483 }, 6484 focusableElements() { 6485 return [...this.$root.querySelectorAll('[role="menuitem"]:not([tabindex="-1"])')]; 6486 }, 6487 focusFirst() { 6488 const items = this.focusableElements(); 6489 if (items.length) items[0].focus(); 6490 }, 6491 trapFocus(event) { 6492 const items = this.focusableElements(); 6493 const index = items.indexOf(document.activeElement); 6494 if (event.shiftKey) { 6495 if (index === 0) { 6496 event.preventDefault(); 6497 items[items.length - 1].focus(); 6498 } 6499 } else { 6500 if (index === items.length - 1) { 6501 event.preventDefault(); 6502 items[0].focus(); 6503 } 6504 } 6505 } 6506 } 6507 } 6508 window.addEventListener('alpine:init', () => Alpine.data('initLanguageSwitcher', initLanguageSwitcher), { 6509 once: true 6510 }) 6511 </script>
6511 6512 </div> 6513 6514 <!-- Additional Header Elements --> 6515 6516 <!--Customer Icon & Dropdown--> 6517 <!-- BLOCK header.customer --> 6518<div 6519 class="relative inline-block" 6520 x-data="{ open: false }" 6521 @keyup.escape="open = false" 6522 @click.outside="open = false"> 6523 <button 6524 type="button" 6525 id="customer-menu" 6526 data-testid="profile-icon" 6527 class="block rounded hover:text-current/80 transition-colors outline-offset-2" 6528 @click="open = !open" 6529 :aria-expanded="open ? 'true' : 'false'" 6530 aria-label="Mein Konto" 6531 title="Mein Konto" 6532 aria-haspopup="true"> 6533 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 19 19" fill="none" aria-hidden="true"> 6534<path d="M2.62104 15.3037C4.65267 14.1554 6.9998 13.5 9.5 13.5C12.0002 13.5 14.3473 14.1554 16.379 15.3037M12.5 7.5C12.5 9.15685 11.1569 10.5 9.5 10.5C7.84315 10.5 6.5 9.15685 6.5 7.5C6.5 5.84315 7.84315 4.5 9.5 4.5C11.1569 4.5 12.5 5.84315 12.5 7.5ZM18.5 9.5C18.5 14.4706 14.4706 18.5 9.5 18.5C4.52944 18.5 0.5 14.4706 0.5 9.5C0.5 4.52944 4.52944 0.5 9.5 0.5C14.4706 0.5 18.5 4.52944 18.5 9.5Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/> 6535</svg> 6536 </button> 6537 <nav 6538 class=" 6539 card rounded-(--header-card-radius) absolute right-0 w-40 py-0 px-0 mt-3 origin-top-right 6540 shadow-lg z-100 border-t-2 border-primary overflow-visible sm:w-48 lg:mt-3 6541 " 6542 x-cloak 6543 x-show="open" 6544 x-transition.origin.top.right 6545 aria-labelledby="customer-menu" 6546 data-testid="profile-dropdown"> 6547 <div class="absolute right-1 -top-2 w-0 h-0 6548 border-l-8 border-l-transparent 6549 border-r-8 border-r-transparent 6550 border-b-8 border-primary"> 6551 </div> 6552 <div class="[&>*:first-child]:rounded-t-(--header-card-radius)"> 6553 6554<a id="customer.header.sign.in.link" 6555 data-testid="login-option" 6556 class="block px-4 py-2 whitespace-nowrap lg:px-5 lg:py-2 hover:bg-bg-secondary" 6557 onclick="hyva.setCookie && hyva.setCookie( 6558 'login_redirect', 6559 window.location.href, 6560 1 6561 )" 6562 href="https://knirps.de/customer/account/index/" 6563 title="Anmelden"> 6564 Anmelden</a> 6565 <a id="customer.header.register.link" 6566 class="block px-4 py-2 whitespace-nowrap lg:px-5 lg:py-2 hover:bg-bg-secondary" 6567 data-testid="register-option" 6568 href="https://knirps.de/customer/account/create/" 6569 title="Ein Konto erstellen"> 6570 Ein Konto erstellen </a> 6571 </div> 6572 </nav> 6573</div> 6574<div class="actions-secondary hidden lg:flex" data-role="add-to-links"> 6575 <a href="https://knirps.de/wishlist/" 6576 class="flex relative group items-center transition-colors hover:text-current/80 " 6577 x-data="initWishlistHeader" 6578 @private-content-loaded.window="receiveWishlistData" 6579 title="Zur Wunschliste"> 6580 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 19 17" fill="none" aria-hidden="true"> 6581<path d="M1.81802 1.81802C0.0606601 3.57538 0.0606601 6.42462 1.81802 8.18198L9.50005 15.864L17.182 8.18198C18.9393 6.42462 18.9393 3.57538 17.182 1.81802C15.4246 0.0606601 12.5754 0.0606602 10.818 1.81802L9.50005 3.13609L8.18198 1.81802C6.42462 0.0606604 3.57538 0.0606604 1.81802 1.81802Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/> 6582</svg> 6583 <template x-if="itemCount"> 6584 <span 6585 class="absolute -top-1/2 -right-1/2 px-1.5 py-1 rounded-full bg-primary text-white text-xs font-semibold leading-none text-center uppercase" 6586 aria-hidden="true" 6587 data-testid="wishlist-item-count" 6588 x-text="itemCount"></span> 6589 </template> 6590 </a> 6591 </div><!-- /BLOCK header.customer --> 6592 <!--Cart Icon--> 6593 <button 6594 id="menu-cart-icon" 6595 data-testid="menu-cart-icon" 6596 class="relative inline-block rounded hover:text-current/80 outline-offset-2 transition-colors" 6597 :class="{'z-30 hover:text-inherit': isCartOpen}" 6598 x-ref="cartButton" 6599 title="Warenkorb anzeigen" 6600 :aria-disabled="isCartEmpty()" 6601 :aria-label="` 6602 Mini-Warenkorb ein-/ausblenden, 6603 ${isCartEmpty() 6604 ? 'Der Warenkorb ist leer' 6605 : cart.summary_count > 1 6606 ? hyva.str('%1 Artikel', cart.summary_count) 6607 : hyva.str('%1 Artikel', cart.summary_count) 6608 }`" 6609 @click.prevent="() => {
6610 $dispatch('toggle-cart', { isOpen: true }) 6611 }" 6612 @toggle-cart.window="toggleCart($event)" 6613 :aria-expanded="isCartOpen" 6614 aria-haspopup="dialog" 6615 > 6616 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 19 19" fill="none" aria-hidden="true"> 6617<path d="M0.5 0.5H2.5L2.9 2.5M4.5 10.5H14.5L18.5 2.5H2.9M4.5 10.5L2.9 2.5M4.5 10.5L2.20711 12.7929C1.57714 13.4229 2.02331 14.5 2.91421 14.5H14.5M14.5 14.5C13.3954 14.5 12.5 15.3954 12.5 16.5C12.5 17.6046 13.3954 18.5 14.5 18.5C15.6046 18.5 16.5 17.6046 16.5 16.5C16.5 15.3954 15.6046 14.5 14.5 14.5ZM6.5 16.5C6.5 17.6046 5.60457 18.5 4.5 18.5C3.39543 18.5 2.5 17.6046 2.5 16.5C2.5 15.3954 3.39543 14.5 4.5 14.5C5.60457 14.5 6.5 15.3954 6.5 16.5Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/> 6618</svg> 6619 <span 6620 x-text="cart.summary_count" 6621 x-show="!isCartEmpty()" 6622 x-cloak 6623 class="absolute -top-1/2 -right-1/2 px-1.5 py-1 rounded-full bg-primary text-white 6624 text-xs font-semibold leading-none text-center uppercase" 6625 aria-hidden="true" 6626 data-testid="cart-item-count"></span> 6627 </button> 6628 </div> 6629 </div> 6630 </div> 6631 </div> 6632 <template x-if="$store.isTablet.value"> 6633 <div class="block bg-search-bg lg:hidden"> 6634 <div 6635 x-ref="searchContainer" 6636 class="text-search-text-closed mx-auto search-container transition-[width,max-width] duration-300 bg-search-bg order-4 6637 md:pl-0 md:order-0 6638 max-lg:container max-lg:px-2 6639 lg:max-w-[360px] lg:w-[360px] lg:bg-transparent"
6640 :class="{'lg:w-[80vw]! lg:max-w-[768px]! xl:max-w-[960px]! 2xl:max-w-[1200px]! text-search-text!': isOpen, 'relative z-100': isOpen}" 6641 x-data="initMiniSearch" 6642 x-init="init()" 6643 @keydown.window.escape="closeSearch()"> 6644 <search role="search"> 6645 <form 6646 id="search_mini_form" 6647 class="form minisearch transition-colors duration-300 relative flex max-w-full mx-auto my-0 px-2 py-2 z-50" 6648 :class="{'bg-search-bg z-100!': isOpen, 'minisearch--no-results': isOpen && !hasDisplayResults() && !isLoadingTopItems }" 6649 action="https://knirps.de/catalogsearch/result/" 6650 method="get" 6651 @submit.prevent="search()" 6652 x-ref="form"> 6653 <div 6654 class="w-full border-b flex items-center z-50 transition-[width,background-color,border-color,border-radius] duration-300 lg:border-b-0 lg:w-[calc(100%-56px)]" 6655 :class="{'rounded-(--search-input-radius) bg-search-accent-bg border-b-transparent! w-[calc(100%-48px)]!': isOpen}"> 6656 <label class="sr-only" for="search"> 6657 Suche </label> 6658 <input 6659 id="search" 6660 x-ref="searchInput" 6661 type="search" 6662 autocomplete="off" 6663 name="q" 6664 value="" 6665 placeholder="Was suchen Sie?" 6666 maxlength="128" 6667 class="w-full text-lg lg:text-xl border-0 bg-transparent transition-[border-color] rounded-none duration-300 lg:border-b lg:border-inherit" 6668 :class="{'lg:border-b-transparent': isOpen}" 6669 @search-open.window.debounce.10="$el.focus(); $el.select()" 6670 @focus="openSearch()" 6671 @focusout="handleInputBlur()" 6672 @focus.once="suggest" 6673 @input.debounce.300="suggest" 6674 @keydown.arrow-down.prevent="focusElement()"> 6675 <button 6676 class="action search rounded-none p-3 hover:text-current/80 shadow-none" 6677 title="Suche" 6678 aria-label="Suche" 6679 @click.prevent="isOpen ? search() : $refs.searchInput.focus()"> 6680 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 25 24" fill="none" aria-hidden="true"> 6681<path fill-rule="evenodd" clip-rule="evenodd" d="M10.1003 4.80002C7.4493 4.80002 5.30027 6.94906 5.30027 9.60002C5.30027 12.251 7.4493 14.4 10.1003 14.4C12.7512 14.4 14.9003 12.251 14.9003 9.60002C14.9003 6.94906 12.7512 4.80002 10.1003 4.80002ZM2.90027 9.60002C2.90027 5.62357 6.12382 2.40002 10.1003 2.40002C14.0767 2.40002 17.3003 5.62357 17.3003 9.60002C17.3003 11.155 16.8073 12.5949 15.9692 13.7719L21.7488 19.5515C22.2174 20.0201 22.2174 20.7799 21.7488 21.2486C21.2802 21.7172 20.5204 21.7172 20.0517 21.2486L14.2721 15.4689C13.0951 16.3071 11.6553 16.8 10.1003 16.8C6.12382 16.8 2.90027 13.5765 2.90027 9.60002Z" fill="currentColor"/> 6682</svg> 6683 </button> 6684 </div> 6685 <button 6686 type="button" 6687 x-show="isOpen" 6688 x-cloak 6689 x-transition:enter="transition ease-out duration-300" 6690 x-transition:enter-start="opacity-0" 6691 x-transition:enter-end="opacity-100" 6692 x-transition:leave="transition ease-in duration-300" 6693 x-transition:leave-start="opacity-100" 6694 x-transition:leave-end="opacity-0" 6695 @click="closeSearch()" 6696 class="action close rounded-none hover:text-current/80 transition-colors p-4 absolute right-2 top-2" 6697 data-testid="search-close-button" 6698 title="Schließen" 6699 aria-label="Schließen"> 6700 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewB
6700ox="0 0 18 18" fill="none" aria-hidden="true"> 6701<path fill-rule="evenodd" clip-rule="evenodd" d="M0.43934 0.43934C1.02513 -0.146447 1.97487 -0.146447 2.56066 0.43934L9 6.87868L15.4393 0.43934C16.0251 -0.146447 16.9749 -0.146447 17.5607 0.43934C18.1464 1.02513 18.1464 1.97487 17.5607 2.56066L11.1213 9L17.5607 15.4393C18.1464 16.0251 18.1464 16.9749 17.5607 17.5607C16.9749 18.1464 16.0251 18.1464 15.4393 17.5607L9 11.1213L2.56066 17.5607C1.97487 18.1464 1.02513 18.1464 0.43934 17.5607C-0.146447 16.9749 -0.146447 16.0251 0.43934 15.4393L6.87868 9L0.43934 2.56066C-0.146447 1.97487 -0.146447 1.02513 0.43934 0.43934Z" fill="currentColor"/> 6702</svg> 6703 </button> 6704 <div 6705 x-cloak 6706 x-show="isOpen" 6707 x-transition:enter="transition ease-out duration-300" 6708 x-transition:enter-start="opacity-0" 6709 x-transition:enter-end="opacity-100" 6710 x-transition:leave="transition ease-in duration-300" 6711 x-transition:leave-start="opacity-100" 6712 x-transition:leave-end="opacity-0" 6713 x-ref="searchDropdown" 6714 role="region" 6715 aria-label="Search suggestions" 6716 aria-live="polite" 6717 aria-atomic="false" 6718 data-testid="search-dropdown" 6719 class="rounded-(--card-radius) rounded-t-none! absolute top-full w-full left-0 right-0 bg-search-bg shadow-lg max-h-[90vh] overflow-y-auto z-100"> 6720 <div 6721 x-cloak 6722 x-show="isLoadingAutocomplete" 6723 class="absolute inset-0 z-20 bg-search-bg/60 flex items-center justify-center pointer-events-auto"> 6724 <svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="2" stroke-linecap="round" class="w-7 h-7 animate-spin" aria-hidden="true"> 6725 <circle style="opacity: .3;" cx="12" cy="12" r="10"/> 6726 <path fill="none" stroke-width="2" d="M12,2 a10,10 0 0,1 10,10"/> 6727</svg> 6728 </div> 6729 <template x-if="isLoadingTopItems && !hasAutocompleteResults() && !topItemsLoaded"> 6730 <div class="container flex flex-col gap-3 mx-auto p-2 pb-3 overflow-hidden" data-testid="search-loading"> 6731 <div class="flex flex-col md:flex-row gap-3"> 6732 <div class="flex flex-row gap-3 md:hidden h-fit"> 6733 <div class="rounded-(--card-radius) p-3 bg-search-card-bg h-fit flex-1"> 6734 <div class="h-5 bg-search-skeleton rounded mb-3 w-1/3 animate-pulse"></div> 6735 <ul class="flex flex-col gap-2"> 6736 <template x-for="i in categoryCount" :key="i"> 6737 <li> 6738 <div class="h-4 bg-search-skeleton rounded animate-pulse"></div> 6739 </li> 6740 </template> 6741 </ul> 6742 </div> 6743 <div class="rounded-(--card-radius) p-3 bg-search-card-bg h-fit flex-1" x-show="trendingQueries.length > 0"> 6744 <div class="h-5 bg-search-skeleton rounded mb-3 w-1/2 animate-pulse"></div> 6745 <ul class="flex flex-col gap-2"> 6746 <template x-for="i in trendingQueries.length" :key="i"> 6747 <li> 6748 <div class="h-4 bg-search-skeleton rounded animate-pulse"></div> 6749 </li> 6750 </template> 6751 </ul> 6752 </div> 6753 </div> 6754 <div class="flex-1"> 6755 <div class="flex md:grid md:grid-cols-3 gap-3 overflow-x-auto md:overflow-x-visible pb-3 md:pb-0"> 6756 <template x-for="i in productC
6756ount" :key="i"> 6757 <div class="rounded-(--card-radius) bg-search-accent-bg p-4 min-w-[160px] md:min-w-0 flex flex-col"> 6758 <div class="aspect-square bg-search-skeleton rounded mb-3 animate-pulse"></div> 6759 <div class="h-4 bg-search-skeleton rounded mb-2 animate-pulse"></div> 6760 <div class="h-5 bg-search-skeleton rounded w-1/3 mt-auto animate-pulse"></div> 6761 </div> 6762 </template> 6763 </div> 6764 </div> 6765 <div class="min-w-64 hidden md:flex flex-col gap-3"> 6766 <div class="rounded-(--card-radius) p-3 flex-1 bg-search-card-bg"> 6767 <div class="h-5 bg-search-skeleton rounded mb-3 w-1/3 animate-pulse"></div> 6768 <ul class="flex flex-col gap-2"> 6769 <template x-for="i in categoryCount" :key="i"> 6770 <li> 6771 <div class="h-4 bg-search-skeleton rounded animate-pulse"></div> 6772 </li> 6773 </template> 6774 </ul> 6775 </div> 6776 <div class="rounded-(--card-radius) p-3 flex-1 bg-search-card-bg" x-show="trendingQueries.length > 0"> 6777 <div class="h-5 bg-search-skeleton rounded mb-3 w-1/2 animate-pulse"></div> 6778 <ul class="flex flex-col gap-2"> 6779 <template x-for="i in trendingQueries.length" :key="i"> 6780 <li> 6781 <div class="h-4 bg-search-skeleton rounded animate-pulse"></div> 6782 </li> 6783 </template> 6784 </ul> 6785 </div> 6786 </div> 6787 </div> 6788 </div> 6789 </template> 6790 <template x-if="!hasDisplayResults() && !isLoadingTopItems && $refs.searchInput.value.length >= minSearchLength"> 6791 <div class="container flex flex-col gap-3 mx-auto p-2 pb-3"> 6792 <div class="flex h-full w-full items-center justify-center py-8"> 6793 <p class="text-lg">Keine Ergebnisse gefunden</p> 6794 </div> 6795 </div> 6796 </template> 6797 <template x-if="hasDisplayResults()"> 6798 <div class="container flex flex-col gap-3 mx-auto p-2 pb-3 overflow-hidden"> 6799 <div class="flex flex-col md:flex-row-reverse gap-3"> 6800 <div class="flex flex-row md:flex-col gap-3 items-stretch md:min-w-64"> 6801 <div class="rounded-(--card-radius) p-3 bg-search-card-bg flex-1" x-show="getDisplayResults().categories.length > 0"> 6802 <span class="text-primary font-semibold mb-2">Kategorien</span> 6803 <ul class="flex flex-col gap-1"> 6804 <template x-for="category in getDisplayResults().categories" :key="category.url"> 6805 <li> 6806 <a :href="category.url" class="hover:text-primary transition-colors [&_>em]:text-primary" x-html="category.attributes?.title || category.attributes?.name || ''"></a> 6807 </li> 6808 </template> 6809 </ul> 6810 </div> 6811 <div class="rounded-(--card-radius) p-3 bg-search-card-bg flex-1" x-show="trendingQueries.length > 0 && !isLoadingTopItems">
6812 <span class="text-primary font-semibold mb-2">Vorschläge</span> 6813 <ul class="flex flex-col gap-1"> 6814 <template x-for="(query, index) in trendingQueries" :key="index"> 6815 <li> 6816 <button 6817 type="button" 6818 @click="search(query)" 6819 class="text-left hover:text-primary transition-colors w-full" 6820 x-text="query"> 6821 </button> 6822 </li> 6823 </template> 6824 </ul> 6825 </div> 6826 </div> 6827 <div class="flex-1"> 6828 <div x-show="getDisplayResults().products.length > 0" class="relative" x-data="horizontalScroll({ containerRef: 'productsScrollContainer' })"> 6829 <button 6830 type="button" 6831 aria-label="Scroll left" 6832 class="rounded-(--card-radius) w-fit h-fit absolute left-0 top-1/2 -translate-y-1/2 z-10 flex items-center p-1.5 bg-search-accent-bg/80 transition-opacity md:hidden" 6833 :class="{ 'opacity-0 pointer-events-none': !canScrollLeft, 'opacity-100': canScrollLeft }" 6834 @click="scrollNav(-1)" 6835 x-show="canScrollLeft" 6836 x-cloak> 6837 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-6 h-6" width="24" height="24" aria-hidden="true"> 6838 <path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd"/> 6839</svg> 6840 </button> 6841 <div 6842 x-ref="productsScrollContainer" 6843 @scroll="updateScrollState()" 6844 class="flex md:grid md:grid-cols-3 gap-3 overflow-x-auto md:overflow-x-visible pb-2 md:pb-0 w-full max-w-full min-w-0"> 6845 <template x-for="(product, productIndex) in getDisplayResults().products.slice(0, productC
6845ount)" :key="product.url"> 6846 <a :href="product.url" @click="trackAutocompleteClick(product, productIndex)" class="rounded-(--card-radius) bg-search-accent-bg p-4 hover:shadow-lg transition-shadow flex flex-col w-[calc(50%-6px)] [content-visibility:auto] contain-[paint] md:w-auto flex-shrink-0 md:shrink"> 6847 <div class="aspect-square bg-white rounded mb-3 flex items-center justify-center overflow-hidden"> 6848 <img 6849 x-show="product.attributes?.image_link" 6850 :src="product.attributes.image_link" 6851 :alt="product.attributes?.title?.untouched || product.attributes?.title || ''" 6852 loading="lazy" 6853 decoding="async" 6854 fetchpriority="low" 6855 class="w-full h-full object-contain" /> 6856 <span x-show="!product.attributes?.image_link" class="text-gray-400 text-sm">Kein Bild verfügbar</span> 6857 </div> 6858 <div class="text-lg font-bold [&_>em]:text-primary" x-html="product.attributes?.title || ''"></div> 6859 <div 6860 class="w-full overflow-x-hidden swatch-attribute-options pb-1 pt-2" 6861 x-data="{ swatches: getProductSwatchesMeta(product) }" 6862 x-show="swatches.visible.length"> 6863 <div class="flex flex-nowrap w-full overflow-auto snap items-center gap-0.5 lg:gap-1 relative swatches-container"> 6864 <template x-for="(color, index) in swatches.visible" :key="`${product.url}-swatch-${index}`"> 6865 <div 6866 class="swatch-option relative cursor-pointer select-none product-option-value-label p-0 w-[30px] h-4 rounded-3 bg-cover bg-size-[30px_20px] bg-center" 6867 :style="`background-color: ${color}`"> 6868 </div> 6869 </template> 6870 <span 6871 class="swatch-counter flex items-center w-[30px] h-4 justify-center bg-bg-primary text-14 rounded-3 leading-170 font-semibold" 6872 x-show="swatches.hiddenCount > 0"> 6873 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6" width="14" height="14" aria-hidden="true"> 6874 <path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15"/> 6875</svg> 6876 </span> 6877 </div> 6878 </div> 6879 <div class="flex flex-row-reverse justify-end items-end gap-1.5 mt-auto pt-3"> 6880 <div 6881 class="text-text-secondary old-price line-through text-sm" 6882 x-show="product.attributes?.price_old && product.attributes.price_old !== product.attributes?.price" 6883 x-text="product.attributes?.price_old"> 6884 </div> 6885 <div 6886 class="text-2xl leading-none font-regular" 6887 :class="{ 'text-price-discounted': product.attributes?.price_old && product.attributes.price_old !== product.attributes?.price }" 6888 x-show="product.attributes?.price" 6889 x-text="product.attributes.price"> 6890 </div> 6891 </div> 6892 </a> 6893 </template> 6894 </div> 6895 <button 6896 type="button" 6897 aria-label="Scroll right" 6898 class="w-fit h-fit roun
6898ded absolute right-0 top-1/2 -translate-y-1/2 z-10 flex items-center p-1.5 bg-search-accent-bg/80 transition-opacity md:hidden" 6899 :class="{ 'opacity-0 pointer-events-none': !canScrollRight, 'opacity-100': canScrollRight }" 6900 @click="scrollNav(1)" 6901 x-show="canScrollRight" 6902 x-cloak> 6903 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-6 h-6" width="24" height="24" aria-hidden="true"> 6904 <path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"/> 6905</svg> 6906 </button> 6907 </div> 6908 <div x-show="getDisplayResults().products.length === 0 && !isLoadingTopItems" class="flex h-full w-full items-center justify-center py-8"> 6909 <p class="text-lg text-text-secondary-darker">Keine Ergebnisse gefunden</p> 6910 </div> 6911 </div> 6912 </div> 6913 <button x-show="hasAutocompleteResults()" type="submit" class="w-full btn btn-primary text-center" data-testid="search-show-all-results"> 6914 Zeige alle Ergebnisse </button> 6915 </div> 6916 </template> 6917 </div> 6918 </form> 6919 </search> 6920 <div 6921 x-cloak 6922 x-show="isOpen" 6923 x-transition:enter="transition ease-out duration-300" 6924 x-transition:enter-start="opacity-0" 6925 x-transition:enter-end="opacity-100" 6926 x-transition:leave="transition ease-in duration-300" 6927 x-transition:leave-start="opacity-100" 6928 x-transition:leave-end="opacity-0" 6929 class="fixed inset-0 bg-black/30 backdrop-blur-sm z-20" 6930 data-testid="search-overlay" 6931 @click="closeSearch()"></div> 6932 </div> 6933 </div> 6934 </template> 6935 <div class="bg-menu-bg"> 6936 <div class="menu container hidden lg:block flex-wrap lg:flex-nowrap lg:order-6 lg:w-full items-center justify-between w-auto mt-0 order-1 z-20 flex-1"> 6937 6938<nav 6939 class="navigation hidden lg:block text-menu-text" 6940 aria-label="Hauptmenü" 6941 x-data="initMenuDesktop" 6942 x-ref="nav-desktop" 6943 @load.window="setActiveMenu" 6944 data-testid="desktop-navigation"> 6945 <ul class="flex flex-wrap gap-x-7.5"> 6946 <li 6947 class="level-0 px-2 transition-colors" 6948 :class="open ? 'bg-menu-open-bg' : ''" 6949 x-data="initMenuDesktopItem" 6950 @click.outside="close" 6951 @keydown.escape="close" 6952 data-testid="desktop-menu-item"> 6953 <button 6954 type="button" 6955 class=" 6956 level-0 w-full flex justify-between items-center gap-1 py-6 transition-colors 6957 text-16 leading-130 font-medium group text-left 6958 aria-expanded:text-menu-zero-level-text-hover data-[has-current]:aria-expanded:text-menu-zero-level-text-hover 6959 " 6960 @click="toggle" 6961 aria-expanded="false" 6962 :aria-expanded="open" 6963 @keydown.enter.prevent="toggle" 6964 @keydown.space.prevent="toggle" 6965 aria-controls="desktop-menu-category-30" 6966 data-testid="desktop-menu-link"> 6967 <span class="flex items-center"> 6968 Regenschirme <span class="sr-only" data-testid="desktop-menu-sr-text"> 6969 (hat ein Untermenü) </span> 6970 </span> 6971 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="transition duration-200 group-aria-expanded:rotate-180 group-aria-expanded:text-inherit" width="22" height="22" aria-hidden="true"> 6972 <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/> 6973</svg> 6974 </button> 6975 <div 6976 id="desktop-menu-category-30" 6977 class="z-30 absolute inset-x-0 flex bg-menu-open-bg" 6978 x-show="open" 6979 x-transition 6980 x-cloak 6981 data-testid="desktop-menu-dropdown"> 6982 <div class="overflow-auto container py-6"> 6983 <div class="grow flex flex-row gap-x-6 items-start -mx-3"> 6984 <ul class="w-full"> 6985 <li 6986 class="break-inside-avoid w-full px-3 py-5"> 6987 <a 6988 href="https://knirps.de/regenschirme.html" 6989 class="level-1 block leading-150 text-16 font-medium hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors" 6990 data-testid="desktop-menu-see-all">Alle Regenschirme ansehen</a> 6991 </li> 6992 <li 6993 class="break-inside-avoid w-full px-3 py-5" 6994 x-data="{ open: false, id: 'desktop\u002Dmenu\u002Dcategory\u002D30\u002Dlvl1\u002D0fc7e70e2352ac50c29626aee473ba85' }" 6995 @level1-toggle.window=" 6996 if ($event.detail.id === id) { 6997 open = $event.detail.open; 6998 } else { 6999 open = false;
7000 } 7001 " 7002 style="width: 300px;"> 7003 <button 7004 type="button" 7005 class="level-1 w-full flex items-center justify-between gap-2 leading-150 text-16 font-medium hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors text-left group" 7006 @click="$dispatch('level1-toggle', { id: 'desktop\u002Dmenu\u002Dcategory\u002D30\u002Dlvl1\u002D0fc7e70e2352ac50c29626aee473ba85', open: !open })" 7007 :aria-expanded="open" 7008 aria-controls="desktop-menu-category-30-lvl1-0fc7e70e2352ac50c29626aee473ba85" 7009 aria-label="Taschenschirme-Menü erweitern" 7010 data-testid="desktop-submenu-link"> 7011 <span>Taschenschirme</span> 7012 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="transition duration-200 group-aria-expanded:rotate-180" width="18" height="18" aria-hidden="true"> 7013 <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/> 7014</svg> 7015 </button> 7016 <ul 7017 id="desktop-menu-category-30-lvl1-0fc7e70e2352ac50c29626aee473ba85" 7018 class="mt-2 space-y-1 transition ease-in-out duration-300" 7019 x-show="open" 7020 x-transition 7021 x-cloak> 7022 <li> 7023 <a 7024 href="https://knirps.de/regenschirme/taschenschirme.html" 7025 class="level-2 block text-14 leading-170 font-light hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors" 7026 data-testid="desktop-submenu-see-all"> 7027 Alle ansehen </a> 7028 </li> 7029 <li> 7030 <a 7031 href="https://knirps.de/regenschirme/taschenschirme/besondere-regenschirme.html" 7032 class="level-2 block text-14 leading-170 font-light hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors" 7033 data-testid="desktop-submenu-child-link">Specials</a> 7034 </li> 7035 <li> 7036 <a 7037 href="https://knirps.de/regenschirme/taschenschirme/taschenschirme-klein.html" 7038 class="level-2 block text-14 leading-170 font-light hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors" 7039 data-testid="desktop-submenu-child-link">Small</a> 7040 </li> 7041 <li> 7042 <a 7043 href="https://knirps.de/regenschirme/taschenschirme/taschenschirme-mittel.html" 7044 class="level-2 block text-14 leading-170 font-light hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors" 7045 data-testid="desktop-submenu-child-link">Medium</a> 7046 </li> 7047 <li> 7048 <a 7049 href="https://knirps.de/regenschirme/taschenschirme/taschenschirme-gross.html" 7050 class="level-2 block text-14 leading-170 font-light hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors" 7051 data-testid="desktop-submenu-child-link">Large</a> 7052 </li> 7053 <li> 7054 <a 7055 href="https://knirps.de/regenschirme/taschenschirme/kinderschirm.html" 7056 class="level-2 block text-14 leading-170 font-light hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors" 7057 data-testid="desktop-submenu-child-link">Kinderschirm</a> 7058 </li> 7059 </ul> 7060 </li> 7061 <li 7062 class="break-inside-avoid w-full px-3 py-5" 7063 x-data="{ open: false, id: 'desktop\u002Dmenu\u002Dcategory\u002D30\u002Dlvl1\u002D7e26318264b17a20c113929446dc50a2' }" 7064 @level1-toggle.window=" 7065 if ($event.detail.id === id) { 7066 open = $event.detail.open; 7067 } else { 7068 open = false;
7069 } 7070 " 7071 style="width: 300px;"> 7072 <button 7073 type="button" 7074 class="level-1 w-full flex items-center justify-between gap-2 leading-150 text-16 font-medium hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors text-left group" 7075 @click="$dispatch('level1-toggle', { id: 'desktop\u002Dmenu\u002Dcategory\u002D30\u002Dlvl1\u002D7e26318264b17a20c113929446dc50a2', open: !open })" 7076 :aria-expanded="open" 7077 aria-controls="desktop-menu-category-30-lvl1-7e26318264b17a20c113929446dc50a2" 7078 aria-label="Stockschirm-Menü erweitern" 7079 data-testid="desktop-submenu-link"> 7080 <span>Stockschirm</span> 7081 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="transition duration-200 group-aria-expanded:rotate-180" width="18" height="18" aria-hidden="true"> 7082 <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/> 7083</svg> 7084 </button> 7085 <ul 7086 id="desktop-menu-category-30-lvl1-7e26318264b17a20c113929446dc50a2" 7087 class="mt-2 space-y-1 transition ease-in-out duration-300" 7088 x-show="open" 7089 x-transition 7090 x-cloak> 7091 <li> 7092 <a 7093 href="https://knirps.de/regenschirme/stockschirme.html" 7094 class="level-2 block text-14 leading-170 font-light hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors" 7095 data-testid="desktop-submenu-see-all"> 7096 Alle ansehen </a> 7097 </li> 7098 <li> 7099 <a 7100 href="https://knirps.de/regenschirme/stockschirme/stockschirme-gross.html" 7101 class="level-2 block text-14 leading-170 font-light hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors" 7102 data-testid="desktop-submenu-child-link">Large</a> 7103 </li> 7104 <li> 7105 <a 7106 href="https://knirps.de/regenschirme/stockschirme/stockschirme-extra-large.html" 7107 class="level-2 block text-14 leading-170 font-light hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors" 7108 data-testid="desktop-submenu-child-link">Extra Large</a> 7109 </li> 7110 </ul> 7111 </li> 7112 <li 7113 class="break-inside-avoid w-full px-3 py-5" 7114 x-data="{ open: false, id: 'desktop\u002Dmenu\u002Dcategory\u002D30\u002Dlvl1\u002Dba63fc51f6adaa55389bbf4ba6b9f9e0' }" 7115 @level1-toggle.window=" 7116 if ($event.detail.id === id) { 7117 open = $event.detail.open; 7118 } else { 7119 open = false;
7120 } 7121 " 7122 style="width: 300px;"> 7123 <a 7124 href="https://knirps.de/regenschirme/uv-schutz.html" 7125 class="level-1 block leading-150 text-16 font-medium hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors" 7126 data-testid="desktop-submenu-link">Regenschirme mit UV-Schutz</a> 7127 </li> 7128 <li 7129 class="break-inside-avoid w-full px-3 py-5" 7130 x-data="{ open: false, id: 'desktop\u002Dmenu\u002Dcategory\u002D30\u002Dlvl1\u002D5c4e975792bb41dd1cb9ac4f3d5c2e99' }" 7131 @level1-toggle.window=" 7132 if ($event.detail.id === id) { 7133 open = $event.detail.open; 7134 } else { 7135 open = false; 7136 } 7137 " 7138 style="width: 300px;"> 7139 <a 7140 href="https://knirps.de/regenschirme/leichte-regenschirme.html" 7141 class="level-1 block leading-150 text-16 font-medium hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors" 7142 data-testid="desktop-submenu-link">Leichte Regenschirme</a> 7143 </li> 7144 <li 7145 class="break-inside-avoid w-full px-3 py-5" 7146 x-data="{ open: false, id: 'desktop\u002Dmenu\u002Dcategory\u002D30\u002Dlvl1\u002Df7357081c01b5fd621b1428c61cab6c1' }" 7147 @level1-toggle.window=" 7148 if ($event.detail.id === id) { 7149 open = $event.detail.open; 7150 } else { 7151 open = false; 7152 } 7153 " 7154 style="width: 300px;"> 7155 <a 7156 href="https://knirps.de/regenschirme/ersatzhuellen.html" 7157 class="level-1 block leading-150 text-16 font-medium hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors" 7158 data-testid="desktop-submenu-link">Ersatzhüllen</a> 7159 </li> 7160 </ul> 7161 </div> 7162 </div> 7163 </div> 7164 </li> 7165 <li 7166 class="level-0 px-2 transition-colors" 7167 :class="open ? 'bg-menu-open-bg' : ''" 7168 x-data="initMenuDesktopItem" 7169 @click.outside="close" 7170 @keydown.escape="close" 7171 data-testid="desktop-menu-item"> 7172 <button 7173 type="button" 7174 class=" 7175 level-0 w-full flex justify-between items-center gap-1 py-6 transition-colors 7176 text-16 leading-130 font-medium group text-left 7177 aria-expanded:text-menu-zero-level-text-hover data-[has-current]:aria-expanded:text-menu-zero-level-text-hover 7178 " 7179 @click="toggle" 7180 aria-expanded="false" 7181 :aria-expanded="open" 7182 @keydown.enter.prevent="toggle" 7183 @keydown.space.prevent="toggle" 7184 aria-controls="desktop-menu-category-36" 7185 data-testid="desktop-menu-link">
7186 <span class="flex items-center"> 7187 Sonnenschirme <span class="sr-only" data-testid="desktop-menu-sr-text"> 7188 (hat ein Untermenü) </span> 7189 </span> 7190 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="transition duration-200 group-aria-expanded:rotate-180 group-aria-expanded:text-inherit" width="22" height="22" aria-hidden="true"> 7191 <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/> 7192</svg> 7193 </button> 7194 <div 7195 id="desktop-menu-category-36" 7196 class="z-30 absolute inset-x-0 flex bg-menu-open-bg" 7197 x-show="open" 7198 x-transition 7199 x-cloak 7200 data-testid="desktop-menu-dropdown"> 7201 <div class="overflow-auto container py-6"> 7202 <div class="grow flex flex-row gap-x-6 items-start -mx-3"> 7203 <ul class="w-full"> 7204 <li 7205 class="break-inside-avoid w-full px-3 py-5"> 7206 <a 7207 href="https://knirps.de/sonnenschirme.html" 7208 class="level-1 block leading-150 text-16 font-medium hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors" 7209 data-testid="desktop-menu-see-all">Alle Sonnenschirme ansehen</a> 7210 </li> 7211 <li 7212 class="break-inside-avoid w-full px-3 py-5" 7213 x-data="{ open: false, id: 'desktop\u002Dmenu\u002Dcategory\u002D36\u002Dlvl1\u002D74a1e9de3ac39bc61a7a4ef6ce660b30' }" 7214 @level1-toggle.window=" 7215 if ($event.detail.id === id) { 7216 open = $event.detail.open; 7217 } else { 7218 open = false; 7219 } 7220 " 7221 style="width: 300px;"> 7222 <a 7223 href="https://knirps.de/sonnenschirme/ampelschirme.html" 7224 class="level-1 block leading-150 text-16 font-medium hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors" 7225 data-testid="desktop-submenu-link">Ampelschirme</a> 7226 </li> 7227 <li 7228 class="break-inside-avoid w-full px-3 py-5" 7229 x-data="{ open: false, id: 'desktop\u002Dmenu\u002Dcategory\u002D36\u002Dlvl1\u002Dd490c3f0e9bea7cd53dbc8760ec0c3e8' }" 7230 @level1-toggle.window=" 7231 if ($event.detail.id === id) { 7232 open = $event.detail.open; 7233 } else { 7234 open = false;
7235 } 7236 " 7237 style="width: 300px;"> 7238 <a 7239 href="https://knirps.de/sonnenschirme/balkonschirme.html" 7240 class="level-1 block leading-150 text-16 font-medium hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors" 7241 data-testid="desktop-submenu-link">Balkonschirme</a> 7242 </li> 7243 <li 7244 class="break-inside-avoid w-full px-3 py-5" 7245 x-data="{ open: false, id: 'desktop\u002Dmenu\u002Dcategory\u002D36\u002Dlvl1\u002D2b148c05d89f845240042ff27942ec51' }" 7246 @level1-toggle.window=" 7247 if ($event.detail.id === id) { 7248 open = $event.detail.open; 7249 } else { 7250 open = false; 7251 } 7252 " 7253 style="width: 300px;"> 7254 <a 7255 href="https://knirps.de/sonnenschirme/mittelstockschirme.html" 7256 class="level-1 block leading-150 text-16 font-medium hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors" 7257 data-testid="desktop-submenu-link">Mittelstockschirm</a> 7258 </li> 7259 <li 7260 class="break-inside-avoid w-full px-3 py-5" 7261 x-data="{ open: false, id: 'desktop\u002Dmenu\u002Dcategory\u002D36\u002Dlvl1\u002D311d948d3e8b3650c91872a794a38792' }" 7262 @level1-toggle.window=" 7263 if ($event.detail.id === id) { 7264 open = $event.detail.open; 7265 } else { 7266 open = false; 7267 } 7268 " 7269 style="width: 300px;"> 7270 <button 7271 type="button" 7272 class="level-1 w-full flex items-center justify-between gap-2 leading-150 text-16 font-medium hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors text-left group" 7273 @click="$dispatch('level1-toggle', { id: 'desktop\u002Dmenu\u002Dcategory\u002D36\u002Dlvl1\u002D311d948d3e8b3650c91872a794a38792', open: !open })" 7274 :aria-expanded="open" 7275 aria-controls="desktop-menu-category-36-lvl1-311d948d3e8b3650c91872a794a38792" 7276 aria-label="Schirmständer-Menü erweitern" 7277 data-testid="desktop-submenu-link">
7278 <span>Schirmständer</span> 7279 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="transition duration-200 group-aria-expanded:rotate-180" width="18" height="18" aria-hidden="true"> 7280 <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/> 7281</svg> 7282 </button> 7283 <ul 7284 id="desktop-menu-category-36-lvl1-311d948d3e8b3650c91872a794a38792" 7285 class="mt-2 space-y-1 transition ease-in-out duration-300" 7286 x-show="open" 7287 x-transition 7288 x-cloak> 7289 <li> 7290 <a 7291 href="https://knirps.de/sonnenschirme/sonnenschirme-schirmstaender.html" 7292 class="level-2 block text-14 leading-170 font-light hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors" 7293 data-testid="desktop-submenu-see-all"> 7294 Alle ansehen </a> 7295 </li> 7296 <li> 7297 <a 7298 href="https://knirps.de/sonnenschirme/sonnenschirme-schirmstaender/sonnenschirme-mittelstockschirmstaender.html" 7299 class="level-2 block text-14 leading-170 font-light hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors" 7300 data-testid="desktop-submenu-child-link">Für Mittelstockschirme</a> 7301 </li> 7302 <li> 7303 <a 7304 href="https://knirps.de/sonnenschirme/sonnenschirme-schirmstaender/ampelschirme-schirmstaender.html" 7305 class="level-2 block text-14 leading-170 font-light hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors" 7306 data-testid="desktop-submenu-child-link">Für Ampelschirme</a> 7307 </li> 7308 </ul> 7309 </li> 7310 <li 7311 class="break-inside-avoid w-full px-3 py-5" 7312 x-data="{ open: false, id: 'desktop\u002Dmenu\u002Dcategory\u002D36\u002Dlvl1\u002Dd0a515ecde4e388ded409a65cb7184ab' }" 7313 @level1-toggle.window=" 7314 if ($event.detail.id === id) { 7315 open = $event.detail.open; 7316 } else { 7317 open = false;
7318 } 7319 " 7320 style="width: 300px;"> 7321 <a 7322 href="https://knirps.de/sonnenschirme/sonnenschirme-schutzhuellen.html" 7323 class="level-1 block leading-150 text-16 font-medium hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors" 7324 data-testid="desktop-submenu-link">Schutzhülle</a> 7325 </li> 7326 <li 7327 class="break-inside-avoid w-full px-3 py-5" 7328 x-data="{ open: false, id: 'desktop\u002Dmenu\u002Dcategory\u002D36\u002Dlvl1\u002Dbc1764a9063a87a63b39d0c92b8c64bb' }" 7329 @level1-toggle.window=" 7330 if ($event.detail.id === id) { 7331 open = $event.detail.open; 7332 } else { 7333 open = false; 7334 } 7335 " 7336 style="width: 300px;"> 7337 <a 7338 href="https://knirps.de/sonnenschirme/sonnenschirme-ersatzteile.html" 7339 class="level-1 block leading-150 text-16 font-medium hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors" 7340 data-testid="desktop-submenu-link">Ersatzteile</a> 7341 </li> 7342 <li 7343 class="break-inside-avoid w-full px-3 py-5" 7344 x-data="{ open: false, id: 'desktop\u002Dmenu\u002Dcategory\u002D36\u002Dlvl1\u002D77432809e8a79453c084e738872e137b' }" 7345 @level1-toggle.window=" 7346 if ($event.detail.id === id) { 7347 open = $event.detail.open; 7348 } else { 7349 open = false; 7350 } 7351 " 7352 style="width: 300px;"> 7353 <a 7354 href="https://knirps.de/sonnenschirme/sonnenschirme-bezuege.html" 7355 class="level-1 block leading-150 text-16 font-medium hover:text-menu-text-hover focus:text-menu-text-hover aria-[current=page]:text-menu-text-hover transition-colors" 7356 data-testid="desktop-submenu-link">Ersatzbezug</a> 7357 </li> 7358 </ul> 7359 </div> 7360 </div> 7361 </div> 7362 </li> 7363 <li> 7364 <a 7365 href="https://knirps.de/bekleidung-accessoires.html" 7366 title="Accessoires" 7367 class=" 7368 level-0 flex py-6 transition-colors text-16 leading-130 font-medium 7369 hover:text-menu-zero-level-text-hover aria-[current=page]:text-menu-zero-level-text-hover 7370 " 7371 data-testid="desktop-menu-link"> 7372 Accessoires </a> 7373 </li> 7374 <li> 7375 <a 7376 href="https://knirps.de/sale.html" 7377 title="Sale" 7378 class=" 7379 level-0 flex py-6 transition-colors text-16 leading-130 font-medium 7380 hover:text-menu-zero-level-text-hover aria-[current=page]:text-menu-zero-level-text-hover 7381 " 7382 data-testid="desktop-menu-link"> 7383 Sale </a> 7384 </li> 7385 <li> 7386 <a href="/blog/" 7387 title="blog" 7388 class="level-0 flex py-6 transition-colors text-16 leading-130 font-medium hover:text-menu-zero-level-text-hover aria-[current=page]:text-menu-zero-level-text-hover" 7389 >Blog</a> 7390</li> 7391<li> 7392 <a href="/kooperationen/" 7393 title="kooperationen" 7394 class="level-0 flex py-6 transition-colors text-16 leading-130 font-medium hover:text-menu-zero-level-text-hover aria-[current=page]:text-menu-zero-level-text-hover" 7395 >Kooperationen</a> 7396</li> 7397 </ul> 7398</nav>
7399<script> 7400 function initMenuDesktop() { 7401 return { 7402 setActiveMenu() { 7403 Array.from(this.$root.querySelectorAll('a')) 7404 .filter(link => link.href === window.location.href.split('?')[0]) 7405 .forEach(item => { 7406 item.setAttribute('aria-current', 'page'); 7407 7408 for (let level = 0; level < 3; level++) { 7409 const closestMenu = item.closest(`.level-${level}`); 7410 7411 if (closestMenu) { 7412 const button = closestMenu.querySelector('button'); 7413 if (button) { 7414 button.setAttribute('data-has-current', ''); 7415 } 7416 } 7417 } 7418 }); 7419 } 7420 } 7421 } 7422 7423 function initMenuDesktopItem() { 7424 return { 7425 open: false, 7426 canHover(func) { 7427 return window.matchMedia('(hover: hover) and (pointer: fine)').matches; 7428 }, 7429 toggle() { 7430 this.open = !this.open; 7431 }, 7432 close() { 7433 this.open = false; 7434 } 7435 } 7436 } 7437 7438 window.addEventListener('alpine:init', () => { 7439 Alpine.data('initMenuDesktop', initMenuDesktop); 7440 Alpine.data('initMenuDesktopItem', initMenuDesktopItem); 7441 }, { 7442 once: true 7443 }) 7444</script>
7444 7445 </div> 7446 </div> 7447 7448 <!--Cart Drawer--> 7449
7450<script type="module"> 7451 import { 7452 initCartDrawer, 7453 hyvaAjaxFormMinicart 7454 } from 'https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/js/components/cart-drawer.js'; 7455 7456 // Make hyvaAjaxFormMinicart available globally for backwards compatibility 7457 window.hyvaAjaxFormMinicart = hyvaAjaxFormMinicart; 7458 7459 window.addEventListener('alpine:init', () => { 7460 Alpine.data('initCartDrawer', () => initCartDrawer({ 7461 maxItemsToDisplay: 10, 7462 showSku: false, 7463 totalsSort: {"discount":"20","grand_total":"100","shipping":"30","subtotal":"10","tax":"40","weee":"35","weee_tax":"35","mollie_payment_fee":"25"} })); 7464 }, { 7465 once: true 7466 }); 7467</script>
7467 7468<section x-data="initCartDrawer"> 7469 <div 7470 class="fixed inset-0 bg-black/30 z-20" 7471 x-show="open" 7472 x-transition.opacity 7473 x-cloak 7474 data-testid="minicart-overlay"></div> 7475 <div 7476 id="cart-drawer" 7477 role="dialog" 7478 aria-modal="true" 7479 aria-labelledby="cart-drawer-title" 7480 class="card mr-2 ml-2 flex flex-col mt-3 p-6 max-w-full z-50 absolute top-(--cart-drawer-offset-top) inset-x-0 right-0 left-0 7481 max-h-[clamp(480px,100vh-var(--cart-drawer-offset-top)-24px,860px)] 7482 shadow-lg border-t-2 border-primary overflow-visible 7483 sm:w-[400px] sm:right-[calc(var(--cart-drawer-offset-right,1rem)-2rem)] sm:left-auto 7484 md:sm:right-[calc(var(--cart-drawer-offset-right,1rem)-1rem)]" 7485 x-show="open" 7486 x-transition.origin.top.right 7487 x-ref="cartDialogContent" 7488 x-bind="cartListeners" 7489 x-cloak 7490 @click.outside="closeCartDrawer" 7491 @keydown.window.escape="closeCartDrawer" 7492 data-testid="minicart-drawer"> 7493 <div class="absolute right-5 md:right-1 -top-2 w-0 h-0 7494 border-l-8 border-l-transparent 7495 border-r-8 border-r-transparent 7496 border-b-8 border-primary"> 7497 </div> 7498 <div 7499 aria-live="polite" 7500 class="sr-only" 7501 x-show="isLoading" 7502 role="status"> 7503 Der Warenkorb wird aktualisiert. Bitte warten... </div> 7504 7505 <div class="flex items-start justify-between gap-3"> 7506 <span 7507 tabindex="-1" 7508 id="cart-drawer-title" 7509 data-testid="minicart-title"> 7510 Warenkorb </span> 7511 <button 7512 type="button" 7513 class="p-3 -mt-3 -mr-3" 7514 @click="closeCartDrawer" 7515 aria-label="Mini-Warenkorb schließen" 7516 data-testid="minicart-close"> 7517 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="20" height="20" aria-hidden="true"> 7518 <path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"/> 7519</svg> 7520 </button> 7521 </div> 7522 7523 7524 <template x-if="cartIsEmpty"> 7525 <div class="grid place-items-center mt-10 mb-8"> 7526 <div class="text-center" data-testid="minicart-empty"> 7527 <div class="max-w-full max-h-full aspect-square w-44 h-44 inline-flex items-center justify-center rounded-full 7528 text-primary outline-2 outline-dashed outline-primary outline-offset-8"> 7529 <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 19 19" fill="none" aria-hidden="true"> 7530<path d="M0.5 0.5H2.5L2.9 2.5M4.5 10.5H14.5L18.5 2.5H2.9M4.5 10.5L2.9 2.5M4.5 10.5L2.20711 12.7929C1.57714 13.4229 2.02331 14.5 2.91421 14.5H14.5M14.5 14.5C13.3954 14.5 12.5 15.3954 12.5 16.5C12.5 17.6046 13.3954 18.5 14.5 18.5C15.6046 18.5 16.5 17.6046 16.5 16.5C16.5 15.3954 15.6046 14.5 14.5 14.5ZM6.5 16.5C6.5 17.6046 5.60457 18.5 4.5 18.5C3.39543 18.5 2.5 17.6046 2.5 16.5C2.5 15.3954 3.39543 14.5 4.5 14.5C5.60457 14.5 6.5 15.3954 6.5 16.5Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/> 7531</svg> 7532 </div> 7533 <p class="mt-10 leading-140 text-20 font-medium"> 7534 Ihr Warenkorb ist leer </p> 7535 <p> 7536 Schauen Sie sich um und lassen Sie sich inspirieren </p> 7537 </div> 7538 </div> 7539 </template> 7540 7541 <template x-if="itemsCount"> 7542 <ul 7543 class="grow flex flex-col overflow-y-auto overscroll-y-contain -mr-2 pr-1" 7544 role="region" 7545 aria-label="Artikel im Warenkorb" 7546 data-testid="minicart-items"> 7547 <template x-for="item in cartItems"> 7548 <li 7549 class="flex min-w-0 gap-4 md:gap-6 items-start border-b pb-4 mb-4 last:border-0 last:mb-6 last:pb-0" 7550 data-testid="minicart-item"> 7551 <template x-if="productIsVisibleInSite"> 7552 <a 7553 class="flex items-center justify-center shrink-0 w-[96px]" 7554 :href="getItemProductUrl(item)" 7555 :aria-label="`Details\u0020anzeigen\u0020von ${item.product_name}`" 7556 :title="item.product_name"> 7557 <img 7558 :src="item.product_image.src" 7559 :width="item.product_image.width" 7560 :height="item.product_image.height" 7561 loading="lazy" 7562 class="aspect-square object-contain" 7563 :alt="`${item.product_name} - Artikelbild`"> 7564 </a> 7565 </template> 7566 <template x-if="productIsNotVisibleInSite"> 7567 <div class="block shrink-0 w-[96px]"> 7568 <img 7569 :src="item.product_image.src" 7570 :width="item.product_image.width" 7571 :height="item.product_image.height" 7572 loading="lazy" 7573 class="aspect-square object-contain" 7574 :alt="`${item.product_name} - Artikelbild`" /> 7575 </div> 7576 </template> 7577 <div class="relative w-full min-w-0"> 7578 <h3 7579 class="font-bold text-16 leading-140 mb-8 pr-10" 7580 x-html="item.product_name" 7581 data-testid="minicart-item-name"></h3> 7582 <div class="flex flex-col gap-2"> 7583 <div class="flex w-full items-start gap-2"> 7584 <dt class="w-auto min-w-16 text-text-secondary text-sm font-medium"> 7585 Menge </dt> 7586 <dd class="ml-auto text-sm font-medium text-right" 7587 data-testid="minicart-item-qty"> 7588 <div 7589 class="flex items-center border h-9 justify-between relative rounded-(--form-radius) w-25 focus-within:border-primary transition-colors" 7590 :class="{'pointer-events-none opacity-50': isLoading}"> 7591 <button 7592 type="button" 7593 @click="decreaseItemQty(item)" 7594 :disabled="item.qty <= 1" 7595 class="transition-colors hover:text-primary focus:text-primary p-1.5 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:text-current" 7596 :aria-label="`Menge\u0020verringern`"> 7597 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="16" height="16" aria-hidden="true"> 7598 <path fill-rule="evenodd" d="M3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z" clip-rule="evenodd"/> 7599</svg> 7600 </button> 7601 <input 7602 type="number" 7603 inputmode="numeric" 7604 :value="item.qty" 7605 @change="updateItemQty(item, $event.target.value)" 7606 class="border-0 h-full max-w-10 p-0 w-auto text-center min-w-6 text-14 7607 [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none 7608 hover:border-0 focus:outline-none focus:ring-0 focus:shadow-none focus:border-0" 7609 min="1" 7610 :aria-label="`Menge`" /> 7611 <button 7612 type="button" 7613 @click="increaseItemQty(item)" 7614 class="transition-colors hover:text-primary focus:text-primary p-1.5" 7615 :aria-label="`Menge\u0020erh\u00F6hen`"> 7616 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="16" height="16" aria-hidden="true"> 7617 <path fill-rule="evenodd" d="M10 3a1 1 0 011 1v5h5a1 1 0 110 2h-5v5a1 1 0 11-2 0v-5H4a1 1 0 110-2h5V4a1 1 0 011-1z" clip-rule="evenodd"/> 7618</svg> 7619 </button> 7620 </div> 7621 </dd> 7622 </div>
7623 <template x-if="showDetails"> 7624 <dl class="flex flex-col gap-2 text-sm"> 7625 <template x-if="showSku"> 7626 <div class="flex w-full items-start gap-2"> 7627 <dt class="w-auto min-w-16 text-text-secondary text-sm font-medium"> 7628 Artikelnr. </dt> 7629 <dd class="ml-auto text-sm font-medium text-right" x-html="item.product_sku"></dd> 7630 </div> 7631 </template> 7632 <template x-for="option in item.options"> 7633 <div class="flex w-full items-start gap-2"> 7634 <dt 7635 class="w-auto min-w-16 text-text-secondary text-sm font-medium" 7636 x-text="option.label"></dt> 7637 <dd class="ml-auto text-sm font-medium text-right" x-html="option.value"></dd> 7638 </div> 7639 </template> 7640 </dl> 7641 </template> 7642 <div class="flex w-full items-start gap-2"> 7643 <dt class="w-auto min-w-16 text-text-secondary text-sm font-medium"> 7644 Preis </dt> 7645 <dd 7646 class="ml-auto text-sm font-medium text-right [&_.price]:font-medium" 7647 data-testid="minicart-item-price"> 7648 <template x-if="!item.product_has_special_price && Number(item.product_price_value) >= Number(item.product_regular_price_value)"> 7649 <span x-text="hyva.formatPrice(Number(item.product_price_value) * Number(item.qty))"></span> 7650 </template> 7651 <template x-if="item.product_has_special_price || Number(item.product_price_value) < Number(item.product_regular_price_value)"> 7652 <span class="flex items-center gap-1"> 7653 <span class="text-red-600 font-bold" x-text="hyva.formatPrice(Number(item.product_price_value) * Number(item.qty))"></span> 7654 <span class="line-through text-text-secondary" x-text="hyva.formatPrice(Number(item.product_regular_price_value) * Number(item.qty))"></span> 7655 </span> 7656 </template> 7657 </dd> 7658 </div> 7659 </div> 7660 <button 7661 type="button" 7662 class=" 7663 absolute top-0 right-0 7664 border rounded-full w-9 h-9 p-0 inline-flex items-center justify-center 7665 hover:border-primary focus:border-primary hover:text-primary focus:text-primary transition-colors duration-200 7666 " 7667 @click="deleteItemFromCart" 7668 :aria-label="`Remove\u0020product\u0020from\u0020cart\u0020\u002D\u0020 ${item.product_name}`" 7669 data-testid="minicart-item-remove"> 7670 <span class="sr-only" x-html="`Remove\u0020product\u0020from\u0020cart\u0020\u002D\u0020 ${item.product_name}`"></span> 7671 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="20" height="20" aria-hidden="true"> 7672 <path fill-rule="evenodd" d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z" clip-rule="evenodd"/> 7673</svg> 7674 </button> 7675 </div> 7676 </li> 7677 </template> 7678 </ul> 7679 </template> 7680 7681
7681<script> 7682 function prepareMollieApplePayMinicart() { 7683 const objectToFormData = (object, prefix = null, formDataObject = null) => { 7684 const formData = formDataObject || new FormData(); 7685 Object.keys(object).forEach(key => { 7686 const value = object[key]; 7687 const name = prefix ? `${prefix}[${key}]` : key; 7688 if (value instanceof Object) { 7689 objectToFormData(value, name, formData); 7690 } else { 7691 formData.append(name, value); 7692 } 7693 }); 7694 7695 return new URLSearchParams(formData).toString(); 7696 }; 7697 7698 return { 7699 totalAmount: 0, 7700 7701 init: () => { 7702 // Normally we would use private-content-loaded to get this information, but this component is 7703 // rendered after this event has been dispatched. So get the information from the browser storage. 7704 const browserStorage = hyva.getBrowserStorage(); 7705 if (browserStorage) { 7706 const cacheStorage = browserStorage.getItem('mage-cache-storage'); 7707 const cart = JSON.parse(cacheStorage).cart; 7708 7709 this.totalAmount = cart.subtotalAmount; 7710 } 7711 7712 window.addEventListener('private-content-loaded', event => { 7713 this.totalAmount = event.detail.data.cart.subtotalAmount 7714 }) 7715 }, 7716 7717 pay: () => { 7718 const amount = this.totalAmount; 7719 let countryCode, postalCode, shippingMethods, selectedShippingMethod, quoteTotals; 7720 7721 const request = { 7722 countryCode: "DE", 7723 currencyCode: "EUR", 7724 supportedNetworks: ["amex","masterCard","visa","maestro","vPay"], 7725 merchantCapabilities: ['supports3DS'], 7726 total: { 7727 label: "Deutsch", 7728 amount: amount 7729 }, 7730 shippingType: 'shipping', 7731 requiredBillingContactFields: [ 7732 'postalAddress', 7733 'name', 7734 'email', 7735 'phone' 7736 ], 7737 requiredShippingContactFields: [ 7738 'postalAddress', 7739 'name', 7740 'email', 7741 'phone' 7742 ] 7743 } 7744 7745 let session = new ApplePaySession(3, request); 7746 7747 const getTotal = () => { 7748 const total = quoteTotals.find(item => item.code === 'grand_total') || quoteTotals[quoteTotals.length - 1]; 7749 7750 total.label = "Deutsch"; 7751 7752 const payload = { total }; 7753 window.dispatchEvent(new CustomEvent('mollie-applepay-total', { 7754 detail: payload, 7755 })); 7756 7757 return payload.total; 7758 }; 7759 7760 const getLineItems = () => { 7761 let totals = [...quoteTotals]; 7762 totals = totals.filter(item => item.code !== 'grand_total'); 7763 7764 const payload = { lineItems: totals }; 7765 window.dispatchEvent(new CustomEvent('mollie-applepay-lineitems', { 7766 detail: payload, 7767 })); 7768 7769 return payload.lineItems; 7770 }; 7771 7772 const handleAjaxError = (message) => { 7773 session.abort(); 7774 7775 dispatchMessages([ 7776 { 7777 text: message, 7778 type: 'error' 7779 } 7780 ]); 7781 }; 7782 7783 session.onpaymentmethodselected = () => { 7784 session.completePaymentMethodSelection(getTotal(), []); 7785 }; 7786 7787 session.onshippingcontactselected = (event) => { 7788 countryCode = event.shippingContact.countryCode; 7789 postalCode = event.shippingContact.postalCode; 7790 7791 fetch(`${BASE_URL}mollie/applePay/shippingMethods?form_key=${hyva.getFormKey()}`, { 7792 method: 'POST', 7793 headers: { 7794 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8', 7795 }, 7796 body: 'countryCode=' + event.shippingContact.countryCode + 7797 '&postalCode=' + event.shippingContact.postalCode 7798 }) 7799 .then(response => { 7800 if (!response.ok) { 7801 throw new Error('Network response was not ok'); 7802 } 7803 return response.json(); 7804 }) 7805 .then(result => { 7806 shippingMethods = result.shipping_methods; 7807 selectedShippingMethod = result.shipping_methods[0]; 7808 quoteTotals = result.totals; 7809 7810 session.completeShippingContactSelection( 7811 ApplePaySession.STATUS_SUCCESS, 7812 result.shipping_methods, 7813 getTotal(), 7814 getLineItems() 7815 ); 7816 }) 7817 .catch(error => handleAjaxError(error)); 7818 }; 7819 7820 session.onshippingmethodselected = (event) => { 7821 selectedShippingMethod = event.shippingMethod; 7822 7823 fetch(`${BASE_URL}mollie/applePay/shippingMethods?form_key=${hyva.getFormKey()}`, { 7824 method: 'POST', 7825 headers: { 7826 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8', 7827 }, 7828 body: objectToFormData({ 7829 shippingMethod: selectedShippingMethod, 7830 countryCode: countryCode, 7831 postalCode: postalCode 7832 }) 7833 }) 7834 .then(response => { 7835 if (!response.ok) { 7836 throw new Error('Network response was not ok'); 7837 } 7838 return response.json(); 7839 }) 7840 .then(result => { 7841 quoteTotals = result.totals; 7842 7843 session.completeShippingMethodSelection( 7844 ApplePaySession.STATUS_SUCCESS, 7845 getTotal(), 7846 getLineItems() 7847 ); 7848 }) 7849 .catch(error => handleAjaxError(error)); 7850 }; 7851 7852 session.onpaymentauthorized = (event) => { 7853 fetch(`${BASE_URL}mollie/applePay/placeOrder?form_key=${hyva.getFormKey()}`, { 7854 method: 'POST', 7855 headers: { 7856 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8', 7857 }, 7858 body: objectToFormData({ 7859 shippingMethod: selectedShippingMethod, 7860 billingAddress: event.payment.billingContact, 7861 shippingAddress: event.payment.shippingContact, 7862 applePayPaymentToken: JSON.stringify(event.payment.token) 7863 }) 7864 }) 7865 .then(response => { 7866 if (!response.ok) { 7867 throw new Error('Network response was not ok'); 7868 } 7869 return response.json(); 7870 }) 7871 .then(result => { 7872 if (!session) { 7873 console.warn('Payment canceled'); 7874 return; 7875 } 7876 7877 if (result.error) { 7878 handleAjaxError(result.error_message); 7879 return; 7880 } 7881 7882 if (!result.url) { 7883 handleAjaxError('Something went wrong, please try again later.'); 7884 return; 7885 } 7886 7887 session.completePayment(ApplePaySession.STATUS_SUCCESS); 7888 7889 window.dispatchEvent(new CustomEvent("reload-customer-section-data")); 7890 7891 setTimeout(() => { 7892 location.href = result.url; 7893 }, 1000); 7894 }) 7895 .catch(error => handleAjaxError(error)); 7896 }; 7897 7898 session.onvalidatemerchant = (event) => { 7899 fetch( 7900 `${BASE_URL}mollie/checkout/applePayValidation?form_key=${hyva.getFormKey()}`, 7901 { 7902 method: 'POST', 7903 headers: { 7904 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8', 7905 }, 7906 body: objectToFormData({validationURL: event.validationURL}), 7907 } 7908 ) 7909 .then((response) => { 7910 if (!response.ok) { 7911 throw new Error('Merchant validation failed'); 7912 } 7913 7914 return response.json() 7915 }) 7916 .then((result) => session.completeMerchantValidation(result)) 7917 .catch(error => handleAjaxError(error)); 7918 }; 7919 7920 session.oncancel = () => { 7921 session = null; 7922 } 7923 7924 session.begin(); 7925 } 7926 } 7927 } 7928 7929 window.addEventListener( 7930 'alpine:init', 7931 () => Alpine.data('prepareMollieApplePayMinicart', prepareMollieApplePayMinicart), 7932 {once: true} 7933 ) 7934</script>
7934 7935 7936 <template x-if="itemsCount"> 7937 <div 7938 class="cart-drawer-totals" 7939 role="region" 7940 aria-label="Warenkorbübersicht" 7941 data-testid="minicart-summary"> 7942 <h3 class="font-bold uppercase text-sm mb-3"> 7943 Zusammenfassung </h3> 7944 <template x-for="(segment, index) in getSortedSegments()" :key="index"> 7945 <div class="text-sm"> 7946 <template x-if="segment.code === 'discount'"> 7947 <div class="flex justify-between mb-3"> 7948 <div x-html="segment.title"></div> 7949 <div class="text-right" x-text="hyva.formatPrice(segment.value)"></div> 7950 </div> 7951 </template> 7952 7953 <template x-if="segment.code === 'subtotal'"> 7954 <div class="flex justify-between mb-3"> 7955 <div x-html="segment.title"></div> 7956 <div class="text-right" x-text="hyva.formatPrice(segment.value)"></div> 7957 </div> 7958 </template> 7959 7960 <template x-if="segment.code === 'tax' && segment.value > 0"> 7961 <div class="flex justify-between mb-3"> 7962 <div x-html="segment.title"></div> 7963 <div class="text-right" x-text="hyva.formatPrice(segment.value)"></div> 7964 </div> 7965 </template> 7966 7967 <template x-if="segment.code === 'grand_total'"> 7968 <dl class="flex gap-2 justify-between items-center text-sm font-bold"> 7969 <dt id="cart-total-label"> 7970 <span class="uppercase font-semibold" x-html="segment.title"></span> 7971 <span class="font-light"> 7972 inkl. MwSt. </span> 7973 </dt> 7974 <dd 7975 x-text="hyva.formatPrice(segment.value)" 7976 data-testid="minicart-total" 7977 aria-labelledby="cart-total-label" 7978 class="text-right"></dd> 7979 </dl> 7980 </template> 7981 </div> 7982 </template> 7983 7984 <!-- BLOCK hyva.minicart_coupon -->
7984<script> 7985 function initMiniCartCouponForm() { 7986 return { 7987 errors: 0, 7988 hasCaptchaToken: 0, 7989 isLoading: false, 7990 hasCouponCode: false, 7991 formData: { 7992 coupon_code: '', 7993 remove: 0 }, 7994 eventListeners: { 7995 ['@minicart-coupon-updated.window'](event) { 7996 if (event.detail && event.detail.couponCode !== undefined) { 7997 const couponCode = event.detail.couponCode || ''; 7998 7999 this.formData.coupon_code = couponCode; 8000 this.hasCouponCode = couponCode ? true : false; 8001 this.formData.remove = couponCode ? 1 : 0; 8002 8003 if (this.$refs.couponInput) { 8004 this.$refs.couponInput.value = couponCode; 8005 } 8006 } 8007 }, 8008 ['@private-content-loaded.window'](event) { 8009 this.isLoading = false; 8010 } 8011 }, 8012 submitForm() { 8013 this.isLoading = true; 8014 const $form = this.$refs.couponForm; 8015 if (!this.hasCaptchaToken) { 8016 this.errors = 1; 8017 8018 8019 const executeGreCaptcha = () => { 8020 grecaptcha.ready(() => { 8021 grecaptcha.execute( 8022 '6LfbaCwmAAAAABn1WOQo1IUaX_yTMxd7m_x\u002DYLsQ', 8023 {action: 'submit'} 8024 ).then((token) => { 8025 const tokenElement = $form['g\u002Drecaptcha\u002Dresponse']; 8026 8027 if (tokenElement && token && token.length > 0) { 8028 $form['g\u002Drecaptcha\u002Dresponse'].value = token; 8029 this.errors = 0; 8030 this.hasCaptchaToken = 1; 8031 (this.submitForm || $form.submit).call(this); 8032 } else { 8033 this.errors = 1; 8034 const error = tokenElement 8035 ? 'Die\u0020ReCaptcha\u002DValidierung\u0020ist\u0020fehlgeschlagen.\u0020Bitte\u0020versuchen\u0020Sie\u0020es\u0020erneut.' 8036 : 'ReCaptcha\u0020token\u0020element\u0020is\u0020missing.\u0020Please\u0020refresh\u0020the\u0020page\u0020and\u0020trying\u0020again.'; 8037 if (this.setErrorMessages) { 8038 this.setErrorMessages([error]) 8039 this.displayErrorMessage = true; 8040 } else { 8041 window.dispatchMessages && window.dispatchMessages([{type: "error", text: error}], 5000); 8042 } 8043 } 8044 }).catch(exception => { 8045 console.error(exception || `An unknown error occurred during ReCaptcha validation. Are the tokens and the domain correctly set up in the Google console?`) 8046 }); 8047 }) 8048 } 8049 8050 if (window.grecaptcha) { 8051 executeGreCaptcha(); 8052 } else { 8053 const recaptchaUrl = "https://www.google.com/recaptcha/api.js?render=6LfbaCwmAAAAABn1WOQo1IUaX_yTMxd7m_x\u002DYLsQ"; 8054 const script = document.createElement('script'); 8055 script.setAttribute('type', 'text/javascript'); 8056 script.setAttribute('src', recaptchaUrl); 8057 document.head.appendChild(script); 8058 8059 script.addEventListener("load", executeGreCaptcha, false); 8060 } 8061 } 8062 8063 if (this.errors === 0) { 8064 $form.submit(); 8065 } else { 8066 this.isLoading = false; 8067 } 8068 } 8069 } 8070 } 8071</script>
8071 8072<div class="coupon-form mt-6" x-data="initMiniCartCouponForm()" x-bind="eventListeners" data-testid="minicart-coupon-form"> 8073 <div> 8074 <h3 class="uppercase text-sm"> 8075 Gutscheincode anwenden </h3> 8076 <form 8077 id="minicart-discount-coupon-form" 8078 class="mt-2" 8079 action="https://knirps.de/checkout/cart/couponPost/" 8080 method="post" 8081 x-ref="couponForm" 8082 @submit.prevent="submitForm()" 8083 data-testid="minicart-coupon-form-element"> 8084 <input name="form_key" type="hidden" value="8hdfTz3HiM3AEb3d" /> 8085 <div class="fieldset coupon"> 8086 <div class="flex gap-2 justify-center" :class="{'pointer-events-none opacity-50': isLoading}"> 8087 <div class="input mb-0! flex-1"> 8088 <input 8089 type="text" 8090 class="input__text peer" 8091 id="minicart_coupon_code" 8092 name="coupon_code" 8093 value="" 8094 x-model="formData.coupon_code" 8095 x-ref="couponInput" 8096 placeholder=" " 8097 :disabled="hasCouponCode || isLoading" 8098 :required="!hasCouponCode" 8099 data-testid="minicart-coupon-input" /> 8100 <label for="minicart_coupon_code" class="input__label"> 8101 Gutscheincode </label> 8102 </div> 8103 <div> 8104 <template x-if="!hasCouponCode"> 8105 <button 8106 type="submit" 8107 value="Anwenden" 8108 class="btn btn-secondary relative flex items-center gap-2" 8109 :disabled="isLoading" 8110 data-testid="minicart-coupon-apply"> 8111 <span x-show="isLoading" class="absolute -translate-y-1/2 -translate-x-1/2 top-1/2 left-1/2" data-testid="minicart-coupon-loader"> 8112 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="2" stroke-linecap="round" class="w-4 h-4 animate-spin" aria-hidden="true"> 8113 <circle style="opacity: .3;" cx="12" cy="12" r="10"/> 8114 <path fill="none" stroke-width="2" d="M12,2 a10,10 0 0,1 10,10"/> 8115</svg> 8116 </span> 8117 <span class="transition-opacity" :class="{'opacity-0': isLoading}">Anwenden</span> 8118 </button> 8119 </template> 8120 <template x-if="hasCouponCode"> 8121 <div> 8122 <input type="hidden" name="remove" value="1" /> 8123 <button 8124 type="submit" 8125 class="btn btn-secondary relative flex items-center gap-2" 8126 value="Gutschein stornieren" 8127 :disabled="isLoading" 8128 data-testid="minicart-coupon-remove"> 8129 <span x-show="isLoading" class="absolute -translate-y-1/2 -translate-x-1/2 top-1/2 left-1/2" data-testid="minicart-coupon-loader"> 8130 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="2" stroke-linecap="round" class="w-4 h-4 animate-spin" aria-hidden="true"> 8131 <circle style="opacity: .3;" cx="12" cy="12" r="10"/> 8132 <path fill="none" stroke-width="2" d="M12,2 a10,10 0 0,1 10,10"/> 8133</svg> 8134 </span> 8135 <span class="transition-opacity" :class="{'opacity-0': isLoading}">Gutschein stornieren</span> 8136 </button> 8137 </div> 8138 </template> 8139 </div> 8140 </div> 8141 <div class="control"> 8142 <input type="hidden" 8143 value="" 8144 name="g-recaptcha-response" 8145 > 8146</div> 8147 </div> 8148 </form> 8149 </div> 8150</div><!-- /BLOCK hyva.minicart_coupon --> 8151 <div class="mt-5"> 8152 <a 8153 href="https://knirps.de/checkout/cart/" 8154 class="btn btn-primary btn-full" 8155 data-testid="minicart-view-button" 8156 aria-label="Alle Artikel im Warenkorb anzeigen und bearbeiten"> 8157 Zur Kasse </a> 8158 </div> 8159 <div class="mt-2">
8160 <div x-html="getSectionDataExtraActions"></div> 8161 </div> 8162 </div> 8163 </template> 8164 8165 <template x-if="cartIsEmpty"> 8166 <div class="flex flex-col mt-8"> 8167 <button 8168 type="button" 8169 @click="closeCartDrawer" 8170 class="btn btn-primary" 8171 aria-describedby="empty-cart-description" 8172 data-testid="minicart-continue-shopping">Weiter einkaufen</button> 8173 8174 <span id="empty-cart-description" class="sr-only"> 8175 Warenkorb schlieÃen und weiter einkaufen </span> 8176 </div> 8177 </template> 8178 <div 8179 class="z-50 fixed inset-0 flex justify-center items-center bg-white/70 select-none" 8180 x-show="isLoading" 8181 x-cloak 8182 x-transition.opacity.duration.200ms 8183> 8184 <div class="flex items-center"> 8185 <svg xmlns="http://www.w3.org/2000/svg" width="54" height="54" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="2" stroke-linecap="round" class="animate-spin" aria-hidden="true"> 8186 <circle style="opacity: .3;" cx="12" cy="12" r="10"/> 8187 <path fill="none" stroke-width="2" d="M12,2 a10,10 0 0,1 10,10"/> 8188</svg> 8189 <div class="ml-10 text-xl"> 8190 Wird geladen ⦠</div> 8191 </div> 8192</div> 8193 </div> 8194</section> 8195 <!--Authentication Pop-Up--> 8196 <!-- BLOCK authentication-popup -->
8196<script> 8197 function initAuthentication() { 8198 return { 8199 open: false, 8200 close() { 8201 this.open = false; 8202 }, 8203 forceAuthentication: false, 8204 checkoutUrl: 'https://knirps.de/checkout/index/', 8205 errors: 0, 8206 hasCaptchaToken: 0, 8207 displayErrorMessage: false, 8208 errorMessages: [], 8209 setErrorMessages(message) { 8210 this.errorMessages = [message]; 8211 this.displayErrorMessage = true; 8212 }, 8213 submitForm() { 8214 // Do not rename $form, the variable is expected to be declared in the recaptcha output 8215 const $form = document.querySelector('#login-form'); 8216 if (!this.hasCaptchaToken) { 8217 this.errors = 1; 8218 8219 8220 const executeGreCaptcha = () => { 8221 grecaptcha.ready(() => { 8222 grecaptcha.execute( 8223 '6LfbaCwmAAAAABn1WOQo1IUaX_yTMxd7m_x\u002DYLsQ', 8224 {action: 'submit'} 8225 ).then((token) => { 8226 const tokenElement = $form['g\u002Drecaptcha\u002Dresponse']; 8227 8228 if (tokenElement && token && token.length > 0) { 8229 $form['g\u002Drecaptcha\u002Dresponse'].value = token; 8230 this.errors = 0; 8231 this.hasCaptchaToken = 1; 8232 (this.submitForm || $form.submit).call(this); 8233 } else { 8234 this.errors = 1; 8235 const error = tokenElement 8236 ? 'Die\u0020ReCaptcha\u002DValidierung\u0020ist\u0020fehlgeschlagen.\u0020Bitte\u0020versuchen\u0020Sie\u0020es\u0020erneut.' 8237 : 'ReCaptcha\u0020token\u0020element\u0020is\u0020missing.\u0020Please\u0020refresh\u0020the\u0020page\u0020and\u0020trying\u0020again.'; 8238 if (this.setErrorMessages) { 8239 this.setErrorMessages([error]) 8240 this.displayErrorMessage = true; 8241 } else { 8242 window.dispatchMessages && window.dispatchMessages([{type: "error", text: error}], 5000); 8243 } 8244 } 8245 }).catch(exception => { 8246 console.error(exception || `An unknown error occurred during ReCaptcha validation. Are the tokens and the domain correctly set up in the Google console?`) 8247 }); 8248 }) 8249 } 8250 8251 if (window.grecaptcha) { 8252 executeGreCaptcha(); 8253 } else { 8254 const recaptchaUrl = "https://www.google.com/recaptcha/api.js?render=6LfbaCwmAAAAABn1WOQo1IUaX_yTMxd7m_x\u002DYLsQ"; 8255 const script = document.createElement('script'); 8256 script.setAttribute('type', 'text/javascript'); 8257 script.setAttribute('src', recaptchaUrl); 8258 document.head.appendChild(script); 8259 8260 script.addEventListener("load", executeGreCaptcha, false); 8261 } 8262 } 8263 8264 if (this.errors === 0) { 8265 this.dispatchLoginRequest($form); 8266 } 8267 }, 8268 onPrivateContentLoaded() { 8269 const data = this.$event.detail.data; 8270 const isLoggedIn = data.customer && data.customer.firstname; 8271 if (data.cart && !isLoggedIn) { 8272 this.forceAuthentication = !data.cart.isGuestCheckoutAllowed; 8273 } 8274 }, 8275 redirectIfAuthenticated() { 8276 const event = this.$event; 8277 this.open = this.forceAuthentication; 8278 8279 if (event.detail && event.detail.url) { 8280 this.checkoutUrl = event.detail.url; 8281 } 8282 if (!this.forceAuthentication) { 8283 window.location.href = this.checkoutUrl; 8284 } 8285 }, 8286 resetErrors() { 8287 this.errors = 0; 8288 }, 8289 dispatchLoginRequest(form) { 8290 this.isLoading = true; 8291 const username = this.$refs['customer-email'].value; 8292 const password = this.$refs['customer-password'].value; 8293 const formKey = hyva.getFormKey(); 8294 const bodyFields = { 8295 'username': username, 8296 'password': password, 8297 'formKey': formKey 8298 }; 8299 const fieldName = 'g\u002Drecaptcha\u002Dresponse'; 8300 const recaptchaField = fieldName && form[fieldName]; 8301 if (recaptchaField) { 8302 bodyFields[fieldName] = recaptchaField.value; 8303 } 8304 fetch('https://knirps.de/customer/ajax/login/', { 8305 method: 'POST', 8306 headers: { 8307 'Content-Type': 'application/json', 8308 'X-Requested-With': 'XMLHttpRequest' 8309 }, 8310 body: JSON.stringify(bodyFields) 8311 } 8312 ).then(response => { 8313 return response.json() 8314 } 8315 ).then(data => { 8316 this.isLoading = false;
8317 if (data.errors) { 8318 this.setErrorMessages(data.message); 8319 this.errors = 1; 8320 this.hasCaptchaToken = 0; 8321 } else { 8322 window.location.href = this.checkoutUrl; 8323 } 8324 }); 8325 }, 8326 eventListeners: { 8327 ['@private-content-loaded.window']() { 8328 this.onPrivateContentLoaded(); 8329 }, 8330 ['@toggle-authentication.window']() { 8331 this.redirectIfAuthenticated(); 8332 }, 8333 ['@pageshow.window'](event) { 8334 if (event.persisted) { 8335 this.close(); 8336 }; 8337 } 8338 } 8339 } 8340 } 8341 8342 window.addEventListener('alpine:init', () => Alpine.data('initAuthentication', initAuthentication), {once: true}) 8343</script>
8343 8344 8345<dialog 8346 id="authentication-popup" 8347 aria-labelledby="cart-drawer-title" 8348 class="open:flex flex-col transition ease-out duration-300 motion-reduce:duration-0 p-0" 8349 x-data="initAuthentication" 8350 x-bind="eventListeners" 8351 x-show="open" 8352 x-htmldialog="close" 8353 closeby="any" 8354 x-transition 8355> 8356 <div class="pt-8 px-8"> 8357 <div class="flex gap-2 justify-between items-center"> 8358 <p class="text-xl"> 8359 <strong>Anmelden</strong> 8360 </p> 8361 <button 8362 type="button" 8363 class="btn bg-transparent border-transparent p-2" 8364 @click="close" 8365 aria-label="Paneel schließen" 8366 > 8367 <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" viewBox="0 0 24 24" aria-hidden="true"><path d="M18 6 6 18M6 6l12 12"/></svg> 8368 </button> 8369 </div> 8370 8371 <div class="message error" x-show="errors" x-cloak> 8372 <template x-for="(message, index) in errorMessages" :key="index"> 8373 <div> 8374 <template x-if="message"> 8375 <span x-html="message"></span> 8376 </template> 8377 </div> 8378 </template> 8379 </div> 8380 </div> 8381 8382 <div class="block-customer-login p-8"> 8383 <p id="authenticate-customer-login" class="text-lg mb-2"> 8384 <strong>Mit Ihrem Konto bestellen</strong> 8385 </p> 8386 8387 <form 8388 id="login-form" 8389 class="form form-login" 8390 method="post" 8391 @submit.prevent="submitForm" 8392 > 8393 <div class="control"> 8394 <input type="hidden" 8395 value="" 8396 name="g-recaptcha-response" 8397 > 8398</div> 8399 <input name="context" type="hidden" value="checkout"> 8400 8401 <div class="flex flex-col gap-4"> 8402 <div class="field email required"> 8403 <label for="form-login-username"> 8404 <span>Ihre E-Mail-Adresse</span> 8405 </label> 8406 <div class="control"> 8407 <input 8408 id="form-login-username" 8409 name="username" 8410 type="email" 8411 class="form-input w-full" 8412 required 8413 autocomplete="off" 8414 x-ref="customer-email" 8415 @change="resetErrors" 8416 > 8417 </div> 8418 </div> 8419 <div class="field password required"> 8420 <label for="form-login-password"> 8421 <span>Passwort</span> 8422 </label> 8423 <div class="control"> 8424 <input 8425 id="form-login-password" 8426 name="password" 8427 type="password" 8428 class="form-input w-full" 8429 required 8430 autocomplete="off" 8431 x-ref="customer-password" 8432 @change="resetErrors" 8433 > 8434 </div> 8435 </div> 8436 </div> 8437 8438 <div class="actions-toolbar"> 8439 <button 8440 type="submit" 8441 class="btn btn-primary" 8442 > 8443 Anmelden </button> 8444 <a 8445 href="https://knirps.de/customer/account/forgotpassword/" 8446 class="underline hover:no-underline" 8447 > 8448 Passwort vergessen? </a> 8449 </div> 8450 </form> 8451 <p class="my-4 text-sm"> 8452 <em> 8453 Dieses Formular ist durch reCAPTCHA geschützt - es gelten die <a class="underline" href="https://policies.google.com/privacy" target="_blank" rel="noopener">Google-Datenschutzbestimmungen</a> und <a class="underline" href="https://policies.google.com/terms" target="_blank" rel="noopener">-Geschäftsbedingungen</a>. </em> 8454</p> 8455 </div> 8456 <div class="block-new-customer p-8 border-t border-gray-300">
8457 <p id="authenticate-new-customer" class="text-lg mb-2"> 8458 <strong>Als neuer Kunde bestellen</strong> 8459 </p> 8460 8461 <div class="block-content"> 8462 <p class="mb-1"> 8463 Das Erstellen eines Kontos hat viele Vorteile: </p> 8464 <ul class="list-disc pl-5"> 8465 <li> Bestell- und Versandstatus ansehen</li> 8466 <li> Bestellverlauf verfolgen</li> 8467 <li> Schneller bestellen</li> 8468 </ul> 8469 <div class="actions-toolbar mt-6 mb-2"> 8470 <a href="https://knirps.de/customer/account/create/" 8471 class="inline-flex btn btn-primary"> 8472 Ein Konto erstellen </a> 8473 </div> 8474 </div> 8475 </div> 8476</dialog> 8477<!-- /BLOCK authentication-popup --></div></header><div class="top-container"> <nav class="breadcrumbs" aria-label="Breadcrumb"> 8478 <div class="container"> 8479 <ol class="items list-reset py-3 flex flex-wrap items-center text-14 leading-140 font-medium"> 8480 <li class="item flex items-center home"> 8481 <a 8482 href="https://knirps.de/" 8483 aria-label="Zur Startseite" 8484 >Startseite</a> 8485 </li> 8486 <li class="item flex items-center cms_page"> 8487 <span aria-hidden="true" class="text-[#949494] px-1 pb-px"> 8488 <svg xmlns="http://www.w3.org/2000/svg" width="9" height="9" viewBox="0 0 14 23" fill="none" aria-hidden="true"> 8489<path d="M2.5 2.00032L11.8333 11.3337L2.5 20.667" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/> 8490</svg> 8491 </span> 8492 <span 8493 class="text-primary" 8494 aria-current="page">Blog</span> 8495 </li> 8496 </ol> 8497 </div> 8498 </nav> 8499</div><main id="maincontent" class="page-main"><div id="contentarea" tabindex="-1"></div> 8500<div class="columns"><div class="column main">
8501<script> 8502 window.getCurrencyCode = "EUR" 8503</script>
8503 8504<style>.cmsp12668-grow { 8505flex-grow: 1 8506} 8507.cmsp12668-underline { 8508text-decoration-line: underline 8509}</style> 8510<div class="magezon-builder magezon-builder-preload"><div class="ls1od4k mgz-element mgz-element-row full_width_row"><div class="mgz-element-inner ls1od4k-s"><style> .bfb-element.required .bfb-element-label label > span:after { color: #e22626; content: '*'; font-size: 1.6rem; font-weight: 500; margin-left: 5px; } </style><div class="inner-content mgz-container"><div class="t2m7ek4 mgz-element mgz-element-column mgz-col-xs-12"><div class="mgz-element-inner t2m7ek4-s"><div class="ha8y4pj mgz-element mgz-child mgz-element-empty_space"><div class="mgz-element-inner ha8y4pj-s"><div class="mgz-element-empty-space"></div></div></div><div class="o24j7px mgz-element mgz-child mgz-element-heading"><div class="mgz-element-inner o24j7px-s"><h1 class="mgz-element-heading-text inline-block relative mb-2 mt-0 text-4xl font-medium leading-tight text-primary" > Immer <b>up-to-date</b>.<span class="dot"><!--.span--></span> </h1></div></div><div class="y33rvbe mgz-element mgz-child mgz-element-text"><div class="mgz-element-inner y33rvbe-s"><div class="blog__heading"><div class="blog__heading__subheading"><span style="font-size: 16px; line-height: 24px;">Der Knirps Blog ist Ihre Anlaufstelle für News, Tipps, Informationen und Neuigkeiten rund um unsere Produkte.</span></div></div></div></div><div class="x18o8oi mgz-element mgz-child mgz-element-empty_space"><div class="mgz-element-inner x18o8oi-s"><div class="mgz-element-empty-space"></div></div></div></div></div></div>
8510<script> 8511 loadScript('https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Hyva_MagezonBuilder/js/jquery.min.js', 'jquery') 8512 .then(() => { 8513 return loadScript('https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Hyva_MagezonBuilder/js/magezon-builder.js', 'mgzbuilder'); 8514 }) 8515 .then(() => { 8516 const elemId = $('.ls1od4k'); 8517 let mgzBuilder = new MagezonBuilder(elemId); 8518 }) 8519</script>
8519</div></div><div class="w5oceek mgz-element mgz-element-row full_width_row"><div class="mgz-element-inner w5oceek-s"><style> .bfb-element.required .bfb-element-label label > span:after { color: #e22626; content: '*'; font-size: 1.6rem; font-weight: 500; margin-left: 5px; } </style><div class="inner-content mgz-container"><div class="nfmswbq mgz-element mgz-element-column mgz-col-md-12"><div class="mgz-element-inner nfmswbq-s"><div class="a1ikqj7 mgz-element mgz-element-row full_width_row"><div class="mgz-element-inner a1ikqj7-s"><style> .bfb-element.required .bfb-element-label label > span:after { color: #e22626; content: '*'; font-size: 1.6rem; font-weight: 500; margin-left: 5px; } </style><div class="inner-content mgz-container"><div class="nl0s6wh mgz-element mgz-element-column mgz-col-xs-12"><div class="mgz-element-inner nl0s6wh-s"><div class="imo5vs0 mgz-element mgz-child mgz-element-call_to_action"><div class="mgz-element-inner imo5vs0-s custom-background"><div class="mgz-cta mgz-animated-content mgz-cta-image-right mgz-bg-transform-zoom-in"><a class="mgz-absolute-link" href="https://knirps.de/sizematters/" title="Size Matters" ></a> <div class="mgz-cta-bg-wrapper mgz-bg-transform-wrapper"><div class="mgz-cta-bg mgz-bg" style="background-image: url(https://knirps.de/media/knirps/Size-Matters/size_matters.png);"></div><div class="mgz-cta-bg-overlay"></div></div><div class="mgz-cta-content mgz-flex-position-middle-center"><div class="mgz-cta-content-inner"><h2 class="mgz-cta-content-item mgz-cta-title mgz-animated-item--grow">Size Matters</h2><div class="mgz-cta-content-item mgz-cta-description mgz-animated-item--grow"><p style="text-align: center;">GröÃe spielt für dich keine Rolle? Für uns schon!</p><p style="text-align: center;"> </p><p style="text-align: center;"><a href="https://knirps.de/sizematters"><span style="font-size: 14px;"><strong>.. mehr erfahren</strong></span></a></p></div></div></div></div></div></div></div></div></div>
8519<script> 8520 loadScript('https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Hyva_MagezonBuilder/js/jquery.min.js', 'jquery') 8521 .then(() => { 8522 return loadScript('https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Hyva_MagezonBuilder/js/magezon-builder.js', 'mgzbuilder'); 8523 }) 8524 .then(() => { 8525 const elemId = $('.a1ikqj7'); 8526 let mgzBuilder = new MagezonBuilder(elemId); 8527 }) 8528</script>
8528</div></div><div class="beoc40j mgz-element mgz-element-row full_width_row mgz-row-equal-height content-top"><div class="mgz-element-inner beoc40j-s"><style> .bfb-element.required .bfb-element-label label > span:after { color: #e22626; content: '*'; font-size: 1.6rem; font-weight: 500; margin-left: 5px; } </style><div class="inner-content mgz-container"><div class="g8s9yos mgz-element mgz-element-column mgz-col-md-4"><div class="mgz-element-inner g8s9yos-s"><div class="f60gsyk mgz-element mgz-child mgz-element-call_to_action"><div class="mgz-element-inner f60gsyk-s custom-background"><div class="mgz-cta mgz-animated-content mgz-cta-image-top mgz-bg-transform-zoom-in"><a class="mgz-absolute-link" href="https://knirps.de/hyperion/" title="Hyperion Ampelschirme" ></a> <div class="mgz-cta-bg-wrapper mgz-bg-transform-wrapper"><div class="mgz-cta-bg mgz-bg" style="background-image: url(https://knirps.de/media/knirps/blog/I_982340508_Hyperion_Prestige_Cacao.jpg);"></div><div class="mgz-cta-bg-overlay"></div></div><div class="mgz-cta-content mgz-flex-position-middle-center"><div class="mgz-cta-content-inner"><h2 class="mgz-cta-content-item mgz-cta-title mgz-animated-item--grow">Hyperion Ampelschirme</h2><div class="mgz-cta-content-item mgz-cta-description mgz-animated-item--grow"><p style="text-align: center;">Exklusiviät für den AuÃenbereich.</p><p style="text-align: center;"> </p><p style="text-align: center;"><a href="https://knirps.de/hyperion"><span style="font-size: 14px;"><strong>.. mehr erfahren</strong></span></a></p></div></div></div></div></div></div></div></div><div class="fs95cte mgz-element mgz-element-column mgz-col-md-4"><div class="mgz-element-inner fs95cte-s"><div class="csk37y9 mgz-element mgz-child mgz-element-call_to_action"><div class="mgz-element-inner csk37y9-s custom-background"><div class="mgz-cta mgz-animated-content mgz-cta-image-top mgz-bg-transform-zoom-in"><a class="mgz-absolute-link" href="https://knirps.de/timber/" title="Knirps Timber" ></a> <div class="mgz-cta-bg-wrapper mgz-bg-transform-wrapper"><div class="mgz-cta-bg mgz-bg" style="background-image: url(https://knirps.de/media/knirps/timber/I_9542301368_Timber_Duomatic_Cucumber_2__1.jpg);"></div><div class="mgz-cta-bg-overlay"></div></div><div class="mgz-cta-content mgz-flex-position-middle-center"><div class="mgz-cta-content-inner"><h2 class="mgz-cta-content-item mgz-cta-title mgz-animated-item--grow">Timber</h2><div class="mgz-cta-content-item mgz-cta-description mgz-animated-item--grow"><p style="text-align: center;">Regenschirme mit Griff aus hochwertigem deutschem Holz.</p><p style="text-align: center;"><span style="font-size: 14px;"><strong><a href="https://knirps.de/timber/">.. mehr erfahren</a></strong></span></p></div></div></div></div></div></div></div></div><div class="hqtcr76 mgz-element mgz-element-column mgz-col-md-4"><div class="mgz-element-inner hqtcr76-s"><div class="kbo0ou6 mgz-element mgz-child mgz-element-call_to_action"><div class="mgz-element-inner kbo0ou6-s custom-background"><div class="mgz-cta mgz-animated-content mgz-cta-image-top mgz-bg-transform-zoom-in"><a class="mgz-absolute-link" href="https://knirps.de/mini/" title="Knirps X MINI" ></a> <div class="mgz-cta-bg-wrapper mgz-bg-transform-wrapper"><div class="mgz-cta-bg mgz-bg" style="background-image: url(https://knirps.de/media/knirps/Kooperationen/Mini/Knirps_SoMe_F_rth_1225_067.jpg);"></div><div class="mgz-cta-bg-overlay"></div></div><div class="mgz-cta-content mgz-flex-position-middle-center"><div class="mgz-cta-content-inner"><h2 class="mgz-cta-content-item mgz-cta-title mgz-animated-item--grow">Knirps X MINI</h2><div class="mgz-cta-content-item mgz-cta-description mgz-animated-item--grow"><p style="text-align: center;"><span style="color: #ffffff;">Zwei Kultmarken machen gemeinsame Sache.</span></p><p style="text-align: center;"><strong><span style="font-size: 14px;"><a href="https://knirps.de/mini">.. mehr erfahren</a></span></strong></p></div></div></div></div></div></div></div></div></div>
8528<script> 8529 loadScript('https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Hyva_MagezonBuilder/js/jquery.min.js', 'jquery') 8530 .then(() => { 8531 return loadScript('https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Hyva_MagezonBuilder/js/magezon-builder.js', 'mgzbuilder'); 8532 }) 8533 .then(() => { 8534 const elemId = $('.beoc40j'); 8535 let mgzBuilder = new MagezonBuilder(elemId); 8536 }) 8537</script>
8537</div></div><div class="mrcipvn mgz-element mgz-element-row full_width_row"><div class="mgz-element-inner mrcipvn-s"><style> .bfb-element.required .bfb-element-label label > span:after { color: #e22626; content: '*'; font-size: 1.6rem; font-weight: 500; margin-left: 5px; } </style><div class="inner-content mgz-container"><div class="rtbnxbx mgz-element mgz-element-column mgz-col-md-12"><div class="mgz-element-inner rtbnxbx-s"><div class="jxqeaun mgz-element mgz-child mgz-element-call_to_action"><div class="mgz-element-inner jxqeaun-s custom-background"><div class="mgz-cta mgz-animated-content mgz-cta-image-left mgz-bg-transform-zoom-in"><a class="mgz-absolute-link" href="https://knirps.de/regenschirme-uv-schutz/" title="Regenschirme mit UV-Schutz" ></a> <div class="mgz-cta-bg-wrapper mgz-bg-transform-wrapper"><div class="mgz-cta-bg mgz-bg" style="background-image: url(https://knirps.de/media/knirps/UV-Schutz/Knirps_Rain_Sun_1.png);"></div><div class="mgz-cta-bg-overlay"></div></div><div class="mgz-cta-content mgz-flex-position-middle-center"><div class="mgz-cta-content-inner"><h2 class="mgz-cta-content-item mgz-cta-title mgz-animated-item--grow">Regenschirme mit UV-Schutz</h2><div class="mgz-cta-content-item mgz-cta-description mgz-animated-item--grow"><p style="text-align: center;">Schirme, die sowohl vor Regen als auch vor Sonne schützen.</p><p style="text-align: center;"> </p><p style="text-align: center;"><span style="font-size: 14px;"><strong>.. <a href="https://knirps.de/regenschirme-uv-schutz/">mehr erfahren</a></strong></span></p></div></div></div></div></div></div></div></div></div>
8537<script> 8538 loadScript('https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Hyva_MagezonBuilder/js/jquery.min.js', 'jquery') 8539 .then(() => { 8540 return loadScript('https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Hyva_MagezonBuilder/js/magezon-builder.js', 'mgzbuilder'); 8541 }) 8542 .then(() => { 8543 const elemId = $('.mrcipvn'); 8544 let mgzBuilder = new MagezonBuilder(elemId); 8545 }) 8546</script>
8546</div></div><div class="f7nlvwi mgz-element mgz-element-row full_width_row"><div class="mgz-element-inner f7nlvwi-s"><style> .bfb-element.required .bfb-element-label label > span:after { color: #e22626; content: '*'; font-size: 1.6rem; font-weight: 500; margin-left: 5px; } </style><div class="inner-content mgz-container"><div class="w7f7p6s mgz-element mgz-element-column mgz-col-md-4"><div class="mgz-element-inner w7f7p6s-s"><div class="xdb079v mgz-element mgz-child mgz-element-call_to_action"><div class="mgz-element-inner xdb079v-s custom-background"><div class="mgz-cta mgz-animated-content mgz-cta-image-top mgz-bg-transform-zoom-in"><a class="mgz-absolute-link" href="https://knirps.de/x4u/" title="Knirps X4U" ></a> <div class="mgz-cta-bg-wrapper mgz-bg-transform-wrapper"><div class="mgz-cta-bg mgz-bg" style="background-image: url(https://knirps.de/media/knirps/X4U/X4U_Display_Artwork_3_Whatever_the_Weather.png);"></div><div class="mgz-cta-bg-overlay"></div></div><div class="mgz-cta-content mgz-flex-position-middle-center"><div class="mgz-cta-content-inner"><h2 class="mgz-cta-content-item mgz-cta-title mgz-animated-item--grow">X4U</h2><div class="mgz-cta-content-item mgz-cta-description mgz-animated-item--grow"><p style="text-align: center;"><span style="color: #ffffff;">Dein cleverer Begleite & Gewinner des Red Dot Design Awards.</span></p><p style="text-align: center;"><span style="font-size: 14px;"><strong><a href="https://knirps.de/x4u">.. mehr erfahren</a></strong></span></p></div></div></div></div></div></div></div></div><div class="dhtnegs mgz-element mgz-element-column mgz-col-md-4"><div class="mgz-element-inner dhtnegs-s"><div class="aeelgq5 mgz-element mgz-child mgz-element-call_to_action"><div class="mgz-element-inner aeelgq5-s custom-background"><div class="mgz-cta mgz-animated-content mgz-cta-image-top mgz-bg-transform-zoom-in"><a class="mgz-absolute-link" href="https://knirps.de/phoenix/" title="Knirps Phoenix" ></a> <div class="mgz-cta-bg-wrapper mgz-bg-transform-wrapper"><div class="mgz-cta-bg mgz-bg" style="background-image: url(https://knirps.de/media/knirps/blog/I_9022245909_Phoenix_245x245_Nature_1_.jpg);"></div><div class="mgz-cta-bg-overlay"></div></div><div class="mgz-cta-content mgz-flex-position-middle-center"><div class="mgz-cta-content-inner"><h2 class="mgz-cta-content-item mgz-cta-title mgz-animated-item--grow">Der neue Phoenix</h2><div class="mgz-cta-content-item mgz-cta-description mgz-animated-item--grow"><p style="text-align: center;"><span style="color: #ffffff;">Mit nur einem Click im Schatten!</span></p><p style="text-align: center;"><strong><span style="font-size: 14px;"><a href="https://knirps.de/phoenix">.. mehr erfahren</a></span></strong></p></div></div></div></div></div></div></div></div><div class="o87oi2q mgz-element mgz-element-column mgz-col-md-4"><div class="mgz-element-inner o87oi2q-s"><div class="ocn0435 mgz-element mgz-child mgz-element-call_to_action"><div class="mgz-element-inner ocn0435-s custom-background"><div class="mgz-cta mgz-animated-content mgz-cta-image-top mgz-bg-transform-zoom-in"><a class="mgz-absolute-link" href="https://knirps.de/regenschirm-re3/" title="Knirps Taschenschirm Re3" ></a> <div class="mgz-cta-bg-wrapper mgz-bg-transform-wrapper"><div class="mgz-cta-bg mgz-bg" style="background-image: url(https://knirps.de/media/knirps/Re3/hajime_style_re3_v5.jpg);"></div><div class="mgz-cta-bg-overlay"></div></div><div class="mgz-cta-content mgz-flex-position-middle-center"><div class="mgz-cta-content-inner"><h2 class="mgz-cta-content-item mgz-cta-title mgz-animated-item--grow">Re<sup>3</sup> - Rethink Umbrellas</h2><div class="mgz-cta-content-item mgz-cta-description mgz-animated-item--grow"><p style="text-align: center;"><span style="color: #ffffff;">Der Re³ ist nicht nur ein Regenschirm, sondern ein einzigartiges Accessoire.</span></p><p style="text-align: center;"><span style="font-size: 14px;"><strong>.. <a href="https://knirps.de/regenschirm-re3/">mehr erfahren</a></strong></span></p></div></div></div></div></div></div></div></div></div>
8546<script> 8547 loadScript('https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Hyva_MagezonBuilder/js/jquery.min.js', 'jquery') 8548 .then(() => { 8549 return loadScript('https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Hyva_MagezonBuilder/js/magezon-builder.js', 'mgzbuilder'); 8550 }) 8551 .then(() => { 8552 const elemId = $('.f7nlvwi'); 8553 let mgzBuilder = new MagezonBuilder(elemId); 8554 }) 8555</script>
8555</div></div><div class="kb7nebb mgz-element mgz-element-row full_width_row mgz-row-equal-height content-top"><div class="mgz-element-inner kb7nebb-s"><style> .bfb-element.required .bfb-element-label label > span:after { color: #e22626; content: '*'; font-size: 1.6rem; font-weight: 500; margin-left: 5px; } </style><div class="inner-content mgz-container"><div class="vbwld4e mgz-element mgz-element-column mgz-col-md-4"><div class="mgz-element-inner vbwld4e-s"><div class="n6jvc34 mgz-element mgz-child mgz-element-call_to_action"><div class="mgz-element-inner n6jvc34-s custom-background"><div class="mgz-cta mgz-animated-content mgz-cta-image-top mgz-bg-transform-zoom-in"><a class="mgz-absolute-link" href="https://knirps.de/apoll/" title="Apoll Sonnenschirme" ></a> <div class="mgz-cta-bg-wrapper mgz-bg-transform-wrapper"><div class="mgz-cta-bg mgz-bg" style="background-image: url(https://knirps.de/media/knirps/apoll/I_9021240200_Apoll240_Light_Grey.jpg);"></div><div class="mgz-cta-bg-overlay"></div></div><div class="mgz-cta-content mgz-flex-position-middle-center"><div class="mgz-cta-content-inner"><h2 class="mgz-cta-content-item mgz-cta-title mgz-animated-item--grow">Apoll</h2><div class="mgz-cta-content-item mgz-cta-description mgz-animated-item--grow"><p style="text-align: center;">Die neuen Mittelmastschirme in Zusammenarbeit mit Design Ballendat.</p><p style="text-align: center;"><span style="font-size: 14px;"><strong><a href="https://knirps.de/apoll"><span style="color: #ffffff;">..</span> mehr erfahren</a></strong></span></p></div></div></div></div></div></div></div></div><div class="m807fig mgz-element mgz-element-column mgz-col-md-4"><div class="mgz-element-inner m807fig-s"><div class="mev8wng mgz-element mgz-child mgz-element-call_to_action"><div class="mgz-element-inner mev8wng-s custom-background"><div class="mgz-cta mgz-animated-content mgz-cta-image-top mgz-bg-transform-zoom-in"><a class="mgz-absolute-link" href="https://knirps.de/vision/" title="Knirps Vision " ></a> <div class="mgz-cta-bg-wrapper mgz-bg-transform-wrapper"><div class="mgz-cta-bg mgz-bg" style="background-image: url(https://knirps.de/media/Knirps_Vision/Vision_Title_ohne_Knirps_.jpg);"></div><div class="mgz-cta-bg-overlay"></div></div><div class="mgz-cta-content mgz-flex-position-middle-center"><div class="mgz-cta-content-inner"><h2 class="mgz-cta-content-item mgz-cta-title mgz-animated-item--grow">Green Product Award Winner 2022</h2><div class="mgz-cta-content-item mgz-cta-description mgz-animated-item--grow"><p style="text-align: center;"><span style="color: #ffffff;">Der Knirps Vision wurde mit dem Green Product Award ausgezeichnet. </span></p><p style="text-align: center;"><span style="font-size: 14px;"><strong><a style="text-decoration: underline;" href="https://www.knirps.de/vision">.. mehr erfahren</a></strong></span></p></div></div></div></div></div></div></div></div><div class="qfi5h1i mgz-element mgz-element-column mgz-col-md-4"><div class="mgz-element-inner qfi5h1i-s"><div class="k0kbj28 mgz-element mgz-child mgz-element-call_to_action"><div class="mgz-element-inner k0kbj28-s custom-background"><div class="mgz-cta mgz-animated-content mgz-cta-image-top mgz-bg-transform-zoom-in"><a class="mgz-absolute-link" href="https://knirps.de/ultra-robuste-leichte-regenschirme/" title="U-Serie" ></a> <div class="mgz-cta-bg-wrapper mgz-bg-transform-wrapper"><div class="mgz-cta-bg mgz-bg" style="background-image: url(https://knirps.de/media/LP-u-serie/I_29001501_U900_Relaunch_GROUP_Quer.jpg);"></div><div class="mgz-cta-bg-overlay"></div></div><div class="mgz-cta-content mgz-flex-position-middle-center"><div class="mgz-cta-content-inner"><h1 class="mgz-cta-content-item mgz-cta-title mgz-animated-item--grow">Ultra Series</h1><div class="mgz-cta-content-item mgz-cta-description mgz-animated-item--grow"><p style="text-align: center;"><span style="color: #ffffff;">Leichte Regenschirme von Knirps, die in jede Tasche passen.</span></p><p style="text-align: center;"><span style="font-size: 14px;"><strong><span style="color: #ffffff;"><a style="color: #ffffff;" href="https://knirps.de/ultra-robuste-leichte-regenschirme/#">.. mehr erfahren</a></span></strong></span></p></div></div></div></div></div></div></div></div></div>
8555<script> 8556 loadScript('https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Hyva_MagezonBuilder/js/jquery.min.js', 'jquery') 8557 .then(() => { 8558 return loadScript('https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Hyva_MagezonBuilder/js/magezon-builder.js', 'mgzbuilder'); 8559 }) 8560 .then(() => { 8561 const elemId = $('.kb7nebb'); 8562 let mgzBuilder = new MagezonBuilder(elemId); 8563 }) 8564</script>
8564</div></div><div class="bh0se3q mgz-element mgz-element-row full_width_row"><div class="mgz-element-inner bh0se3q-s"><style> .bfb-element.required .bfb-element-label label > span:after { color: #e22626; content: '*'; font-size: 1.6rem; font-weight: 500; margin-left: 5px; } </style><div class="inner-content mgz-container"><div class="jyn4hie mgz-element mgz-element-column mgz-col-md-6"><div class="mgz-element-inner jyn4hie-s"><div class="yctgn9o mgz-element mgz-child mgz-element-call_to_action"><div class="mgz-element-inner yctgn9o-s custom-background"><div class="mgz-cta mgz-animated-content mgz-cta-image-top mgz-bg-transform-zoom-in"><a class="mgz-absolute-link" href="https://knirps.de/regenschirm-lexikon" title="Regenschirme mit UV-Schutz" ></a> <div class="mgz-cta-bg-wrapper mgz-bg-transform-wrapper"><div class="mgz-cta-bg mgz-bg" style="background-image: url(https://knirps.de/media/knirps/blog/knirps_blog_regenschirm_lexikon.jpg);"></div><div class="mgz-cta-bg-overlay"></div></div><div class="mgz-cta-content mgz-flex-position-middle-center"><div class="mgz-cta-content-inner"><h2 class="mgz-cta-content-item mgz-cta-title mgz-animated-item--grow">Regenschirm Lexikon</h2><div class="mgz-cta-content-item mgz-cta-description mgz-animated-item--grow"><p style="text-align: center;">Regenschirme von A bis Z.</p><p style="text-align: center;"><span style="font-size: 14px;"><strong>.. <a href="https://knirps.de/regenschirm-lexikon">mehr erfahren</a></strong></span></p></div></div></div></div></div></div></div></div><div class="vqtqgt9 mgz-element mgz-element-column mgz-col-md-6"><div class="mgz-element-inner vqtqgt9-s"><div class="km3nqbp mgz-element mgz-child mgz-element-call_to_action"><div class="mgz-element-inner km3nqbp-s custom-background"><div class="mgz-cta mgz-animated-content mgz-cta-image-top mgz-bg-transform-zoom-in"><a class="mgz-absolute-link" href="https://knirps.de/windtunnel" title="Windtunneltest" ></a> <div class="mgz-cta-bg-wrapper mgz-bg-transform-wrapper"><div class="mgz-cta-bg mgz-bg" style="background-image: url(https://knirps.de/media/LP-Qualitaet/Regenschirme-knirps-hochwertige-qualitaet.jpg);"></div><div class="mgz-cta-bg-overlay"></div></div><div class="mgz-cta-content mgz-flex-position-middle-center"><div class="mgz-cta-content-inner"><h2 class="mgz-cta-content-item mgz-cta-title mgz-animated-item--grow">Windtunnel Test</h2><div class="mgz-cta-content-item mgz-cta-description mgz-animated-item--grow"><p style="text-align: center;">Unsere Regenschirme im Windtunneltest.</p><p style="text-align: center;"><span style="font-size: 14px;"><strong>.. <a href="https://knirps.de/windtunnel">mehr erfahren</a></strong></span></p></div></div></div></div></div></div></div></div></div>
8564<script> 8565 loadScript('https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Hyva_MagezonBuilder/js/jquery.min.js', 'jquery') 8566 .then(() => { 8567 return loadScript('https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Hyva_MagezonBuilder/js/magezon-builder.js', 'mgzbuilder'); 8568 }) 8569 .then(() => { 8570 const elemId = $('.bh0se3q'); 8571 let mgzBuilder = new MagezonBuilder(elemId); 8572 }) 8573</script>
8573</div></div></div></div></div>
8573<script> 8574 loadScript('https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Hyva_MagezonBuilder/js/jquery.min.js', 'jquery') 8575 .then(() => { 8576 return loadScript('https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Hyva_MagezonBuilder/js/magezon-builder.js', 'mgzbuilder'); 8577 }) 8578 .then(() => { 8579 const elemId = $('.w5oceek'); 8580 let mgzBuilder = new MagezonBuilder(elemId); 8581 }) 8582</script>
8582</div></div><div class="sviof2x mgz-element mgz-element-row full_width_row"><div class="mgz-element-inner sviof2x-s"><style> .bfb-element.required .bfb-element-label label > span:after { color: #e22626; content: '*'; font-size: 1.6rem; font-weight: 500; margin-left: 5px; } </style><div class="inner-content mgz-container"><div class="tn4oym6 mgz-element mgz-element-column mgz-col-xs-12"><div class="mgz-element-inner tn4oym6-s"><div class="m8upkua mgz-element mgz-element-row full_width_row"><div class="mgz-element-inner m8upkua-s"><style> .bfb-element.required .bfb-element-label label > span:after { color: #e22626; content: '*'; font-size: 1.6rem; font-weight: 500; margin-left: 5px; } </style><div class="inner-content mgz-container"><div class="n8plai0 mgz-element mgz-element-column mgz-col-md-12"><div class="mgz-element-inner n8plai0-s"><div class="peb9ipg mgz-element mgz-child mgz-element-call_to_action"><div class="mgz-element-inner peb9ipg-s custom-background"><div class="mgz-cta mgz-animated-content mgz-cta-image-top mgz-bg-transform-zoom-in"><a class="mgz-absolute-link" href="https://knirps.de/rookie/" title="Knirps Rookie" ></a> <div class="mgz-cta-bg-wrapper mgz-bg-transform-wrapper"><div class="mgz-cta-bg mgz-bg" style="background-image: url(https://knirps.de/media/knirps/Rookie/P_8539_8540_Rookie_Triple_Pink_Triple_Blue_1.jpg);"></div><div class="mgz-cta-bg-overlay"></div></div><div class="mgz-cta-content mgz-flex-position-middle-center"><div class="mgz-cta-content-inner"><h2 class="mgz-cta-content-item mgz-cta-title mgz-animated-item--grow">ROOKIE</h2><div class="mgz-cta-content-item mgz-cta-description mgz-animated-item--grow"><p style="text-align: center;"><span style="color: #ffffff;">Mit dem ROOKIE immer trocken und sicher am Schulweg. </span></p><p style="text-align: center;"><span style="font-size: 14px;"><strong><span style="color: #ffffff;"><a style="color: #ffffff;" href="https://knirps.de/rookie/">.. mehr erfahren</a></span></strong></span></p></div></div></div></div></div></div></div></div></div>
8582<script> 8583 loadScript('https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Hyva_MagezonBuilder/js/jquery.min.js', 'jquery') 8584 .then(() => { 8585 return loadScript('https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Hyva_MagezonBuilder/js/magezon-builder.js', 'mgzbuilder'); 8586 }) 8587 .then(() => { 8588 const elemId = $('.m8upkua'); 8589 let mgzBuilder = new MagezonBuilder(elemId); 8590 }) 8591</script>
8591</div></div></div></div></div>
8591<script> 8592 loadScript('https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Hyva_MagezonBuilder/js/jquery.min.js', 'jquery') 8593 .then(() => { 8594 return loadScript('https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Hyva_MagezonBuilder/js/magezon-builder.js', 'mgzbuilder'); 8595 }) 8596 .then(() => { 8597 const elemId = $('.sviof2x'); 8598 let mgzBuilder = new MagezonBuilder(elemId); 8599 }) 8600</script>
8600</div></div></div></div></div><div id="newsletter-container container"> 8601 8602</div> 8603</main><footer class="page-footer"><div class="footer content"><div class="text-footer-text"> 8604 <div class="bg-footer-content-bg"> 8605 <div class="container flex mx-auto justify-between flex-wrap"> 8606 <div 8607 class="flex flex-1 py-8 gap-8 flex-col md:flex-row md:items-start md:justify-start" 8608 x-data="{ 8609 openColumn: null, 8610 isDesktop: window.matchMedia('(min-width: 768px)').matches 8611 }" 8612 x-init=" 8613 const mediaQuery = window.matchMedia('(min-width: 768px)'); 8614 const handler = (e) => { isDesktop = e.matches }; 8615 mediaQuery.addEventListener('change', handler); 8616 $watch('isDesktop', () => {}); 8617 " 8618 > 8619 <div x-defer="intersect" x-id="['column-1']" class="md:flex-1"> 8620 <button 8621 role="tab" 8622 class="group flex w-full items-center text-left justify-between md:pointer-events-none md:hidden" 8623 @click="openColumn = openColumn === 'column-1' ? null : 'column-1'" 8624 :aria-expanded="openColumn === 'column-1'" 8625 :aria-controls="$id('column-1')" 8626 > 8627 <p class="font-semibold uppercase">Ãber Knirps</p> 8628 <span 8629 x-cloak 8630 class="transition-transform group-aria-expanded:rotate-180 md:hidden" 8631 > 8632 <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none" role="img"> 8633<path fill-rule="evenodd" clip-rule="evenodd" d="M5.29289 7.29289C5.68342 6.90237 6.31658 6.90237 6.70711 7.29289L10 10.5858L13.2929 7.29289C13.6834 6.90237 14.3166 6.90237 14.7071 7.29289C15.0976 7.68342 15.0976 8.31658 14.7071 8.70711L10.7071 12.7071C10.3166 13.0976 9.68342 13.0976 9.29289 12.7071L5.29289 8.70711C4.90237 8.31658 4.90237 7.68342 5.29289 7.29289Z" fill="currentColor"/> 8634<title>chevron-down</title></svg> 8635 8636 </span> 8637 </button> 8638 <div 8639 role="tabpanel" 8640 x-show="isDesktop || openColumn === 'column-1'" 8641 x-collapse 8642 x-cloak 8643 :aria-labelledby="$id('column-1')" 8644 :aria-hidden="(isDesktop || openColumn === 'column-1') ? 'false' : 'true'" 8645 > 8646 <ul class="mt-3 md:mt-0 gap-1.5 flex flex-col text-sm"> 8647 <li class="mb-4"> 8648 <a href="https://knirps.de/unternehmen" 8649 >Das Unternehmen</a 8650 > 8651 </li> 8652 <li class="mb-4"> 8653 <a href="https://knirps.de/internationale-partner">Internationale Partner</a> 8654 </li> 8655 <li class="mb-4"> 8656 <a href="https://knirps.de/blog" 8657 >Blog</a 8658 > 8659 </li> 8660 <li class="mb-4"> 8661 <a href="https://knirps.de/impressum" 8662 >Impressum</a 8663 > 8664 </li> 8665 <li class="mb-4"> 8666 <a href="https://manage.kmail-lists.com/subscriptions/subscribe?a=YyB7FJ&g=R8ZNBC">Newsletter</a> 8667 </li> 8668 <li> 8669 <a href="https://knirps.de/b2b-individuelle-schirme">B2B - individuelle Schirme</a> 8670 </li> 8671 </ul> 8672 </div> 8673 </div> 8674 8675 <div x-defer="intersect" x-id="['column-2']" class="md:flex-1"> 8676 <button 8677 role="tab" 8678 class="group flex w-full items-center text-left justify-between md:pointer-events-none md:hidden" 8679 @click="openColumn = openColumn === 'column-2' ? null : 'column-2'" 8680 :aria-expanded="openColumn === 'column-2'" 8681 :aria-controls="$id('column-2')" 8682 > 8683 <p class="font-semibold uppercase">Kundenservice</p>
8684 <span 8685 x-cloak 8686 class="transition-transform group-aria-expanded:rotate-180 md:hidden" 8687 > 8688 <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none" role="img"> 8689<path fill-rule="evenodd" clip-rule="evenodd" d="M5.29289 7.29289C5.68342 6.90237 6.31658 6.90237 6.70711 7.29289L10 10.5858L13.2929 7.29289C13.6834 6.90237 14.3166 6.90237 14.7071 7.29289C15.0976 7.68342 15.0976 8.31658 14.7071 8.70711L10.7071 12.7071C10.3166 13.0976 9.68342 13.0976 9.29289 12.7071L5.29289 8.70711C4.90237 8.31658 4.90237 7.68342 5.29289 7.29289Z" fill="currentColor"/> 8690<title>chevron-down</title></svg> 8691 8692 </span> 8693 </button> 8694 <div 8695 role="tabpanel" 8696 x-show="isDesktop || openColumn === 'column-2'" 8697 x-collapse 8698 x-cloak 8699 :aria-labelledby="$id('column-2')" 8700 :aria-hidden="(isDesktop || openColumn === 'column-2') ? 'false' : 'true'" 8701 > 8702 <ul class="mt-3 md:mt-0 gap-1.5 flex flex-col text-sm"> 8703 8704 <li class="mb-4"> 8705 <a href="https://knirps.de/aktionsbedingungen" 8706 >Aktionsbedingungen</a 8707 > 8708 </li> 8709 <li class="mb-4"> 8710 <a href="https://knirps.de/kundeninformation" 8711 >Kundeninformation & AGB</a 8712 > 8713 </li> 8714 <li class="mb-4"> 8715 <a href="https://knirps.de/informationen-versand-lieferlaender" 8716 >Versand & Lieferländer</a 8717 > 8718 </li> 8719 <li class="mb-4">
8720 <a href="https://knirps.de/ruecksendungen" 8721 >Rücksendungen</a 8722 > 8723 </li> 8724 <li class="mb-4"> 8725 <a href="https://knirps.de/widerrufsbelehrung" 8726 >Widerrufsbelehrung</a 8727 > 8728 </li> 8729 <li class="mb-4"> 8730 <a href="https://knirps.de/zahlungsmoeglichkeiten" 8731 >Zahlungsmöglichkeiten</a 8732 > 8733 </li> 8734 </ul> 8735 </div> 8736 </div> 8737 8738 <div x-defer="intersect" x-id="['column-3']" class="md:flex-1"> 8739 <button 8740 role="tab" 8741 class="group flex w-full items-center text-left justify-between md:pointer-events-none md:hidden" 8742 @click="openColumn = openColumn === 'column-3' ? null : 'column-3'" 8743 :aria-expanded="openColumn === 'column-3'" 8744 :aria-controls="$id('column-3')" 8745 > 8746 <p class="font-semibold uppercase">Produktinformationen</p> 8747 <span 8748 x-cloak 8749 class="transition-transform group-aria-expanded:rotate-180 md:hidden" 8750 > 8751 <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none" role="img"> 8752<path fill-rule="evenodd" clip-rule="evenodd" d="M5.29289 7.29289C5.68342 6.90237 6.31658 6.90237 6.70711 7.29289L10 10.5858L13.2929 7.29289C13.6834 6.90237 14.3166 6.90237 14.7071 7.29289C15.0976 7.68342 15.0976 8.31658 14.7071 8.70711L10.7071 12.7071C10.3166 13.0976 9.68342 13.0976 9.29289 12.7071L5.29289 8.70711C4.90237 8.31658 4.90237 7.68342 5.29289 7.29289Z" fill="currentColor"/> 8753<title>chevron-down</title></svg> 8754 8755 </span> 8756 </button> 8757 <div 8758 role="tabpanel" 8759 x-show="isDesktop || openColumn === 'column-3'" 8760 x-collapse 8761 x-cloak 8762 :aria-labelledby="$id('column-3')" 8763 :aria-hidden="(isDesktop || openColumn === 'column-3') ? 'false' : 'true'" 8764 > 8765 <ul class="mt-3 md:mt-0 gap-1.5 flex flex-col text-sm"> 8766 <li class="mb-4"> 8767 <a href="https://knirps.de/faqs-haeufig-gestellte-fragen" 8768 >FAQ - Häufig gestellte Fragen</a 8769 > 8770 </li> 8771 <li class="mb-4"> 8772 <a href="https://knirps.de/garantie" 8773 >Garantie</a 8774 > 8775 </li> 8776 <li class="mb-4"> 8777 <a href="https://knirps.de/contact" 8778 >Kontakt</a 8779 > 8780 </li> 8781 <li class="mb-4"> 8782 <a href="https://www.calameo.com/dopplerschirme/read/00563470286772cc67f30?authid=p0D8BBcX2ld2" 8783 >Sonnenschirm-Katalog 2026</a 8784 > 8785 </li> 8786 <li class="mb-4"> 8787 <a href="https://www.calameo.com/dopplerschirme/read/00563470224e6f895c204" 8788 >Sonnenschirm-Ersatzteilkatalog</a 8789 > 8790 </li> 8791 <li class="mb-4"> 8792 <a href="https://knirps.de/datenschutz">Datenschutz</a> 8793 <li> 8794 <a href="#" onClick="__ucCmp.showSecondLayer();">Datenschutzeinstellungen</a> 8795 </li> 8796 </ul> 8797 </div> 8798 </div> 8799 </div> <div class="pt-8 footer-right max-md:w-full max-md:pb-5 max-md:pt-0 max-md:[&>div]:justify-between"> 8800 <div class="flex flex-row-reverse md:flex-col gap-1 md:items-end py-3 px-0"> 8801 <style>.cmsb12737-flex { 8802display: flex 8803} 8804.cmsb12737-items-center { 8805align-items: center 8806} 8807.cmsb12737-justify-between { 8808justify-content: space-between 8809} 8810.cmsb12737-gap-5 { 8811gap: 1.25rem 8812} 8813@media (min-width: 768px) { 8814.cmsb12737-md\:items-start { 8815align-items: flex-start 8816} 8817}</style> 8818<style>.cmsb12737-flex { 8819display: flex 8820} 8821.cmsb12737-items-center { 8822align-items: center 8823} 8824.cmsb12737-justify-between { 8825justify-content: space-between 8826} 8827.cmsb12737-gap-5 { 8828gap: 1.25rem 8829} 8830@media (min-width: 768px) { 8831.cmsb12737-md\:items-start { 8832align-items: flex-start 8833} 8834}</style> 8835<div class="cmsb12737-justify-between cmsb12737-flex cmsb12737-gap-5 cmsb12737-items-center cmsb12737-md:items-start"> 8836 <a href="https://www.facebook.com/dopplerschirme" target="_blank" rel="noopener noreferrer" aria-label="Facebook"> 8837 <svg xmlns="http://www.w3.org/2000/svg" width="33" height="33" viewBox="0 0 33 33" fill="none" role="img"> 8838<path d="M17.1445 26.7855V17.0109H20.4255L20.9167 13.2016H17.1445V10.7695C17.1445 9.66659 17.4508 8.91493 19.0325 8.91493L21.0496 8.914V5.50699C20.7006 5.46074 19.5033 5.35706 18.1103 5.35706C15.2019 5.35706 13.2108 7.13222 13.2108 10.3924V13.2017H9.92139V17.011H13.2107V26.7856L17.1445 26.7855Z" fill="currentColor"/> 8839<title>facebook</title></svg> 8840 8841 </a> 8842 <a href="https://www.instagram.com/dopplerschirme" target="_blank" rel="noopener noreferrer" aria-label="Instagram"> 8843 <svg xmlns="http://www.w3.org/2000/svg" width="33" height="33" viewBox="0 0 33 33" fill="none" role="img"> 8844<path d="M12.7242 16.0714C12.7242 14.2223 14.2228 12.7229 16.0719 12.7229C17.921 12.7229 19.4203 14.2223 19.4203 16.0714C19.4203 17.9205 17.921 19.4199 16.0719 19.4199C14.2228 19.4199 12.7242 17.9205 12.7242 16.0714ZM10.9141 16.0714C10.9141 18.92 13.2232 21.2292 16.0719 21.2292C18.9205 21.2292 21.2297 18.92 21.2297 16.0714C21.2297 13.2227 18.9205 10.9136 16.0719 10.9136C13.2232 10.9136 10.9141 13.2227 10.9141 16.0714ZM20.2285 10.7091C20.2284 10.9475 20.299 11.1805 20.4314 11.3788C20.5637 11.5771 20.7519 11.7316 20.9721 11.823C21.1924 11.9143 21.4347 11.9383 21.6685 11.8918C21.9024 11.8454 22.1172 11.7307 22.2858 11.5622C22.4545 11.3937 22.5694 11.179 22.616 10.9452C22.6626 10.7114 22.6388 10.469 22.5476 10.2487C22.4565 10.0284 22.3021 9.84012 22.1039 9.7076C21.9057 9.57507 21.6727 9.50428 21.4343 9.50419H21.4339C21.1143 9.50434 20.8079 9.63131 20.5819 9.85722C20.3559 10.0831 20.2288 10.3895 20.2285 10.7091ZM12.0138 24.2475C11.0345 24.2029 10.5022 24.0397 10.1485 23.9019C9.67953 23.7194 9.34493 23.5019 8.99312 23.1506C8.64132 22.7993 8.42355 22.465 8.24178 21.996C8.10389 21.6425 7.94077 21.11 7.89625 20.1307C7.84755 19.0719 7.83783 18.7539 7.83783 16.0715C7.83783 13.3891 7.84836 13.0719 7.89625 12.0122C7.94085 11.0329 8.10518 10.5015 8.24178 10.1469C8.42436 9.67792 8.6418 9.34331 8.99312 8.99151C9.34444 8.63971 9.67873 8.42194 10.1485 8.24017C10.5021 8.10228 11.0345 7.93915 12.0138 7.89464C13.0726 7.84594 13.39
884407 7.83622 16.0719 7.83622C18.7531 7.83622 19.0714 7.84674 20.1311 7.89464C21.1104 7.93923 21.6418 8.10356 21.9964 8.24017C22.4654 8.42194 22.8 8.64019 23.1518 8.99151C23.5036 9.34283 23.7206 9.67792 23.9032 10.1469C24.041 10.5005 24.2042 11.0329 24.2487 12.0122C24.2974 13.0719 24.3071 13.3891 24.3071 16.0715C24.3071 18.7539 24.2974 19.071 24.2487 20.1307C24.2041 21.11 24.0402 21.6423 23.9032 21.996C23.7206 22.465 23.5031 22.7996 23.1518 23.1506C22.8005 23.5016 22.4654 23.7194 21.9964 23.9019C21.6429 24.0398 21.1104 24.203 20.1311 24.2475C19.0723 24.2962 18.7543 24.3059 16.0719 24.3059C13.3895 24.3059 13.0723 24.2962 12.0138 24.2475ZM11.9307 6.08756C10.8613 6.13626 10.1307 6.30581 9.49254 6.55412C8.83169 6.81054 8.27224 7.15455 7.71319 7.71271C7.15415 8.27087 6.81103 8.8312 6.55461 9.49205C6.3063 10.1306 6.13675 10.8609 6.08805 11.9302C6.03855 13.0012 6.02722 13.3436 6.02722 16.0714C6.02722 18.7992 6.03855 19.1416 6.08805 20.2126C6.13675 21.282 6.3063 22.0122 6.55461 22.6507C6.81103 23.3112 7.15423 23.8721 7.71319 24.43C8.27216 24.988 8.83169 25.3315 9.49254 25.5886C10.1319 25.8369 10.8613 26.0065 11.9307 26.0552C13.0022 26.1039 13.3441 26.116 16.0719 26.116C18.7997 26.116 19.1421 26.1047 20.2131 26.0552C21.2825 26.0065 22.0127 25.8369 22.6512 25.5886C23.3116 25.3315 23.8715 24.9882 24.4305 24.43C24.9896 23.8719 25.332 23.3112 25.5891 22.6507C25.8374 22.0122 26.0078 21.2819 26.0557 20.2126C26.1044 19.1408 26.1157 18.7992 26.1157 16.0714C26.1157 13.3436 26.1044 13.0012 26.0557 11.9302C26.007 10.8608 25.8374 10.1302 25.5891 9.49205C25.332 8.8316 24.9887 8.27175 24.4305 7.71271C23.8724 7.15366 23.3116 6.81054 22.652 6.55412C22.0127 6.30581 21.2824 6.13546 20.2139 6.08756C19.1429 6.03887 18.8005 6.02673 16.0727 6.02673C13.3449 6.02673 13.0022 6.03806 11.9307 6.08756Z" fill="currentColor"/> 8845<title>instagram</title></svg> 8846 8847 </a> 8848 <a href="https://www.youtube.com/dopplerschirme" target="_blank" rel="noopener noreferrer" aria-label="Pinterest"> 8849 <svg xmlns="http://www.w3.org/2000/svg" width="33" height="33" viewBox="0 0 33 33" fill="none" role="img"> 8850<path d="M13.3932 20.0922L20.3441 16.0743L13.3932 12.0565V20.0922ZM28.8754 9.60559C29.0495 10.2351 29.17 11.0788 29.2504 12.1502C29.3441 13.2217 29.3843 14.1458 29.3843 14.9493L29.4647 16.0743C29.4647 19.0074 29.2504 21.1636 28.8754 22.5431C28.5406 23.7484 27.7638 24.5252 26.5584 24.8601C25.929 25.0342 24.7772 25.1547 23.0093 25.2351C21.2682 25.3288 19.6745 25.369 18.2013 25.369L16.0718 25.4493C10.4602 25.4493 6.96467 25.2351 5.58521 24.8601C4.37985 24.5252 3.60306 23.7484 3.26824 22.5431C3.09413 21.9136 2.9736 21.0699 2.89324 19.9984C2.79949 18.927 2.75931 18.0029 2.75931 17.1993L2.67896 16.0743C2.67896 13.1413 2.89324 10.9851 3.26824 9.60559C3.60306 8.40023 4.37985 7.62345 5.58521 7.28863C6.21467 7.11452 7.36646 6.99398 9.13431 6.91363C10.8754 6.81988 12.4691 6.7797 13.9423 6.7797L16.0718 6.69934C21.6834 6.69934 25.179 6.91363 26.5584 7.28863C27.7638 7.62345 28.5406 8.40023 28.8754 9.60559Z" fill="#EBEDEC"/> 8851<title>youtube</title></svg> 8852 8853 </a> 8854</div> 8855 <div class="my-8"> 8856 <h3 class="text-lg mb-3 lg:text-xl">Zahlungsmöglichkeiten</h3> 8857 <ul 8858 class="flex flex-wrap gap-3 [&_li]:w-full [&_li]:max-w-20 justify-center lg:justify-start" 8859 > 8860 <li> 8861 <svg xmlns="http://www.w3.org/2000/svg" width="60" height="40" viewBox="0 0 60 41" fill="none" class="w-full h-auto" role="img"> 8862<rect x="0.5" y="1.03571" width="59" height="39" rx="3.5" fill="white" stroke="#F3F3F3"/> 8863<path fill-rule="evenodd" clip-rule="evenodd" d="M27.3502 20.7918L27.6114 19.1834L27.0296 19.1702H24.251L26.182 7.3007C26.188 7.26476 26.2075 7.23139 26.2359 7.20765C26.2644 7.18392 26.3008 7.1709 26.3388 7.1709H31.024C32.5795 7.1709 33.6528 7.48461 34.2132 8.10391C34.4759 8.39443 34.6433 8.69811 34.7243 9.03217C34.8092 9.38278 34.8106 9.80161 34.7278 10.3125L34.7217 10.3497V10.6771L34.9845 10.8214C35.2057 10.9352 35.3815 11.0654 35.5164 11.2145C35.7411 11.463 35.8865 11.7787 35.9479 12.1529C36.0114 12.5378 35.9904 12.996 35.8865 13.5147C35.7666 14.1112 35.5728 14.6308 35.311 15.0558C35.0704 15.4475 34.7637 15.7725 34.3995 16.0242C34.0519 16.2635 33.6388 16.4451 33.1718 16.5613C32.7192 16.6755 32.2032 16.7332 31.6373 16.7332H31.2727C31.0121 16.7332 30.7588 16.8242 30.56 16.9874C30.3606 17.1539 30.2289 17.3815 30.1884 17.6304L30.1609 17.7752L29.6993 20.6104L29.6785 20.7144C29.6729 20.7473 29.6633 20.7638 29.6494 20.7749C29.6369 20.785 29.619 20.7918 29.6015 20.7918H27.3502Z" fill="#28356A"/> 8864<path fill-rule="evenodd" clip-rule="evenodd" d="M35.2336 10.3876C35.2197 10.4742 35.2036 10.5628 35.1857 10.6538C34.5679 13.7291 32.454 14.7915 29.7543 14.7915H28.3797C28.0496 14.7915 27.7713 15.0239 27.7199 15.3396L26.8168 20.893C26.7834 21.1004 26.9482 21.2872 27.1639 21.2872H29.602C29.8906 21.2872 30.1359 21.0839 30.1813 20.8079L30.2053 20.6878L30.6643 17.8639L30.6938 17.709C30.7387 17.432 30.9846 17.2286 31.2732 17.2286H31.6378C33.9999 17.2286 35.849 16.2989 36.3895 13.6086C36.6152 12.4847 36.4984 11.5463 35.901 10.8863C35.7202 10.6873 35.4959
886410.5221 35.2336 10.3876Z" fill="#298FC2"/> 8865<path fill-rule="evenodd" clip-rule="evenodd" d="M34.5871 10.1377C34.4927 10.111 34.3953 10.0868 34.2954 10.065C34.195 10.0437 34.0921 10.0249 33.9862 10.0083C33.6156 9.95026 33.2095 9.92273 32.7745 9.92273H29.1023C29.0118 9.92273 28.9259 9.94253 28.8491 9.97834C28.6796 10.0573 28.5539 10.2127 28.5234 10.403L27.7421 15.1997L27.7197 15.3396C27.7711 15.0238 28.0494 14.7915 28.3795 14.7915H29.7541C32.4538 14.7915 34.5677 13.7285 35.1855 10.6538C35.204 10.5628 35.2195 10.4742 35.2334 10.3875C35.0771 10.3071 34.9078 10.2383 34.7255 10.1798C34.6805 10.1652 34.634 10.1513 34.5871 10.1377Z" fill="#22284F"/> 8866<path fill-rule="evenodd" clip-rule="evenodd" d="M28.5232 10.403C28.5537 10.2127 28.6795 10.0573 28.8489 9.9789C28.9263 9.94295 29.0117 9.92315 29.1022 9.92315H32.7744C33.2093 9.92315 33.6155 9.95082 33.9861 10.0089C34.092 10.0253 34.1949 10.0443 34.2953 10.0656C34.3952 10.0873 34.4926 10.1115 34.587 10.1381C34.6339 10.1517 34.6803 10.1658 34.7258 10.1798C34.9081 10.2384 35.0775 10.3077 35.2338 10.3876C35.4177 9.2511 35.2323 8.47732 34.5985 7.77665C33.8996 7.00518 32.6385 6.67505 31.0247 6.67505H26.3394C26.0098 6.67505 25.7286 6.90739 25.6776 7.22368L23.7262 19.2153C23.6877 19.4525 23.8764 19.6665 24.1232 19.6665H27.0157L28.5232 10.403Z" fill="#28356A"/> 8867<path fill-rule="evenodd" clip-rule="evenodd" d="M13.5462 24.0565H10.1302C9.89638 24.0565 9.69757 24.2212 9.66105 24.445L8.27945 32.9366C8.25203 33.1042 8.38592 33.2552 8.56123 33.2552H10.192C10.4258 33.2552 10.6246 33.0907 10.6611 32.8665L11.0337 30.5761C11.0697 30.3519 11.2689 30.1872 11.5022 30.1872H12.5836C14.8338 30.1872 16.1324 29.1316 16.4717 27.0399C16.6244 26.1246 16.4781 25.4056 16.036 24.902C15.5505 24.3491 14.6894 24.0565 13.5462 24.0565ZM13.9401 27.158C13.7533 28.3463 12.8167 28.3463 11.9113 28.3463H11.3957L11.7574 26.1271C11.7789 25.9929 11.8987 25.8942 12.0386 25.8942H12.2749C12.8917 25.8942 13.4736 25.8942 13.7743 26.235C13.9536 26.4383 14.0085 26.7405 13.9401 27.158Z" fill="#28356A"/> 8868<path fill-rule="evenodd" clip-rule="evenodd" d="M23.8445 27.0556H22.2086C22.0693 27.0556 21.9488 27.1543 21.9274 27.2884L21.855 27.732L21.7407 27.5712C21.3865 27.0729 20.5968 26.9064 19.8087 26.9064C18.0009 26.9064 16.457 28.2337 16.1563 30.0955C16.0001 31.0241 16.2222 31.9123 16.7658 32.5316C17.2643 33.1009 17.9775 33.3383 18.8261 33.3383C20.2827 33.3383 21.0902 32.4304 21.0902 32.4304L21.0173 32.871C20.9899 33.0395 21.1238 33.1906 21.2981 33.1906H22.7715C23.0058 33.1906 23.2037 33.0259 23.2406 32.8017L24.1247 27.3742C24.1527 27.2071 24.0192 27.0556 23.8445 27.0556ZM21.5642 30.142C21.4064 31.0479 20.6647 31.6561 19.7187 31.6561C19.2437 31.6561 18.8641 31.5083 18.6203 31.2285C18.3785 30.9506 18.2867 30.555 18.3635 30.1143C18.511 29.2162 19.2651 28.5881 20.1967 28.5881C20.6612 28.5881 21.0389 28.7378 21.2876 29.0199C21.5368 29.3052 21.6357 29.7032 21.5642 30.142Z" fill="#28356A"/> 8869<path fill-rule="evenodd" clip-rule="evenodd" d="M32.4306 27.1913H30.7867C30.6299 27.1913 30.4826 27.2669 30.3937 27.3933L28.1265 30.6307L27.1655 27.5196C27.105 27.3249 26.9198 27.1913 26.7099 27.1913H25.0947C24.8982 27.1913 24.762 27.3773 24.8244 27.5565L26.6351 32.7075L24.9328 35.0371C24.7989 35.2206 24.9338 35.4729 25.165 35.4729H26.8069C26.9627 35.4729 27.1085 35.3992 27.1969 35.2754L32.6643 27.6247C32.7952 27.4417 32.6608 27.1913 32.4306 27.1913Z" fill="#28356A"/> 8870<path fill-rule="evenodd" clip-rule="evenodd" d="M37.9108 24.0565H34.4944C34.2611 24.0565 34.0623 24.2212 34.0258 24.445L32.6442 32.9366C32.6168 33.1042 32.7507 33.2552 32.925 33.2552H34.6782C34.8409 33.2552 34.9803 33.14 35.0057 32.9831L35.3979 30.5761C35.4338 30.3519 35.6332 30.1872 35.8664 30.1872H36.9474C39.1979 30.1872 40.4962 29.1316 40.8359 27.0399C40.9892 26.1246 40.8419 25.4056 40.3998 24.902C39.9147 24.3491 39.0541 24.0565 37.9108 24.0565ZM38.305 27.158C38.1186 28.3463 37.182 28.3463 36.276 28.3463H35.7611L36.1232 26.1271C36.1446 25.9929 36.2635 25.8942 36.4039 25.8942H36.6402C37.2565 25.8942 37.8389 25.8942 38.1396 26.235C38.3189 26.4383 38.3734 26.7405 38.305 27.158Z" fill="#298FC2"/> 8871<path fill-rule="evenodd" clip-rule="evenodd" d="M48.207 27.0556H46.5722C46.4318 27.0556 46.3125 27.1543 46.2915 27.2884L46.219 27.732L46.1042 27.5712C45.7501 27.0729 44.9608 26.9064 44.1726 26.9064C42.365 26.9064 40.8216 28.2337 40.521 30.0955C40.3651 31.0241 40.5863 31.9123 41.1297 32.5316C41.6293 33.1009 42.3415 33.3383 43.1902 33.3383C44.6466 33.3383 45.4543 32.4304 45.4543 32.4304L45.3814 32.871C45.354 33.0395 45.4877 33.1906 45.6632 33.1906H47.1361C47.3694 33.1906 47.5682 33.0259 47.6047 32.8017L48.4892 27.3742C48.5162 27.2071 48.3823 27.0556 48.207 27.0556ZM45.9268 30.142C45.77 3
88711.0479 45.0272 31.6561 44.0811 31.6561C43.6071 31.6561 43.2266 31.5083 42.9827 31.2285C42.7411 30.9506 42.6502 30.555 42.726 30.1143C42.8744 29.2162 43.6276 28.5881 44.5592 28.5881C45.0237 28.5881 45.4013 28.7378 45.6501 29.0199C45.9002 29.3052 45.9992 29.7032 45.9268 30.142Z" fill="#298FC2"/> 8872<path fill-rule="evenodd" clip-rule="evenodd" d="M49.9989 24.2899L48.5968 32.937C48.5694 33.1046 48.7032 33.2556 48.8775 33.2556H50.2871C50.5214 33.2556 50.7201 33.0911 50.7561 32.8669L52.1386 24.3757C52.1662 24.208 52.0323 24.0565 51.858 24.0565H50.2797C50.1403 24.0569 50.0204 24.1558 49.9989 24.2899Z" fill="#298FC2"/> 8873<title>paypal-rectangle</title></svg> 8874 8875 </li> 8876 <li> 8877 <img src="https://dopplerschirme.com/static/version1781857740/frontend/Hyva/base/de_DE/images/payment-icons/visa.svg" alt="Visa" width="60" height="40"> 8878 </li> 8879 <li> 8880 <svg xmlns="http://www.w3.org/2000/svg" width="60" height="40" viewBox="0 0 60 41" fill="none" class="w-full h-auto" role="img"> 8881<rect x="0.5" y="1.03571" width="59" height="39" rx="3.5" fill="white" stroke="#F3F3F3"/> 8882<path d="M35.4932 29.5122H24.7852V11.0479H35.4932V29.5122Z" fill="#FF5F00"/> 8883<path d="M25.4712 20.2786C25.4712 16.533 27.299 13.1965 30.1453 11.0464C28.0639 9.47413 25.437 8.53569 22.5821 8.53569C15.8234 8.53569 10.3447 13.7931 10.3447 20.2786C10.3447 26.764 15.8234 32.0214 22.5821 32.0214C25.437 32.0214 28.0639 31.083 30.1453 29.5107C27.299 27.3606 25.4712 24.0241 25.4712 20.2786Z" fill="#EB001B"/> 8884<path d="M49.9351 20.2786C49.9351 26.764 44.4565 32.0214 37.6978 32.0214C34.8429 32.0214 32.216 31.083 30.1338 29.5107C32.9809 27.3606 34.8087 24.0241 34.8087 20.2786C34.8087 16.533 32.9809 13.1965 3
88840.1338 11.0464C32.216 9.47413 34.8429 8.53569 37.6978 8.53569C44.4565 8.53569 49.9351 13.7931 49.9351 20.2786Z" fill="#F79E1B"/> 8885<title>mastercard-rectangle</title></svg> 8886 8887 </li> 8888 <li> 8889 <svg xmlns="http://www.w3.org/2000/svg" width="60" height="40" viewBox="0 0 60 41" fill="none" class="w-full h-auto" role="img"> 8890<rect x="0.5" y="1.03571" width="59" height="39" rx="3.5" fill="white" stroke="#F3F3F3"/> 8891<path fill-rule="evenodd" clip-rule="evenodd" d="M18.1833 15.4622C17.7469 15.967 17.0486 16.3651 16.3503 16.3082C16.2631 15.6258 16.6049 14.9006 17.005 14.4528C17.4414 13.9338 18.2051 13.5641 18.8234 13.5357C18.8961 14.2466 18.6125 14.9433 18.1833 15.4622ZM18.8161 16.4433C18.201 16.4087 17.6396 16.6241 17.1863 16.7981C16.8945 16.9101 16.6474 17.0049 16.4594 17.0049C16.2485 17.0049 15.9912 16.905 15.7024 16.7929C15.3239 16.6459 14.8911 16.4779 14.4374 16.4859C13.3972 16.5002 12.4298 17.076 11.8988 17.9931C10.8078 19.8272 11.6152 22.5428 12.6698 24.0357C13.1863 24.775 13.8045 25.5855 14.6192 25.557C14.9776 25.5438 15.2354 25.4369 15.5022 25.3262C15.8094 25.1989 16.1285 25.0665 16.6267 25.0665C17.1077 25.0665 17.4129 25.1954 17.7058 25.3191C17.9843 25.4368 18.2518 25.5497 18.6488 25.5428C19.4926 25.5286 20.0236 24.8035 20.54 24.0641C21.0973 23.2706 21.3422 22.4962 21.3794 22.3787L21.3837 22.3651C21.3829 22.3642 21.376 22.3611 21.3639 22.3557L21.3638 22.3557C21.1775 22.2723 19.7535 21.6352 19.7399 19.9267C19.7262 18.4927 20.8693 17.7661 21.0493 17.6517C21.0603 17.6447 21.0676 17.64 21.071 17.6376C20.3436 16.5855 19.2089 16.4717 18.8161 16.4433ZM24.6569 25.4646V14.3817H28.912C31.1087 14.3817 32.6434 15.8604 32.6434 18.0215C32.6434 20.1826 31.0796 21.6755 28.8538 21.6755H26.4172V25.4646H24.6569ZM26.4172 15.8319H28.4465C29.974 15.8319 30.8468 16.6281 30.8468 18.0286C30.8468 19.4291 29.974 20.2324 28.4392 20.2324H26.4172V15.8319ZM38.4551 24.1352C37.9896 25.0025 36.964 25.5499 35.8584 25.5499C34.2218 25.5499 33.0799 24.5973 33.0799 23.1613C33.0799 21.7395 34.1855 20.922 36.2294 20.8011L38.426 20.6731V20.0618C38.426 19.1589 37.8223 18.6684 36.7458 18.6684C35.8584 18.6684 35.2111 19.1163 35.0801 19.7987H33.4945C33.5454 18.3627 34.9274 17.3177 36.7967 17.3177C38.8115 17.3177 40.1208 18.3485 40.1208 19.948V25.4646H38.4915V24.1352H38.4551ZM36.3312 24.2348C35.3929 24.2348 34.7965 23.794 34.7965 23.1186C34.7965 22.422 35.3711 22.0167 36.4694 21.9528L38.426 21.8319V22.4575C38.426 23.4954 37.5241 24.2348 36.3312 24.2348ZM45.5252 25.8983C44.8196 27.839 44.0122 28.4788 42.2957 28.4788C42.1647 28.4788 41.7283 28.4646 41.6265 28.4362V27.1068C41.7356 27.121 42.0047 27.1352 42.1429 27.1352C42.9212 27.1352 43.3576 26.8153 43.6267 25.9836L43.7868 25.4931L40.8045 17.4243H42.6448L44.7178 23.9717H44.7542L46.8272 17.4243H48.6165L45.5252 25.8983Z" fill="black"/> 8892<title>applepay-rectangle</title></svg> 8893 8894 </li> 8895 <li> 8896 <svg xmlns="http://www.w3.org/2000/svg" width="60" height="40" viewBox="0 0 60 41" fill="none" class="w-full h-auto" role="img"> 8897<rect x="0.5" y="1.03571" width="59" height="39" rx="3.5" fill="white" stroke="#F3F3F3"/> 8898<path fill-rule="evenodd" clip-rule="evenodd" d="M28.88 24.6539V20.1428V20.1419H31.4046C32.4454 20.1425 33.3201 19.8264 34.0287 19.1935C34.7449 18.5929 35.1453 17.7292 35.1249 16.8291C35.1391 15.9339 34.7394 15.0767 34.0287 14.478C33.3263 13.8416 32.3816 13.4944 31.4046 13.5135H27.3521V24.6539H28.88ZM28.88 18.7739V14.8851V14.8842H31.4425C32.0136 14.8691 32.5642 15.0844 32.9544 15.4753C33.347 15.8328 33.5685 16.3238 33.5685 16.8366C33.5685 17.3494 33.347 17.8405 32.9544 18.1979C32.5594 18.5806 32.0106 18.7897 31.4425 18.7739H28.88Z" fill="#5F6368"/> 8899<path fill-rule="evenodd" clip-rule="evenodd" d="M41.3204 17.6308C40.6669 17.0655 39.7754 16.7828 38.646 16.7828C37.1952 16.7828 36.0996 17.2806 35.3594 18.2762L36.7051 19.0699C37.2024 18.3956 37.8779 18.0584 38.7314 18.0584C39.2756 18.0524 39.8022 18.2387 40.2062 18.5802C40.6091 18.8921 40.8409 19.3572 40.8374 19.8468V20.1739C40.2502 19.8628 39.503 19.7073 38.5957 19.7073C37.5327 19.7085 36.683 19.9419 36.0465 20.4077C35.41 20.8735 35.0917 21.5008 35.0917 22.2895C35.0779 23.0077 35.4105 23.6935 35.9971 24.1562C36.6007 24.6539 37.3508 24.9028 38.2474 24.9028C39.2977 24.9028 40.1392 24.4673 40.7719 23.5962H40.8383V24.6539H42.2999V19.9562C42.3005 18.9713 41.974 18.1962 41.3204 17.6308ZM37.176 23.2539C36.8559 23.0379 36.6671 22.6902 36.6692 22.3206C36.6692 21.9055 36.877 21.5597 37.2955 21.2753C37.71 20.995 38.2275 20.8548 38.8482 20.8548C39.7005 20.8548 40.3648 21.0326 40.8412 21.3882C40.8412 21.9891 40.5882 22.5126 40.082 22.9588C39.6261 23.3859 39.008 23.6263 38.3632 23.6273C37.9333 23.6348 37.5139 23.5029 37.176 23.2539Z" fill="#5F6368"/> 8900<path fill-rule="evenodd" clip-rule="evenodd" d="M50.6899 17.0317L45.5877 28.0139H44.0104L45.9038 24.1712L42.5488 17.0317H44.2097L46.6346 22.5072H46.6678L49.0262 17.0317H50.6899Z" fill="#5F6368"/> 8901<path fill-rule="evenodd" clip-rule="evenodd" d="M22.7054 19.1704C22.706 18.7342 22.6666 18.2988 22.5877 17.869H16.1436V20.3339H19.8345C19.6819 21.1294 19.1888 21.832 18.4697 22.2788V23.8788H20.6725C21.9623 22.765 22.7054 21.1179 22.7054 19.1704Z" fill="#4285F4"/> 8902<path fill-rule="evenodd" clip-rule="evenodd" d="M16.1434 25.4246C17.9875 25.4246 19.5401 24.8575 20.6724 23.8797L18.4696 22.2797C17.8565 22.6691 17.0669 22.8913 16.1434 22.8913C14.3611 22.8913 12.8483 21.766 12.3073 20.2495H10.0381V21.8984C11.198 24.0601 13.5603 25.4245 16.1434 25.4246Z" fill="#34A853"/> 8903<path fill-rule="evenodd" clip-rule="evenodd" d="M12.3074 20.2495C12.0214 19.4549 12.0214 18.5943 12.3074 17.7997V16.1508H10.0382C9.06801 17.9589 9.06801 20.0903 10.0382 21.8984L12.3074 20.2495Z" fill="#FBBC04"/> 8904<path fill-rule="evenodd" clip-rule="evenodd" d="M16.1434 15.1579C17.1179 15.143 18.0595 15.4878 18.7648 16.1179L20.7151 14.2912C19.4784 13.2033 17.84 12.606 16.1434 12.6246C13.5603 12.6247 11.198 13.989 10.0381 16.1508L12.3073 17.7997C12.8483 16.2832 14.3611 15.1579 16.1434 15.1579Z" fill="#EA4335"/> 8905<title>googlepay-rectangle</title></svg> 8906 8907 </li> 8908 <li> 8909 <svg xmlns="http://www.w3.org/2000/svg" width="60" height="40" viewBox="0 0 60 41" fill="none" class="w-full h-auto" role="img"> 8910<rect x="0.5" y="1.03571" width="59" height="39" rx="3.5" fill="white" stroke="#F3F3F3"/> 8911<path d="M54.4736 16.7388H55.0635C55.1619 16.7389 55.2109 16.7816 55.2109 16.8638C55.2003 16.9503 55.1749 17.0343 55.1367 17.1129L52.8203 22.9263C52.6301 23.4037 52.41 23.7466 52.1611 23.9547C51.9123 24.1625 51.5865 24.2668 51.1836 24.2662C50.9813 24.2688 50.7796 24.2438 50.584 24.1929C50.5184 24.1791 50.4588 24.1445 50.415 24.0943C50.385 24.0466 50.3668 23.9925 50.3623 23.9371V23.6119C50.3623 23.4804 50.4147 23.4146 50.5205 23.4146C50.5737 23.417 50.6266 23.4241 50.6787 23.4351C50.7722 23.451 50.8671 23.4576 50.9619 23.4556C51.1854 23.4695 51.4072 23.4034 51.585 23.2691C51.7324 23.1446 51.8653 22.9159 51.9844 22.5836L52.1846 22.0582L50.1562 17.1129C50.1182 17.0343 50.0931 16.9503 50.083 16.8638C50.083 16.7815 50.1319 16.7389 50.2295 16.7388H50.8613C50.9422 16.7312 51.024 16.7494 51.0938 16.7906C51.1531 16.8559 51.1958 16.9344 51.2188 17.0191L52.6943 21.0474L54.1162 17.0191C54.1392 16.9344 54.1819 16.8559 54.2412 16.7906C54.3109 16.7494 54.3927 16.7312 54.4736 16.7388ZM42.124 16.5855C42.4394 16.5797 42.7526 16.6422 43.041 16.7681C43.3126 16.891 43.5509 17.0763 43.7354 17.3082C43.9361 17.565 44.0839 17.858 44.1719 18.1705C44.2785 18.541 44.3304 18.925 44.3252 19.3101C44.33 19.7033 44.2754 20.0952 44.1621 20.4722C44.0673 20.7923 43.9118 21.0919 43.7041 21.355C43.5113 21.5943 43.2661 21.788 42.9873 21.9214C42.6944 22.0555 42.3736 22.1214 42.0508 22.1148C41.447
89115 22.1245 40.8633 21.905 40.4199 21.5015V23.9341C40.4284 23.9914 40.4087 24.0495 40.3672 24.0904C40.3257 24.1312 40.267 24.1505 40.209 24.1422H39.5869C39.5289 24.1505 39.4702 24.1313 39.4287 24.0904C39.3873 24.0495 39.3675 23.9914 39.376 23.9341V16.9478C39.3679 16.8906 39.3883 16.8334 39.4297 16.7925C39.4711 16.7518 39.529 16.7319 39.5869 16.7398H40.0498C40.1102 16.7342 40.171 16.7533 40.2168 16.7925C40.2626 16.8318 40.2901 16.8881 40.293 16.9478L40.3457 17.2798C40.5979 17.0606 40.8864 16.8853 41.1982 16.7613C41.4928 16.6455 41.8069 16.5855 42.124 16.5855ZM6.55176 16.5484C7.04069 16.5484 7.67944 16.6769 8.06348 17.0416C8.51419 17.4577 8.51184 18.0029 8.50879 18.5982C8.50854 18.6472 8.50781 18.697 8.50781 18.7466V20.2877C8.50781 20.7029 8.66452 20.9099 8.8291 21.1275C8.84859 21.1533 8.86822 21.1792 8.8877 21.2056C8.9516 21.2931 8.96552 21.4025 8.8877 21.4683C8.68234 21.6375 8.31721 21.9503 8.11719 22.1265L8.10938 22.1246C8.04328 22.1809 7.94823 22.1903 7.87207 22.148C7.58781 21.9148 7.50173 21.7889 7.37012 21.5953C7.34746 21.562 7.32349 21.5261 7.29688 21.4879C6.74483 22.0418 6.35446 22.2076 5.64062 22.2076C4.79537 22.2075 4.1377 21.6925 4.1377 20.6636C4.13787 19.8603 4.58218 19.3147 5.2041 19.0464C5.66348 18.8477 6.27669 18.7853 6.80664 18.732C6.9052 18.7221 7.00148 18.7129 7.09277 18.7027V18.3326C7.08814 18.1638 7.06499 17.9932 6.9707 17.856C6.84803 17.6737 6.61524 17.5992 6.40723 17.5992C6.0242 17.5992 5.6833 17.7926 5.59961 18.1929C5.58902 18.2864 5.51518 18.3615 5.4209 18.3755L4.45605 18.2711C4.40792 18.2643 4.36416 18.2388 4.33594 18.1998C4.30771 18.1607 4.29739 18.1111 4.30664 18.064C4.52988 16.9004 5.5963 16.5485 6.55176 16.5484ZM19.7139 16.5455C20.2019 16.5455 20.8407 16.674 21.2256 17.0386C21.677 17.4526 21.6744 17.9933 21.6709 18.5855C21.6706 18.6375 21.6699 18.69 21.6699 18.7427V20.2857C21.6699 20.6998 21.8258 20.9063 21.9902 21.1236C22.0098 21.1495 22.0302 21.1761 22.0498 21.2027C22.1172 21.2938 22.1311 21.4011 22.0449 21.4615C21.8395 21.6307 21.4753 21.9435 21.2754 22.1187C21.2089 22.1744 21.1142 22.1831 21.0381 22.1412C20.7525 21.9069 20.6677 21.7826 20.5342 21.5865C20.5119 21.5537 20.4881 21.5186 20.4619 21.481C19.9108 22.035 19.5178 22.2007 18.8066 22.2007C17.9612 22.2007 17.3037 21.6859 17.3037 20.6578C17.3039 19.8536 17.745 19.3079 18.374 19.0396C18.8345 18.84 19.4518 18.7781 19.9834 18.7252C20.0798 18.7156 20.1734 18.7067 20.2627 18.6968V18.3297C20.258 18.1608 20.2347 17.9898 20.1396 17.8531C20.0205 17.671 19.7832 17.5953 19.5762 17.5953C19.1931 17.5953 18.854 17.7895 18.7695 18.19C18.7587 18.2832 18.6858 18.3581 18.5918 18.3726L17.6182 18.2691C17.5696 18.2625 17.5255 18.2362 17.4971 18.1968C17.4688 18.1576 17.4583 18.1084 17.4678 18.0611C17.6918 16.8963 18.7583 16.5455 19.7139 16.5455ZM29.418 16.5425C30.9087 16.5425 31.7147 17.8049 31.7148 19.4088C31.7148 20.9593 30.8261 22.189 29.418 22.189C27.9558 22.1889 27.1593 20.9274 27.1592 19.356C27.1592 17.7845 27.9655 16.5426 29.418 16.5425ZM47.4453 16.5923C48.1118 16.5923 48.6031 16.7274 48.9189 16.9966C49.2348 17.266 49.3939 17.6847 49.3945 18.2525V21.7994C49.4025 21.8565 49.3822 21.9139 49.3408 21.9547C49.2995 21.9953 49.2414 22.0153 49.1836 22.0074H48.7305C48.673 22.013 48.615 21.9949 48.5713 21.9576C48.5277 21.9204 48.5018 21.8669 48.499 21.8101L48.4453 21.4673C48.1975 21.6789 47.9147 21.8468 47.6094 21.9644C47.3197 22.0789 47.0103 22.1389 46.6982 22.1402C46.1933 22.1402 45.7932 21.9997 45.498 21.7193C45.203 21.4389 45.0549 21.0636 45.0537 20.5933C45.0537 20.0885 45.2356 19.6849 45.6006 19.3834C45.9657 19.0818 46.4577 18.9316 47.0752 18.9322C47.5226 18.939 47.9679 18.9973 48.4014 19.107V18.4254C48.4013 18.0514 48.3167 17.7882 48.1484 17.6363C47.9801 17.4846 47.6855 17.4084 47.2646 17.4078C46.7407 17.4127 46.2195 17.492 45.7188 17.6441L45.6396 17.6705C45.6112 17.6804 45.581 17.6856 45.5508 17.6861C45.4621 17.6859 45.4141 17.6238 45.4141 17.4986V17.2213C45.4073 17.1512 45.4226 17.0808 45.457 17.0191C45.5025 16.9689 45.5603 16.9303 45.625 16.9088C45.8923 16.8017 46.1712 16.7251 46.4561 16.6802C46.7825 16.622 47.1136 16.5924 47.4453 16.5923ZM14.79 16.5611C15.3192 16.4804 15.8517 16.687 16.1826 17.1021C16.5016 17.5299 16.4355 18.1542 16.4355 18.6959V21.9029C16.4346 21.9525 16.4133 21.9994 16.377 22.0338C16.3407 22.068 16.2924 22.0875 16.2422 22.0865H15.2383C15.1396 22.0814 15.0619 22.0013 15.0605 21.9039V19.2095C15.0605 18.9957 15.0793 18.4608 15.0322 18.2574C14.9576 17.9155 14.7321 17.8189 14.4414 17.8189C14.1751 17.827 13.9394 17.9914 13.8418 18.2359C13.7388 18.4936 13.7471 18.9204 13.7471 19.2095V21.9029C13.7461 21.9524 13.7256 21.9994 13.6895 22.0338C13.6533 22.0681 13.6048 22.0873 13.5547 22.0865H12.5479C12.4495 22.0808 12.3719 22.001 12.3701 21.9039V19.2095C12.3701 18.6424 12.4592 17.8072 11.748 17.8072C11.037 17.8073 11.0547 18.6197 11.0547 19.2095V21.9029C11.0537 21.9525 11.0325 21.9994 10.9961 22.0338C10.9598 22.068 10.9116 22.0875 10.8613 22.0865H9.85645C9.76334 22.0817 9.68782 22.01 9.67871 21.9185V16.8345C9.68222 16.7328 9.76781 16.6519 9.87109 16.6529H10.8066C10.9026 16.6581 10.9791 16.7341 10.9844 16.8287V17.4918H11.0029C11.2465 16.8495 11.7066 16.5504 12.3252 16.5504C12.9437 16.5504 13.3462 16.8497 13.6279 17.4918C13.8161 16.9974 14.2608 16.6419 14.79 16.5611ZM35.1699 16.5357C35.6197 16.5357 36.0592 16.6961 36.3428 17.1343C36.6049 17.5411 36.6045 18.2257 36.6045 18.7173V21.9156C36.5898 22.0088 36.5077 22.0775 36.4121 22.0757H35.4014C35.311 22.0717 35.236 22.004 35.2236 21.9156V18.7076C35.2096 18.2443 35.1164 17.7868 34.5957 17.7867C34.3379 17.7984 34.1101 17.9569 34.0137 18.1929C33.8732 18.5032 33.8555 18.8142 33.8555 19.1578V21.8931C33.8516 21.9963 33.7639 22.0777 33.6592 22.0757H32.6572C32.5587 22.0705 32.4808 21.9905 32.4795 21.8931V16.8091C32.4901 16.7126 32.5744 16.6407 32.6729 16.6431H33.6045C33.6892 16.6459 33.762 16.7035 33.7822 16.7847V17.5621H33.8018C34.0827 16.867 34.4766 16.5357 35.1699 16.5357ZM26.3877 16.6343C26.4378 16.6327 26.4866 16.6506 26.5225 16.6851C26.5584 16.7197 26.5786 16.7675 26.5781 16.817V17.44C26.5781 17.5443 26.4892 17.6814 26.3301 17.897L24.6191 20.3043C25.2538 20.2894 25.9251 20.3829 26.502 20.7027C26.6085 20.7587 26.6763 20.8669 26.6797 20.9859V21.7642C26.6796 21.8711 26.5618 21.9942 26.4365 21.9302C25.3417 21.3755 24.042 21.3784 22.9492 21.9371C22.8346 21.9975 22.7148 21.8751 22.7148 21.7681V21.0279C22.7044 20.8533 22.7465 20.6793 22.8369 20.5289L24.8184 17.7242H23.0908C23.0406 17.7261 22.9912 17.7079 22.9551 17.6734C22.9191 17.6389 22.899 17.5911 22.8994 17.5416V16.817C22.8971 16.7674 22.9164 16.719 22.9521 16.6841C22.9879 16.6494 23.0368 16.6316 23.0869 16.6343H26.3877ZM47.2881 19.6392C46.494 19.6392 46.0971 19.9411 46.0977 20.5435C46.0977 20.8063 46.1718 21.009 46.3193 21.1509C46.4669 21.2928 46.6776 21.3634 46.9512 21.3629C47.1993 21.3597 47.4453 21.3147 47.6777 21.2291C47.9386 21.1345 48.1838 21.0014 48.4043 20.8345V19.774C48.2219 19.7317 48.0365 19.6994 47.8506 19.6763C47.6641 19.6522 47.4762 19.6396 47.2881 19.6392ZM41.8301 17.4146C41.3197 17.4186 40.8241 17.5861 40.4189 17.8922V20.7847C40.8682 21.1178 41.3315 21.2843 41.8086 21.2838C42.777 21.2837 43.2607 20.6406 43.2607 19.355C43.2606 18.0698 42.784 17.4225 41.8301 17.4136V17.4146ZM7.09668 19.4976C6.37061 19.4977 5.60374 19.651 5.60352 20.4937C5.60352 20.9232 5.82894 21.2125 6.21387 21.2125C6.49635 21.2123 6.74924 21.0408 6.90918 20.7623C7.09744 20.4322 7.09703 20.1229 7.09668 19.7584V19.4976ZM20.2646 19.4927C19.5384 19.4927 18.7705 19.6457 18.7705 20.4898C18.7705 20.9184 18.996 21.2076 19.3809 21.2076C19.6626 21.2076 19.917 21.0361 20.0762 20.7584C20.265 20.4266 20.2649 20.1156 20.2646 19.7466V19.4927ZM29.4277 17.5806C28.6875 17.5808 28.6406 18.5743 28.6406 19.1949C28.6406 19.2016 28.6406 19.2085 28.6406 19.2154C28.6405 19.8441 28.64 21.141 29.418 21.1412C30.2047 21.1412 30.2344 20.0716 30.2344 19.4195C30.2344 18.9918 30.2156 18.4777 30.084 18.0718C29.971 17.7215 29.7459 17.5806 29.4277 17.5806Z" fill="#232F3E"/> 8912<path fill-rule="evenodd" clip-rule="evenodd" d="M24.55 25.3185C24.7785 24.7584 25.287 23.5032 25.0452 23.199H25.0469C24.8062 22.8942 23.4549 23.0542 22.8471 23.1261L22.8459 23.1263C22.6609 23.1482 22.6325 22.9896 22.7987 22.8747C23.8779 22.1271 25.
89126461 22.3409 25.8515 22.5934C26.0568 22.8458 25.7954 24.5936 24.7847 25.428C24.6291 25.556 24.4807 25.4876 24.55 25.3185ZM17.288 26.1827C19.6385 26.1827 22.3756 25.4508 24.2611 24.0791V24.0817C24.5731 23.8503 24.3055 23.5102 23.9873 23.6434C21.9292 24.4994 19.7199 24.9462 17.4863 24.9582C14.3873 24.9582 11.3897 24.1203 8.96463 22.7292C8.75217 22.6074 8.59393 22.8221 8.77173 22.979C11.1064 25.056 14.1436 26.1985 17.288 26.1827Z" fill="#FF9900"/> 8913<title>amazonpay-rectangle</title></svg> 8914 8915 </li> 8916 <li> 8917 <svg xmlns="http://www.w3.org/2000/svg" width="60" height="40" viewBox="0 0 60 41" fill="none" class="w-full h-auto" role="img"> 8918<rect x="0.5" y="1.03571" width="59" height="39" rx="3.5" fill="#F4B6C7" stroke="#F3F3F3"/> 8919<path d="M22.7778 18.6578C23.606 18.6578 24.374 18.9108 25.0103 19.3414V18.8638H27.2622V26.3287H25.0103V25.8521C24.374 26.2827 23.6061 26.5357 22.7778 26.5357C20.5858 26.5357 18.8083 24.7724 18.8081 22.5972C18.8081 20.4218 20.5856 18.6578 22.7778 18.6578ZM46.5386 18.6578C47.3668 18.6578 48.1348 18.9108 48.771 19.3414V18.8638H51.0229V26.3287H48.771V25.8521C48.1348 26.2826 47.3669 26.5357 46.5386 26.5357C44.3465 26.5357 42.5691 24.7724 42.5688 22.5972C42.5688 20.4218 44.3464 18.6578 46.5386 18.6578ZM53.4146 23.6812C54.1948 23.6814 54.8274 24.3092 54.8276 25.0836C54.8276 25.8579 54.1949 26.4857 53.4146 26.4859C52.634 26.4859 52.0005 25.858 52.0005 25.0836C52.0007 24.3091 52.6341 23.6812 53.4146 23.6812ZM13.9028 15.5357C13.9028 17.873 12.9856 20.0475 11.3501 21.6636L14.8003 26.3326H11.7173L7.96729 21.2584L8.93506 20.5386C10.5398 19.3456 11.4604 17.5224 11.4604 15.5357H13.9028ZM7.66846 15.5357V26.3316H5.17236V15.5357H7.66846ZM17.8853 26.3287H15.5278V15.5367H17.8853V26.3287ZM30.7466 19.8365C31.198 19.2534 32.0392 18.8649 32.9536 18.8648V21.0367C32.9447 21.0366 32.9362 21.0357 32.9272 21.0357C32.0361 21.0357 30.7515 21.6685 30.7515 22.8443V26.3287H28.4409V18.8648H30.7466V19.8365ZM38.5669 18.6636C40.3811 18.6636 41.7727 19.8447 41.7729 21.5816V26.3287H39.5239V22.3912C39.5239 21.3024 38.9542 20.7154 37.9644 20.7154C37.0411 20.7156 36.2741 21.2712 36.2739 22.4058V26.3287H34.0044V18.8648H36.2466V19.7056C36.8158 18.9409 37.6672 18.6636 38.5669 18.6636ZM22.9624 20.6763C21.8354 20.6763 20.9214 21.5365 20.9214 22.5972C20.9216 23.6578 21.8355 24.5172 22.9624 24.5172C24.0892 24.517 25.0022 23.6576 25.0024 22.5972C25.0024 21.5366 24.0894 20.6765 22.9624 20.6763ZM46.7231 20.6763C45.596 20.6763 44.6821 21.5365 44.6821 22.5972C44.6824 23.6578 45.5961 24.5172 46.7231 24.5172C47.85 24.517 48.763 23.6577 48.7632 22.5972C48.7632 21.5366 47.8501 20.6765 46.7231 20.6763Z" fill="#17120F"/> 8920<title>klarna-rectangle</title></svg> 8921 8922 </li> 8923 <li> 8924 <svg xmlns="http://www.w3.org/2000/svg" width="60" height="40" viewBox="0 0 60 41" fill="none" class="w-full h-auto" role="img"> 8925<rect x="0.5" y="1.03571" width="59" height="39" rx="3.5" fill="white" stroke="#F3F3F3"/> 8926<path fill-rule="evenodd" clip-rule="evenodd" d="M8.09424 26.8841L8.55209 26.8394C8.57961 26.9887 8.63555 27.0982 8.71975 27.1683C8.80409 27.2383 8.91774 27.2732 9.06084 27.2732C9.21237 27.2732 9.32646 27.2421 9.40341 27.18C9.48021 27.1178 9.51854 27.0451 9.51854 26.9618C9.51854 26.9084 9.50241 26.863 9.47029 26.8254C9.43804 26.7879 9.3818 26.7554 9.30145 26.7275C9.2464 26.7093 9.12121 26.6767 8.92573 26.6297C8.67402 26.5696 8.49763 26.4955 8.39612 26.4075C8.25346 26.2838 8.18214 26.133 8.18214 25.9549C8.18214 25.8406 8.21573 25.7334 8.28306 25.6338C8.35024 25.534 8.44732 25.458 8.57384 25.4059C8.70051 25.3538 8.85337 25.3276 9.03242 25.3276C9.32483 25.3276 9.54488 25.3899 9.69271 25.5141C9.84054 25.6385 9.91808 25.8044 9.92548 26.0119L9.45387 26.0298C9.43374 25.9139 9.39053 25.8306 9.32424 25.7796C9.25809 25.7288 9.1588 25.7033 9.02636 25.7033C8.88963 25.7033 8.78278 25.7305 8.70539 25.7849C8.65552 25.8197 8.63066 25.8663 8.63066 25.9247C8.63066 25.9781 8.65404 26.0236 8.70066 26.0617C8.75985 26.1098 8.90383 26.16 9.13261 26.212C9.36123 26.2641 9.53037 26.318 9.64003 26.3741C9.74953 26.4301 9.83536 26.5067 9.89736 26.6037C9.95922 26.701 9.99029 26.8209 9.99029 26.9638C9.99029 27.0934 9.95315 27.2147 9.87886 27.3277C9.80458 27.4408 9.69966 27.5248 9.56397 27.5798C9.42827 27.6347 9.25913 27.
89266623 9.05655 27.6623C8.76177 27.6623 8.53536 27.5961 8.37732 27.4635C8.21943 27.331 8.12502 27.138 8.09424 26.8841Z" fill="#0B4A8E"/> 8927<path fill-rule="evenodd" clip-rule="evenodd" d="M10.479 25.9896H10.9275V27.622H10.479V25.9896ZM10.479 25.3679H10.9275V25.766H10.479V25.3679Z" fill="#0B4A8E"/> 8928<path fill-rule="evenodd" clip-rule="evenodd" d="M13.0208 27.622H12.5723V26.787C12.5723 26.6104 12.5627 26.4962 12.5437 26.4444C12.5247 26.3926 12.4939 26.3521 12.4511 26.3233C12.4083 26.2947 12.3568 26.2802 12.2968 26.2802C12.2197 26.2802 12.1506 26.3008 12.0893 26.3419C12.028 26.383 11.9862 26.4374 11.9635 26.5052C11.9407 26.5729 11.9295 26.6981 11.9295 26.881V27.622H11.481V25.9896H11.8971V26.2294C12.0443 26.0427 12.2299 25.9493 12.4533 25.9493C12.5519 25.9493 12.642 25.9667 12.7235 26.001C12.8051 26.0354 12.8668 26.0793 12.9087 26.1327C12.9505 26.1861 12.9797 26.2466 12.9961 26.3144C13.0125 26.3821 13.0208 26.4792 13.0208 26.6054V27.622Z" fill="#0B4A8E"/> 8929<path fill-rule="evenodd" clip-rule="evenodd" d="M13.928 26.7706C13.928 26.9443 13.9623 27.0715 14.0313 27.1521C14.1001 27.233 14.185 27.2732 14.2861 27.2732C14.3943 27.2732 14.4857 27.2318 14.5605 27.1491C14.635 27.0664 14.6725 26.9437 14.6725 26.7813C14.6725 26.6118 14.6367 26.4859 14.5652 26.4036C14.4936 26.3214 14.4033 26.2802 14.2939 26.2802C14.1877 26.2802 14.1001 26.3207 14.0313 26.4013C13.9623 26.4822 13.928 26.6051 13.928 26.7706ZM13.5257 27.7293L14.0343 27.783C14.0429 27.8438 14.0626 27.8856 14.0934 27.9085C14.136 27.9411 14.203 27.9574 14.2945 27.9574C14.4115 27.9574 14.4993 27.9406 14.5579 27.9068C14.5971 27.8842 14.627 27.8478 14.6472 27.7976C14.661 27.7615 14.668 27.6955 14.668 27.5991L14.6693 27.3608C14.537 27.535 14.3692 27.622 14.1656 27.622C13.9384 27.622 13.7588 27.5292 13.6262 27.3433C13.5222 27.1965 13.4702 27.0136 13.4702 26.7949C13.4702 26.5207 13.5383 26.3113 13.6746 26.1665C13.8109 26.0218 13.9804 25.9493 14.183 25.9493C14.392 25.9493 14.5644 26.0382 14.7002 26.2157V25.9896H15.1165V27.457C15.1165 27.65 15.1001 27.7943 15.0671 27.8896C15.0342 27.9852 14.988 28.0601 14.9285 28.1144C14.8691 28.1688 14.7897 28.2115 14.6904 28.2423C14.5912 28.273 14.4657 28.2885 14.314 28.2885C14.0274 28.2885 13.824 28.2407 13.704 28.1452C13.584 28.0498 13.5241 27.9287 13.5241 27.782C13.5241 27.7675 13.5247 27.7501 13.5257 27.7293Z" fill="#0B4A8E"/> 8930<path fill-rule="evenodd" clip-rule="evenodd" d="M15.6533 25.3679H16.1018V27.622H15.6533V25.3679Z" fill="#0B4A8E"/> 8931<path fill-rule="evenodd" clip-rule="evenodd" d="M17.6639 26.6694C17.6608 26.5423 17.6272 26.4458 17.5631 26.3796C17.4992 26.3134 17.4214 26.2802 17.3296 26.2802C17.2315 26.2802 17.1504 26.3153 17.0865 26.385C17.0224 26.4547 16.991 26.5496 16.9921 26.6694H17.6639ZM17.6408 27.1077L18.0847 27.1793C18.0273 27.3366 17.9366 27.4565 17.8127 27.5388C17.6889 27.6213 17.5338 27.6623 17.3478 27.6623C17.0532 27.6623 16.8352 27.5692 16.6939 27.383C16.5822 27.2338 16.5264 27.0456 16.5264 26.8181C16.5264 26.5467 16.5996 26.3339 16.7464 26.18C16.8931 26.0262 17.0785 25.9493 17.3027 25.9493C17.5547 25.9493 17.7534 26.0301 17.899 26.1914C18.0446 26.3529 18.1142 26.6001 18.1078 26.9333H16.9842C16.9873 27.0618 17.0237 27.1617 17.0933 27.2333C17.1628 27.3045 17.2495 27.3403 17.3534 27.3403C17.424 27.3403 17.4835 27.322 17.5316 27.2852C17.5797 27.2486 17.6162 27.1893 17.6408 27.1077Z" fill="#0B4A8E"/> 8932<path fill-rule="evenodd" clip-rule="evenodd" d="M19.5752 27.622V25.3679H21.3002V25.7481H20.047V26.249H21.2123V26.6292H20.047V27.2419H21.3464V27.622H19.5752Z" fill="#0B4A8E"/> 8933<path fill-rule="evenodd" clip-rule="evenodd" d="M22.9499 27.622V27.3775C22.8882 27.4647 22.8073 27.534 22.7068 27.5853C22.6063 27.6366 22.5004 27.6623 22.3888 27.6623C22.275 27.6623 22.1732 27.6382 22.0828 27.5899C21.9925 27.5417 21.9271 27.4739 21.8867 27.3867C21.8463 27.2994 21.8262 27.1787 21.8262 27.0247V25.9896H22.2747V26.7404C22.2747 26.9702 22.2828 27.111 22.2994 27.1627C22.3158 27.2148 22.3457 27.2557 22.3892 27.2861C22.4327 27.3163 22.4878 27.3313 22.5547 27.3313C22.631 27.3313 22.6995 27.3113 22.7599 27.2706C22.8204 27.2301 22.8617 27.1799 22.8841 27.1198C22.9063 27.0598 22.9175 26.9128 22.9175 26.679V25.9896H23.3
893366V27.622H22.9499Z" fill="#0B4A8E"/> 8934<path fill-rule="evenodd" clip-rule="evenodd" d="M24.3514 27.622H23.9028V25.9896H24.3189V26.2217C24.3901 26.1121 24.4541 26.0394 24.5109 26.0033C24.5677 25.9674 24.6321 25.9493 24.7043 25.9493C24.8061 25.9493 24.9044 25.9767 24.9988 26.0312L24.8623 26.4092C24.7869 26.3621 24.7164 26.3385 24.6516 26.3385C24.5887 26.3385 24.5356 26.3552 24.4919 26.3884C24.4483 26.4219 24.414 26.4822 24.3889 26.5693C24.3639 26.6565 24.3514 26.8393 24.3514 27.1172V27.622Z" fill="#0B4A8E"/> 8935<path fill-rule="evenodd" clip-rule="evenodd" d="M25.6375 26.8058C25.6375 26.9685 25.6773 27.0929 25.757 27.1793C25.8368 27.2658 25.9351 27.309 26.0521 27.309C26.169 27.309 26.2671 27.2658 26.3463 27.1793C26.4255 27.0929 26.4651 26.9673 26.4651 26.8028C26.4651 26.6423 26.4255 26.5187 26.3463 26.4324C26.2671 26.3459 26.169 26.3027 26.0521 26.3027C25.9351 26.3027 25.8368 26.3459 25.757 26.4324C25.6773 26.5187 25.6375 26.6433 25.6375 26.8058ZM25.1797 26.7826C25.1797 26.6386 25.2162 26.4992 25.2895 26.3644C25.3626 26.2297 25.4662 26.1268 25.6004 26.0558C25.7345 25.9848 25.8844 25.9493 26.0498 25.9493C26.3054 25.9493 26.5148 26.0298 26.6781 26.1908C26.8413 26.3518 26.923 26.5553 26.923 26.8012C26.923 27.0491 26.8405 27.2547 26.6756 27.4177C26.5108 27.5808 26.3031 27.6623 26.0529 27.6623C25.8981 27.6623 25.7504 27.6283 25.61 27.5606C25.4694 27.4926 25.3626 27.3931 25.2895 27.2619C25.2162 27.1306 25.1797 26.9711 25.1797 26.7826Z" fill="#0B4A8E"/> 8936<path fill-rule="evenodd" clip-rule="evenodd" d="M28.8554 25.7481V26.3922H29.1123C29.2973 26.3922 29.421 26.3804 29.4835 26.3567C29.5458 26.3329 29.5948 26.2957 29.6301 26.245C29.6655 26.1945 29.6832 26.1357 29.6832 26.0686C29.6832 25.986 29.6584 25.9179 29.6087 25.8642C29.5589 25.8105 29.496 25.777 29.42 25.7636C29.3639 25.7533 29.2514 25.7481 29.0822 25.7481H28.8554ZM28.3838 27.622V25.3679H29.1388C29.4248 25.3679 29.6114 25.3793 29.6983 25.4018C29.8318 25.4356 29.9435 25.5093 30.0336 25.6226C30.1237 25.7358 30.1687 25.8822 30.1687 26.0617C30.1687 26.2001 30.1428 26.3163 30.0909 26.4109C30.0391 26.5051 29.9731 26.5792 29.8932 26.633C29.8133 26.687 29.732 26.7225 29.6495 26.7399C29.5371 26.7616 29.3747 26.7723 29.162 26.7723H28.8554V27.622H28.3838Z" fill="#0B4A8E"/> 8937<path fill-rule="evenodd" clip-rule="evenodd" d="M31.5776 26.8394C31.5203 26.858 31.4299 26.88 31.3062 26.9058C31.1825 26.9314 31.1015 26.9568 31.0636 26.9814C31.0053 27.0216 30.9765 27.0725 30.9765 27.1342C30.9765 27.1951 30.9996 27.2474 31.046 27.2918C31.0926 27.336 31.1518 27.3582 31.2239 27.3582C31.3042 27.3582 31.3807 27.3324 31.4538 27.2811C31.5077 27.2419 31.5432 27.194 31.5601 27.1374C31.5716 27.1003 31.5776 27.0297 31.5776 26.9257V26.8394ZM30.9765 26.486L30.5741 26.4145C30.6197 26.2563 30.6982 26.1394 30.8094 26.0634C30.9209 25.9874 31.0863 25.9493 31.3058 25.9493C31.5051 25.9493 31.6537 25.9722 31.7512 26.0178C31.8487 26.0637 31.9175 26.1217 31.9572 26.1919C31.997 26.2622 32.0169 26.3914 32.0169 26.5794L32.0124 27.0846C32.0124 27.2283 32.0195 27.3344 32.0337 27.4026C32.048 27.4708 32.0748 27.544 32.114 27.622H31.6701C31.6582 27.5938 31.644 27.5518 31.627 27.4963C31.6196 27.471 31.6143 27.4544 31.6113 27.4462C31.535 27.5182 31.4534 27.5723 31.3666 27.6084C31.2797 27.6443 31.1872 27.6623 31.0887 27.6623C30.9149 27.6623 30.7779 27.6165 30.6779 27.5252C30.5778 27.4338 30.5278 27.3181 30.5278 27.1784C30.5278 27.0861 30.5506 27.0037 30.5961 26.9313C30.6418 26.8589 30.7057 26.8033 30.7878 26.7648C30.8701 26.7265 30.9886 26.6926 31.1434 26.6638C31.3522 26.6259 31.4969 26.5905 31.5776 26.5576V26.5139C31.5776 26.4298 31.5563 26.3698 31.5137 26.3339C31.4709 26.2981 31.3905 26.2802 31.2722 26.2802C31.1923 26.2802 31.13 26.2955 31.0851 26.3259C31.0403 26.3564 31.004 26.4098 30.9765 26.486Z" fill="#0B4A8E"/> 8938<path fill-rule="evenodd" clip-rule="evenodd" d="M32.3394 25.9896H32.8156L33.2203 27.1485L33.6157 25.9896H34.0781L33.3746 27.8477C33.3353 27.9433 33.2978 28.0161 33.2623 28.0665C33.2268 28.1167 33.1858 28.1577 33.1396 28.1889C33.0933 28.2202 33.0368 28.2448 32.9693 28.2622C32.9018 28.2798 32.8256 28.2885 32.7407 28.2885C32.6547 28.2885 32.5701 28.2798 32.4873 28.2623L32.4456 27.9238C32.5159 27.9374 32.5795 27.944 32.6359 27.944C32.7405 27.944 32.8176 27.9141 32.8678 27.8546C32.918 27.7947 32.9563 27.7187 32.9829 27.6266L32.3394 25.9896Z" fill="#0B4A8E"/> 8939<path fill-rule="evenodd" clip-rule="evenodd" d="M34.4277 25.9896H34.8393V26.2125C34.9871 26.0371 35.163 25.9493 35.3673 25.9493C35.4756 25.9493 35.5697 25.9708 35.6494 26.0139C35.7292 26.0571 35.7946 26.1224 35.8455 26.2095C35.9198 26.1224 36.0002 26.0571 36.086 26.0139C36.1721 25.9708 36.2637 25.9493 36.3614 25.9493C36.4857 25.9493 36.5907 25.9737 36.6767 26.0226C36.7627 26.0711 36.8271 26.1428 36.8695 26.2374C36.9002 26.3071 36.9156 26.4201 36.9156 26.5762V27.622H36.467V26.687C36.467 26.5247 36.4516 26.4201 36.421 26.3728C36.3796 26.311 36.3161 26.2802 36.2304 26.2802C36.1678 26.2802 36.1089 26.2987 36.0539 26.3358C35.9988 26.3728 35.9592 26.4269 35.9349 26.4983C35.9105 26.5696 35.8982 26.6824 35.8982 26.8364V27.622H35.4497V26.7256C35.4497 26.5662 35.4418 26.4637 35.4259 26.4173C35.41 26.3711 35.3855 26.3368 35.352 26.3142C35.3186 26.2917 35.2734 26.2802 35.2162 26.2802C35.1474 26.2802 35.0854 26.2983 35.0303 26.3342C34.9753 26.3701 34.9359 26.4221 34.9119 26.4898C34.8881 26.5576 34.8763 26.6699 34.8763 26.8271V27.622H34.4277V25.9896Z" fill="#0B4A8E"/> 8940<path fill-rule="evenodd" clip-rule="evenodd" d="M38.4604 26.6694C38.4571 26.5423 38.4237 26.4458 38.3595 26.3796C38.2957 26.3134 38.2177 26.2802 38.126 26.2802C38.028 26.2802 37.9468 26.3153 37.883 26.385C37.8189 26.4547 37.7875 26.5496 37.7886 26.6694H38.4604ZM38.4373 27.1077L38.8813 27.1793C38.8237 27.3366 38.7331 27.4565 38.6093 27.5388C38.4853 27.6213 38.3303 27.6623 38.1442 27.6623C37.8497 27.6623 37.6317 27.5692 37.4903 27.383C37.3785 27.2338 37.3228 27.0456 37.3228 26.8181C37.3228 26.5467 37.3963 26.3339 37.5428 26.18C37.6896 26.0262 37.8749 25.9493 38.0992 25.9493C38.3512 25.9493 38.5498 26.0301 38.6954 26.1914C38.841 26.3529 38.9107 26.6001 38.9044 26.9333H37.7806C37.7839 27.0618 37.8203 27.1617 37.8898 27.2333C37.9592 27.3045 38.0459 27.3403 38.15 27.3403C38.2205 27.3403 38.2799 27.322 38.328 27.2852C38.3764 27.2486 38.4128 27.1893 38.4373 27.1077Z" fill="#0B4A8E"/> 8941<path fill-rule="evenodd" clip-rule="evenodd" d="M40.9007 27.622H40.4522V26.787C40.4522 26.6104 40.4426 26.4962 40.4238 26.4444C40.4047 26.3926 40.3738 26.3521 40.331 26.3233C40.2882 26.2947 40.2367 26.2802 40.1766 26.2802C40.0997 26.2802 40.0304 26.3008 39.9693 26.3419C39.9081 26.383 39.8662 26.4374 39.8434 26.5052C39.8208 26.5729 39.8094 26.6981 39.8094 26.881V27.622H39.3608V25.9896H39.777V26.2294C39.9243 26.0427 40.1098 25.9493 40.3332 25.9493C40.4318 25.9493 40.522 25.9667 40.6034 26.001C40.685 26.0354 40.7468 26.0793 40.7887 26.1327C40.8306 26.1861 40.8596 26.2466 40.876 26.3144C40.8926 26.3821 40.9007 26.4792 40.9007 26.6054V27.622Z" fill="#0B4A8E"/> 8942<path fill-rule="evenodd" clip-rule="evenodd" d="M42.2239 25.9896V26.3339H41.9186V26.9944C41.9186 27.1281 41.9214 27.2061 41.9272 27.2281C41.9328 27.2503 41.9458 27.2685 41.9661 27.2829C41.9865 27.2972 42.0111 27.3045 42.0402 27.3045C42.0811 27.3045 42.1397 27.2907 42.2169 27.263L42.2561 27.5976C42.1527 27.6407 42.0356 27.6623 41.905 27.6623C41.8246 27.6623 41.7526 27.6492 41.6882 27.623C41.624 27.5969 41.5768 27.5629 41.5466 27.5212C41.5165 27.4797 41.4958 27.4235 41.4843 27.3526C41.4747 27.3022 41.4701 27.2005 41.4701 27.0475V26.3339H41.2666V25.9896H41.4701V25.6631L41.9186 25.4082V25.9896H42.2239Z" fill="#0B4A8E"/> 8943<path fill-rule="evenodd" clip-rule="evenodd" d="M42.4761 27.1614L42.9246 27.0943C42.9437 27.1777 42.9823 27.241 43.0405 27.2844C43.0988 27.3277 43.1802 27.3492 43.2849 27.3492C43.4005 27.3492 43.4874 27.3286 43.5455 27.2874C43.5847 27.2583 43.6044 27.2198 43.6044 27.1711C43.6044 27.1382 43.5936 27.1108 43.5723 27.0893C43.5498 27.0685 43.4998 27.0495 43.422 27.0319C43.0596 26.9545 42.8297 26.8839 42.733 26.8202C42.5986 26.7319 42.5316 26.609 42.5316 26.452C42.5316 26.31 42.5894 26.1908 42.7056 26.0943C42.8219 25.9977 43.002 25.9493 43.246 25.9493C43.4783 25.9493 43.6509 25.9855 43.7639 26.0578C43.8768 26.1302 43.9547 26.2372 43.9974 26.3787L43.5766 26.4547C43.5584 26.3913 43.5238 26.3425 43.4729 26.3087C43.4218 26.2748 43.3492 26.2579 43.2549 26.2579C43.1359 26.2579 43.0505 26.2738 42.9992 26.306C42.9647 26.3286 42.9477 26.3579 42.9477 26.394C42.9477 26.4251 42.9625 26.4514 42.9924 26.4732C43.0328 26.5019 43.1726 26.5427 43.4116 26.5954C43.6506 26.648 43.8175 26.7125 43.9124 26.7887C44.0059 26.866 44.0529 26.9738 44.0529 27.1119C44.0529 27.2623 43.9881 27.3917 43.8589 27.4999C43.7295 27.6082 43.5383 27.6623 43.2849 27.6623C43.0551 27.6623 42.8731 27.6173 42.739 27.5275C42.605 27.4375 42.5174 27.3157 42.4761 27.1614Z" fill="#0B4A8E"/> 8944<path fill-rule="evenodd" clip-rule="evenodd" d="M46.7832 26.7321L46.4574 25.8957L46.1425 26.7321H46.7832ZM47.6481 27.622H47.1402L46.9387 27.1122H45.9993L45.8072 27.622H45.3081L46.2109 25.3679H4
89446.707L47.6481 27.622Z" fill="#0B4A8E"/> 8945<path fill-rule="evenodd" clip-rule="evenodd" d="M48.4178 27.622H47.9692V25.9896H48.3854V26.2217C48.4565 26.1121 48.5203 26.0394 48.5773 26.0033C48.634 25.9674 48.6983 25.9493 48.7707 25.9493C48.8725 25.9493 48.9706 25.9767 49.0652 26.0312L48.9287 26.4092C48.8531 26.3621 48.7828 26.3385 48.718 26.3385C48.655 26.3385 48.6018 26.3552 48.5582 26.3884C48.5145 26.4219 48.4802 26.4822 48.4553 26.5693C48.4302 26.6565 48.4178 26.8393 48.4178 27.1172V27.622Z" fill="#0B4A8E"/> 8946<path fill-rule="evenodd" clip-rule="evenodd" d="M50.3603 26.6694C50.357 26.5423 50.3234 26.4458 50.2595 26.3796C50.1954 26.3134 50.1176 26.2802 50.026 26.2802C49.9277 26.2802 49.8468 26.3153 49.7829 26.385C49.7188 26.4547 49.6873 26.5496 49.6885 26.6694H50.3603ZM50.3372 27.1077L50.7812 27.1793C50.7237 27.3366 50.633 27.4565 50.5092 27.5388C50.3853 27.6213 50.2302 27.6623 50.0442 27.6623C49.7496 27.6623 49.5315 27.5692 49.3902 27.383C49.2784 27.2338 49.2227 27.0456 49.2227 26.8181C49.2227 26.5467 49.2961 26.3339 49.4428 26.18C49.5893 26.0262 49.7749 25.9493 49.9991 25.9493C50.251 25.9493 50.4497 26.0301 50.5955 26.1914C50.7409 26.3529 50.8106 26.6001 50.8043 26.9333H49.6805C49.6838 27.0618 49.7202 27.1617 49.7896 27.2333C49.8593 27.3045 49.946 27.3403 50.0497 27.3403C50.1204 27.3403 50.1798 27.322 50.228 27.2852C50.2761 27.2486 50.3125 27.1893 50.3372 27.1077Z" fill="#0B4A8E"/> 8947<path fill-rule="evenodd" clip-rule="evenodd" d="M52.1946 26.8394C52.1375 26.858 52.047 26.88 51.9232 26.9058C51.7995 26.9314 51.7187 26.9568 51.6807 26.9814C51.6224 27.0216 51.5935 27.0725 51.5935 27.1342C51.5935 27.1951 51.6166 27.2474 51.6632 27.2918C51.7097 27.336 51.7689 27.3582 51.841 27.3582C51.9213 27.3582 51.9978 27.3324 52.0709 27.2811C52.1248 27.2419 52.1603 27.194 52.1772 27.1374C52.1887 27.1003 52.1946 27.0297 52.1946 26.9257V26.8394ZM51.5935 26.486L51.1912 26.4145C51.2368 26.2563 51.3152 26.1394 51.4265 26.0634C51.5379 25.9874 51.7033 25.9493 51.9228 25.9493C52.1221 25.9493 52.2707 25.9722 52.3682 26.0178C52.4657 26.0637 52.5345 26.1217 52.5742 26.1919C52.614 26.2622 52.634 26.3914 52.634 26.5794L52.6294 27.0846C52.6294 27.2283 52.6365 27.3344 52.6507 27.4026C52.6651 27.4708 52.6918 27.544 52.7309 27.622H52.2871C52.2753 27.5938 52.2612 27.5518 52.2441 27.4963C52.2368 27.471 52.2313 27.4544 52.2284 27.4462C52.152 27.5182 52.0706 27.5723 51.9838 27.6084C51.8969 27.6443 51.8043 27.6623 51.7057 27.6623C51.532 27.6623 51.395 27.6165 51.2949 27.5252C51.195 27.4338 51.145 27.3181 51.145 27.1784C51.145 27.0861 51.1677 27.0037 51.2132 26.9313C51.2588 26.8589 51.3227 26.8033 51.4049 26.7648C51.4871 26.7265 51.6057 26.6926 51.7605 26.6638C51.9693 26.6259 52.114 26.5905 52.1946 26.5576V26.5139C52.1946 26.4298 52.1733 26.3698 52.1307 26.3339C52.0881 26.2981 52.0076 26.2802 51.8892 26.2802C51.8093 26.2802 51.747 26.2955 51.7022 26.3259C51.6575 26.3564 51.6211 26.4098 51.5935 26.486Z" fill="#0B4A8E"/> 8948<path fill-rule="evenodd" clip-rule="evenodd" d="M17.9992 16.5106H14.9452C14.9452 16.0258 14.8863 15.7005 14.7691 15.5349C14.5874 15.2899 14.0857 15.1673 13.2647 15.1673C12.4674 15.1673 11.9389 15.2378 11.6809 15.3791C11.4231 15.5208 11.2941 15.8289 11.2941 16.3034C11.2941 16.7329 11.4083 17.0157 11.6374 17.1512C11.8015 17.2474 12.0183 17.3039 12.2887 17.3208L12.9046 17.3629C14.2245 17.4476 15.0489 17.5073 15.3777 17.5412C16.4216 17.643 17.1783 17.9114 17.6479 18.3465C18.0174 18.686 18.2377 19.1297 18.308 19.6775C18.3492 20.0053 18.3696 20.3761 18.3696 20.7881C18.3696 21.7379 18.2759 22.4334 18.0883 22.8742C17.7482 23.683 16.9843 24.1938 15.7958 24.4083C15.2978 24.4991 14.536 24.5444 13.5114 24.5444C11.8011 24.5444 10.6091 24.446 9.9361 24.248C9.11009 24.0056 8.56552 23.5144 8.30197 22.7748C8.15518 22.363 8.08252 21.6773 8.08252 20.7174H11.1365C11.1365 20.8245 11.1368 20.9064 11.1368 20.9627C11.1368 21.475 11.2891 21.8044 11.5929 21.9511C11.8035 22.0523 12.0577 22.1054 12.3566 22.1117H13.4793C14.0523 22.1117 14.4179 22.0834 14.5757 22.0264C14.8564 21.9196 15.0406 21.7478 15.1287 21.5099C15.1754 21.3635 15.1987 21.174 15.1987 20.9421C15.1987 20.4228 15.0026 20.1068 14.6112 19.9934C14.4649 19.9486 13.7839 19.8862 12.5684 19.8071C11.5923 19.7396 10.9142 19.6748 10.5345 19.612C9.53464 19.4311 8.86829 19.0591 8.53578 18.4944C8.24352 18.0145 8.09732 17.2884 8.09732 16.3172C8.09732 15.5776 8.17634 14.9845 8.33423 14.5384C8.49227 14.0922 8.74695 13.7534 9.0984 13.5217C9.61321 13.166 10.272 12.9572 11.
89480739 12.8948C11.7412 12.8386 12.4813 12.8098 13.2955 12.8098C14.5773 12.8098 15.4908 12.8811 16.0354 13.0223C17.3644 13.3677 18.0288 14.335 18.0288 15.9247C18.0288 16.055 18.0189 16.25 17.9992 16.5106Z" fill="#0B4A8E"/> 8949<path fill-rule="evenodd" clip-rule="evenodd" d="M34.7121 18.762H36.7587C37.4076 18.7394 37.8022 18.6912 37.9443 18.6156C38.1383 18.5124 38.2685 18.3059 38.3333 17.996C38.3747 17.7898 38.3955 17.4833 38.3955 17.0759C38.3955 16.577 38.3543 16.2072 38.2716 15.9656C38.1535 15.6273 37.8707 15.4212 37.4228 15.3463C37.3343 15.335 37.1223 15.329 36.7863 15.329H34.7121V18.762ZM31.4292 24.5445V12.7474H37.5453C38.3842 12.7474 39.0244 12.8137 39.4642 12.9461C40.4701 13.2509 41.1451 13.8751 41.4907 14.8184C41.6692 15.3134 41.7584 16.0588 41.7584 17.054C41.7584 18.2507 41.6594 19.1107 41.4637 19.6342C41.0714 20.6695 40.2638 21.2659 39.0445 21.4205C38.9011 21.4437 38.291 21.4644 37.2141 21.481L36.6691 21.4986H34.712V24.5445H31.4292Z" fill="#0B4A8E"/> 8950<path fill-rule="evenodd" clip-rule="evenodd" d="M48.1135 20.2074L46.5754 15.0936L45.0827 20.2074H48.1135ZM48.7655 22.5056H44.3762L43.7866 24.5445H40.3901L44.055 12.7474H49.007L52.7168 24.5445H49.3917L48.7655 22.5056Z" fill="#0B4A8E"/> 8951<path fill-rule="evenodd" clip-rule="evenodd" d="M26.8979 14.4072C28.2519 14.4072 29.4603 15.0104 30.2546 15.9553L30.9622 14.4879C29.8555 13.4762 28.3492 12.8525 26.6879 12.8525C24.1012 12.8525 21.8885 14.3634 20.9803 16.5022H19.6004L18.7856 18.1915H20.5608C20.5475 18.3483 20.5389 18.5051 20.5389 18.6651C20.5389 18.8588 20.5493 19.0501 20.5691 19.2392H19.6769L18.8623 20.9291H21.0226C21.9567 23.0138 24.1417 24.4773 26.6879 24.4773C27.971 24.4773 29.1616 24.1055 30.1475 23.4704V21.3993C29.3536 22.2734 28.1924 22.8259 26.8979 22.8259C25.3846 22.8259 24.0535 22.0712 23.2784 20.9291H27.8023L28.6169 19.2392H22.6128C22.5819 19.0358 22.5653 18.828 22.5653 18.6163C22.5653 18.4732 22.573 18.3315 22.5872 18.1915H29.1218L29.9365 16.5022H23.1524C23.9026 15.2499 25.2988 14.4072 26.8979 14.4072Z" fill="#F6BC25"/> 8952<title>sepa-rectangle</title></svg> 8953 8954 </li> 8955 8956 </ul> 8957</div> 8958 </div> 8959 </div> 8960 </div> 8961 </div> 8962 <div class="bg-footer-content-bg"> 8963 <div 8964 class="container my-6 language-switcher-wrapper" 8965 role="region" 8966 data-testid="language-switcher"> 8967 <div class="w-full flex items-center justify-center gap-3 language-switcher"> 8968 <p 8969 id="language-switcher-heading" 8970 class="text-text-secondary text-16 leading-150 font-medium text-right language-switcher-heading" 8971 data-testid="language-switcher-text"> 8972 Nicht die richtige Sprache? </p> 8973 <div class="text-left"> 8974 <div x-data="initLanguageSwitcher" 8975 class="language-switcher w-full" 8976 x-id="['language-switcher']" 8977 :data-testid="$id('language-switcher')"> 8978 <div x-id="['menu-options']" class="relative inline-block text-left"> 8979 <div class="flex items-center group"> 8980 <button @click.prevent="toggleOpen" 8981 @click.outside="setOpenFalse" 8982 @keydown.window.escape="setOpenFalse" 8983 type="button" 8984 :id="$id('menu-options')" 8985 class="w-full border-0 shadow-none uppercase text-12 font-medium leading-130 flex items-center 8986 transition-colors group-hover:text-current/80 group-aria-expanded:text-current/80" 8987 aria-haspopup="true" 8988 :aria-expanded="open" 8989 aria-label="Sprachauswahl" 8990 title="Sprachauswahl"> 8991 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 19 19" fill="none" class="inline mr-1 transition-colors" aria-hidden="true"> 8992<path d="M0.554929 8.5H2.5C3.60457 8.5 4.5 9.39543 4.5 10.5V11.5C4.5 12.6046 5.39543 13.5 6.5 13.5C7.60457 13.5 8.5 14.3954 8.5 15.5V18.4451M5.5 1.43552V3C5.5 4.38071 6.61929 5.5 8 5.5H8.5C9.60457 5.5 10.5 6.39543 10.5 7.5C10.5 8.60457 11.3954 9.5 12.5 9.5C13.6046 9.5 14.5 8.60457 14.5 7.5C14.5 6.39543 15.3954 5.5 16.5 5.5L17.5645 5.5M12.5 17.9879V15.5C12.5 14.3954 13.3954 13.5 14.5 13.5H17.5645M18.5 9.5C18.5 14.4706 14.4706 18.5 9.5 18.5C4.52944 18.5 0.5 14.4706 0.5 9.5C0.5 4.52944 4.52944 0.5 9.5 0.5C14.4706 0.5 18.5 4.52944 18.5 9.5Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/> 8993</svg>
8994 <span class="inline-block align-middle">de</span> 8995 8996 <span :class="{ 'rotate-180': open }" class="inline-block transform transition-all duration-200 align-middle"> 8997 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-5 h-5" width="18" height="18" aria-hidden="true"> 8998 <path stroke-linecap="round" stroke-linejoin="round" d="M19 9l-7 7-7-7"/> 8999</svg> 9000 </span> 9001 </button> 9002 </div> 9003 <nav x-cloak 9004 x-show="open" 9005 x-transition.origin.top.right 9006 @keydown.tab="trapFocus($event)" 9007 @keydown.shift.tab="trapFocus($event)" 9008 class="bg-white rounded-(--header-card-radius) [&>*:first-child]:rounded-t-(--header-card-radius) border-t-2 border-primary absolute left-0 top-full z-20 mt-3 origin-top-left overflow-visible shadow-lg" 9009 role="menu" 9010 aria-orientation="vertical" 9011 :aria-labelledby="$id('menu-options')"> 9012 <a href="https://knirps.de/stores/store/redirect/___store/knirps_en/___from_store/default/uenc/aHR0cHM6Ly9rbmlycHMuY29tL2Jsb2cv/" 9013 role="menuitem" 9014 tabindex="0" 9015 data-item-num="1" 9016 data-lang-code="en" 9017 class="text-text-secondary first:rounded-t-[5px] px-4 py-2 hover:bg-bg-secondary flex items-center justify-between gap-2"> 9018 9019 <span class="flex items-center gap-2 w-5 h-5"> 9020 <img src="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Doppler_StoreSwitcher/flags/4x3/gb.svg" 9021 alt="English" 9022 class="w-5 h-5 rounded-full object-cover" /> 9023 </span> 9024 9025 <span class="text-12 font-medium leading-130">Global</span> 9026 <span class="code text-8 font-medium leading-130 text-right">EN</span> 9027 </a> 9028 <a href="https://knirps.de/stores/store/redirect/___store/knirps_fr/___from_store/default/uenc/aHR0cHM6Ly9rbmlycHMuZnIvYmxvZy8~/" 9029 role="menuitem" 9030 tabindex="0" 9031 data-item-num="2" 9032 data-lang-code="fr" 9033 class="text-text-secondary first:rounded-t-[5px] px-4 py-2 hover:bg-bg-secondary flex items-center justify-between gap-2"> 9034 9035 <span class="flex items-center gap-2 w-5 h-5"> 9036 <img src="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Doppler_StoreSwitcher/flags/4x3/fr.svg" 9037 alt="Français" 9038 class="w-5 h-5 rounded-full object-cover" /> 9039 </span> 9040
9041 <span class="text-12 font-medium leading-130">Français</span> 9042 <span class="code text-8 font-medium leading-130 text-right">FR</span> 9043 </a> 9044 <a href="https://knirps.de/stores/store/redirect/___store/knirps_nl/___from_store/default/uenc/aHR0cHM6Ly9rbmlycHMubmwvYmxvZy8~/" 9045 role="menuitem" 9046 tabindex="0" 9047 data-item-num="3" 9048 data-lang-code="nl" 9049 class="text-text-secondary first:rounded-t-[5px] px-4 py-2 hover:bg-bg-secondary flex items-center justify-between gap-2"> 9050 9051 <span class="flex items-center gap-2 w-5 h-5"> 9052 <img src="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Doppler_StoreSwitcher/flags/4x3/nl.svg" 9053 alt="Nederlands" 9054 class="w-5 h-5 rounded-full object-cover" /> 9055 </span> 9056 9057 <span class="text-12 font-medium leading-130">Nederlands</span> 9058 <span class="code text-8 font-medium leading-130 text-right">NL</span> 9059 </a> 9060 <a href="https://knirps.de/stores/store/redirect/___store/ch_de/___from_store/default/uenc/aHR0cHM6Ly9rbmlycHMuY2gvYmxvZy8~/" 9061 role="menuitem" 9062 tabindex="0" 9063 data-item-num="4" 9064 data-lang-code="ch-de" 9065 class="text-text-secondary first:rounded-t-[5px] px-4 py-2 hover:bg-bg-secondary flex items-center justify-between gap-2"> 9066 9067 <span class="flex items-center gap-2 w-5 h-5"> 9068 <img src="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Doppler_StoreSwitcher/flags/4x3/ch.svg" 9069 alt="Deutsch" 9070 class="w-5 h-5 rounded-full object-cover" /> 9071 </span> 9072 9073 <span class="text-12 font-medium leading-130">Schweiz</span> 9074 <span class="code text-8 font-medium leading-130 text-right">CH-DE</span> 9075 </a> 9076 <a href="https://knirps.de/stores/store/redirect/___store/knirps_cz/___from_store/default/uenc/aHR0cHM6Ly9rbmlycHMuY3ovYmxvZy8~/" 9077 role="menuitem" 9078 tabindex="0" 9079 data-item-num="5" 9080 data-lang-code="cz" 9081 class="text-text-secondary first:rounded-t-[5px] px-4 py-2 hover:bg-bg-secondary flex items-center justify-between gap-2"> 9082 9083 <sp
9083an class="flex items-center gap-2 w-5 h-5"> 9084 <img src="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Doppler_StoreSwitcher/flags/4x3/cz.svg" 9085 alt="Czech" 9086 class="w-5 h-5 rounded-full object-cover" /> 9087 </span> 9088 9089 <span class="text-12 font-medium leading-130">ÄeÅ¡tina</span> 9090 <span class="code text-8 font-medium leading-130 text-right">CZ</span> 9091 </a> 9092 <div class="absolute left-1 -top-2 w-0 h-0 9093 border-l-8 border-l-transparent 9094 border-r-8 border-r-transparent 9095 border-b-8 border-primary language-arrow"> 9096 </div> 9097 </nav> 9098 </div> 9099 </div> 9100
9100<script> 9101 function initLanguageSwitcher() { 9102 return { 9103 open: false, 9104 toggleOpen() { 9105 this.open = !this.open; 9106 if (this.open) this.$nextTick(() => this.focusFirst()); 9107 }, 9108 setOpenFalse() { 9109 this.open = false; 9110 }, 9111 focusableElements() { 9112 return [...this.$root.querySelectorAll('[role="menuitem"]:not([tabindex="-1"])')]; 9113 }, 9114 focusFirst() { 9115 const items = this.focusableElements(); 9116 if (items.length) items[0].focus(); 9117 }, 9118 trapFocus(event) { 9119 const items = this.focusableElements(); 9120 const index = items.indexOf(document.activeElement); 9121 if (event.shiftKey) { 9122 if (index === 0) { 9123 event.preventDefault(); 9124 items[items.length - 1].focus(); 9125 } 9126 } else { 9127 if (index === items.length - 1) { 9128 event.preventDefault(); 9129 items[0].focus(); 9130 } 9131 } 9132 } 9133 } 9134 } 9135 window.addEventListener('alpine:init', () => Alpine.data('initLanguageSwitcher', initLanguageSwitcher), { 9136 once: true 9137 }) 9138 </script>
9138 9139 </div> 9140 </div> 9141</div> </div> 9142 <div class="bg-footer-content-bg lg:pt-3"> 9143 <div class="container px-6 flex mx-auto justify-between flex-wrap flex-col-reverse lg:flex-row"> 9144 <div class="w-full lg:w-auto"> 9145 <img src="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/svg/knirps-logo.svg" alt="Knirps" class="w-full h-auto lg:w-auto" /> 9146 </div> 9147 <div class="flex justify-center flex-wrap"> 9148 <p class="lg:hidden w-full mb-3 text-center font-light text-sm">Weitere Marken der doppler Group:</p> 9149 <div class="flex gap-8 mb-8"> 9150 <a href="https://dopplerschirme.com/de/"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="54" height="38" viewBox="0 0 54 38" fill="none" role="img"> 9151<rect width="53.7393" height="37.5944" fill="url(#pattern0_4741_1249)"/> 9152<defs> 9153<pattern id="pattern0_4741_1249" patternContentUnits="objectBoundingBox" width="1" height="1"> 9154<use xlink:href="#image0_4741_1249" transform="scale(0.00107296 0.00153374)"/> 9155</pattern> 9156<image id="image0_4741_1249" width="932" height="652" preserveAspectRatio="none" xlink:href="data:image/png;base64,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"/> 9157</defs> 9158<title>doppler-logo</title></svg> 9159</a> 9160 <a href="https://doppler-manufaktur.com/"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="50" height="38" viewBox="0 0 50 38" fill="none" role="img"> 9161<rect width="49.3693" height="37.5944" fill="url(#pattern0_4741_1250)"/> 9162<defs> 9163<pattern id="pattern0_4741_1250" patternContentUnits="objectBoundingBox" width="1" height="1"> 9164<use xlink:href="#image0_4741_1250" transform="scale(0.000957854 0.00125786)"/> 9165</pattern> 9166<image id="image0_4741_1250" width="1044" height="795" preserveAspectRatio="none" xlink:href="data:image/png;base64,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"/> 9167</defs> 9168<title>manufaktur-logo</title></svg> 9169</a> 9170 </div> 9171 </div> 9172</div> </div> 9173 <div class="bg-footer-copyright-bg"> 9174 <div class="container mx-auto footer-copyright md:w-auto" 9175 data-testid="footer-copyright"> 9176 <small class="flex items-center justify-center text-14 leading-140 pt-8 pb-6 lg:pt-6 lg:pb-4 font-medium"> 9177 ©2026 Knirps </small> 9178</div> </div> 9179</div></div></footer> <!-- added by Trusted Shops app: Start --> 9180
9180<script async data-desktop-y-offset="0" data-mobile-y-offset="0" data-desktop-disable-reviews="false" data-desktop-enable-custom="false" data-desktop-position="left" data-desktop-custom-width="156" data-desktop-enable-fadeout="false" data-disable-mobile="false" data-disable-trustbadge="false" data-mobile-custom-width="156" data-mobile-disable-reviews="false" data-mobile-enable-custom="false" data-mobile-position="left" data-color-scheme="os-default" charset="UTF-8" src="//widgets.trustedshops.com/js/X40BC1F0140BDF7B04FF6E9761E3543A6.js" ></script>
9180 <!-- End --> 9181
9181<script data-ommit="true" nonce="MW8zbHFodjIwMXlkMHZyNXk1Z2htd2p6a2FwNHo5a24="> 9182 9183 document.addEventListener("DOMContentLoaded", () => 9184 { 9185 let bind = () => 9186 { 9187 Object.entries( 9188 { 9189 add_to_cart: event => 9190 { 9191 AEC.add(event.currentTarget, dataLayer, event); 9192 }, 9193 remove_from_cart:event => 9194 { 9195 AEC.remove(event.currentTarget, dataLayer, event); 9196 }, 9197 select_item:event => 9198 { 9199 AEC.click(event.currentTarget, dataLayer, event); 9200 }, 9201 add_to_wishlist:event => 9202 { 9203 AEC.wishlist(event.currentTarget, dataLayer, event); 9204 }, 9205 remove_from_wishlist:event => 9206 { 9207 AEC.wishlistRemove(event.currentTarget, dataLayer, event); 9208 }, 9209 add_to_compare:event => 9210 { 9211 AEC.compare(event.currentTarget, dataLayer, event); 9212 }, 9213 add_to_cart_swatch:event => 9214 { 9215 AEC.addSwatch(event.currentTarget, dataLayer, event); 9216 } 9217 }).forEach(([event, callback]) => 9218 { 9219 [...document.querySelectorAll('[data-event]:not([data-bound])')].filter(element => { return element.dataset.event === event; }
9219).forEach(element => 9220 { 9221 element.addEventListener('click', callback); 9222 9223 if (element?.dataset?.post) 9224 { 9225 const post = element?.dataset?.post, postParse = JSON.parse(post); 9226 9227 if (postParse?.action?.includes('delete')) 9228 { 9229 element.dataset.postreaction = post; 9230 9231 element.removeAttribute('data-post'); 9232 } 9233 } 9234 9235 element.dataset.bound = true; 9236 }); 9237 }); 9238 }; 9239 9240 bind(); 9241 9242 if("PerformanceObserver" in window) 9243 { 9244 const observer = new PerformanceObserver((items) => 9245 { 9246 items.getEntries().filter(({ initiatorType }) => initiatorType === "xmlhttprequest").forEach((entry) => 9247 { 9248 bind(); 9249 }); 9250 }); 9251 9252 observer.observe( 9253 { 9254 entryTypes: ["resource"] 9255 }); 9256 } 9257 }); 9258 9259</script>
9259<script data-ommit="true" nonce="MW8zbHFodjIwMXlkMHZyNXk1Z2htd2p6a2FwNHo5a24="> 9260 window.addEventListener('ec:products-appended', function (event) { 9261 var nodes = (event.detail && event.detail.items) || []; 9262 9263 if (!nodes.length || typeof window.DopplerEc === 'undefined') { 9264 return; 9265 } 9266 9267 // Bind first: if anything below throws, the new tiles are still clickable-and-tracked. 9268 window.DopplerEc.bindEvents(nodes); 9269 9270 // The appended nodes are <li> wrappers; the stamped elements are the anchors inside. 9271 var stamped = []; 9272 9273 nodes.forEach(function (node) { 9274 if (!node.querySelectorAll) { 9275 return; 9276 } 9277 9278 stamped = stamped.concat( 9279 Array.prototype.slice.call( 9280 node.querySelectorAll('[data-event=select_item]') 9281 ) 9282 ); 9283 }); 9284 9285 if (!stamped.length) { 9286 return; 9287 } 9288 9289 // Reuse the list attribution from the impression already on the page, so the appended page 9290 // is reported against the same list as the first one. 9291 var listContext = (function () { 9292 var events = (window.dataLayer || []).filter(function (entry) { 9293 return entry && entry.event === 'view_item_list' && entry.ecommerce; 9294 }); 9295 9296 var last = events.length ? events[events.length - 1].ecommerce : {}; 9297 9298 return { 9299 item_list_id: last.item_list_id, 9300 item_list_name: last.item_list_name 9301 }; 9302 })(); 9303 9304 window.DopplerEc.pushItemList( 9305 window.DopplerEc.collectItems(stamped, listContext), 9306 listContext 9307 ); 9308 }); 9309</script>
vendor: 1 bytes, line 9309
9309
9310<script data-ommit="true" nonce="MW8zbHFodjIwMXlkMHZyNXk1Z2htd2p6a2FwNHo5a24="> 9311 9312 document.addEventListener("DOMContentLoaded", () => 9313 { 9314 var PromotionTrack = ((dataLayer) => 9315 { 9316 return { 9317 apply: () => 9318 { 9319 var promotions = [], position = 0; 9320 9321 document.querySelectorAll('[data-promotion]').forEach(promotion => 9322 { 9323 let entity = 9324 { 9325 promotion_id: promotion.dataset.promotionId, 9326 promotion_name: promotion.dataset.promotionName, 9327 creative_name: promotion.dataset.promotionCreative, 9328 creative_slot: promotion.dataset.promotionPosition 9329 }; 9330 9331 AEC.EventDispatcher.trigger('ec.cookie.promotion.entity', entity, 9332 { 9333 element: promotion 9334 }); 9335 9336 promotions.push(entity); 9337 9338 promotion.addEventListener('click', (event) => 9339 { 9340 var data = 9341 { 9342 'event': 'select_promotion', 9343 'ecommerce': 9344 { 9345 'items': 9346 [ 9347 { 9348 promotion_id: event.target.dataset.promotionId, 9349 promotion_name: event.target.dataset.promotionName, 9350 creative_name: event.target.dataset.promotionCreative, 9351 creative_slot: event.target.dataset.promotionPosition 9352 } 9353 ] 9354 } 9355 }; 9356 9357 AEC.Cookie.promotionClick(data, promotion).push(dataLayer); 9358 9359 /** 9360 * Save persistent data 9361 */ 9362 AEC.Persist.push(AEC.Persist.CONST_KEY_PROMOTION, 9363 { 9364 'promotion': data.ecommerce.items[0] 9365 }); 9366 }); 9367 }); 9368 9369 if (promotions.length) 9370 { 9371 AEC.Cookie.promotion( 9372 { 9373 'event':'view_promotion', 9374 'ecommerce': 9375 { 9376 'items': promotions 9377 } 9378 }).push(dataLayer); 9379 } 9380 9381 return this; 9382 } 9383 } 9384 })(dataLayer).apply(); 9385 }); 9386</script>
9386<script data-ommit="true" nonce="MW8zbHFodjIwMXlkMHZyNXk1Z2htd2p6a2FwNHo5a24="> 9387 9388 document.addEventListener("DOMContentLoaded", () => 9389 { 9390 (() => 9391 { 9392 let map = {}, trace = {}; 9393 9394 document.querySelectorAll('[data-widget]').forEach((element) => 9395 { 9396 let widget = element.dataset.widget; 9397 9398 let entity = 9399 { 9400 9401 item_id: element.dataset.id, 9402 item_id_numeric:parseInt(element.dataset?.numeric), 9403 item_name: element.dataset.name, 9404 item_list_name: element.dataset.list, 9405 item_list_id: element.dataset.list, 9406 item_brand: element.dataset.brand, 9407 category: element.dataset.category, 9408 price: parseFloat(element.dataset.price), 9409 index: parseFloat(element.dataset.position), 9410 currency: AEC.GA4.currency, 9411 quantity: 1, 9412 google_business_vertical: 'retail' 9413 }; 9414 9415 Object.assign(entity, entity, AEC.GA4.augmentCategories(entity)); 9416 9417 let attributes = element.dataset.attributes; 9418 9419 if (attributes) 9420 { 9421 Object.entries(JSON.parse(attributes)).forEach(([key, value]) => 9422 { 9423 entity[key] = value; 9424 }); 9425 } 9426 9427 if (!map.hasOwnProperty(widget)) 9428 { 9429 map[widget] = []; 9430 9431 map[widget].trace = {}; 9432 map[widget].entry = []; 9433 map[widget].item_list_id = ''; 9434 map[widget].item_list_name = ''; 9435 } 9436 9437 if (!map[widget].trace.hasOwnProperty(element.dataset.id)) 9438 { 9439 map[widget].trace[element.dataset.id] = true; 9440 9441 map[widget].entry.push(entity); 9442 9443 map[widget].item_list_id = entity.item_list_id; 9444 map[widget].item_list_name = entity.item_list_name; 9445 } 9446 }); 9447 9448 Object.entries(map).forEach(([key, value]) => 9449 { 9450 if (value.entry.length) 9451 { 9452 let data = 9453 { 9454 event: 'view_item_list', 9455 ecommerce: 9456 { 9457 item_list_id: value.item_list_id, 9458 item_list_name: value.item_list_name, 9459 items: value.entry 9460 } 9461 }; 9462 9463 if ('undefined' !== typeof dataLayer) 9464 { 9465 (function(callback) 9466 { 9467 if (AEC.Const.COOKIE_DIRECTIVE) 9468 { 9469 AEC.CookieConsent.queue(callback).process(); 9470 } 9471 else 9472 { 9473 callback.apply(window,[]); 9474 } 9475 }) 9476 ( 9477 (function(dataLayer, data) 9478 { 9479 return function() 9480 { 9481 AEC.EventDispatcher.trigger('ec.widget.view.data', data); 9482 9483 if (AEC.reset) 9484 { 9485 dataLayer.push({ ecommerce: null }); 9486 } 9487 9488 dataLayer.push(data); 9489 } 9490 })(dataLayer, data) 9491 ); 9492 } 9493 } 9494 }); 9495 })(); 9496 }); 9497 9498</script>
9498<script data-ommit="true" nonce="MW8zbHFodjIwMXlkMHZyNXk1Z2htd2p6a2FwNHo5a24="> 9499 9500 if (typeof dataLayer !== "undefined") 9501 { 9502 9503 9504 AEC.Request.get(AEC.url('datalayer/index/events'), {}, response => 9505 { 9506 Object.entries(response.events).forEach(([key, event]) => 9507 { 9508 dataLayer.push(event); 9509 }); 9510 }); 9511 9512 9513 9514 AEC.EventDispatcher.on('ec.facebook.loaded', () => 9515 { 9516 }); 9517 9518 9519 if (window.google_tag_params) 9520 { 9521 (function(callback) 9522 { 9523 if (AEC.Const.COOKIE_DIRECTIVE) 9524 { 9525 AEC.CookieConsent.queue(callback, "cookieConsentGranted").process(); 9526 } 9527 else 9528 { 9529 callback.apply(window,[]); 9530 } 9531 }) 9532 ( 9533 (function(dataLayer) 9534 { 9535 return () => 9536 { 9537 AEC.Cookie.remarketing({ event:'fireRemarketingTag', google_tag_params: window.google_tag_params }).push(dataLayer); 9538 } 9539 })(dataLayer) 9540 ); 9541 } 9542 9543 9544 9545 window.addEventListener('load', event => 9546 { 9547 if (!AEC.gtm()) 9548 { 9549 AEC.Request.post(AEC.url('datalayer/index/datalayer'), { data: dataLayerTransport.serialize() }, response => 9550 { 9551 console.log('Google Tag Manager may be blocked by Ad-Blocker or not included in page'); 9552 }); 9553 } 9554 }); 9555 9556 } 9557 else 9558 { 9559 console.log('dataLayer[] is not intialized. Check if GTM is installed properly'); 9560 } 9561 9562</script>
vendor: 1 bytes, line 9562
9562
9563<script type="module"> 9564 import { 9565 initMiniSearch 9566 } from 'https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Doppler_LuigisBoxAutocomplete/js/search-form.js'; 9567 9568 window.addEventListener('alpine:init', () => { 9569 window.Alpine.data('initMiniSearch', () => initMiniSearch({ 9570 minSearchLength: 2, 9571 trackerId: '610584\u002D770525', 9572 productCount: 6, 9573 categoryCount: 5, 9574 hitFields: 'image_link,title,price,price_old,swatch,sku', 9575 messages: { 9576 placeholder: 'Was\u0020suchen\u0020Sie\u003F', 9577 minSearchLengthError: 'Die\u0020minimale\u0020L\u00E4nge\u0020der\u0020Suchbegriffe\u0020ist\u00202\u0020Zeichen', 9578 offlineMessage: 'You\u0020are\u0020currently\u0020offline.\u0020Quick\u0020search\u0020is\u0020unavailable.', 9579 apiErrorMessage: 'Beim\u0020Verbinden\u0020mit\u0020der\u0020Luigi\u0027s\u0020Box\u0020API\u0020ist\u0020ein\u0020Fehler\u0020aufgetreten', 9580 networkErrorMessage: 'Network\u0020error\u0020occurred.\u0020Please\u0020try\u0020again.', 9581 parseErrorMessage: 'Failed\u0020to\u0020process\u0020search\u0020results.', 9582 unknownErrorMessage: 'An\u0020unexpected\u0020error\u0020occurred.\u0020Try\u0020using\u0020standard\u0020search.', 9583 missingTrackerId: 'Tracker\u002DID\u0020fehlt' 9584 } 9585 })); 9586 }, {
9587 once: true 9588 }); 9589</script>
vendor: 1 bytes, line 9589
9589
9590<script> 9591 let SnapSlider = class { 9592 constructor(el, { 9593 labelSepparator = 'von', 9594 autoPager, 9595 groupPager 9596 } = {}) { 9597 this.el = el; 9598 this.track = this.el.querySelector("[data-track]"); 9599 if (!this.track) { 9600 console.warn( 9601 "No Slider track defined, reverting back to CSS slider.\nPlease create a wrapper for your slides with the attribute data-track", 9602 this.el 9603 ); 9604 return; 9605 } 9606 this.initialLoad = true; 9607 this.slides = []; 9608 this.inViewObserver; 9609 this.mutationObserver; 9610 this.resizeObserver; 9611 this.pager = this.el.querySelector("[data-pager]"); 9612 this.navBtns = Array.from( 9613 this.el.querySelectorAll("[data-next], [data-prev]") 9614 ); 9615 this.slideLabelSepparator = this.el.dataset.slideLabelSepparator || labelSepparator; 9616 this.useAutoPager = autoPager || this.el.hasAttribute("data-auto-pager") || false; 9617 this.useGroupPager = groupPager || this.el.hasAttribute("data-group-pager") || false; 9618 this.sliderLabel = this.el.hasAttribute("aria-label") && this.el.getAttribute("aria-label").toLowerCase().trim().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, ""); 9619 this.sliderId = this.el.id || this.sliderLabel || "slider"; 9620 this.markerIdName = "data-target-id"; 9621 this.pagerClasses = this.el.dataset.pagerClass || "snap-pager"; 9622 this.markerClasses = this.el.dataset.markerClass || "snap-marker"; 9623 this.init(); 9624 } 9625 init() { 9626 this.setupSlides(); 9627 this.setupNav(); 9628 if (this.useAutoPager) { 9629 this.createPager(); 9630 } else { 9631 this.setupPager(); 9632 } 9633 this.setupObservers(); 9634 this.setupMutationObserver(); 9635 this.setupResizeObserver(); 9636 this.el.addEventListener("click", this.eventHandler.bind(this)); 9637 this.el.addEventListener("keydown", this.eventHandler.bind(this)); 9638 } 9639 destroy() { 9640 this.inViewObserver?.disconnect(); 9641 this.mutationObserver?.disconnect(); 9642 this.resizeObserver?.disconnect(); 9643 this.el.removeEventListener("click", this.eventHandler.bind(this)); 9644 this.el.removeEventListener("keydown", this.eventHandler.bind(this)); 9645 } 9646 roundUpIfGreaterThan(number, min = 8) { 9647 const decimalPart = number - Math.floor(number); 9648 return decimalPart >= min ? Math.ceil(number) : Math.floor(number); 9649 } 9650 getInViewItems() { 9651 const inViewSlides = this.track.querySelectorAll("[data-in-view]"); 9652 const firstInViewSlide = inViewSlides[0] || null; 9653 const lastInViewSlide = inViewSlides[inViewSlides.length - 1] || null; 9654 const isAtStart = firstInViewSlide === this.slides[0]; 9655 const isAtEnd = lastInViewSlide === this.slides[this.slides.length - 1]; 9656 return { 9657 inViewSlides, 9658 totalInViewSlides: inViewSlides.length, 9659 firstInViewSlide, 9660 lastInViewSlide, 9661 isAtStart, 9662 isAtEnd, 9663 hasNoOverflow: isAtStart && isAtEnd 9664 }; 9665 } 9666 groupPagerMarkers() { 9667 if (this.slides.length === 0 || !this.pager || !this.useGroupPager) return; 9668 const totalVisibleSlides = this.roundUpIfGreaterThan( 9669 this.track.offsetWidth / this.slides[0].offsetWidth 9670 ); 9671 const markers = Array.from(this.pager.querySelectorAll("a, button")); 9672 markers.forEach((marker, index) => { 9673 marker.style.display = index % totalVisibleSlides === 0 ? null : "none"; 9674 }); 9675 } 9676 handleInView(entries) { 9677 entries.forEach((entry) => { 9678 const marker = this.pager && (this.pager.querySelector(`[href="#${entry.target.id}"]`) || this.pager.querySelector( 9679 `[${this.markerIdName}="${entry.target.id}"]` 9680 )); 9681 entry.target.toggleAttribute("data-in-view", entry.isIntersecting); 9682 entry.target.toggleAttribute("inert", !entry.isIntersecting); 9683 marker?.setAttribute("aria-current", entry.isIntersecting); 9684 marker?.setAttribute("tabindex", entry.isIntersecting ? "0" : "-1"); 9685 }); 9686 const { 9687 isAtStart, 9688 isAtEnd, 9689 hasNoOverflow 9690 } = this.getInViewItems(); 9691 this.navBtns.forEach((btn) => { 9692 if (btn.hasAttribute("data-next")) { 9693 btn.style.visibility = hasNoOverflow ? "hidden" : null; 9694 isAtEnd ? btn.setAttribute("disabled", "") : btn.removeAttribute("disabled"); 9695 } 9696 if (btn.hasAttribute("data-prev")) { 9697 btn.style.visibility = hasNoOverflow ? "hidden" : null; 9698 isAtStart ? btn.setAttribute("disabled", "") : btn.removeAttribute("disabled"); 9699 } 9700 }); 9701 if (this.pager) { 9702 this.pager.style.visibility = hasNoOverflow ? "hidden" : null; 9703 } 9704 if (!this.initialLoad) { 9705 this.el.dispatchEvent( 9706 new CustomEvent("slideChange", { 9707 detail: this.getInViewItems() 9708 }) 9709 ); 9710 } else { 9711 this.initialLoad = false;
9712 } 9713 if (document.activeElement.parentElement.hasAttribute("data-pager")) { 9714 const activeItems = this.pager.querySelectorAll('[tabindex="0"]'); 9715 if (activeItems.length) { 9716 activeItems[0].focus({ preventScroll: true }); 9717 } 9718 } 9719 } 9720 getSlides() { 9721 if (!this.track) return []; 9722 return Array.from(this.track.children).filter( 9723 (child) => child.tagName.toLowerCase() !== "template" && child.tagName.toLowerCase() !== "style" && child.tagName.toLowerCase() !== "script" 9724 ); 9725 } 9726 refreshSlides() { 9727 this.initialLoad = true; 9728 this.slides = this.getSlides(); 9729 this.setupSlides(); 9730 if (this.useAutoPager) { 9731 this.createPager(); 9732 } else { 9733 this.setupPager(); 9734 } 9735 this.groupPagerMarkers(); 9736 this.setupObservers(); 9737 } 9738 setupSlides() { 9739 this.slides = this.getSlides(); 9740 this.slides.forEach((slide, index) => { 9741 const totalSlides = this.slides.length; 9742 const currentSlide = index + 1; 9743 const existingLabel = slide.getAttribute("aria-label") || ""; 9744 const isImage = slide.tagName.toLowerCase() === "img" || slide.tagName.toLowerCase() === "picture"; 9745 const slideLabelTag = isImage ? "alt" : "aria-label"; 9746 const hasAutoLabel = existingLabel.startsWith( 9747 `${currentSlide} ${this.slideLabelSepparator} ` 9748 ); 9749 if (!slide.hasAttribute("id")) { 9750 slide.setAttribute( 9751 "id", 9752 `${this.sliderId}-item-${currentSlide}` 9753 ); 9754 } 9755 if (!slide.hasAttribute(slideLabelTag) || slide.getAttribute(slideLabelTag) === "" || hasAutoLabel) { 9756 slide.setAttribute( 9757 slideLabelTag, 9758 `${currentSlide} ${this.slideLabelSepparator} ${totalSlides}` 9759 ); 9760 } 9761 if (slide.tagName.toLowerCase() === "div" && !slide.hasAttribute("role")) { 9762 slide.setAttribute("role", "group"); 9763 } 9764 if (this.pager && !isImage) { 9765 slide.setAttribute("role", "tabpanel"); 9766 } 9767 if (slide.getAttribute("role") === "group") { 9768 slide.setAttribute("aria-roledescription", "item"); 9769 } 9770 }); 9771 if (!this.el.hasAttribute("role") && this.el.tagName !== "SECTION") { 9772 this.el.setAttribute("role", "region"); 9773 } 9774 if (!this.el.hasAttribute("aria-roledescription")) { 9775 this.el.setAttribute("aria-roledescription", "carousel"); 9776 } 9777 this.track.setAttribute("tabindex", 0); 9778 this.track.setAttribute("aria-live", "polite"); 9779 } 9780 setupNav() { 9781 this.navBtns.forEach((btn) => { 9782 btn.setAttribute("disabled", ""); 9783 btn.removeAttribute("hidden"); 9784 btn.classList.remove("invisible"); 9785 btn.style.visibility = null; 9786 }); 9787 } 9788 createPager() { 9789 const newPager = document.createElement("nav"); 9790 newPager.setAttribute("data-pager", ""); 9791 newPager.setAttribute("role", "tablist"); 9792 newPager.classList.add(...this.pagerClasses.split(" ")); 9793 this.slides.forEach((slide, index) => { 9794 const marker = document.createElement("button"); 9795 const slideId = slide.id || `${this.sliderId}-item-${index + 1}`; 9796 marker.setAttribute(this.markerIdName, slideId); 9797 marker.classList.add(...this.markerClasses.split(" ")); 9798 this.setupPagerMarker(marker, index); 9799 newPager.appendChild(marker); 9800 if (slide.tagName.toLowerCase() !== "img" && slide.tagName.toLowerCase() !== "picture") { 9801 slide.removeAttribute("aria-roledescription"); 9802 slide.setAttribute("role", "tabpanel"); 9803 } 9804 }); 9805 if (this.pager) { 9806 this.pager.setAttribute("role", "tablist"); 9807 this.pager.replaceChildren(...newPager.children); 9808 } else { 9809 this.track.after(newPager); 9810 this.pager = this.el.querySelector("[data-pager]"); 9811 } 9812 } 9813 setupPager() { 9814 if (!this.pager) return; 9815 this.pager.setAttribute("role", "tablist"); 9816 const items = Array.from(this.pager.querySelectorAll("a, button"));
9817 items.forEach((marker, index) => this.setupPagerMarker(marker, index)); 9818 } 9819 setupPagerMarker(marker, index) { 9820 const markerId = marker.getAttribute("href")?.slice(1) || marker.getAttribute(this.markerIdName); 9821 const slideId = markerId || `${this.sliderId}-item-${index + 1}`; 9822 if (!markerId) { 9823 marker.setAttribute(this.markerIdName, slideId); 9824 } 9825 marker.setAttribute("role", "tab"); 9826 marker.setAttribute("aria-controls", slideId); 9827 marker.setAttribute("aria-posinset", index + 1); 9828 marker.setAttribute("aria-setsize", this.slides.length); 9829 marker.setAttribute("tabindex", "-1"); 9830 if (!marker.hasAttribute("aria-label")) { 9831 marker.setAttribute("aria-label", `Slide ${index + 1}`); 9832 } 9833 } 9834 setupObservers() { 9835 if (this.inViewObserver) { 9836 this.inViewObserver.disconnect(); 9837 } 9838 this.inViewObserver = new IntersectionObserver( 9839 this.handleInView.bind(this), { 9840 root: this.track, 9841 threshold: 0.8 9842 } 9843 ); 9844 this.slides.forEach((slide) => this.inViewObserver.observe(slide)); 9845 } 9846 setupMutationObserver() { 9847 this.mutationObserver = new MutationObserver( 9848 this.refreshSlides.bind(this) 9849 ); 9850 this.mutationObserver.observe(this.track, { 9851 childList: true, 9852 subtree: false 9853 }); 9854 } 9855 setupResizeObserver() { 9856 this.resizeObserver = new ResizeObserver( 9857 this.groupPagerMarkers.bind(this) 9858 ); 9859 this.resizeObserver.observe(this.el); 9860 } 9861 goToSlideDir(dir = "next") { 9862 const { 9863 firstInViewSlide, 9864 lastInViewSlide 9865 } = this.getInViewItems(); 9866 const isPrev = dir === "prev"; 9867 let targetSlide = isPrev ? firstInViewSlide?.previousElementSibling : lastInViewSlide?.nextElementSibling; 9868 if (!targetSlide) return; 9869 if (targetSlide.tagName.toLowerCase() === "template") { 9870 targetSlide = isPrev ? targetSlide?.previousElementSibling : targetSlide?.nextElementSibling; 9871 } 9872 targetSlide.scrollIntoView({ block: "nearest", inline: isPrev ? "end" : "start" }); 9873 } 9874 pagerToSlide(event) { 9875 if (!event.target.closest("[data-pager]")) return; 9876 const marker = event.target.closest("a, button"); 9877 if (!marker) return; 9878 event.preventDefault(); 9879 const slideId = marker.getAttribute("href")?.slice(1) || marker.getAttribute(this.markerIdName); 9880 const targetSlide = this.track.querySelector(`#${slideId}`); 9881 targetSlide?.scrollIntoView({ block: "nearest", inline: "start" }); 9882 } 9883 eventHandler(event) { 9884 const target = event.target.closest( 9885 "[data-next], [data-prev], [data-pager]" 9886 ); 9887 if (!target) return; 9888 if (event.type === "click") { 9889 if (target.hasAttribute("data-next")) { 9890 this.goToSlideDir("next"); 9891 } else if (target.hasAttribute("data-prev")) { 9892 this.goToSlideDir("prev"); 9893 } else if (target.closest("[data-pager]")) { 9894 this.pagerToSlide(event); 9895 } 9896 } 9897 if (event.type === "keydown" && target.closest("[data-pager]")) { 9898 if (event.key === "ArrowRight") { 9899 this.goToSlideDir("next"); 9900 } else if (event.key === "ArrowLeft") { 9901 this.goToSlideDir("prev"); 9902 } 9903 } 9904 } 9905 }; 9906 9907 (() => { 9908 function alpineSnapSlider(Alpine) { 9909 Alpine.directive("snap-slider", (el, { 9910 modifiers 9911 }, { 9912 cleanup 9913 }) => { 9914 const autoPager = modifiers.includes("auto-pager");
9915 const groupPager = modifiers.includes("group-pager"); 9916 const slider = new SnapSlider(el, { 9917 autoPager, 9918 groupPager 9919 }); 9920 cleanup(() => { 9921 slider.destroy(); 9922 }); 9923 }); 9924 } 9925 9926 document.addEventListener("alpine:init", () => { 9927 window.Alpine.plugin(alpineSnapSlider); 9928 }); 9929 })(); 9930 //# sourceURL=alpine-snap-slider.js 9931</script>
vendor: 1 bytes, line 9931
9931
9932<script> 9933 (() => { 9934 // src/dialog.js 9935 function dialog_default(Alpine) { 9936 Alpine.directive("htmldialog", fylgjaAlpineDialog); 9937 9938 function fylgjaAlpineDialog(el, { 9939 expression, 9940 modifiers 9941 }, { 9942 evaluateLater, 9943 cleanup 9944 }) { 9945 const evaluate = expression.length ? evaluateLater(expression) : () => {}; 9946 const lockPageScroll = modifiers.includes("noscroll"); 9947 const closeby = modifierValue(modifiers, "closeby", "any"); 9948 el.style.display = null; 9949 el.hidden = false; 9950 el.style.length === 0 && el.removeAttribute("style"); 9951 el.addEventListener("keydown", escapeDialog); 9952 el.addEventListener("click", backdropDialog); 9953 el.addEventListener("submit", methodDialog); 9954 9955 function scrollLock(use = true) { 9956 document.body.style.overflow = use ? "hidden" : ""; 9957 } 9958 9959 function methodDialog(event) { 9960 if (event.target.getAttribute("method") === "dialog" || event.submitter && event.submitter.getAttribute("formmethod") === "dialog") { 9961 evaluate(); 9962 } 9963 } 9964 9965 function escapeDialog(event) { 9966 if (event.key !== "Escape") 9967 return; 9968 event.preventDefault(); 9969 if (closeby !== "any" && closeby !== "closerequest") 9970 return; 9971 evaluate(); 9972 } 9973 9974 function backdropDialog(event) { 9975 if (event.target !== el || closeby !== "any") 9976 return; 9977 const rect = el.getBoundingClientRect(); 9978 const isInDialog = rect.top <= event.clientY && event.clientY <= rect.top + rect.height && rect.left <= event.clientX && event.clientX <= rect.left + rect.width; 9979 if (isInDialog) 9980 return; 9981 evaluate(); 9982 } 9983 el._x_doShow = () => { 9984 if (el.hasAttribute("open")) 9985 return; 9986 el.showModal(); 9987 scrollLock(lockPageScroll); 9988 }; 9989 el._x_doHide = () => { 9990 if (!el.hasAttribute("open")) 9991 return; 9992 el.close(); 9993 scrollLock(false); 9994 }; 9995 cleanup(() => { 9996 el.removeEventListener("keydown", escapeDialog); 9997 el.removeEventListener("click", backdropDialog); 9998 el.removeEventListener("submit", methodDialog); 9999 scrollLock(false); 10000 }); 10001 } 10002 } 10003 10004 function modifierValue(modifiers, key, fallback) { 10005 if (modifiers.indexOf(key) === -1) 10006 return fallback; 10007 const rawValue = modifiers[modifiers.indexOf(key) + 1]; 10008 if (!rawValue) 10009 return fallback; 10010 if (key === "closeby") { 10011 const allowedValues = ["auto", "none", "closerequest", "any"]; 10012 const options = allowedValues.join(", "); 10013 if (!allowedValues.includes(rawValue)) { 10014 console.warn( 10015 `"${rawValue}" is not one of the allowed values for closeby: ${options}` 10016 ); 10017 } 10018 return fallback; 10019 } 10020 return rawValue; 10021 } 10022 10023 // src/cdn.js 10024 document.addEventListener("alpine:init", () => { 10025 window.Alpine.plugin(dialog_default); 10026 }); 10027 })(); 10028</script>
vendor: 1 bytes, line 10028
10028
10029<script> 10030 (() => { 10031 function src_default(Alpine) { 10032 Alpine.directive("intersect", Alpine.skipDuringClone((el, { value, expression, modifiers }, { evaluateLater, cleanup }) => { 10033 let evaluate = evaluateLater(expression); 10034 let options = { 10035 rootMargin: getRootMargin(modifiers), 10036 threshold: getThreshold(modifiers) 10037 }; 10038 let observer = new IntersectionObserver((entries) => { 10039 entries.forEach((entry) => { 10040 if (entry.isIntersecting === (value === "leave")) 10041 return; 10042 evaluate(); 10043 modifiers.includes("once") && observer.disconnect(); 10044 }); 10045 }, options); 10046 observer.observe(el); 10047 cleanup(() => { 10048 observer.disconnect(); 10049 }); 10050 })); 10051 } 10052 function getThreshold(modifiers) { 10053 if (modifiers.includes("full")) 10054 return 0.99; 10055 if (modifiers.includes("half")) 10056 return 0.5; 10057 if (!modifiers.includes("threshold")) 10058 return 0; 10059 let threshold = modifiers[modifiers.indexOf("threshold") + 1]; 10060 if (threshold === "100") 10061 return 1; 10062 if (threshold === "0") 10063 return 0; 10064 return Number(`.${threshold}`); 10065 } 10066 function getLengthValue(rawValue) { 10067 let match = rawValue.match(/^(-?[0-9]+)(px|%)?$/); 10068 return match ? match[1] + (match[2] || "px") : void 0; 10069 } 10070 function getRootMargin(modifiers) { 10071 const key = "margin"; 10072 const fallback = "0px 0px 0px 0px"; 10073 const index = modifiers.indexOf(key); 10074 if (index === -1) 10075 return fallback; 10076 let values = []; 10077 for (let i = 1; i < 5; i++) { 10078 values.push(getLengthValue(modifiers[index + i] || "")); 10079 } 10080 values = values.filter((v) => v !== void 0); 10081 return values.length ? values.join(" ").trim() : fallback; 10082 } 10083 10084 document.addEventListener("alpine:init", () => { 10085 window.Alpine.plugin(src_default); 10086 }); 10087 })(); 10088 //# sourceURL=alpine-intersect.js 10089</script>
vendor: 1 bytes, line 10089
10089
10090<script> 10091 for (const [selector, deferUntil] of Object.entries({".product-slider section[x-data]:not([x-data] [x-data])":"intersect",".product-info [x-data]:not([x-data] [x-data])":"intersect","#filters-content [x-data]:not([x-data] [x-data])":"intersect","#review_form":"intersect","section[x-data^=initRecentlyViewedProductsComponent]":"intersect","div[x-data^=initBundleOptions]":"intersect","#product_addtocart_form [x-data]:not([x-data] [x-data])":"intersect","#notice-cookie-block":"idle"})) { 10092 document.querySelectorAll(selector).forEach(el => el.setAttribute('x-defer', `${deferUntil}`)); 10093 } 10094 //# sourceURL=alpine-defer-rules.js 10095</script>
vendor: 1 bytes, line 10095
10095
10096<script> 10097 (() => { 10098 const hasAlpine = new Promise(resolve => { 10099 window.addEventListener('alpine:initialized', resolve, {once: true, passive: true}); 10100 }); 10101 10102 const hasInteract = new Promise(resolve => { 10103 (events => { 10104 const onInteract = () => { 10105 resolve(); 10106 events.forEach(type => window.removeEventListener(type, onInteract)); 10107 } 10108 events.forEach(type => window.addEventListener(type, onInteract, {once: true, passive: true})) 10109 })(['touchstart', 'mouseover', 'wheel', 'scroll', 'keydown']) 10110 }); 10111 10112 const onIntersect = (el) => { 10113 return new Promise(resolve => { 10114 const observer = new IntersectionObserver(entries => { 10115 for (const entry of entries) { 10116 if (entry.isIntersecting) { 10117 observer.disconnect() 10118 resolve(); 10119 } 10120 } 10121 }, {}); 10122 observer.observe(el); 10123 }); 10124 } 10125 10126 function runComponent(el) { 10127 hasAlpine.then(() => { 10128 el.removeAttribute('x-ignore'); 10129 queueMicrotask(() => Alpine.initTree(el)); 10130 }); 10131 } 10132 10133 function initDeferredComponents() { 10134 document.querySelectorAll('[x-data][x-defer]').forEach(el => { 10135 el.setAttribute('x-ignore', ''); 10136 const deferUntil = (el.getAttribute('x-defer') || '').trim(); 10137 switch (deferUntil) { 10138 case 'interact': 10139 hasInteract.then(() => runComponent(el)); 10140 break; 10141 case 'intersect': 10142 onIntersect(el).then(() => runComponent(el)) 10143 break; 10144 case 'idle': 10145 window.requestIdleCallback 10146 ? window.requestIdleCallback(() => runComponent(el), {timeout: 4000}) 10147 : setTimeout(() => runComponent(el), 4000); 10148 break; 10149 case 'eager': 10150 runComponent(el); 10151 break; 10152 default: 10153 if (deferUntil.startsWith('event:') && deferUntil.length > 6) { 10154 window.addEventListener(deferUntil.substring(6), () => runComponent(el), {once: true, passive: true}); 10155 } 10156 } 10157 }); 10158 } 10159 10160 window.addEventListener('alpine:init', initDeferredComponents, {once: true, passive: true}); 10161 })(); 10162 //# sourceURL=alpine-defer.js 10163</script>
vendor: 1 bytes, line 10163
10163
vendor: 3,136 bytes, lines 10164-10266
10164<script> 10165(() => { 10166 // packages/collapse/src/index.js 10167 function src_default(Alpine) { 10168 Alpine.directive("collapse", collapse); 10169 collapse.inline = (el, { modifiers }) => { 10170 if (!modifiers.includes("min")) 10171 return; 10172 el._x_doShow = () => { 10173 }; 10174 el._x_doHide = () => { 10175 }; 10176 }; 10177 10178 function collapse(el, { modifiers }) { 10179 let duration = modifierValue(modifiers, "duration", 250) / 1e3; 10180 let floor = modifierValue(modifiers, "min", 0); 10181 let fullyHide = !modifiers.includes("min"); 10182 if (!el._x_isShown) 10183 el.style.height = `${floor}px`; 10184 if (!el._x_isShown && fullyHide) 10185 el.hidden = true; 10186 if (!el._x_isShown) 10187 el.style.overflow = "hidden"; 10188 let setFunction = (el2, styles) => { 10189 let revertFunction = Alpine.setStyles(el2, styles); 10190 return styles.height ? () => { 10191 } : revertFunction; 10192 }; 10193 let transitionStyles = { 10194 transitionProperty: "height", 10195 transitionDuration: `${duration}s`, 10196 transitionTimingFunction: "cubic-bezier(0.4, 0.0, 0.2, 1)" 10197 }; 10198 el._x_transition = { 10199 in(before = () => { 10200 }, after = () => { 10201 }) { 10202 if (fullyHide) 10203 el.hidden = false; 10204 if (fullyHide) 10205 el.style.display = null; 10206 let current = el.getBoundingClientRect().height; 10207 el.style.height = "auto"; 10208 let full = el.getBoundingClientRect().height; 10209 if (current === full) { 10210 current = floor; 10211 } 10212 Alpine.transition(el, Alpine.setStyles, { 10213 during: transitionStyles, 10214 start: { height: current + "px" }, 10215 end: { height: full + "px" } 10216 }, () => el._x_isShown = true, () => { 10217 if (Math.abs(el.getBoundingClientRect().height - full) < 1) { 10218 el.style.overflow = null; 10219 } 10220 }); 10221 }, 10222 out(before = () => { 10223 }, after = () => { 10224 }) { 10225 let full = el.getBoundingClientRect().height; 10226 Alpine.transition(el, setFunction, { 10227 during: transitionStyles, 10228 start: { height: full + "px" }, 10229 end: { height: floor + "px" } 10230 }, () => el.style.overflow = "hidden", () => { 10231 el._x_isShown = false; 10232 if (el.style.height == `${floor}px` && fullyHide) { 10233 el.style.display = "none"; 10234 el.hidden = true; 10235 } 10236 }); 10237 } 10238 }; 10239 } 10240 } 10241 10242 function modifierValue(modifiers, key, fallback) { 10243 if (modifiers.indexOf(key) === -1) 10244 return fallback; 10245 const rawValue = modifiers[modifiers.indexOf(key) + 1]; 10246 if (!rawValue) 10247 return fallback; 10248 if (key === "duration") { 10249 let match = rawValue.match(/([0-9]+)ms/); 10250 if (match) 10251 return match[1]; 10252 } 10253 if (key === "min") { 10254 let match = rawValue.match(/([0-9]+)px/); 10255 if (match) 10256 return match[1]; 10257 } 10258 return rawValue; 10259 } 10260 10261 // packages/collapse/builds/cdn.js 10262 document.addEventListener("alpine:init", () => { 10263 window.Alpine.plugin(src_default); 10264 }); 10265})(); 10266</script>
vendor: 1 bytes, line 10266
10266
10267<script> 10268 (() => { 10269 document.addEventListener("alpine:init", () => { 10270 const createBreakpointStore = (defaultBreakpoint) => { 10271 return { 10272 breakpoint: defaultBreakpoint, 10273 matchMedia: null, 10274 value: false, 10275 init() { 10276 this.setBreakpoint(this.breakpoint); 10277 }, 10278 setBreakpoint(width) { 10279 if (this.matchMedia) { 10280 this.matchMedia.removeEventListener('change', this.handleChange); 10281 } 10282 10283 this.breakpoint = width; 10284 this.matchMedia = window.matchMedia(`(max-width: ${width}px)`); 10285 this.value = this.matchMedia.matches; 10286 10287 const handleChange = (event) => { 10288 this.value = event.matches; 10289 }; 10290 10291 this.handleChange = handleChange; 10292 this.matchMedia.addEventListener('change', this.handleChange); 10293 } 10294 }; 10295 }; 10296 10297 window.Alpine.store('isMobile', createBreakpointStore(768)); 10298 window.Alpine.store('isTablet', createBreakpointStore(1024)); 10299 }); 10300 })(); 10301</script>
10301<script> 10302 (() => { 10303 document.addEventListener("alpine:init", () => { 10304 window.Alpine.data('horizontalScroll', function(config = {}) { 10305 return { 10306 containerRef: config.containerRef || 'scrollContainer', 10307 canScrollLeft: null, 10308 canScrollRight: null, 10309 scrollAmount: config.scrollAmount || 0.85, 10310 threshold: config.threshold !== undefined ? config.threshold : 5, 10311 mutationObserver: null, 10312 resizeObserver: null, 10313 resizeHandler: null, 10314 updateTimeout: null, 10315 init() { 10316 this.$nextTick(() => { 10317 this.updateScrollState(); 10318 this.observeChanges(); 10319 }); 10320 10321 this.resizeHandler = () => { 10322 this.debouncedUpdateScrollState(); 10323 }; 10324 10325 window.addEventListener('resize', this.resizeHandler); 10326 }, 10327 observeChanges() { 10328 const container = this.$refs[this.containerRef]; 10329 if (!container) { 10330 return; 10331 } 10332 10333 this.mutationObserver = new MutationObserver(() => { 10334 this.$nextTick(() => { 10335 this.debouncedUpdateScrollState(); 10336 }); 10337 }); 10338 10339 this.mutationObserver.observe(container, { 10340 childList: true, 10341 subtree: true, 10342 attributes: false, 10343 }); 10344 10345 this.resizeObserver = new ResizeObserver(() => { 10346 this.debouncedUpdateScrollState(); 10347 }); 10348 10349 this.resizeObserver.observe(container); 10350 }, 10351 debouncedUpdateScrollState() { 10352 if (this.updateTimeout) { 10353 clearTimeout(this.updateTimeout); 10354 } 10355 this.updateTimeout = setTimeout(() => { 10356 this.updateScrollState(); 10357 }, 16); 10358 }, 10359 updateScrollState() { 10360 const container = this.$refs[this.containerRef]; 10361 if (!container) { 10362 return; 10363 } 10364 const scrollLeft = container.scrollLeft, 10365 scrollWidth = container.scrollWidth, 10366 clientWidth = container.clientWidth, 10367 maxScroll = scrollWidth - clientWidth; 10368 10369 this.canScrollLeft = scrollLeft > this.threshold; 10370 this.canScrollRight = scrollLeft < maxScroll - this.threshold; 10371 }, 10372 scrollNav(direction) { 10373 const container = this.$refs[this.containerRef]; 10374 if (!container) { 10375 return; 10376 } 10377 const scrollAmount = container.clientWidth * this.scrollAmount; 10378 10379 container.scrollBy({ 10380 left: scrollAmount * direction, 10381 behavior: 'smooth', 10382 }); 10383 setTimeout(() => this.updateScrollState(), 300); 10384 }, 10385 destroy() { 10386 if (this.mutationObserver) { 10387 this.mutationObserver.disconnect(); 10388 } 10389 if (this.resizeObserver) { 10390 this.resizeObserver.disconnect(); 10391 } 10392 if (this.resizeHandler) { 10393 window.removeEventListener('resize', this.resizeHandler); 10394 } 10395 if (this.updateTimeout) { 10396 clearTimeout(this.updateTimeout); 10397 } 10398 }, 10399 }; 10400 }); 10401 }); 10402 })(); 10403</script>
10403 10404
10405<script type="module" 10406 src="https://knirps.de/static/version1790753864/frontend/Hyva/knirps/de_DE/Hyva_Theme/js/alpine3.min.js" 10407 defer 10408 crossorigin 10409></script>
vendor: 1 bytes, line 10409
10409
10410<script> 10411 function dispatchMessages(messages, hideAfter) { 10412 const messagesEvent = new CustomEvent("messages-loaded", { 10413 detail: { 10414 messages: messages, 10415 hideAfter: hideAfter 10416 } 10417 }); 10418 window.dispatchEvent(messagesEvent); 10419 } 10420 10421 if (typeof hyva === 'undefined' || (!hyva.getBrowserStorage || !hyva.getCookie || !hyva.setCookie)) { 10422 console.warn("Hyvä helpers are not loaded yet. Make sure they are included before this script"); 10423 } 10424 10425 (function( hyva, undefined ) { 10426 10427 hyva.initFormKey = () => { 10428 const inputSelector = 'input[name="form_key"]', 10429 formKey = hyva.getFormKey(); 10430 10431 Array.from(document.querySelectorAll(inputSelector)).map(function (input) { 10432 input.value = formKey 10433 }); 10434 } 10435 10436 hyva.initMessages = () => { 10437 try { 10438 const messages = hyva.getCookie('mage-messages'); 10439 window.mageMessages = messages ? JSON.parse(decodeURIComponent(messages).replace(/\+/g, ' ')) : []; 10440 10441 dispatchMessages(window.mageMessages); 10442 10443 // empty `mage-messages` cookie 10444 const skipSetDomain = true; 10445 hyva.setCookie('mage-messages','', -1, skipSetDomain); 10446 10447 } catch (error) { 10448 console.warn('Error parsing Cookie Messages:', error); 10449 } 10450 } 10451 10452 window.addEventListener('DOMContentLoaded', hyva.initFormKey); 10453 hyva.alpineInitialized(hyva.initMessages) 10454 10455 }( window.hyva = window.hyva || {} )); 10456 //# sourceURL=hyva-cookies.js 10457</script>
vendor: 1 bytes, line 10457
10457
10458<script> 10459 { 10460 const private_content_key = 'mage-cache-storage'; 10461 const private_content_expire_key = 'mage-cache-timeout'; 10462 const private_content_version_key = 'private_content_version'; 10463 const section_data_ids_key = 'section_data_ids'; 10464 const mage_cache_session_id_key = 'mage-cache-sessid'; 10465 const last_visited_store_key = 'last_visited_store'; 10466 10467 const ttl = 7884000; 10468 10469 if (typeof hyva === 'undefined' || (!hyva.getBrowserStorage || !hyva.getCookie || !hyva.setCookie)) { 10470 console.warn("Hyvä helpers are not loaded yet. Make sure they are included before this script"); 10471 } 10472 10473 function loadSectionData () { 10474 const browserStorage = hyva.getBrowserStorage(); 10475 if (!browserStorage) { 10476 typeof window.dispatchMessages !== "undefined" && window.dispatchMessages( 10477 [{ 10478 type: "warning", 10479 text: "Bitte aktivieren Sie LocalStorage in Ihrem Browser." 10480 }] 10481 ); 10482 return; 10483 } 10484 try { 10485 let isInvalid = false; 10486 10487 if (hyva.getCookie(last_visited_store_key) !== CURRENT_STORE_CODE) { 10488 isInvalid = true; 10489 } 10490 hyva.setCookie(last_visited_store_key, CURRENT_STORE_CODE, false, false); 10491 10492 if (!hyva.getCookie(mage_cache_session_id_key)) { 10493 isInvalid = true; 10494 browserStorage.removeItem(private_content_key); 10495 const skipSetDomain = true; 10496 const days = false; 10497 hyva.setCookie(mage_cache_session_id_key, true, days, skipSetDomain) 10498 } 10499 10500 const cookieVersion = hyva.getCookie(private_content_version_key); 10501 const storageVersion = browserStorage.getItem(private_content_version_key); 10502 10503 if (cookieVersion && !storageVersion || cookieVersion !== storageVersion) { 10504 isInvalid = true; 10505 } 10506 10507 const privateContentExpires = browserStorage.getItem(private_content_expire_key); 10508 if (privateContentExpires && new Date(privateContentExpires) < new Date()) { 10509 browserStorage.removeItem(private_content_key); 10510 } 10511 10512 if (isInvalid && cookieVersion) { 10513 fetchPrivateContent([]); 10514 } else if (cookieVersion && storageVersion && cookieVersion === storageVersion) { 10515 const privateContent = JSON.parse(browserStorage.getItem(private_content_key)); 10516 if ( 10517 privateContent && 10518 privateContentExpires && 10519 privateContent.cart && 10520 privateContent.customer 10521 ) { 10522 dispatchPrivateContent(privateContent); 10523 } else { 10524 fetchPrivateContent([]); 10525 } 10526 } else { 10527 if (document.getElementById('default-section-data')) { 10528 const privateContent = JSON.parse(document.getElementById('default-section-data').innerText.trim()); 10529 dispatchPrivateContent(privateContent); 10530 } else { 10531 dispatchPrivateContent({}); 10532 } 10533 } 10534 10535 } catch (error) { 10536 console.warn('Error retrieving Private Content:', error); 10537 } 10538 } 10539 10540 hyva.alpineInitialized(loadSectionData) 10541 window.addEventListener('reload-customer-section-data', loadSectionData); 10542 10543 window.processSectionDataBeforeDispatch = window.processSectionDataBeforeDispatch || (data => data); 10544 10545 function dispatchPrivateContent(data) { 10546 10547 const privateContentEvent = new CustomEvent("private-content-loaded", { 10548 detail: { 10549 data: window.processSectionDataBeforeDispatch(data) 10550 } 10551 }); 10552 window.dispatchEvent(privateContentEvent); 10553 } 10554 10555 function fetchPrivateContent(sections) { 10556 fetch(`${BASE_URL}customer/section/load/?sections=${encodeURIComponent(sections.join(','))}`, { 10557 method: 'GET', 10558 headers: { 10559 'Content-Type': 'application/json', 10560 'X-Requested-With': 'XMLHttpRequest' 10561 } 10562 }) 10563 .then(response => response.ok && response.json()) 10564 .then( 10565 data => { 10566 if (data) { 10567 try { 10568 const browserStorage = hyva.getBrowserStorage(); 10569 10570 // merge new data preserving non-invalidated sections 10571 const oldSectionData = JSON.parse(browserStorage.getItem(private_content_key) || '{}') || {}; 10572 10573 if ((! data.cart || ! data.cart.cartId) && oldSectionData['checkout-data']) { 10574 delete oldSectionData['checkout-data']; 10575 } 10576 const newSectionData = Object.assign(oldSectionData, data); 10577 10578 dispatchPrivateContent(newSectionData); 10579 10580 // don't persist messages, they've been dispatched already 10581 if (newSectionData.messages && newSectionData.messages.messages ) { 10582 newSectionData.messages.messages = []; 10583 } 10584 10585 browserStorage.setItem(private_content_key, JSON.stringify(newSectionData)); 10586 10587 const expiresAt = new Date(Date.now() + (ttl * 1000)).toISOString(); 10588 browserStorage.setItem(private_content_expire_key, expiresAt); 10589 10590 const newCookieVersion = hyva.getCookie(private_content_version_key); 10591 browserStorage.setItem(private_content_version_key, newCookieVersion); 10592 10593 // We don't need the section_data_ids in Hyvä, but we store them for compatibility 10594 // with Luma Fallback. Otherwise, not all sections are loaded in Luma Checkout 10595 hyva.setCookie( 10596 section_data_ids_key, 10597 JSON.stringify( 10598 Object.keys(data).reduce((sectionDataIds, sectionKey) => { 10599 sectionDataIds[sectionKey] = data[sectionKey]['data_id']; 10600 return sectionDataIds; 10601 }, {}) 10602 ), 10603 false, 10604 true 10605 ); 10606 } catch (error) { 10607 console.warn("Couldn't store privateContent", error); 10608 } 10609 } 10610 } 10611 ); 10612 } 10613 } 10614 //# sourceURL=hyva-private-content.js 10615</script>
vendor: 1 bytes, line 10615
10615
10616<script> 10617 (() => { 10618 document.addEventListener('submit', event => event.target.action = event.target.action.replace('%25uenc%25', hyva.getUenc())); 10619 })() 10620</script>
vendor: 1 bytes, line 10620
10620
10621<script> 10622 (events => { 10623 const dispatchUserInteractionEvent = () => { 10624 events.forEach(type => window.removeEventListener(type, dispatchUserInteractionEvent)) 10625 window.dispatchEvent(new Event('init-external-scripts')) 10626 }; 10627 events.forEach(type => window.addEventListener(type, dispatchUserInteractionEvent, {once: true, passive: true})) 10628 })(['touchstart', 'mousemove', 'wheel', 'scroll', 'keydown']); 10629 //# sourceURL=hyva-init-external-scripts.js 10630</script>
10630 10631 10632<div 10633 id="scroll-to-top" 10634 class="z-30 fixed bottom-6 sm:bottom-12 lg:bottom-16 right-4 sm:left-auto sm:right-8 md:right-12 lg:right-20" 10635 x-data="initScrollToTop" 10636 x-cloak 10637 x-show="visible" 10638 x-transition.duration.250ms 10639 x-bind="eventListeners"> 10640 <button 10641 type="button" 10642 class="btn shadow-lg text-primary bg-white rounded-full mx-auto p-3 border-0" 10643 @click="scrollToTop" 10644 aria-label="Zurück zum Seitenanfang scrollen"> 10645 <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" aria-hidden="true"> 10646<path fill-rule="evenodd" clip-rule="evenodd" d="M3.95157 11.6486C3.48294 11.1799 3.48294 10.4201 3.95157 9.9515L11.1516 2.7515C11.6202 2.28287 12.38 2.28287 12.8486 2.7515L20.0486 9.9515C20.5173 10.4201 20.5173 11.1799 20.0486 11.6486C19.58 12.1172 18.8202 12.1172 18.3516 11.6486L13.2001 6.49708L13.2001 20.4C13.2001 21.0628 12.6628 21.6 12.0001 21.6C11.3374 21.6 10.8001 21.0628 10.8001 20.4L10.8001 6.49708L5.64863 11.6486C5.18 12.1172 4.4202 12.1172 3.95157 11.6486Z" fill="currentColor"/> 10647</svg> 10648 10649 </button> 10650 10651
10651<script> 10652 function initScrollToTop() { 10653 return { 10654 visible: false, 10655 scrollOffset: 200, 10656 scrollPosition: 0, 10657 init() { 10658 scrollPosition = document.documentElement.scrollTop; 10659 this.$watch('scrollPosition', (pos, prevPos) => { 10660 this.visible = pos > this.scrollOffset; 10661 }); 10662 }, 10663 scrollToTop() { 10664 this.visible = false; 10665 document.documentElement.scrollIntoView({ 10666 behavior: 'smooth' 10667 }) 10668 }, 10669 eventListeners: { 10670 ['@scroll.window.throttle.50ms']() { 10671 this.scrollPosition = document.documentElement.scrollTop; 10672 }, 10673 ['@scroll.window.debounce.4000ms']() { 10674 this.visible = false; 10675 } 10676 } 10677 } 10678 } 10679 window.addEventListener('alpine:init', () => Alpine.data('initScrollToTop', initScrollToTop), { 10680 once: true 10681 }); 10682 </script>
10682 10683 </div>
10683<script> 10684 function initConfigurableOptions(productId, optionConfig) { 10685 10686 function findPathParam(key) { 10687 const baseUrl = (BASE_URL.substring(0, 2) === '//' ? 'http:' : '') + BASE_URL; 10688 const baseUrlParts = (new URL(baseUrl)).pathname.replace(/\/$/, '').split('/'); 10689 const pathParts = window.location.pathname.split('/').slice(baseUrlParts.length + 3); 10690 for (let i = 0; i < pathParts.length; i += 2) { 10691 if (pathParts[i] === key && pathParts.length > i) { 10692 return pathParts[i + 1]; 10693 } 10694 } 10695 } 10696 10697 return { 10698 optionConfig, 10699 productId, 10700 itemId: (new URLSearchParams(window.location.search)).get('id') || findPathParam('id'), 10701 allowedAttributeOptions: [], 10702 selectedValues: [], 10703 tierPricesMap: [], 10704 parentIsSaleable: false, 10705 init() { 10706 this.findAllowedAttributeOptions(); 10707 this.$nextTick(() => { 10708 if (typeof this.optionConfig.defaultValues === 'object') { 10709 for (const [attributeId, value] of Object.entries(this.optionConfig.defaultValues)) { 10710 this.changeOption(attributeId, value + ''); 10711 } 10712 } 10713 this.preselectQuerystringItems(); 10714 this.preselectLocationHashItems(); 10715 this.updateDeliveryInfo(); 10716 }); 10717 window.addEventListener('hashchange', () => this.preselectLocationHashItems()); 10718 }, 10719 productIndex: 0, 10720 productIndexForPrice: 0, 10721 optionIsActive(attributeId, optionId) { 10722 return !!this.getAllowedAttributeOptions(attributeId).find( 10723 option => option.id === optionId 10724 ) 10725 }, 10726 optionIsEnabled(attributeId, optionId) { 10727 for (const productId in this.optionConfig.index) { 10728 if (this.optionConfig.index[productId][attributeId] === optionId) { 10729 return true; 10730 } 10731 } 10732 return false; 10733 }, 10734 findSimpleIndex() { 10735 this.productIndex = this.calculateSimpleIndexForPartialSelection(this.selectedValues); 10736 this.productIndexForPrice = this.findCheapestProductForPartialSelection(this.selectedValues); 10737 }, 10738 calculateSimpleIndexForPartialSelection(selectedValues) { 10739 if (selectedValues.length === 0) return 0; 10740 return this.findProductIdsForPartialSelection(selectedValues)[0]; 10741 }, 10742 calculateSimpleIndexForFullSelection(selectedValues) { 10743 if (!this.isFullSelection(selectedValues)) return false; 10744 10745 const productIndexes = this.optionConfig.index; 10746 return Object.keys(productIndexes).find(productIndex => { 10747 const productCandidateOptions = productIndexes[productIndex]; 10748 10749 for (const productOption in productCandidateOptions) { 10750 if ( 10751 !selectedValues[productOption] || 10752 String(selectedValues[productOption]) !== String(productCandidateOptions[productOption]) 10753 ) { 10754 return false; 10755 } 10756 } 10757 return productIndex; 10758 }); 10759 }, 10760 findAllowedAttributeOptions() { 10761 this.allowedAttributeOptions = this.calculateAllowedAttributeOptions(this.selectedValues); 10762 }, 10763 calculateAllowedAttributeOptions(selectedValues) { 10764 const allAttributes = this.optionConfig.attributes; 10765 const allAttributesSorted = Object.values(allAttributes).sort((a, b) => { 10766 return a.position - b.position 10767 }); 10768 10769 const newAllowedAttributeOptions = []; 10770 10771 allAttributesSorted.forEach(attribute => { 10772 const selectionWithoutAttr = Object.assign({}, this.removeAttrFromSelection(selectedValues, attribute.id)); 10773 const availableIndexes = this.calculateAvailableProductIndexes(selectionWithoutAttr); 10774 newAllowedAttributeOptions[attribute.id] = allAttributes[attribute.id].options.filter(option => { 10775 return !!option.products.find(product => { 10776 return availableIndexes.includes(product); 10777 }) 10778 }); 10779 }); 10780 return newAllowedAttributeOptions; 10781 }, 10782 calculateAvailableProductIndexes(selectedOptions) { 10783 if (Object.keys(selectedOptions).length === 0) { 10784 if (Object.values(this.optionConfig.salable || {}).length) { 10785 return [].concat.apply([], [].concat.apply([], Object.values(this.optionConfig.salable).map(Object.values))).filter((x, i, a) => a.indexOf(x) === i) 10786 } 10787 return Object.keys(this.optionConfig.index); 10788 } 10789 10790 const selectedIds = Object.keys(selectedOptions); 10791 if (Object.values(this.optionConfig.salable || {}).length) { 10792 const selectedOptionIndexes = selectedIds.map(attrId => { 10793 const optionValue = selectedOptions[attrId]; 10794 return this.optionConfig.salable[attrId] && this.optionConfig.salable[attrId][optionValue] || [] 10795 }) 10796 return selectedOptionIndexes.reduce((acc, optionIndexes) => { 10797 return acc.filter(index => optionIndexes.includes(index)); 10798 }); 10799 } else { 10800 const productIndexes = this.optionConfig.index; 10801 return Object.keys(productIndexes).filter(index => { 10802 for (const attrId of selectedIds) { 10803 if (productIndexes[index][attrId] !== `${selectedOptions[attrId]}`) return false 10804 } 10805 return true 10806 }); 10807 } 10808 }, 10809 findAttributeByOptionId(optionId) { 10810 for (const attributeId in this.optionConfig.attributes) { 10811 const attributeOptions = this.optionConfig.attributes[attributeId].options || []; 10812 if (attributeOptions.find(option => String(option.id) === String(optionId))) { 10813 return attributeId; 10814 } 10815 } 10816 }, 10817 getAllowedAttributeOptions(attributeId) { 10818 return this.allowedAttributeOptions[attributeId] || [] 10819 }, 10820 getAllAttributeOptions(attributeId) { 10821 return ( 10822 this.optionConfig.attributes[attributeId] && 10823 this.optionConfig.attributes[attributeId].options 10824 ) || [] 10825 }, 10826 getProductIdsForOption(option) { 10827 const attributeId = this.findAttributeByOptionId(option.id); 10828 const allOptions = this.optionConfig.attributes[attributeId]; 10829 const opt = (allOptions && allOptions.options || []).find(o => o.id === option.id); 10830 return opt && opt.products ? 10831 opt.products : []; 10832 }, 10833 findProductIdsForPartialSelection(optionSelection) { 10834 const candidateProducts = Object.values(optionSelection).reduce((candidates, optionId) => { 10835 const newCandidates = this.getProductIdsForOption({ 10836 id: optionId 10837 }); 10838 return candidates === null ? 10839 newCandidates : 10840 candidates.filter(productId => newCandidates.includes(productId)); 10841 }, null); 10842 return candidateProducts || []; 10843 },
10844 findCheapestProductForPartialSelection(optionSelection) { 10845 const candidateProducts = this.findProductIdsForPartialSelection(optionSelection); 10846 return candidateProducts.reduce((cheapest, simpleIdx) => { 10847 // in the first iteration we start with simpleIdx as the currently cheapest product 10848 if (!this.optionConfig.optionPrices[cheapest]) return simpleIdx; 10849 const knownCheapestPrice = this.optionConfig.optionPrices[cheapest].finalPrice.amount; 10850 return knownCheapestPrice > this.optionConfig.optionPrices[simpleIdx].finalPrice.amount ? 10851 simpleIdx : 10852 cheapest; 10853 }, 0) 10854 }, 10855 findProductIdToUseForOptionPrice(option) { 10856 // try to find a product for a complete selection 10857 const attributeId = this.findAttributeByOptionId(option.id); 10858 const optionSelection = Object.assign({}, this.selectedValues, { 10859 [attributeId]: option.id 10860 }); 10861 const matchingSimpleIndex = this.calculateSimpleIndexForFullSelection(optionSelection); 10862 // if there is no complete selection, use the cheapest product for the option 10863 return matchingSimpleIndex || this.findCheapestProductForPartialSelection(optionSelection); 10864 }, 10865 getAttributeOptionLabel(option) { 10866 const optionProduct = this.findProductIdToUseForOptionPrice(option); 10867 10868 if ((!optionProduct) || (optionProduct === this.productIndexForPrice)) { 10869 return option.label; 10870 } 10871 10872 const currentPrice = this.getOptionPriceAdjustmentBasePrice(); 10873 10874 if (this.optionConfig.optionPrices[optionProduct]) { 10875 const optionPrice = this.optionConfig.optionPrices[optionProduct].finalPrice.amount; 10876 if (optionPrice !== currentPrice) { 10877 return option.label + ' ' + hyva.formatPrice(optionPrice - currentPrice, true); 10878 } 10879 } 10880 return option.label; 10881 }, 10882 getOptionPriceAdjustmentBasePrice() { 10883 if (this.optionConfig.optionPrices[this.productIndexForPrice]) { 10884 return this.optionConfig.optionPrices[this.productIndexForPrice].finalPrice.amount 10885 } 10886 return this.optionConfig.prices.finalPrice.amount; // default price if no option selection 10887 }, 10888 clearOptionIfActive(optionId, value) { 10889 if (this.selectedValues[optionId] === value) { 10890 this.blurLabel() 10891 this.changeOption(optionId, '') 10892 } 10893 }, 10894 removeAttrFromSelection(selectedValues, attributeId) { 10895 const { 10896 [attributeId]: removed, ...newSelection 10897 } = selectedValues; 10898 return newSelection; 10899 }, 10900 getTierPricesForProduct(productIndex) { 10901 if (this.tierPricesMap && this.tierPricesMap[productIndex]) { 10902 const tierPricesObj = this.tierPricesMap[productIndex]; 10903 return Object.values(tierPricesObj).map(tier => ({ 10904 price_qty: parseFloat(tier.price_qty), 10905 price: parseFloat(tier.price) 10906 })); 10907 } 10908 return []; 10909 }, 10910 changeOption(attributeId, value) { 10911 if (value === '') { 10912 this.selectedValues = this.removeAttrFromSelection(this.selectedValues, attributeId) 10913 } else if ( 10914 value && 10915 this.getAllowedAttributeOptions(attributeId).find( 10916 option => String(option.id) === String(value) 10917 ) 10918 ) { 10919 this.selectedValues[attributeId] = value; 10920 } 10921 this.findSimpleIndex(); 10922 this.findAllowedAttributeOptions(); 10923 this.updatePrices(); 10924 this.updateGallery(); 10925 this.updateDeliveryInfo(); 10926 10927 const candidates = this.findProductIdsForPartialSelection(this.selectedValues); 10928 const tierPrices = this.getTierPricesForProduct(this.productIndex); 10929 10930 window.dispatchEvent( 10931 new CustomEvent( 10932 'configurable-selection-changed', { 10933 detail: { 10934 productId: String(this.productId), 10935 optionId: attributeId, 10936 value: value, 10937 productIndex: this.productIndex, 10938 isFullSelection: this.isFullSelection(this.selectedValues), 10939 selectedValues: this.selectedValues, 10940 candidates: candidates, 10941 selectedSku: this.optionConfig.sku[this.productIndex] || null, 10942 skuCandidates: Object.values(candidates).map(id => this.optionConfig.sku[id]), 10943 tierPrices: tierPrices 10944 } 10945 } 10946 ) 10947 ); 10948 }, 10949 calculateIsMinimalPrice() { 10950 return !this.isFullSelection(this.selectedValues); 10951 }, 10952 isFullSelection(selectedValues) { 10953 return Object.values(selectedValues).length === Object.keys(this.optionConfig.attributes).length; 10954 }, 10955 updatePrices() { 10956 const value = this.optionConfig.optionPrices[this.productIndexF
10956orPrice] || this.optionConfig.prices; 10957 window.dispatchEvent( 10958 new CustomEvent( 10959 "update-prices-" + this.productId, { 10960 detail: Object.assign( 10961 value, { 10962 isMinimalPrice: this.calculateIsMinimalPrice() 10963 } 10964 ) 10965 } 10966 ) 10967 ); 10968 }, 10969 updateDeliveryInfo() { 10970 let isOutOfStock = false; 10971 10972 if (this.isFullSelection(this.selectedValues) && 10973 this.optionConfig.productStockAlert?.child?.[this.productIndex]) { 10974 isOutOfStock = this.optionConfig.productStockAlert.child[this.productIndex].stock_status === 0; 10975 } else { 10976 isOutOfStock = !this.parentIsSaleable; 10977 } 10978 10979 this.$dispatch('update-stock-status', { 10980 isOutOfStock: isOutOfStock, 10981 productId: this.productId 10982 }); 10983 }, 10984 updateGallery() { 10985 if (this.productIndex) { 10986 const images = this.optionConfig.images[this.productIndex]; 10987 images && window.dispatchEvent(new CustomEvent( 10988 "update-gallery", { 10989 detail: this.sortImagesByPosition(images) 10990 } 10991 )); 10992 } else { 10993 window.dispatchEvent(new Event("reset-gallery")); 10994 } 10995 }, 10996 sortImagesByPosition(images) { 10997 return images.sort((x, y) => { 10998 return x.position === y.position ? 0 : (parseInt(x.position) > parseInt(y.position) ? 1 : -1) 10999 }); 11000 }, 11001 onGetCartData(data) { 11002 }, 11003 preselectCartItems(data) { 11004 // pre-select options based on cart data for current (quote) itemId 11005 const cart = data && data.cart; 11006 if (cart && cart.items) { 11007 const cartItem = cart.items.find((item) => { 11008 return ( 11009 item.item_id === this.itemId && 11010 item.product_id === this.productId 11011 ) 11012 }); 11013 if (cartItem && cartItem.options && cartItem.options.length) { 11014 cartItem.options.map(option => { 11015 this.changeOption(option.option_id, option.option_value); 11016 }) 11017 } 11018 } 11019 }, 11020 preselectQuerystringItems() { 11021 // pre-select option like ?size=167 11022 const urlQueryParams = new URLSearchParams(window.location.search.replace('?', '')); 11023 this.preselectItemsBasedOnLocation(attribute => urlQueryParams.get(attribute.code)); 11024 }, 11025 preselectLocationHashItems() { 11026 // pre-select option like #144=167, or #color_conf=167 â Luigi's Box emits the 11027 // attribute code rather than its id, and the autocomplete panel links straight to 11028 // the LB url without passing through Doppler\LuigisBox\Model\ProductUrlNormalizer. 11029 const urlHashParams = new URLSearchParams(window.location.hash.replace('#', '')); 11030 this.preselectItemsBasedOnLocation( 11031 attribute => urlHashParams.get(attribute.id) || urlHashParams.get(attribute.code) 11032 ); 11033 }, 11034 preselectItemsBasedOnLocation(getLocationValue) { 11035 Object.values(this.optionConfig.attributes).map(attribute => { 11036 const v = getLocationValue(attribute); 11037 v && this.changeOption(attribute.id, v) 11038 }); 11039 }, 11040 isOutOfStock(attributeId, optionId) { 11041 const productIds = this.getProductIdsForOption({ 11042 id: optionId 11043 }); 11044 if (!productIds.length) { 11045 return false;
11046 } 11047 11048 return productIds.every(productId => { 11049 return this.optionConfig.productStockAlert && 11050 this.optionConfig.productStockAlert.child[productId] && 11051 this.optionConfig.productStockAlert.child[productId].stock_status === 0; 11052 }); 11053 } 11054 } 11055 } 11056</script>
vendor: 1 bytes, line 11056
11056
11057<script> 11058 function initSwatchOptions(swatchConfig) { 11059 return { 11060 swatchConfig, 11061 getAttributeSwatchData(attributeId) { 11062 const swatchConfig = Object.assign({}, this.swatchConfig[attributeId]); 11063 swatchConfig['details'] = JSON.parse(swatchConfig['additional_data']); 11064 11065 return swatchConfig; 11066 }, 11067 mapSwatchTypeNumberToTypeCode(typeNumber) { 11068 switch ("" + typeNumber) { 11069 case "1": 11070 return "color" 11071 case "2": 11072 return "image" 11073 case "3": 11074 return "empty" 11075 case "0": 11076 default: 11077 return "text" 11078 } 11079 }, 11080 getTypeOfFirstOption(attributeId) { 11081 for (const optionId in this.swatchConfig[attributeId]) { 11082 const option = this.swatchConfig[attributeId][optionId]; 11083 if (typeof option.type !== 'undefined') { 11084 return this.mapSwatchTypeNumberToTypeCode(option.type); 11085 } 11086 } 11087 }, 11088 getVisualSwatchType(attributeId, targetOptionId) { 11089 // If a type configuration is present for the given option id, use it 11090 const config = this.swatchConfig[attributeId]; 11091 if (config[targetOptionId] && typeof config[targetOptionId].type !== 'undefined') { 11092 return this.mapSwatchTypeNumberToTypeCode(config[targetOptionId].type); 11093 } 11094 11095 // Otherwise - if no config is present for the target option - use the type of the first option 11096 // with a type property from the attribute, thus assuming its the same type as the target option. 11097 // (This edge case condition can occur on single swatch products if some options are not salable) 11098 return this.getTypeOfFirstOption(attributeId); 11099 }, 11100 getSwatchType(attributeId, optionId) { 11101 // Deserialize the attribute details the first time they are used 11102 if (this.swatchConfig[attributeId] && ! this.swatchConfig[attributeId].details) { 11103 this.swatchConfig[attributeId] = this.getAttributeSwatchData(attributeId); 11104 } 11105 const type = this.swatchConfig[attributeId] && 11106 this.swatchConfig[attributeId].details && 11107 this.swatchConfig[attributeId].details.swatch_input_type || 11108 "empty"; 11109 return type === 'visual' ? this.getVisualSwatchType(attributeId, optionId) : type; 11110 }, 11111 isTextSwatch(attributeId, optionId) { 11112 return this.getSwatchType(attributeId, optionId) === 'text'; 11113 }, 11114 isVisualSwatch(attributeId, optionId) { 11115 const type = this.getSwatchType(attributeId, optionId); 11116 11117 return ['image', 'color'].includes(type); 11118 }, 11119 getSwatchBackgroundStyle(attributeId, optionId) { 11120 const config = this.getSwatchConfig(attributeId, optionId); 11121 const type = this.getSwatchType(attributeId, optionId); 11122 11123 if (type === "color") { 11124 return 'background-color:' + config.value; 11125 } else if (type === "image") { 11126 return "background: #ffffff url('" + config.value + "') no-repeat center; background-size: cover;"; 11127 } else { 11128 return ''; 11129 } 11130 }, 11131 getSwatchText(attributeId, optionId) { 11132 const config = this.getSwatchConfig(attributeId, optionId); 11133 return config.label || config.value || this.getOptionLabelFromOptionConfig(attributeId, optionId); 11134 }, 11135 getOptionLabelFromOptionConfig(attributeId, optionId) { 11136 // Fallback if no value is present in swatchConfig data 11137 // Reference issue https://gitlab.hyva.io/hyva-themes/magento2-default-theme/-/issues/190 11138 const option = this.getAllAttributeOptions(attributeId).filter(option => option.id === optionId); 11139 return option && option[0] && option[0].label ||''; 11140 }, 11141 getSwatchConfig(attributeId, optionId) { 11142 return this.swatchConfig[attributeId] && this.swatchConfig[attributeId][optionId] 11143 ? this.swatchConfig[attributeId][optionId] 11144 : false;
11145 }, 11146 activeTooltipItem: false, 11147 tooltipPositionElement: false, 11148 isTooltipVisible() { 11149 return this.activeTooltipItem && 11150 this.getSwatchConfig( 11151 this.activeTooltipItem.attribute, 11152 this.activeTooltipItem.item 11153 ); 11154 }, 11155 isFirstItemCol() { 11156 return this.activeTooltipItem.index === 0; 11157 }, 11158 getTooltipImageStyle(attributeId, optionId) { 11159 const config = this.getSwatchConfig(attributeId, optionId); 11160 const type = this.getSwatchType(attributeId, optionId); 11161 11162 if (type === "color") { 11163 return 'background-color:' + config.value + '; width: 110px; height: 90px;'; 11164 } else if (type === "image") { 11165 return "background: #ffffff url('" + config.thumb + 11166 "') center center no-repeat; width: 110px; height: 90px;"; 11167 } else { 11168 return 'display:none'; 11169 } 11170 }, 11171 getTooltipPosition() { 11172 return this.tooltipPositionElement ? 11173 `top: ${this.tooltipPositionElement.offsetTop}px;` + 11174 `left: ${ 11175 this.tooltipPositionElement.offsetLeft - ( 11176 this.tooltipPositionElement.closest('.snap') && 11177 this.tooltipPositionElement.closest('.snap').scrollLeft || 11178 0 11179 ) 11180 }px;` : '' 11181 }, 11182 getTooltipLabel() { 11183 return this.getSwatchConfig(this.activeTooltipItem.attribute, this.activeTooltipItem.item).label 11184 }, 11185 focusedLabel: false, 11186 focusLabel(optionId) { 11187 this.focusedLabel = optionId; 11188 }, 11189 blurLabel() { 11190 this.focusedLabel = false; 11191 }, 11192 showSwatches: false, 11193 initShowSwatchesIntersect() { 11194 if ('IntersectionObserver' in window && !window.scrollY) { 11195 let io = new IntersectionObserver( 11196 entries => { 11197 entries.map(entry => { 11198 if (entry.isIntersecting) { 11199 this.showSwatches = true; 11200 this.calculateVisibleSwatches(); 11201 io.unobserve(this.$root); 11202 } 11203 }) 11204 } 11205 ); 11206 io.observe(this.$root); 11207 } else { 11208 this.showSwatches = true 11209 this.calculateVisibleSwatches(); 11210 } 11211 11212 window.addEventListener('resize', () => { 11213 this.calculateVisibleSwatches(); 11214 }); 11215 }, 11216 11217 calculateVisibleSwatches() { 11218 const swatchesWrapper = this.$refs.swatchesWrapper; 11219 if (swatchesWrapper) { 11220 const swatches = swatchesWrapper.querySelectorAll('.js-swatch'); 11221 const visibleSwatches = Array.from(swatches).filter(swatch => { 11222 return swatch.offsetWidth > 0 && swatch.offsetHeight > 0; 11223 }); 11224 console.log('visibleSwatches', visibleSwatches); 11225 } 11226 }, 11227 } 11228 } 11229</script>
vendor: 1 bytes, line 11229
11229
11230<script> 11231 'use strict'; 11232 11233 const grecaptchaV2LoadCallbacks = []; 11234 11235 function executeRecaptchaLoadCallbacks () { 11236 while (window.grecaptcha && grecaptchaV2LoadCallbacks.length > 0) { 11237 const callback = grecaptchaV2LoadCallbacks.pop(); 11238 typeof callback === 'string' ? window[callback]() : callback(); 11239 } 11240 } 11241 11242 (function() { 11243 const loadRecaptchaScript = (event) => { 11244 11245 if (window.grecaptcha || !event.target.form) { 11246 return; 11247 } 11248 11249 const url = 'https://www.google.com/recaptcha/api.js?onload=executeRecaptchaLoadCallbacks'; 11250 const siteKey = '6LfbaCwmAAAAABn1WOQo1IUaX_yTMxd7m_x\u002DYLsQ'; 11251 const script = document.createElement('script'); 11252 script.type = 'text/javascript'; 11253 script.src = siteKey ? `${url}&render=${siteKey}` : `${url}&render=explicit`; 11254 script.async = true; 11255 document.head.appendChild(script); 11256 11257 script.addEventListener('load', () => { 11258 Array.from(document.querySelectorAll('button[data-recaptcha-btn]:disabled')).forEach(btn => btn.removeAttribute('disabled')); 11259 }); 11260 } 11261 11262 window.forceLoadRecaptchaScript = (form) => { 11263 loadRecaptchaScript({target: {form: form || 'dummy'}}); 11264 executeRecaptchaLoadCallbacks(); 11265 }; 11266 11267 document.body.addEventListener('input', loadRecaptchaScript, { once: true }); 11268 document.body.addEventListener('focus', loadRecaptchaScript, { once: true }); 11269 11270 }()); 11271 11272</script>
vendor: 1 bytes, line 11272
11272
11273<script> 11274 (function () { 11275 const modals = []; 11276 const excludedFromFocusTrapping = new Set(); 11277 11278 function trapFocusInNextModalWithOverlay() { 11279 for (let idx = modals.length -1; idx >= 0; idx--) { 11280 const nextOnStack = modals[idx]; 11281 const nextDialogElement = nextOnStack.instance.$refs[nextOnStack.name]; 11282 if (! isOverlayDisabled(nextDialogElement)) { 11283 hyva.trapFocus(nextDialogElement); 11284 break; 11285 } 11286 } 11287 } 11288 11289 function focusables(dialogElement) { 11290 const selector = 'button, [href], input, textarea, select, details, [tabindex]:not([tabindex="-1"])'; 11291 return Array.from(dialogElement.querySelectorAll(selector)) 11292 .filter(el => !el.hasAttribute('disabled')); 11293 } 11294 11295 function firstVisible(elements) { 11296 const a = Array.from(elements); 11297 for (let i = 0; i < a.length; i++) { 11298 if (a[i].offsetWidth || a[i].offsetHeight || a[i].getClientRects().length) return a[i]; 11299 } 11300 return null; 11301 } 11302 11303 function isInViewport(element) { 11304 const rect = element && element.getBoundingClientRect(); 11305 return rect && 11306 rect.top >= 0 && 11307 rect.left >= 0 && 11308 rect.right <= window.innerWidth && 11309 rect.bottom <= window.innerHeight; 11310 } 11311 11312 function setFocusAfterTransition(dialogElement, duration) { 11313 const nested = Array.from(dialogElement.querySelectorAll('[role="dialog"]')); 11314 const candidates = Array.from(dialogElement.querySelectorAll('[x-focus-first]')); 11315 next: for (let candidate of candidates) { 11316 for (let child of nested) { 11317 if (child.contains(candidate)) continue next; 11318 } 11319 setTimeout(() => candidate.focus(), 50); 11320 break; 11321 } 11322 window.setTimeout(() => { 11323 const focusElement = firstVisible(dialogElement.querySelectorAll('[x-focus-first]')) || 11324 focusables(dialogElement)[0] || 11325 null; 11326 focusElement && isInViewport(focusElement) && focusElement.focus(); 11327 }, Math.max(1, duration)); 11328 } 11329 11330 function determineTrigger($refs, dialog, trigger) { 11331 if (typeof trigger === 'undefined' && typeof dialog === 'object' && dialog.target instanceof HTMLElement) { 11332 return dialog.target; 11333 } 11334 if (typeof dialog === 'string' && typeof trigger === 'object' && trigger.target instanceof HTMLElement) { 11335 return trigger.target; 11336 } 11337 if (typeof trigger === 'string') { 11338 try { 11339 return $refs[trigger] || document.querySelector(trigger) 11340 } catch (e) {} 11341 } 11342 if (trigger instanceof Element) { 11343 return trigger; 11344 } 11345 11346 return null; 11347 } 11348 11349 function isOverlayDisabled(dialog) { 11350 return dialog && dialog.hasAttribute('x-no-overlay') 11351 } 11352 11353 function areRemainingModalsWithoutOverlay(modals) 11354 { 11355 const overflowDisabled = modals.map(modal => modal.instance.$refs[modal.name]).filter(isOverlayDisabled); 11356 11357 return overflowDisabled.length === modals.length; 11358 } 11359 11360 window.hyva.modal = function(options = {}) { 11361 if (this.$el && this.$el.dataset && this.$el.dataset.options) { 11362 try { 11363 options = Object.assign(options, JSON.parse(this.$el.dataset.options || '{}')); 11364 } catch (e) { 11365 throw new Error('Cannot read the dialog options from the data-options attribute: not valid JSON'); 11366 } 11367 } 11368 11369 const config = Object.assign({ 11370 dialog: 'dialog', duration: 300, transitionEnter: 'transition ease-out duration-300', 11371 transitionEnterStart: 'opacity-0', 11372 transitionEnterEnd: 'opacity-100', 11373 transitionLeave: 'transition ease-in duration-300', 11374 transitionLeaveStart: 'opacity-100', 11375 transitionLeaveEnd: 'opacity-0', 11376 }, options); 11377 let lastHide = 0; 11378 11379 return { 11380 opened: {}, 11381 show(dialog, trigger) { 11382 const focusTargetAfterHide = determineTrigger(this.$refs, dialog, trigger); 11383 const name = typeof dialog === 'string' ? dialog : config.dialog; 11384 const dialogElement = this.$refs[name]; 11385 if (! dialogElement) { 11386 return; 11387 } 11388 const useOverlay = ! dialogElement.hasAttribute('x-no-overlay'); 11389 11390 dialogElement.scrollTop = 0; 11391 11392 if (this.opened[name]) { 11393 return; 11394 } 11395 11396 if (focusTargetAfterHide) { 11397 focusTargetAfterHide.setAttribute('aria-expanded', 'true'); 11398 } 11399 11400 this.opened[name] = true; 11401 useOverlay && this.$nextTick(() => hyva.trapFocus(dialogElement)); 11402 setFocusAfterTransition(dialogElement, config.duration); 11403 11404 const frame = {name, instance: this, focusTarget: focu
11404sTargetAfterHide, time: Date.now()}; 11405 11406 modals.push(frame); 11407 if (useOverlay) { 11408 document.body.classList.add('overflow-hidden'); 11409 } 11410 return new Promise(resolve => frame.resolve = resolve); 11411 }, 11412 cancel() { 11413 this.hide(false); 11414 }, 11415 ok() { 11416 this.hide(true); 11417 }, 11418 hide(value) { 11419 if (Date.now() - lastHide < config.duration) { 11420 return; 11421 } 11422 lastHide = Date.now(); 11423 11424 const modal = modals.pop() || {}; 11425 if (! modal.instance) { 11426 return; 11427 } 11428 11429 const name = modal.name; 11430 this.opened[name] = false; 11431 hyva.releaseFocus(modal.instance.$refs[modal.name]) 11432 trapFocusInNextModalWithOverlay(); 11433 11434 const nextFocusAfterHide = modal.focusTarget; 11435 nextFocusAfterHide && setTimeout(() => { 11436 nextFocusAfterHide.setAttribute('aria-expanded', 'false'); 11437 nextFocusAfterHide.focus() 11438 }, config.duration); 11439 11440 if (modals.length === 0 || areRemainingModalsWithoutOverlay(modals)) { 11441 document.body.classList.remove('overflow-hidden'); 11442 } 11443 11444 modal.resolve(value); 11445 }, 11446 overlay(dialog) { 11447 dialog = this.$el.dataset.dialogRefName || dialog; 11448 const name = typeof dialog === 'string' ? dialog : config.dialog; 11449 return { 11450 ['x-show']() { 11451 return this.opened[name] 11452 }, 11453 ['x-transition:enter']: config.transitionEnter, 11454 ['x-transition:enter-start']: config.transitionEnterStart, 11455 ['x-transition:enter-end']: config.transitionEnterEnd, 11456 ['x-transition:leave']: config.transitionLeave, 11457 ['x-transition:leave-start']: config.transitionLeaveStart, 11458 ['x-transition:leave-end']: config.transitionLeaveEnd, 11459 ['@hyva-modal-show.window'](event) { 11460 event.detail && event.detail.dialog === name && this.show(name, event.detail.focusAfterHide) 11461 } 11462 }; 11463 }, 11464 showDialogOnInit() { 11465 const parent = this.$el.closest('[data-dialog-ref-name]'); 11466 if (parent && parent.dataset.dialogRefName) { 11467 this.$dispatch('hyva-modal-show', {dialog: parent.dataset.dialogRefName}) 11468 } 11469 } 11470 }; 11471 } 11472 11473 window.hyva.modal.peek = () => modals.length > 0 && modals[modals.length -1] 11474 11475 window.hyva.modal.pop = function () { 11476 if (modals.length > 0) { 11477 const modal = modals[modals.length -1]; 11478 modal.instance.hide(); 11479 } 11480 } 11481 11482 window.hyva.modal.excludeSelectorsFromFocusTrap = function (selectors) { 11483 typeof selectors === 'string' || selectors instanceof String 11484 ? excludedFromFocusTrapping.add(selectors) 11485 : selectors.map(selector => excludedFromFocusTrapping.add(selector)); 11486 } 11487 11488 window.hyva.modal.eventListeners = { 11489 keydown: event => { 11490 if (event.key === 'Escape') { 11491 window.hyva.modal.pop(); 11492 } 11493 }, 11494 click: event => { 11495 if (modals.length > 0) { 11496 const modal = modals[modals.length -1]; 11497 const dialog = modal.instance.$refs[modal.name]; 11498 if (modal.time + 50 < Date.now() && // if last click processing is more than 50ms ago 11499 ! isOverlayDisabled(dialog) && // if dialog has overlay 11500 ! dialog.contains(event.target)) { // if click is outside of dialog 11501 modal.instance.hide(); 11502 } 11503 } 11504 } 11505 }; 11506 11507 document.addEventListener('keydown', window.hyva.modal.eventListeners.keydown); 11508 11509 document.addEventListener('click', window.hyva.modal.eventListeners.click); 11510 })(); 11511 window.addEventListener('alpine:init', () => { 11512 Alpine.data('hyvaModal', window.hyva.modal); 11513 }, {once: true}); 11514</script>
11514 11515 11516<div 11517 x-data="initAdvancedPopup" 11518 x-init="fetchAndShowPopup()"> 11519 <div 11520 x-cloak 11521 x-bind="overlay('advanced-popup')" 11522 :class="responsive ? 'popup popup--drawer' : 'popup'" 11523 data-testid="advanced-popup-overlay" 11524 style="display: none;"> 11525 <div 11526 x-ref="advanced-popup" 11527 role="dialog" 11528 aria-modal="true" 11529 :aria-labelledby="popupData?.title ? 'advanced-popup-title' : false" 11530 :aria-label="popupData?.title ? false : 'Popup message'" 11531 :x-no-overlay="clickableOverlay ? null : true" 11532 :class="{ 11533 'popup__content-wrapper': true, 11534 'popup__drawer': responsive, 11535 'popup__drawer--hidden': responsive && !isOpen 11536 }" 11537 data-testid="advanced-popup-dialog"> 11538 <div class="popup__header"> 11539 <button 11540 class="popup__close" 11541 aria-label="Close popup message" 11542 @click="closePopup()" 11543 type="button" 11544 data-testid="advanced-popup-close" 11545 x-focus-first> 11546 <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18" fill="none" aria-hidden="true"> 11547<path fill-rule="evenodd" clip-rule="evenodd" d="M0.43934 0.43934C1.02513 -0.146447 1.97487 -0.146447 2.56066 0.43934L9 6.87868L15.4393 0.43934C16.0251 -0.146447 16.9749 -0.146447 17.5607 0.43934C18.1464 1.02513 18.1464 1.97487 17.5607 2.56066L11.1213 9L17.5607 15.4393C18.1464 16.0251 18.1464 16.9749 17.5607 17.5607C16.9749 18.1464 16.0251 18.1464 15.4393 17.5607L9 11.1213L2.56066 17.5607C1.97487 18.1464 1.02513 18.1464 0.43934 17.5607C-0.146447 16.9749 -0.146447 16.0251 0.43934 15.4393L6.87868 9L0.43934 2.56066C-0.146447 1.97487 -0.146447 1.02513 0.43934 0.43934Z" fill="currentColor"/> 11548</svg> 11549 </button> 11550 </div> 11551 <h2 11552 id="advanced-popup-title" 11553 class="popup__title text-xl font-bold px-12" 11554 x-show="popupData?.title" 11555 x-text="popupData?.title" 11556 data-testid="advanced-popup-title"></h2> 11557 <div class="popup__content" x-html="content || ''"></div> 11558 <div aria-live="polite" class="sr-only" x-text="statusMessage"></div> 11559 </div> 11560 </div> 11561</div> 11562
11563<script> 11564 const initAdvancedPopup = () => ({ 11565 ...(typeof hyva !== 'undefined' && typeof hyva.modal === 'function' ? hyva.modal() : {}), 11566 ajaxUrl: 'https://knirps.de/advancedpopup/ajax/load/', 11567 content: '', 11568 popupData: null, 11569 delay: 0, 11570 customHide: false, 11571 hideDuration: 7, 11572 responsive: false, 11573 clickableOverlay: true, 11574 loading: false, 11575 isOpen: false, 11576 statusMessage: '', 11577 11578 fetchAndShowPopup() { 11579 if (window.location.pathname.includes('/checkout')) { 11580 return; 11581 } 11582 11583 this.scheduleReveal(); 11584 }, 11585 11586 scheduleReveal() { 11587 const run = () => { 11588 window.requestAnimationFrame(() => { 11589 window.requestAnimationFrame(() => this.resolvePopup()); 11590 }); 11591 }; 11592 11593 if (document.readyState === 'complete') { 11594 run(); 11595 } else { 11596 window.addEventListener('load', run, { 11597 once: true 11598 }); 11599 } 11600 }, 11601 11602 resolvePopup() { 11603 const cached = sessionStorage.getItem('advanced_popup_cache'); 11604 11605 if (cached !== null) { 11606 this.applyCachedPopup(cached); 11607 return; 11608 } 11609 11610 this.loadPopup(); 11611 }, 11612 11613 async loadPopup() { 11614 if (this.loading) { 11615 return; 11616 } 11617 11618 this.loading = true; 11619 11620 try { 11621 const response = await fetch(this.ajaxUrl, { 11622 method: 'POST', 11623 headers: { 11624 'Content-Type': 'application/json', 11625 'X-Requested-With': 'XMLHttpRequest', 11626 }, 11627 }); 11628 11629 if (!response.ok) { 11630 throw new Error('Failed to fetch popup data'); 11631 } 11632 11633 const data = await response.json(); 11634 const hasPopup = Boolean(data.success && data.result && Object.keys(data.result).length > 0); 11635 11636 sessionStorage.setItem('advanced_popup_cache', hasPopup ? JSON.stringify(data.result) : ''); 11637 11638 if (!hasPopup) { 11639 return; 11640 } 11641 11642 this.popupData = data.result; 11643 this.processPopupData(); 11644 } catch (error) { 11645 console.error('Error loading advanced popup:', error); 11646 } finally { 11647 this.loading = false; 11648 } 11649 }, 11650 11651 applyCachedPopup(cached) { 11652 if (!cached) { 11653 return; 11654 } 11655 11656 try { 11657 this.popupData = JSON.parse(cached); 11658 } catch (error) { 11659 console.error('Error parsing cached advanced popup data:', error); 11660 return; 11661 } 11662 11663 this.processPopupData(); 11664 }, 11665 11666 processPopupData() { 11667 if (!this.popupData) { 11668 return; 11669 } 11670 11671 const popupIdentifier = this.formatIdentifier(this.popupData.title); 11672 11673 if (sessionStorage.getItem(popupIdentifier)) { 11674 return; 11675 } 11676 11677 if (this.popupData.custom_hide && this.isPopupHidden(popupIdentifier)) { 11678 return; 11679 } 11680 11681 this.content = this.popupData.content || ''; 11682 this.delay = parseInt(this.popupData.delay, 10) || 0; 11683 this.customHide = Boolean(Number(this.popupData.custom_hide)); 11684 this.hideDuration = parseInt(this.popupData.hide_duration, 10) || 7; 11685 this.responsive = Boolean(Number(this.popupData.responsive)); 11686 this.clickableOverlay = Boolean(Number(this.popupData.clickable_overlay)); 11687 11688 const reveal = () => this.showPopup(popupIdentifier); 11689 11690 if (this.delay > 0) { 11691 setTimeout(reveal, this.delay); 11692 return; 11693 } 11694 11695 reveal(); 11696 }, 11697 11698 showPopup(identifier) { 11699 this.show('advanced-popup'); 11700 this.statusMessage = 'Popup\u0020message\u0020opened'; 11701 11702 setTimeout(() => { 11703 this.isOpen = true; 11704 this.markPopupAsSeen(identifier); 11705 }, 100); 11706 }, 11707 11708 markPopupAsSeen(identifier) { 11709 sessionStorage.setItem(identifier, 'true'); 11710 11711 if (!this.customHide) { 11712 return; 11713 } 11714 11715 const expirationTime = Date.now() + (this.hideDuration * 24 * 60 * 60 * 1000); 11716 localStorage.setItem(`${identifier}_expires`, expirationTime.toString()); 11717 }, 11718 11719 isPopupHidden(identifier) { 11720 const expirationTime = localStorage.getItem(`${identifier}_expires`); 11721 11722 if (!expirationTime) { 11723 return false;
11724 } 11725 11726 if (Date.now() >= parseInt(expirationTime, 10)) { 11727 localStorage.removeItem(`${identifier}_expires`); 11728 return false; 11729 } 11730 11731 return true; 11732 }, 11733 11734 closePopup() { 11735 this.isOpen = false; 11736 this.statusMessage = 'Popup\u0020message\u0020closed'; 11737 11738 setTimeout(() => { 11739 this.hide(); 11740 }, 100); 11741 }, 11742 11743 formatIdentifier(title) { 11744 const safeTitle = String(title ?? 'popup') 11745 .toLowerCase() 11746 .trim() 11747 .replace(/\s+/g, '_') 11748 .replace(/[^a-z0-9_]/g, ''); 11749 11750 return `advanced_popup_${safeTitle || 'popup'}`; 11751 }, 11752 }); 11753 11754 window.addEventListener('alpine:init', () => { 11755 Alpine.data('initAdvancedPopup', initAdvancedPopup); 11756 }, { 11757 once: true 11758 }); 11759</script>
11759 11760
11761<script> 11762 'use strict'; 11763 11764 function responseSerialize(response) { 11765 if (response.redirected) { 11766 window.location.href = response.url; 11767 } else if (response.ok) { 11768 return response.json(); 11769 } else { 11770 // Check if result is Promise then throw to new Error 11771 let defaultErrMsg = 'Something went wrong. Please contact the website admin for more information.', 11772 result; 11773 result = response.text(); 11774 if (typeof result?.then === 'function') { 11775 result.then(res => { 11776 let errorMessage; 11777 try { 11778 errorMessage = JSON.parse(res); 11779 errorMessage = errorMessage?.message ? errorMessage.message : defaultErrMsg; 11780 } catch (e) { 11781 errorMessage = defaultErrMsg; 11782 } 11783 window.dispatchMessages([ 11784 { 11785 type: 'error', 11786 text: errorMessage 11787 } 11788 ], 3000); 11789 }); 11790 } else { 11791 throw new Error(defaultErrMsg); 11792 } 11793 } 11794 } 11795 11796 if (typeof window.buildRestAPIUrl !== 'function') { 11797 window.buildRestAPIUrl = function (url, params = {}) { 11798 const method = 'rest', 11799 storeCode = 'default', 11800 version = 'V1', 11801 serviceUrl = ':method/:storeCode/:version'; 11802 11803 let urlParts; 11804 11805 params.method = method; 11806 params.storeCode = storeCode; 11807 params.version = version; 11808 11809 url = serviceUrl + url; 11810 11811 urlParts = url.split('/'); 11812 urlParts = urlParts.filter(Boolean); 11813 11814 Object.entries(urlParts).forEach (entry => { 11815 let [key, part] = entry; 11816 part = part.replace(':', ''); 11817 11818 if (params[part] !== undefined) { 11819 urlParts[key] = params[part]; 11820 } 11821 }); 11822 11823 return urlParts.join('/'); 11824 } 11825 } 11826 11827 if (typeof window.isObjectEmpty !== 'function') { 11828 window.isObjectEmpty = function (obj) { 11829 return ( 11830 Object.prototype.toString.call(obj) === '[object Object]' && 11831 JSON.stringify(obj) === '{}' 11832 ); 11833 } 11834 } 11835 11836 if (typeof window.mergeDeep !== 'function') { 11837 /** 11838 * Deep merge two objects. 11839 * 11840 * @param target 11841 * @param sources 11842 * @returns {*} 11843 */ 11844 window.mergeDeep = (target, ...sources) => { 11845 /** 11846 * Simple object check. 11847 * 11848 * @param item 11849 * @returns {boolean} 11850 */ 11851 const isObject = (item) => { 11852 return (item && typeof item === 'object' && !Array.isArray(item)); 11853 }; 11854 11855 if (!sources.length) return target; 11856 const source = sources.shift(); 11857 11858 if (isObject(target) && isObject(source)) { 11859 for (const key in source) { 11860 if (isObject(source[key])) { 11861 if (!target[key]) Object.assign(target, { [key]: {} }); 11862 mergeDeep(target[key], source[key]); 11863 } else { 11864 Object.assign(target, { [key]: source[key] }); 11865 } 11866 } 11867 } 11868 11869 return mergeDeep(target, ...sources); 11870 } 11871 } 11872</script>
vendor: 1 bytes, line 11872
11872
11873<script type="text/x-magento-init"> 11874 { 11875 "#product_stock_alert_container": { 11876 "bssStockAlertEventHandle": {} 11877 } 11878 } 11879</script>
11879<script nonce="MW8zbHFodjIwMXlkMHZyNXk1Z2htd2p6a2FwNHo5a24="> 11880 11881 (() => 11882 { 11883 const { fetch: originalFetch } = window; 11884 11885 window.fetch = async (...args) => 11886 { 11887 let [resource, config ] = args; 11888 11889 let targetUrl = (resource instanceof Request) ? resource.url : resource.toString(); 11890 11891 const response = await originalFetch(resource, config); 11892 11893 if (-1 !== targetUrl.indexOf('checkout.payment.methods')) 11894 { 11895 response.clone().text().then(data => 11896 { 11897 const result = JSON.parse(data); 11898 11899 const payment_method = result?.serverMemo?.data?.method; 11900 11901 ((payload, method) => 11902 { 11903 payload['event'] = 'add_payment_info'; 11904 payload['payment_type'] = method; 11905 11906 dataLayer.push({ ecommerce: null }); 11907 dataLayer.push(payload); 11908 11909 })(AEC.Checkout.data.payload, payment_method); 11910 11911 }).catch(error => {}); 11912 } 11913 11914 const json = () => response.clone().json().then((data) => 11915 { 11916 switch (true) 11917 { 11918 case -1 !== targetUrl.indexOf('removeItem'): 11919 11920 if (data.hasOwnProperty('dataLayer') && 'undefined' !== typeof dataLayer) 11921 { 11922 AEC.Cookie.remove(data.dataLayer).push(dataLayer); 11923 } 11924 11925 break; 11926 11927 case -1 !== targetUrl.indexOf('graphql'): 11928 11929 if (!AEC?.Checkout?.data?.payload) 11930 { 11931 break; 11932 } 11933 11934 if (data.hasOwnProperty('data') && data.data.hasOwnProperty('setPaymentMethodOnCart') && 'undefined' !== typeof dataLayer) 11935 { 11936 let method = data.data.setPaymentMethodOnCart.cart.selected_payment_method.title; 11937 11938 ((payload, method) => 11939 { 11940 payload['event'] = 'add_payment_info'; 11941 payload['payment_type'] = method; 11942 11943 dataLayer.push({ ecommerce: null }); 11944 dataLayer.push(payload); 11945 11946 })(AEC.Checkout.data.payload, method); 11947 } 11948 11949 if (data.hasOwnProperty('data') && data.data.hasOwnProperty('cart') && 'undefined' !== typeof dataLayer) 11950 { 11951 let methods = []; 11952 11953 data.data.cart.shipping_addresses.forEach(address => 11954 { 11955 methods.push(address.selected_shipping_method); 11956 }); 11957 11958 if (methods.length) 11959 { 11960 methods.forEach(method => 11961 { 11962 ((payload, method) => 11963 { 11964 payload['event'] = 'add_shipping_info'; 11965 payload['shipping_tier'] = method.carrier_code; 11966 11967 dataLayer.push({ ecommerce: null }); 11968 dataLayer.push(payload); 11969 11970 })(AEC.Checkout.data.payload.ecommerce, method); 11971 }); 11972 } 11973 } 11974 11975 if (data.hasOwnProperty('data') && data.data.hasOwnProperty('setShippingMethodsOnCart') && 'undefined' !== typeof dataLayer) 11976 { 11977 let methods = []; 11978 11979 data.data.setShippingMethodsOnCart.cart.shipping_addresses.forEach(address => 11980 { 11981 methods.push(address.selected_shipping_method); 11982 }); 11983 11984 if (methods.length) 11985 { 11986 methods.forEach(method => 11987 { 11988 ((payload, method) => 11989 { 11990 payload['event'] = 'add_shipping_info'; 11991 payload['shipping_tier'] = method.carrier_code; 11992 11993 dataLayer.push({ ecommerce: null }); 11994 dataLayer.push(payload); 11995 11996 })(AEC.Checkout.data.payload.ecommerce, method); 11997 }); 11998 } 11999 } 12000 12001 break; 12002 } 12003 12004 return data; 12005 }); 12006 12007 response.json = json; 12008 12009 return response; 12010 }; 12011 12012 12013 /** 12014 * Custom variants 12015 */ 12016 AEC.EventDispatcher.on('ec.variants', variants => 12017 { 12018 if (!variants.length) 12019 { 12020 [...document.querySelectorAll('[name^="super_attribute"')].forEac
12020h(input => 12021 { 12022 if (input.parentNode.classList.contains('border-primary')) 12023 { 12024 var name = input.getAttribute('name'), id = name.substring(name.indexOf('[') + 1, name.lastIndexOf(']')); 12025 12026 Object.entries(AEC.SUPER).forEach(([key, attribute]) => 12027 { 12028 if (attribute.id == id) 12029 { 12030 attribute.options.forEach(option => 12031 { 12032 if (option.value_index == input.value) 12033 { 12034 variants.push( 12035 { 12036 id: id, 12037 option: option.value_index, 12038 text: option.label 12039 }); 12040 } 12041 }); 12042 } 12043 }); 12044 } 12045 }); 12046 } 12047 }); 12048 12049 window.addEventListener('add-to-cart', event => 12050 { 12051 let element = [...document.querySelectorAll('[data-event=add_to_cart]')].filter(node => 12052 { 12053 return node.dataset.id === event.detail.product_sku; 12054 }); 12055 12056 if (element) 12057 { 12058 AEC.add(element[0], dataLayer); 12059 } 12060 }); 12061 12062 window.addEventListener('cart-data-updated', event => 12063 { 12064 dataLayer.push( 12065 { 12066 event: 'update_cart', 12067 payload: event.detail.cart 12068 }); 12069 }); 12070 12071 window.addEventListener('checkout:payment:method-activate', event => 12072 { 12073 ((payload, method) => 12074 { 12075 document.querySelectorAll('label[for="payment-method-' + method + '"]').forEach(label => 12076 { 12077 let title = label.textContent.trim(), method_code = event.detail.method; 12078 12079 (title => 12080 { 12081 payload['event'] = 'add_payment_info'; 12082 payload['payment_type'] = title; 12083 12084 dataLayer.push({ ecommerce: null }); 12085 dataLayer.push(payload); 12086 12087 })(title); 12088 12089 12090 }); 12091 12092 })(AEC.Checkout.data.payload, event.detail.method); 12093 }); 12094 12095 window.addEventListener('checkout:payment:method-activate', event => 12096 { 12097 ((payload, method) => 12098 { 12099 document.querySelectorAll('label[for="payment-method-' + method + '"]').forEach(label => 12100 { 12101 let title = label.textContent.trim(), method_code = event.detail.method; 12102 12103 (title => 12104 { 12105 payload['event'] = 'add_payment_info'; 12106 payload['payment_type'] = title; 12107 12108 dataLayer.push({ ecommerce: null }); 12109 dataLayer.push(payload); 12110 12111 })(title); 12112 12113 12114 }); 12115 12116 })(AEC.Checkout.data.payload, event.detail.method); 12117 }); 12118 12119 window.addEventListener('checkout:shipping:method-activate', event => 12120 { 12121 ((payload, method) => 12122 { 12123 (title => 12124 { 12125 payload['event'] = 'add_shipping_info'; 12126 payload['shipping_tier'] = title; 12127 12128 12129 dataLayer.push({ ecommerce: null }); 12130 dataLayer.push(payload); 12131 12132 })(method); 12133 12134 })(AEC.Checkout.data.payload, event.detail.method); 12135 }); 12136 12137 window.addEventListener('load', event => 12138 { 12139 let observer_payment = new MutationObserver(function(mutations) 12140 { 12141 mutations.forEach(mutationRecord => 12142 { 12143 if (mutationRecord.target.classList.contains('active')) 12144 { 12145 ((payload, method) => 12146 { 12147 payload['event'] = 'add_payment_info'; 12148 payload['payment_type'] = method; 12149 12150 dataLayer.push({ ecommerce: null }); 12151 dataLayer.push(payload); 12152 12153 })(AEC.Checkout.data.payload, mutationRecord.target.id); 12154 } 12155 }) 12156 }); 12157 12158 let observer_shipping = new MutationObserver(function(mutations) 12159 { 12160 mutations.forEach(mutationRecord => 12161 { 12162 if (mutationRecord.target.classList.contains('active')) 12163 { 12164 ((payload, method) => 12165 { 12166 payload['event'] = 'add_shipping_info'; 12167 payload['shipping_tier'] = method; 12168 12169 dataLayer.push({ ecommerce: null }); 12170 dataLayer.push(payload); 12171 12172 })(AEC.Checkout.data.payload, mutationRecord.target.id); 12173 } 12174 }) 12175 }); 12176 12177 document.querySelectorAll("ol[id=payment-method-list] li").forEach(target => 12178 { 12179 observer_payment.observe(target, 12180 { 12181 attributes:true, 12182 attributeFilter:['style', 'class'] 12183 }); 12184 }); 12185 12186 document.querySelectorAll("ol[id=shipping-method-list] li").forEach(target => 12187 {
12188 observer_shipping.observe(target, 12189 { 12190 attributes:true, 12191 attributeFilter:['style', 'class'] 12192 }); 12193 }); 12194 }); 12195 12196 })(); 12197 12198</script>
vendor: 1 bytes, line 12198
12198
12199<script type="text/json" id="default-section-data"> 12200 {"messages":[],"customer":[],"compare-products":[],"last-ordered-items":[],"cart":[],"directory-data":{"AT":{"name":"\u00d6sterreich","regions":{"102":{"code":"BL","name":"Burgenland"},"99":{"code":"KN","name":"K\u00e4rnten"},"96":{"code":"NO","name":"Nieder\u00f6sterreich"},"97":{"code":"OO","name":"Ober\u00f6sterreich"},"98":{"code":"SB","name":"Salzburg"},"100":{"code":"ST","name":"Steiermark"},"101":{"code":"TI","name":"Tirol"},"103":{"code":"VB","name":"Vorarlberg"},"95":{"code":"WI","name":"Wien"}}},"BE":{"name":"Belgien","regions":{"577":{"code":"VAN","name":"Antwerpen"},"578":{"code":"WBR","name":"Brabant wallon"},"579":{"code":"BRU","name":"Brussels-Capital Region"},"580":{"code":"WHT","name":"Hainaut"},"582":{"code":"WLG","name":"Li\u00e8ge"},"581":{"code":"VLI","name":"Limburg"},"583":{"code":"WLX","name":"Luxembourg"},"584":{"code":"WNA","name":"Namur"},"585":{"code":"VOV","name":"Oost-Vlaanderen"},"586":{"code":"VBR","name":"Vlaams-Brabant"},"587":{"code":"VWV","name":"West-Vlaanderen"}}},"DE":{"name":"Deutschland","regions":{"80":{"code":"BAW","name":"Baden-W\u00fcrttemberg"},"81":{"code":"BAY","name":"Bayern"},"82":{"code":"BER","name":"Berlin"},"83":{"code":"BRG","name":"Brandenburg"},"84":{"code":"BRE","name":"Bremen"},"85":{"code":"HAM","name":"Hamburg"},"86":{"code":"HES","name":"Hessen"},"87":{"code":"MEC","name":"Mecklenburg-Vorpommern"},"79":{"code":"NDS","name":"Niedersachsen"},"88":{"code":"NRW","name":"Nordrhein-Westfalen"},"89":{"code":"RHE","name":"Rheinland-Pfalz"},"90":{"code":"SAR","name":"Saarland"},"91":{"code":"SAS","name":"Sachsen"},"92":{"code":"SAC","name":"Sachsen-Anhalt"},"93":{"code":"SCN","name":"Schleswig-Holstein"},"94":{"code":"THE","name":"Th\u00fcringen"}}},"DK":{"name":"D\u00e4nemark","regions":{"901":{"code":"DK-84","name":"Hovedstaden"},"902":{"code":"DK-82","name":"Midtjylland"},"903":{"code":"DK-81","name":"Nordjylland"},"904":{"code":"DK-85","name":"Sj\u00e6lland"},"905":{"code":"DK-83","name":"Syddanmark"}}},"ES":{"name":"Spanien","regions":{"130":{"code":"A Coru\u0441a","name":"A Coru\u00f1a"},"131":{"code":"Alava","name":"Alava"},"132":{"code":"Albacete","name":"Albacete"},"133":{"code":"Alicante","name":"Alicante"},"134":{"code":"Almeria","name":"Almeria"},"135":{"code":"Asturias","name":"Asturias"},"136":{"code":"Avila","name":"Avila"},"137":{"code":"Badajoz","name":"Badajoz"},"138":{"code":"Baleares","name":"Baleares"},"139":{"code":"Barcelona","name":"Barcelona"},"140":{"code":"Burgos","name":"Burgos"},"141":{"code":"Caceres","name":"Caceres"},"142":{"code":"Cadiz","name":"Cadiz"},"143":{"code":"Cantabria","name":"Cantabria"},"144":{"code":"Castellon","name":"Castellon"},"145":{"code":"Ceuta","name":"Ceuta"},"146":{"code":"Ciudad Real","name":"Ciudad Real"},"147":{"code":"Cordoba","name":"Cordoba"},"148":{"code":"Cuenca","name":"Cuenca"},"149":{"code":"Girona","name":"Girona"},"150":{"code":"Granada","name":"Granada"},"151":{"code":"Guadalajara","name":"Guadalajara"},"152":{"code":"Guipuzcoa","name":"Guipuzcoa"},"153":{"code":"Huelva","name":"Huelva"},"154":{"code":"Huesca","name":"Huesca"},"155":{"code":"Jaen","name":"Jaen"},"156":{"code":"La Rioja","name":"La Rioja"},"157":{"code":"Las Palmas","name":"Las Palmas"},"158":{"code":"Leon","name":"Leon"},"159":{"code":"Lleida","name":"Lleida"},"160":{"code":"Lugo","name":"Lugo"},"161":{"code":"Madrid","name":"Madrid"},"162":{"code":"Malaga","name":"Malaga"},"163":{"code":"Melilla","name":"Melilla"},"164":{"code":"Murcia","name":"Murcia"},"165":{"code":"Navarra","name":"Navarra"},"166":{"code":"Ourense","name":"Ourense"},"167":{"code":"Palencia","name":"Palencia"},"168":{"code":"Pontevedra","name":"Pontevedra"},"169":{"code":"Salamanca","name":"Salamanca"},"170":{"code":"Santa Cruz de Tenerife","name":"Santa Cruz de Tenerife"},"171":{"code":"Segovia","name":"Segovia"},"172":{"code":"Sevilla","name":"Sevilla"},"173":{"code":"Soria","name":"Soria"},"174":{"code":"Tarragona","name":"Tarragona"},"175":{"code":"Teruel","name":"Teruel"},"176":{"code":"Toledo","name":"Toledo"},"177":{"code":"Valencia","name":"Valencia"},"178":{"code":"Valladolid","name":"Valladolid"}
12200,"179":{"code":"Vizcaya","name":"Vizcaya"},"180":{"code":"Zamora","name":"Zamora"},"181":{"code":"Zaragoza","name":"Zaragoza"}}},"FI":{"name":"Finnland","regions":{"339":{"code":"Ahvenanmaa","name":"Ahvenanmaa"},"333":{"code":"Etel\u00e4-Karjala","name":"Etel\u00e4-Karjala"},"326":{"code":"Etel\u00e4-Pohjanmaa","name":"Etel\u00e4-Pohjanmaa"},"325":{"code":"Etel\u00e4-Savo","name":"Etel\u00e4-Savo"},"337":{"code":"It\u00e4-Uusimaa","name":"It\u00e4-Uusimaa"},"322":{"code":"Kainuu","name":"Kainuu"},"335":{"code":"Kanta-H\u00e4me","name":"Kanta-H\u00e4me"},"330":{"code":"Keski-Pohjanmaa","name":"Keski-Pohjanmaa"},"331":{"code":"Keski-Suomi","name":"Keski-Suomi"},"338":{"code":"Kymenlaakso","name":"Kymenlaakso"},"320":{"code":"Lappi","name":"Lappi"},"334":{"code":"P\u00e4ij\u00e4t-H\u00e4me","name":"P\u00e4ij\u00e4t-H\u00e4me"},"328":{"code":"Pirkanmaa","name":"Pirkanmaa"},"327":{"code":"Pohjanmaa","name":"Pohjanmaa"},"323":{"code":"Pohjois-Karjala","name":"Pohjois-Karjala"},"321":{"code":"Pohjois-Pohjanmaa","name":"Pohjois-Pohjanmaa"},"324":{"code":"Pohjois-Savo","name":"Pohjois-Savo"},"329":{"code":"Satakunta","name":"Satakunta"},"336":{"code":"Uusimaa","name":"Uusimaa"},"332":{"code":"Varsinais-Suomi","name":"Varsinais-Suomi"}}},"FR":{"name":"Frankreich","regions":{"182":{"code":"1","name":"Ain"},"183":{"code":"2","name":"Aisne"},"184":{"code":"3","name":"Allier"},"185":{"code":"4","name":"Alpes-de-Haute-Provence"},"187":{"code":"6","name":"Alpes-Maritimes"},"188":{"code":"7","name":"Ard\u00e8che"},"189":{"code":"8","name":"Ardennes"},"190":{"code":"9","name":"Ari\u00e8ge"},"191":{"code":"10","name":"Aube"},"192":{"code":"11","name":"Aude"},"193":{"code":"12","name":"Aveyron"},"249":{"code":"67","name":"Bas-Rhin"},"194":{"code":"13","name":"Bouches-du-Rh\u00f4ne"},"195":{"code":"14","name":"Calvados"},"196":{"code":"15","name":"Cantal"},"197":{"code":"16","name":"Charente"},"198":{"code":"17","name":"Charente-Maritime"},"199":{"code":"18","name":"Cher"},"200":{"code":"19","name":"Corr\u00e8ze"},"201":{"code":"2A","name":"Corse-du-Sud"},"203":{"code":"21","name":"C\u00f4te-d'Or"},"204":{"code":"22","name":"C\u00f4tes-d'Armor"},"205":{"code":"23","name":"Creuse"},"261":{"code":"79","name":"Deux-S\u00e8vres"},"206":{"code":"24","name":"Dordogne"},"207":{"code":"25","name":"Doubs"},"208":{"code":"26","name":"Dr\u00f4me"},"273":{"code":"91","name":"Essonne"},"209":{"code":"27","name":"Eure"},"210":{"code":"28","name":"Eure-et-Loir"},"211":{"code":"29","name":"Finist\u00e8re"},"212":{"code":"30","name":"Gard"},"214":{"code":"32","name":"Gers"},"215":{"code":"33","name":"Gironde"},"250":{"code":"68","name":"Haut-Rhin"},"202":{"code":"2B","name":"Haute-Corse"},"213":{"code":"31","name":"Haute-Garonne"},"225":{"code":"43","name":"Haute-Loire"},"234":{"code":"52","name":"Haute-Marne"},"252":{"code":"70","name":"Haute-Sa\u00f4ne"},"256":{"code":"74","name":"Haute-Savoie"},"269":{"code":"87","name":"Haute-Vienne"},"186":{"code":"5","name":"Hautes-Alpes"},"247":{"code":"65","name":"Hautes-Pyr\u00e9n\u00e9es"},"274":{"code":"92","name":"Hauts-de-Seine"},"216":{"code":"34","name":"H\u00e9rault"},"217":{"code":"35","name":"Ille-et-Vilaine"},"218":{"code":"36","name":"Indre"},"219":{"code":"37","name":"Indre-et-Loire"},"220":{"code":"38","name":"Is\u00e8re"},"221":{"code":"39","name":"Jura"},"222":{"code":"40","name":"Landes"},"223":{"code":"41","name":"Loir-et-Cher"},"224":{"code":"42","name":"Loire"},"226":{"code":"44","name":"Loire-Atlantique"},"227":{"code":"45","name":"Loiret"},"228":{"code":"46","name":"Lot"},"229":{"code":"47","name":"Lot-et-Garonne"},"230":{"code":"48","name":"Loz\u00e8re"},"231":{"code":"49","name":"Maine-et-Loire"},"232":{"code":"50","name":"Manche"},"233":{"code":"51","name":"Marne"},"235":{"code":"53","name":"Mayenne"},"236":{"code":"54","name":"Meurthe-et-Moselle"},"237":{"code":"55","name":"Meuse"},"238":{"code":"56","name":"Morbihan"},"239":{"code":"57","name":"Moselle"},"240":{"code":"58","name":"Ni\u00e8vre"},"241":{"code":"59","name":"Nord"},"242":{"code":"60","name":"Oise"},"243":{"code":"61","name":"Orne"},"257":{"code":"75","name":"Paris"},"244":{"code":"62","name":"Pas-de-Calais"},"245":{"code":"63","name":"Puy-de-D\u00f4me"},"246":{"code":"64","name":"Pyr\u00e9n\u00e9es-Atlantiques"},"248":{"code":"66","name":"Pyr\u00e9n\u00e9es-Orientales"},"251":{"code":"69","name":"Rh\u00f4ne"},"253":{"code":"71","name":"Sa\u00f4ne-et-Loire"},"254":{"code":"72","name":"Sarthe"},"255":{"code":"73","name":"Savoie"},"259":{"code":"77","name":"Seine-et-Marne"},"258":{"code":"76","name":"Seine-Maritime"},"275":{"code":"93","name":"Seine-Saint-Denis"},"262":{"code":"80","name":"Somme"},"263":{"code":"81","name":"Tarn"},"264":{"code":"82","name":"Tarn-et-Garonne"},"272":{"code":"90","name":"Territoire-de-Belfort"},"277":{"code":"95","name":"Val-d'Oise"}
12200,"276":{"code":"94","name":"Val-de-Marne"},"265":{"code":"83","name":"Var"},"266":{"code":"84","name":"Vaucluse"},"267":{"code":"85","name":"Vend\u00e9e"},"268":{"code":"86","name":"Vienne"},"270":{"code":"88","name":"Vosges"},"271":{"code":"89","name":"Yonne"},"260":{"code":"78","name":"Yvelines"}}},"HR":{"name":"Kroatien","regions":{"518":{"code":"HR-07","name":"Bjelovarsko-bilogorska \u017eupanija"},"523":{"code":"HR-12","name":"Brodsko-posavska \u017eupanija"},"530":{"code":"HR-19","name":"Dubrova\u010dko-neretvanska \u017eupanija"},"532":{"code":"HR-21","name":"Grad Zagreb"},"529":{"code":"HR-18","name":"Istarska \u017eupanija"},"515":{"code":"HR-04","name":"Karlova\u010dka \u017eupanija"},"517":{"code":"HR-06","name":"Koprivni\u010dko-kri\u017eeva\u010dka \u017eupanija"},"513":{"code":"HR-02","name":"Krapinsko-zagorska \u017eupanija"},"520":{"code":"HR-09","name":"Li\u010dko-senjska \u017eupanija"},"531":{"code":"HR-20","name":"Me\u0111imurska \u017eupanija"},"525":{"code":"HR-14","name":"Osje\u010dko-baranjska \u017eupanija"},"522":{"code":"HR-11","name":"Po\u017ee\u0161ko-slavonska \u017eupanija"},"519":{"code":"HR-08","name":"Primorsko-goranska \u017eupanija"},"526":{"code":"HR-15","name":"\u0160ibensko-kninska \u017eupanija"},"514":{"code":"HR-03","name":"Sisa\u010dko-moslava\u010dka \u017eupanija"},"528":{"code":"HR-17","name":"Splitsko-dalmatinska \u017eupanija"},"516":{"code":"HR-05","name":"Vara\u017edinska \u017eupanija"},"521":{"code":"HR-10","name":"Viroviti\u010dko-podravska \u017eupanija"},"527":{"code":"HR-16","name":"Vukovarsko-srijemska \u017eupanija"},"524":{"code":"HR-13","name":"Zadarska \u017eupanija"},"512":{"code":"HR-01","name":"Zagreba\u010dka \u017eupanija"}}},"HU":{"name":"Ungarn"},"IT":{"name":"Italien","regions":{"714":{"code":"AG","name":"Agrigento"},"715":{"code":"AL","name":"Alessandria"},"716":{"code":"AN","name":"Ancona"},"717":{"code":"AO","name":"Aosta"},"719":{"code":"AR","name":"Arezzo"},"720":{"code":"AP","name":"Ascoli-Piceno"},"721":{"code":"AT","name":"Asti"},"722":{"code":"AV","name":"Avellino"},"723":{"code":"BA","name":"Bari"},"724":{"code":"BT","name":"Barletta-Andria-Trani"},"725":{"code":"BL","name":"Belluno"},"726":{"code":"BN","name":"Benevento"},"727":{"code":"BG","name":"Bergamo"},"728":{"code":"BI","name":"Biella"},"729":{"code":"BO","name":"Bologna"},"730":{"code":"BZ","name":"Bolzano"},"731":{"code":"BS","name":"Brescia"},"732":{"code":"BR","name":"Brindisi"},"733":{"code":"CA","name":"Cagliari"},"734":{"code":"CL","name":"Caltanissetta"},"735":{"code":"CB","name":"Campobasso"},"736":{"code":"CI","name":"Carbonia Iglesias"},"737":{"code":"CE","name":"Caserta"},"738":{"code":"CT","name":"Catania"},"739":{"code":"CZ","name":"Catanzaro"},"740":{"code":"CH","name":"Chieti"},"741":{"code":"CO","name":"Como"},"742":{"code":"CS","name":"Cosenza"},"743":{"code":"CR","name":"Cremona"},"744":{"code":"KR","name":"Crotone"},"745":{"code":"CN","name":"Cuneo"},"746":{"code":"EN","name":"Enna"},"747":{"code":"FM","name":"Fermo"},"748":{"code":"FE","name":"Ferrara"},"749":{"code":"FI","name":"Firenze"},"750":{"code":"FG","name":"Foggia"},"751":{"code":"FC","name":"Forli-Cesena"},"752":{"code":"FR","name":"Frosinone"},"753":{"code":"GE","name":"Genova"},"754":{"code":"GO","name":"Gorizia"},"755":{"code":"GR","name":"Grosseto"},"756":{"code":"IM","name":"Imperia"},"757":{"code":"IS","name":"Isernia"},"718":{"code":"AQ","name":"L'Aquila"},"758":{"code":"SP","name":"La-Spezia"},"759":{"code":"LT","name":"Latina"},"760":{"code":"LE","name":"Lecce"},"761":{"code":"LC","name":"Lecco"},"762":{"code":"LI","name":"Livorno"},"763":{"code":"LO","name":"Lodi"},"764":{"code":"LU","name":"Lucca"},"765":{"code":"MC","name":"Macerata"},"766":{"code":"MN","name":"Mantova"},"767":{"code":"MS","name":"Massa-Carrara"},"768":{"code":"MT","name":"Matera"},"769":{"code":"VS","name":"Medio Campidano"},"770":{"code":"ME","name":"Messina"},"771":{"code":"MI","name":"Milano"},"772":{"code":"MO","name":"Modena"},"773":{"code":"MB","name":"Monza-Brianza"},"774":{"code":"NA","name":"Napoli"},"775":{"code":"NO","name":"Novara"},"776":{"code":"NU","name":"Nuoro"},"777":{"code":"OG","name":"Ogliastra"},"778":{"code":"OT","name":"Olbia Tempio"},"779":{"code":"OR","name":"Oristano"},"780":{"code":"PD","name":"Padova"},"781":{"code":"PA","name":"Palermo"},"782":{"code":"PR","name":"Parma"},"783":{"code":"PV","name":"Pavia"},"784":{"code":"PG","name":"Perugia"},"785":{"code":"PU","name":"Pesaro-Urbino"},"786":{"code":"PE","name":"Pescara"},"787":{"code":"PC","name":"Piacenza"},"788":{"code":"PI","name":"Pisa"},"789":{"code":"PT","name":"Pistoia"},"790":{"code":"PN","name":"Pordenone"},"791":{"code":"PZ","name":"Potenza"},"792":{"code":"PO","name":"Prato"},"793":{"code":"RG","name":"Ragusa"},"794":{"code":"RA","name":"Ravenna"},"795":{"code":"RC","name":"Reggio-Calabria"},"796":{"code":"RE","name":"Reggio-Emilia"},"797":{"code":"RI","name":"Rieti"},"798":{"code":"RN","name":"Rimini"},"799":{"code":"RM","name":"Roma"},"800":{"code":"RO","name":"Rovigo"},"801":{"code":"SA","name":"Salerno"},"802":{"code":"SS","name":"Sassari"},"803":{"code":"SV","name":"Savona"},"804":{"code":"SI","name":"Siena"},"805":{"code":"SR","name":"Siracusa"},"806":{"code":"SO","name":"Sondrio"},"807":{"code":"TA","name":"Taranto"},"808":{"code":"TE","name":"Teramo"},"809":{"code":"TR","name":"Terni"},"810":{"code":"TO","name":"Torino"},"811":{"code":"TP","name":"Trapani"},"812":{"code":"TN","name":"Trento"},"813":{"code":"TV","name":"Treviso"},"814":{"code":"TS","name":"Trieste"},"815":{"code":"UD","name":"Udine"},"816":{"code":"VA","name":"Varese"},"817":{"code":"VE","name":"Venezia"},"818":{"code":"VB","name":"Verbania"},"819":{"code":"VC","name":"Vercelli"},"820":{"code":"VR","name":"Verona"}
12200,"821":{"code":"VV","name":"Vibo-Valentia"},"822":{"code":"VI","name":"Vicenza"},"823":{"code":"VT","name":"Viterbo"}}},"LU":{"name":"Luxemburg"},"NL":{"name":"Niederlande"},"PL":{"name":"Polen","regions":{"824":{"code":"PL-02","name":"dolno\u015bl\u0105skie"},"825":{"code":"PL-04","name":"kujawsko-pomorskie"},"826":{"code":"PL-06","name":"lubelskie"},"827":{"code":"PL-08","name":"lubuskie"},"830":{"code":"PL-14","name":"mazowieckie"},"829":{"code":"PL-12","name":"ma\u0142opolskie"},"831":{"code":"PL-16","name":"opolskie"},"832":{"code":"PL-18","name":"podkarpackie"},"833":{"code":"PL-20","name":"podlaskie"},"834":{"code":"PL-22","name":"pomorskie"},"835":{"code":"PL-24","name":"\u015bl\u0105skie"},"836":{"code":"PL-26","name":"\u015bwi\u0119tokrzyskie"},"837":{"code":"PL-28","name":"warmi\u0144sko-mazurskie"},"838":{"code":"PL-30","name":"wielkopolskie"},"839":{"code":"PL-32","name":"zachodniopomorskie"},"828":{"code":"PL-10","name":"\u0142\u00f3dzkie"}}},"PT":{"name":"Portugal","regions":{"1006":{"code":"PT-01","name":"Aveiro"},"1007":{"code":"PT-02","name":"Beja"},"1008":{"code":"PT-03","name":"Braga"},"1009":{"code":"PT-04","name":"Bragan\u00e7a"},"1010":{"code":"PT-05","name":"Castelo Branco"},"1011":{"code":"PT-06","name":"Coimbra"},"1012":{"code":"PT-07","name":"\u00c9vora"},"1013":{"code":"PT-08","name":"Faro"},"1014":{"code":"PT-09","name":"Guarda"},"1015":{"code":"PT-10","name":"Leiria"},"1016":{"code":"PT-11","name":"Lisboa"},"1017":{"code":"PT-12","name":"Portalegre"},"1018":{"code":"PT-13","name":"Porto"},"1025":{"code":"PT-30","name":"Regi\u00e3o Aut\u00f3noma da Madeira"},"1024":{"code":"PT-20","name":"Regi\u00e3o Aut\u00f3noma dos A\u00e7ores"},"1019":{"code":"PT-14","name":"Santar\u00e9m"},"1020":{"code":"PT-15","name":"Set\u00fabal"},"1021":{"code":"PT-16","name":"Viana do Castelo"},"1022":{"code":"PT-17","name":"Vila Real"},"1023":{"code":"PT-18","name":"Viseu"}}},"SE":{"name":"Schweden","regions":{"1036":{"code":"SE-K","name":"Blekinge l\u00e4n"},"1037":{"code":"SE-W","name":"Dalarnas l\u00e4n"},"1039":{"code":"SE-X","name":"G\u00e4vleborgs l\u00e4n"},"1038":{"code":"SE-I","name":"Gotlands l\u00e4n"},"1040":{"code":"SE-N","name":"Hallands l\u00e4n"},"1041":{"code":"SE-Z","name":"J\u00e4mtlands l\u00e4n"},"1042":{"code":"SE-F","name":"J\u00f6nk\u00f6pings l\u00e4n"},"1043":{"code":"SE-H","name":"Kalmar l\u00e4n"},"1044":{"code":"SE-G","name":"Kronobergs l\u00e4n"},"1045":{"code":"SE-BD","name":"Norrbottens l\u00e4n"},"1055":{"code":"SE-T","name":"\u00d6rebro l\u00e4n"},"1056":{"code":"SE-E","name":"\u00d6sterg\u00f6tlands l\u00e4n"},"1046":{"code":"SE-M","name":"Sk\u00e5ne l\u00e4n"},"1048":{"code":"SE-D","name":"S\u00f6dermanlands l\u00e4n"},"1047":{"code":"SE-AB","name":"Stockholms l\u00e4n"},"1049":{"code":"SE-C","name":"Uppsala l\u00e4n"},"1050":{"code":"SE-S","name":"V\u00e4rmlands l\u00e4n"},"1051":{"code":"SE-AC","name":"V\u00e4sterbottens l\u00e4n"},"1052":{"code":"SE-Y","name":"V\u00e4sternorrlands l\u00e4n"},"1053":{"code":"SE-U","name":"V\u00e4stmanlands l\u00e4n"},"1054":{"code":"SE-O","name":"V\u00e4stra G\u00f6talands l\u00e4n"}}},"SI":{"name":"Slowenien"},"data_id":1791127424},"captcha":[],"instant-purchase":[],"loggedAsCustomer":[],"persistent":[],"review":[],"payments":[],"wishlist":{"items":[]},"doppler-wishlist-ids":[],"recently_viewed_product":[],"recently_compared_product":[],"product_data_storage":[],"paypal-billing-agreement":[],"paypal-buyer-country":[]}</script>
12200 12201</div>
12201<script type="text/x-magento-init">{"*": 12202 {"Magento_Persistent/js/remember-me-config": { 12203 "config": {"persistenceConfig":{"isRememberMeCheckboxVisible":true,"isRememberMeCheckboxChecked":true}} 12204 }}}</script>
12204<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"2f5b4235967c4e12855a97d830489375","r":1,"spa":2}' crossorigin="anonymous"></script>
12204 12205</body> 12206</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.