{"id":66702,"date":"2025-08-26T17:06:28","date_gmt":"2025-08-26T15:06:28","guid":{"rendered":"https:\/\/www.diamantrad.com\/?page_id=66702"},"modified":"2026-04-01T15:00:12","modified_gmt":"2026-04-01T13:00:12","slug":"bikes-without-motor","status":"publish","type":"page","link":"https:\/\/www.diamantrad.com\/da-DK\/bikes\/bikes-without-motor\/","title":{"rendered":"Bikes without motor"},"content":{"rendered":"\n<div class=\"wp-block-cover\"><img data-dominant-color=\"797190\" data-has-transparency=\"false\" loading=\"lazy\" decoding=\"async\" width=\"2250\" height=\"1500\" sizes=\"auto, (max-width: 2250px) 100vw, 2250px\" class=\"wp-block-cover__image-background wp-image-56764 size-full not-transparent\" alt=\"Di 25 mahon lifestyle 67i3404 300dpihero\" src=\"https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I3404_300dpihero-png.avif\" style=\"--dominant-color: #797190; object-position:71% 60%\" data-object-fit=\"cover\" data-object-position=\"71% 60%\" srcset=\"https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I3404_300dpihero-png.avif 2250w, https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I3404_300dpihero-300x200.avif 300w, https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I3404_300dpihero-1024x683.avif 1024w, https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I3404_300dpihero-768x512.avif 768w, https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I3404_300dpihero-1536x1024.avif 1536w, https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I3404_300dpihero-2048x1365.avif 2048w\" \/><span aria-hidden=\"true\" class=\"wp-block-cover__background has-color-primary-hover-background-color has-background-dim-30 has-background-dim\"><\/span><div class=\"wp-block-cover__inner-container is-layout-constrained wp-block-cover-is-layout-constrained\">\n<p class=\"has-text-align-center has-large-font-size\"><\/p>\n\n\n<div class=\"lazyblock-cover-text-mp6W1 wp-block-lazyblock-cover-text\"><div class=\"covertext container py-5 d-flex flex-column colorscheme-light justify-content-center\" id=\"covertext-mp6W1\">\r\n  <div class=\"lazyblock-inner-blocks\">\n\n<h2 class=\"wp-block-heading\">Cykler uden motor<\/h2>\n\n\n\n<h4 class=\"wp-block-heading\">Ren cykelgl\u00e6de<\/h4>\n\n<\/div>\r\n<\/div><\/div><\/div><\/div>\n\n\n<div class=\"lazyblock-nncontainer-Z2vC7Ps wp-block-lazyblock-nncontainer\"><div class=\"section-standard\">\r\n  <div class=\"container\" id=\"container-Z2vC7Ps\">\r\n    <div class=\"row\">\r\n      <div class=\"col py-4 py-lg-5\">\r\n        <div class=\"lazyblock-inner-blocks\">\n\n<p>En cykel uden motor repr\u00e6senterer stadig den perfekte balance mellem enkelhed, funktionalitet og lethed. Din ikke-elektriske cykel er din n\u00f8gle til cykelpendling, underst\u00f8tter din aktive fritid og tager dig med p\u00e5 store eventyr \u2013 uden brug af batterier. Vi er stadig dybt passionerede omkring renheden ved en motorfri k\u00f8retur. Det er her, alle bev\u00e6gelser starter. Vi fokuserer p\u00e5 gennemt\u00e6nkte detaljer, holdbar teknologi og tidl\u00f8st design for at give dig en uovertruffen k\u00f8reoplevelse. Hop p\u00e5 \u2013 det bedste tidspunkt at cykle er altid lige nu!<\/p>\n\n<\/div>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n<\/div><\/div>\n\n<div class=\"lazyblock-nncontainer-ZVJqeu wp-block-lazyblock-nncontainer\"><div class=\"section-light\">\r\n  <div class=\"container\" id=\"container-ZVJqeu\">\r\n    <div class=\"row\">\r\n      <div class=\"col py-4 py-lg-5\">\r\n        <div class=\"lazyblock-inner-blocks\">\n<div class=\"lazyblock-bikefinder-1wAG4F wp-block-lazyblock-bikefinder\"><template id=\"bikeTeaserComponent\">\n  <template x-if=\"frames.value.length\">\n    <div class=\"bikefinder-tile px-3 py-4 px-lg-4\" :class=\"classNames\">\n      <div class=\"bikefinder-tile-content\">\n        <a :href=\"selectedFrame.value.link\" class=\"bikefinder-title\">\n          <h4\n            class=\"mb-0\"\n            x-text=\"extractOrCleanString(selectedFrame.value.title)\"\n          ><\/h4>\n        <\/a>\n\n        <p\n          class=\"bikefinder-subtitle\"\n          x-text=\"$store.utils.t($store.utils.translations.frames[extractOrCleanString(selectedFrame.value.title, true)])\"\n        ><\/p>\n\n        <div\n          class=\"bikefinder-preis\"\n          x-text=\"getAbText() + ' ' + formatNumber(selectedFrame.value.price_lowest) + ' ' + getCurrency()\"\n        ><\/div>\n        <a :href=\"selectedFrame.value.link\" class=\"color-images mx-auto mb-4\"\n          ><picture>\n            <img\n              :src=\"selectedFrameImage.value\"\n              class=\"img-fluid lazy\"\n              :alt=\"selectedFrame.value.title\"\n          \/><\/picture>\n        <\/a>\n\n        <div class=\"bikefinder-controls mb-3\">\n          <div class=\"color-switch\">\n            <template x-for=\"(color, index) in selectedFrame.value.colors\">\n              <span\n                @click=\"onColorClicked(color)\"\n                :class=\"'bike-color-' + color.value.toLowerCase()\"\n                data-bs-toggle=\"tooltip\"\n                data-bs-placement=\"top\"\n                :title=\"color.description\"\n              ><\/span>\n            <\/template>\n          <\/div>\n\n          <div class=\"bikefinder-rahmen\">\n            <ul\n              class=\"nav nav-tabs\"\n              x-data=\"{ frames: framesAsGenerations ? selectedFrameByGeneration: frames }\"\n            >\n              <template x-for=\"(frame, index) in frames.value\">\n                <li\n                  class=\"nav-item\"\n                  @click=\"onFrameClicked(frame)\"\n                  x-show=\"!framesAsGenerations || isFrameInFiltered(frame)\"\n                >\n                  <span\n                    class=\"nav-link\"\n                    :class=\"selectedFrame.value.id == frame.id ? 'active' : ''\"\n                    x-data=\"{ meta: getFrameMeta(frame.frameType) }\"\n                  >\n                    <img\n                      width=\"48\"\n                      height=\"28\"\n                      :src=\"meta.icon\"\n                      data-bs-toggle=\"tooltip\"\n                      data-bs-placement=\"top\"\n                      :title=\"$store.utils.t(meta.text)\"\n                    \/>\n                  <\/span>\n                <\/li>\n              <\/template>\n            <\/ul>\n          <\/div>\n        <\/div>\n      <\/div>\n      <template x-if=\"framesAsGenerations\">\n        <div\n          x-data=\"generation({ generations: frames, generationClickedCallback: generationsCallback })\"\n        ><\/div>\n      <\/template>\n    <\/div>\n  <\/template>\n<\/template>\n\n<script>\n  document.addEventListener(\"alpine:init\", () => {\n    Alpine.data(\n      \"biketeaser\",\n      ({ frames, framesAsGenerations, framesMeta }) => ({\n        template: null,\n        frames: { value: frames },\n        selectedFrameByGeneration: { value: [] },\n        selectedFrame: { value: null },\n        framesMeta: framesMeta,\n        selectedFrameImage: {},\n        framesAsGenerations: framesAsGenerations,\n        generationsCallback: null,\n        classNames: \"\",\n        currentVariant: null,\n        init() {\n          this.setup();\n          this.$nextTick(() => {\n            this.mounted();\n            this.render();\n          });\n        },\n        setup() {\n          this.template = document.getElementById(\"bikeTeaserComponent\");\n        },\n        mounted() {\n          if (this.frames.value.length) {\n            if (this.framesAsGenerations) {\n              this.selectedFrameByGeneration.value = this.frames.value[0];\n              this.selectedFrame.value = this.frames.value[0];\n            } else {\n              this.selectedFrame.value = this.frames.value;\n            }\n\n            const frame = this.getFrameWithSpecialRecommendedRetailpriceOrFirst(\n              this.selectedFrame.value,\n            );\n\n            let variant = this.getVariantsWithKey(\n              frame,\n              \"special_recommended_retailprice\",\n            )[0];\n            if (!variant) {\n              variant = frame.variants[0];\n            }\n\n            const uniqueFrameImageOfVariant = this.getImageByVariant(\n              frame,\n              variant,\n            );\n\n            this.selectedFrame.value = frame;\n            this.selectedFrameImage = uniqueFrameImageOfVariant;\n\n            this.setClassNames(variant.id);\n          }\n          this.generationsCallback = this.onGenerationClicked.bind(this);\n        },\n        render() {\n          this.$el.innerHTML = this.template.innerHTML;\n        },\n        getFrameWithSpecialRecommendedRetailpriceOrFirst(frames) {\n          const frame = frames.find((frame) => {\n            return frame.hasOwnProperty(\"special_recommended_retailprice\");\n          });\n          return frame ? frame : frames[0];\n        },\n        getVariantsWithKey(frame, key, value = \"\") {\n          if (\n            frame.commonValues.hasOwnProperty(key) &&\n            (value ? frame.commonValues[key] === value : true)\n          ) {\n            return frame.variants;\n          }\n\n          return frame.variants.filter((variant) => {\n            return variant[key] && (value ? variant[key] === value : true);\n          });\n        },\n        getRecomendedRetailpriceVariantColor(color) {\n          const variantsWithPrice = this.getVariantsWithKey(\n            this.selectedFrame.value,\n            \"special_recommended_retailprice\",\n          );\n\n          const variantsWithColor = this.getVariantsWithKey(\n            this.selectedFrame.value,\n            \"primary_basecolour\",\n            color.value,\n          );\n\n          const variantsWithPriceIds = variantsWithPrice.map(\n            (variant) => variant.id,\n          );\n          let variant = variantsWithPrice.find((variant) =>\n            variantsWithPriceIds.includes(variant.id),\n          );\n          if (!variant) {\n            variant = variantsWithColor.length ? variantsWithColor[0] : this.selectedFrame.value.variants[0];\n          }\n\n          return {\n            value: variant ? variant.value : \"\",\n            variantId: variant ? variant.id : null,\n          };\n        },\n        getImageByVariant(frame, variant) {\n          if (!variant) {\n            return { value: frame?.commonValues?.pos_image, variantId: null };\n          }\n          const uniqueImage = frame.images?.find((image) => {\n            return image.value == variant[image.propertyPath];\n          });\n\n          return uniqueImage\n            ? { value: uniqueImage.value, variantId: variant.id }\n            : { value: frame.commonValues?.pos_image, variantId: variant.id };\n        },\n        isFrameInFiltered(frame) {\n          return frame.hasVariants.length ? true : false;\n        },\n        extractTextInBrackets(text) {\n          const match = text.match(\/\\((.*?)\\)\/);\n          return match ? match[1] : \"\";\n        },\n        onFrameClicked(frame) {\n          this.selectedFrame.value = frame;\n          const variantsWithPrice = this.getVariantsWithKey(\n            frame,\n            \"special_recommended_retailprice\",\n          );\n\n          const variantsWithPosImage = this.getVariantsWithKey(\n            frame,\n            \"pos_image\",\n          );\n\n          const variantsWithPriceIds = variantsWithPrice.map(\n            (variant) => variant.id,\n          );\n\n          let variant = variantsWithPrice.find((variant) =>\n            variantsWithPriceIds.includes(variant.id),\n          );\n          if (!variant) {\n            variant = frame.variants[0];\n          }\n\n          const uniqueFrameImageOfVariant = this.getImageByVariant(\n            frame,\n            variant,\n          );\n\n          this.selectedFrameImage = uniqueFrameImageOfVariant;\n          this.setClassNames(variant.id);\n        },\n        onGenerationClicked(generation) {\n          this.selectedFrameByGeneration.value = generation;\n          this.selectedFrame.value = this.selectedFrameByGeneration.value[0];\n          this.selectedFrameImage = this.selectedFrame.value.images[0];\n          this.setClassNames(this.selectedFrame.value.images[0].variantId);\n        },\n        onColorClicked(color) {\n          this.selectedFrameImage = this.selectedFrame.value.images.find(\n            (image) => image.variantId == color.variantId,\n          );\n\n          const colorRetailprice =\n            this.getRecomendedRetailpriceVariantColor(color);\n          this.setClassNames(colorRetailprice.variantId);\n        },\n        setClassNames(variantId) {\n          \/\/ Maybe many?\n          this.currentVariant = this.selectedFrame.value.variants.find(\n            (variant) => {\n              return variant.id === variantId;\n            },\n          );\n\n          let names = [];\n          if (this.isReducedPrice(this.currentVariant) && this.isLastChance()) {\n            names.push(\"sale\");\n            names.push(\"lastchance\");\n          } else if (this.isReducedPrice(this.currentVariant)) {\n            names.push(\"sale\");\n          } else if (this.isLastChance()) {\n            names.push(\"lastchance\");\n          }\n\n          if (this.isNewBike()) {\n            names.push(\"newbike\");\n          }\n          this.classNames = names.join(\" \");\n        },\n        getPriceText(price) {\n          return \"Ab \" + price + \" EUR\";\n        },\n        formatNumber(number) {\n          if (this.$store.utils.country === \"CH\") {\n            return number.toString().replace(\/\\B(?=(\\d{3})+(?!\\d))\/g, \"'\");\n          } else {\n            return number.toString().replace(\/\\B(?=(\\d{3})+(?!\\d))\/g, \".\");\n          }\n        },\n        getAbText() {\n          const lang = this.$store.utils.lang;\n          return (\n            {\n              da: \"Fra\",\n              de: \"Ab\",\n              en: \"From\",\n              fi: \"Alkaen\",\n              fr: \"\u00c0 partir de\",\n              nl: \"Vanaf\",\n              pl: \"Od\",\n              sv: \"Fr\u00e5n\",\n            }[lang] || \"Ab\"\n          );\n        },\n        getCurrency() {\n          const currencyMap = {\n            CH: \"CHF\",\n            DK: \"DKK\",\n            GB: \"GBP\",\n            PL: \"PLN\",\n            SE: \"SEK\",\n          };\n          const country = this.$store.utils.country;\n          return currencyMap[country] || \"EUR\";\n        },\n        isReducedPrice(variant) {\n          if (variant && variant.special_recommended_retailprice) {\n            return variant.special_recommended_retailprice;\n          }\n          return this.selectedFrame.value.specialRecommendedRetailprice.find(\n            (price) => price.variantId === this.selectedFrame.value.id,\n          );\n        },\n        isLastChance() {\n          return this.selectedFrame.value.lastchance;\n        },\n        isNewBike() {\n          return this.selectedFrame.value.newbike;\n        },\n        removeAllBrackets(str) {\n          const regex = \/\\[.*?\\]|\\(.*?\\)|\\{.*?\\}\/g;\n          return str.replace(regex, \"\");\n        },\n        extractBrackets(str) {\n          const regex = \/\\[.*?\\]|\\(.*?\\)|\\{.*?\\}\/g;\n\n          const matches = str.match(regex);\n\n          return matches || [];\n        },\n        getFrameMeta(frameType) {\n          return this.framesMeta[frameType] || { icon: '', text: '' };\n        },\n        extractOrCleanString(str, returnExtracted = false) {\n          if (!str) return \"\";\n          const pattern =\n            \/\\(?\\b(HCH|MIT|Lowstep|SCH|TIE|Midstep|Stepover|HER|TRA)\\b\\)?\/i;\n          const match = str.match(pattern);\n\n          if (match) {\n            return returnExtracted\n              ? match[1]\n              : str.replace(pattern, \"\").replace(\/\\s+\/g, \" \").trim();\n          }\n\n          return returnExtracted ? null : str.trim();\n        },\n      }),\n    );\n  });\n<\/script>\n<template id=\"generationComponent\">\n  <template x-if=\"getGenerationWithoutActive().length\">\n    <div class=\"dropdown bikefinder-generations\">\n      <button\n        class=\"btn btn-secondary dropdown-toggle p-0\"\n        type=\"button\"\n        :id=\"'dropdownGenerations-' + selectedGeneration.id\"\n        data-bs-toggle=\"dropdown\"\n        aria-expanded=\"false\"\n        x-text=\"$store.utils.t($store.utils.translations.futureGenerations)\"\n      ><\/button>\n      <div\n        class=\"dropdown-menu dropdown-generations\"\n        :aria-labelledby=\"'dropdownGenerations-' + selectedGeneration.id\"\n      >\n        <template\n          x-for=\"(generation, index) in getGenerationWithoutActive(generations)\"\n          :key=\"'genNav-' + index\"\n        >\n          <a\n            @click=\"onGenerationClicked(generation)\"\n            class=\"dropdown-item\"\n            x-text=\"mainTitle(generation)\"\n          ><\/a>\n        <\/template>\n      <\/div>\n    <\/div>\n  <\/template>\n<\/template>\n\n<script>\n  document.addEventListener(\"alpine:init\", () => {\n    Alpine.data(\"generation\", ({ generations, generationClickedCallback }) => ({\n      template: null,\n      generations: generations,\n      selectedGeneration: {},\n      selectedFrameImage: {},\n      generationClickedCallback: generationClickedCallback,\n      init() {\n        this.setup();\n        this.$nextTick(() => {\n          this.mounted();\n          this.render();\n        });\n      },\n      setup() {\n        this.template = document.getElementById(\"generationComponent\");\n      },\n      mounted() {\n        if (this.generations.value.length) {\n          this.selectedGeneration = this.generations.value[0];\n        }\n      },\n      render() {\n        this.$el.innerHTML = this.template.innerHTML;\n      },\n      onGenerationClicked(generation) {\n        this.generationClickedCallback(generation);\n        this.selectedGeneration = generation;\n      },\n      active(generation, selectedGeneration) {\n        return generation === selectedGeneration;\n      },\n      getGenerationWithoutActive() {\n        return this.generations.value.filter(\n          (generation) => generation != this.selectedGeneration\n        );\n      },\n      getGenerationFrame(generation) {\n        return generation[0];\n      },\n      extractOrCleanString(str, returnExtracted = false) {\n        const pattern =\n          \/\\(?\\b(HCH|MIT|Lowstep|SCH|TIE|Midstep|Stepover|HER|TRA)\\b\\)?\/i;\n        const match = str.match(pattern);\n\n        if (match) {\n          return returnExtracted\n            ? match[1]\n            : str.replace(pattern, \"\").replace(\/\\s+\/g, \" \").trim();\n        }\n\n        return returnExtracted ? null : str.trim();\n      },\n      mainTitle(generation) {\n        let frame = this.getGenerationFrame(generation);\n        let title = this.extractOrCleanString(frame.title);\n        return (\n          title +\n          \" \" +\n          this.addModelYear(frame) +\n          \" - \" +\n          this.formatNumber(frame.price_lowest) +\n          \" \" +\n          this.getCurrency()\n        );\n      },\n      addModelYear(frame) {\n        if (frame.modelYear) {\n          return \" (\" + frame.modelYear + \")\";\n        }\n        return \"\";\n      },\n      getCurrency() {\n        const currencyMap = {\n          CH: \"CHF\",\n          DK: \"DKK\",\n          GB: \"GBP\",\n          PL: \"PLN\",\n          SE: \"SEK\",\n        };\n        const country = this.$store.utils.country;\n        return currencyMap[country] || \"EUR\";\n      },\n      formatNumber(number) {\n        if (this.$store.utils.country === \"CH\") {\n          return number.toString().replace(\/\\B(?=(\\d{3})+(?!\\d))\/g, \"'\");\n        } else {\n          return number.toString().replace(\/\\B(?=(\\d{3})+(?!\\d))\/g, \".\");\n        }\n      },\n    }));\n  });\n<\/script>\n<template id=\"filterComponent\">\n  <template x-if=\"showReset\">\n    <div id=\"filter\" class=\"bikefinder-filter mb-5 text-start\">\n      <h5 class=\"text-uppercase h-underline mt-4 position-relative\">\n        Filter\n        <div x-show=\"isFilterActive()\" class=\"small reset-filters\">\n          <span\n            @click=\"resetFilter()\"\n            class=\"btn-reset-filters\"\n            x-text=\"$store.utils.t($store.utils.translations.resetFilter)\"\n          >\n          <\/span>\n        <\/div>\n      <\/h5>\n      <div class=\"bike-counter mb-4\">\n        <span id=\"bikeCount\" x-text=\"countOfFilteredBikes.value\"><\/span> Bikes\n      <\/div>\n\n      <!-- Biketyp -->\n      <h5\n        class=\"mb-1\"\n        x-text=\"$store.utils.t($store.utils.translations.bikeType)\"\n      ><\/h5>\n      <div\n        class=\"small text-grey mb-2\"\n        x-text=\"$store.utils.t($store.utils.translations.bikeTypeSpeed)\"\n      ><\/div>\n      <div\n        x-key=\"'typeLineSelection'\"\n        x-data=\"lineselection(\n        { \n            items: typeFilterProps.sort((a, b) => a.context.order < b.context.order ? -1 : 1),\n            onSelected: onTypeSelected,\n            selectedFilter: selectedFilter,\n        }\n      )\"\n      ><\/div>\n\n      <template x-if=\"!hideBattery\">\n        <div class=\"bikefinder-filter-akku\">\n          <!-- Akku -->\n          <h5\n            class=\"mb-1\"\n            x-text=\"$store.utils.t($store.utils.translations.battery)\"\n          ><\/h5>\n          <div\n            class=\"small text-grey mb-2\"\n            x-text=\"$store.utils.t($store.utils.translations.unitBattery)\"\n          ><\/div>\n          <div\n            x-show=\"showReset\"\n            x-data=\"sliderselection(\n            { \n                items: batteryFilterProps,\n                onSelected: onBatterySelected,\n                id: 'battery-slider',\n                domLoaded: domLoaded,\n                options: { step: 100, values: true }\n            }\n          )\"\n          ><\/div>\n        <\/div>\n      <\/template>\n\n      <!-- Rahmenformen -->\n      <h5 x-text=\"$store.utils.t($store.utils.translations.frameShape)\"><\/h5>\n\n      <div\n        x-key=\"'frameLineSelection'\"\n        x-data=\"lineselection(\n        { \n            items: frameFilterProps.sort((a, b) => a.context.order < b.context.order ? -1 : 1),\n            onSelected: onFrameSelected,\n            selectedFilter: selectedFilter,\n        }\n      )\"\n      ><\/div>\n\n      <!-- Schaltung -->\n      <h5 x-text=\"$store.utils.t($store.utils.translations.gear)\"><\/h5>\n      <div\n        x-data=\"choiceselection(\n        { \n            items: gearFilterProps,\n            onSelected: onGearSelected \n        }\n      )\"\n      ><\/div>\n\n      <!-- Preis -->\n      <h5\n        class=\"mb-1\"\n        x-text=\"$store.utils.t($store.utils.translations.price)\"\n      ><\/h5>\n      <div\n        class=\"small text-grey mb-2\"\n        x-text=\"$store.utils.t($store.utils.translations.inCurrency)\"\n      ><\/div>\n      <div\n        x-data=\"sliderselection(\n        { \n            items: priceFilterProps,\n            onSelected: onPriceSelected,\n            id: 'price-slider',\n            domLoaded: domLoaded,\n            options: { step: 100 }\n        }\n      )\"\n      ><\/div>\n\n      <!-- Sale -->\n      <h5 x-text=\"$store.utils.t($store.utils.translations.sale)\"><\/h5>\n      <div\n        x-data=\"multiplechoiceselection(\n        { \n            items: saleFilterProps.concat(lastchanceFilterProps),\n            onSelected: onSaleOrLastchanceSelected \n        }\n      )\"\n      ><\/div>\n\n      <!-- Farben -->\n      <h5 x-text=\"$store.utils.t($store.utils.translations.color)\"><\/h5>\n      <div\n        x-data=\"colorselection(\n        { \n            items: colorFilterProps,\n            onSelected: onColorSelected \n        }\n      )\"\n      ><\/div>\n\n      <!-- Gewicht -->\n      <h5\n        class=\"mb-1\"\n        x-text=\"$store.utils.t($store.utils.translations.weight)\"\n      ><\/h5>\n      <div\n        class=\"small text-grey mb-2\"\n        x-text=\"$store.utils.t($store.utils.translations.unitWeight)\"\n      ><\/div>\n      <div\n        class=\"rslider\"\n        x-data=\"sliderselection(\n        { \n            items: weightFilterProps,\n            onSelected: onWeightSelected,\n            id: 'weight-slider',\n            domLoaded: domLoaded\n        }\n      )\"\n      ><\/div>\n    <\/div>\n  <\/template>\n<\/template>\n\n<script>\n  document.addEventListener(\"alpine:init\", () => {\n    Alpine.data(\n      \"filter\",\n      ({\n        frameFilterProps,\n        typeFilterProps,\n        batteryFilterProps,\n        gearFilterProps,\n        priceFilterProps,\n        weightFilterProps,\n        saleFilterProps,\n        lastchanceFilterProps,\n        newbikeFilterProps,\n        countOfFilteredBikes,\n        maxBikesCount,\n        colorFilterProps,\n        selectedFilter,\n        controller,\n      }) => ({\n        template: null,\n        frameFilterProps: frameFilterProps,\n        typeFilterProps: typeFilterProps,\n        batteryFilterProps: batteryFilterProps,\n        gearFilterProps: gearFilterProps,\n        priceFilterProps: priceFilterProps,\n        weightFilterProps: weightFilterProps,\n        saleFilterProps: saleFilterProps,\n        lastchanceFilterProps: lastchanceFilterProps,\n        newbikeFilterProps: newbikeFilterProps,\n        countOfFilteredBikes: countOfFilteredBikes,\n        maxBikesCount: maxBikesCount,\n        colorFilterProps: colorFilterProps,\n        selectedFrame: {},\n        selectedFrameImage: {},\n        controller: controller,\n        showReset: true,\n        domLoaded: false,\n        domUpdate: { value: 0 },\n        selectedFilter: selectedFilter,\n        hideBattery: false,\n        init() {\n          this.setup();\n          this.$nextTick(() => {\n            this.mounted();\n            this.render();\n          });\n        },\n        setup() {\n          this.template = document.getElementById(\"filterComponent\");\n        },\n        mounted() {},\n        render() {\n          this.$el.innerHTML = this.template.innerHTML;\n\n          document.addEventListener(\"DOMContentLoaded\", () => {\n            this.domLoaded = true;\n          });\n\n          this.$watch(\"selectedFilter\", (filter) => {\n            this.hideFilterSections(filter);\n          });\n        },\n        hideFilterSections(filter) {\n          \/\/ Hide Battery\n          const hideBattery = [\"Bike\", \"S-Pedelec\"].includes(\n            filter.properties?.category?.value\n          );\n\n          if (hideBattery) {\n            this.hideBattery = true;\n          } else {\n            this.hideBattery = false;\n          }\n        },\n        onFrameSelected(property, initial = true) {\n          this.controller.filterAddPropertyAction(property, initial);\n        },\n        onTypeSelected(property, initial = true) {\n          this.controller.filterAddPropertyAction(property, initial);\n        },\n        onBatterySelected(property, initial = true) {\n          this.controller.filterAddPropertyAction(property, initial);\n        },\n        onGearSelected(property, initial = true) {\n          this.controller.filterAddPropertyAction(property, initial);\n        },\n        onPriceSelected(property, initial = true) {\n          this.controller.filterAddPropertyAction(property, initial);\n        },\n        onWeightSelected(property, initial = true) {\n          this.controller.filterAddPropertyAction(property, initial);\n        },\n        onSaleOrLastchanceSelected(property, checked, initial = true) {\n          if (checked) {\n            this.controller.filterAddPropertyAction(property, initial);\n          } else {\n            this.controller.filterRemovePropertyAction(property);\n          }\n        },\n        onColorSelected(property, initial = true) {\n          this.controller.filterAddPropertyAction(property, true);\n        },\n        resetFilter() {\n          this.showReset = false;\n          this.controller.resetFilterAction();\n\n          this.$nextTick(() => {\n            this.showReset = true;\n          });\n        },\n        isFilterActive() {\n          return !this.selectedFilter.initial;\n        },\n      })\n    );\n  });\n<\/script>\n<template id=\"lineSelectionComponent\">\n  <div class=\"bikefilter-biketyp mb-4\">\n    <ul class=\"nav nav-tabs\">\n      <template x-for=\"(item, index) in items\">\n        <li class=\"nav-item\">\n          <button\n            @click=\"selected(item, index)\"\n            class=\"nav-link\"\n            :class=\"activeItem &#038;&#038; activeItem.value === item.value ? 'active' : ''\"\n            style=\"outline: none\"\n            data-bs-toggle=\"tooltip\"\n            data-placement=\"top\"\n            :title=\"$store.utils.t(item.context.text)\"\n          >\n            <template x-if=\"item.context &#038;&#038; item.context.type == 'icon'\">\n              <img :src=\"item.context.icon\" style=\"width: 48px; height: 28px\" \/>\n            <\/template>\n            <template x-if=\"item.context &#038;&#038; item.context.type == 'text'\">\n              <span\n                style=\"width: 48px; height: 28px\"\n                x-text=\"$store.utils.t(item.context.text)\"\n              ><\/span>\n            <\/template>\n          <\/button>\n        <\/li>\n      <\/template>\n    <\/ul>\n  <\/div>\n<\/template>\n\n<script>\n  document.addEventListener(\"alpine:init\", () => {\n    Alpine.data(\"lineselection\", ({ items, onSelected, selectedFilter }) => ({\n      template: null,\n      items: items,\n      onSelected: onSelected,\n      selectedFilter: selectedFilter,\n      selectedIndex: -1,\n      activeItem: null,\n      init() {\n        this.setup();\n        this.$nextTick(() => {\n          this.mounted();\n          this.render();\n        });\n      },\n      setup() {\n        this.template = document.getElementById(\"lineSelectionComponent\");\n      },\n      mounted() {\n        this.$watch(\"selectedFilter\", (filter) => {\n          this.activeItem = this.findActiveItem(filter);\n        });\n      },\n      render() {\n        this.$el.innerHTML = this.template.innerHTML;\n      },\n      selected(item, index) {\n        this.selectedIndex = index;\n        this.onSelected(item, false);\n      },\n      findActiveItem(filter) {\n        if (this.items[0].propertyPath in filter.properties) {\n          let found = this.items.find((item) => {\n            return (\n              item.value === filter.properties[this.items[0].propertyPath].value\n            );\n          });\n          return found;\n        }\n      },\n    }));\n  });\n<\/script>\n<template id=\"sliderSelectionComponent\">\n\t<div :style=\"!sliderReady ? 'opacity: 0' : ''\" class=\"bikefilter-rahmenform mb-4 mt-3\">\n\t\t<div :style=\"!domLoaded &#038;&#038; !slider ? 'opacity: 0' : ''\">\n\t\t\t<input :id=\"id\" type=\"range\" \/>\n\t\t<\/div>\n\t<\/div>\n<\/template>\n\n<script>\n\tdocument.addEventListener(\"alpine:init\", () => {\n\t\tAlpine.data(\"sliderselection\", ({ items, onSelected, id, domLoaded, options = {} }) => ({\n\t\t\ttemplate: null,\n\t\t\titems: [],\n\t\t\tonSelected: onSelected,\n\t\t\tid: id,\n\t\t\tvalue: 0,\n\t\t\tslider: items,\n\t\t\tdomLoaded: domLoaded,\n\t\t\tmin: 0,\n\t\t\tmax: 0,\n\t\t\toptions: options,\n\t\t\tinitial: true,\n\t\t\tsliderReady: false,\n\t\t\tinit() {\n\t\t\t\tthis.setup();\n\t\t\t\tthis.$nextTick(() => {\n\t\t\t\t\tthis.mounted();\n\t\t\t\t\tthis.render();\n\t\t\t\t});\n\t\t\t},\n\t\t\tsetup() {\n\t\t\t\tthis.template = document.getElementById(\"sliderSelectionComponent\");\n\t\t\t},\n\t\t\tmounted() {\n\t\t\t\tif (items.length) {\n\t\t\t\t\tthis.items = items.sort((a, b) => (Number(a.value) > Number(b.value) ? 1 : -1));\n\n\t\t\t\t\tthis.min = this.items[0].value;\n\t\t\t\t\tthis.max = this.items.slice(-1)[0].value;\n\t\t\t\t\tthis.value = this.max;\n\t\t\t\t}\n\t\t\t},\n\t\t\trender() {\n\t\t\t\tthis.$el.innerHTML = this.template.innerHTML;\n\n\t\t\t\tdocument.addEventListener(\"DOMContentLoaded\", () => {\n\t\t\t\t\tthis.domLoaded = true;\n\t\t\t\t\tthis.initRangeSlider();\n\t\t\t\t});\n\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tif (!this.domLoaded) {\n\t\t\t\t\t\tthis.initRangeSlider();\n\t\t\t\t\t}\n\t\t\t\t}, 400);\n\t\t\t},\n\t\t\tinitRangeSlider() {\n\t\t\t\tthis.domLoaded = true;\n\t\t\t\tthis.initial = true;\n\n\t\t\t\tconst min = this.roundMin(parseInt(this.min, 10));\n\t\t\t\tconst max = this.roundMax(parseInt(this.max, 10));\n\n\t\t\t\tthis.slider = new rSlider({\n\t\t\t\t\ttarget: \"#\" + this.id,\n\t\t\t\t\tvalues: options.values && options.values == true ? this.getAllValues() : { min: min, max: max },\n\t\t\t\t\trange: true,\n\t\t\t\t\ttooltip: true,\n\t\t\t\t\tstep: options.step ? options.step : 1,\n\t\t\t\t\tscale: false,\n\t\t\t\t\tlabels: true,\n\t\t\t\t\tvariableWidth: true,\n\t\t\t\t\tunit: \"kg\",\n\t\t\t\t\tset: [this.min, this.max],\n\t\t\t\t\tonChange: (vals) => {\n\t\t\t\t\t\t\/\/ vals is not correct so get from index\n\t\t\t\t\t\tlet min = Number(this.slider.conf.values[this.slider.values.start]);\n\t\t\t\t\t\tlet max = Number(this.slider.conf.values[this.slider.values.end]);\n\t\t\t\t\t\tthis.setValue(min, max);\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tconst sliderElements = document.querySelectorAll(\".rs-container\");\n\t\t\t\tsliderElements.forEach((element) => {\n\t\t\t\t\telement.addEventListener(\"mousedown\", () => {\n\t\t\t\t\t\tthis.initial = false;\n\t\t\t\t\t});\n\t\t\t\t\telement.addEventListener(\"touchstart\", () => {\n\t\t\t\t\t\tthis.initial = false;\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\tthis.sliderReady = true;\n\t\t\t},\n\t\t\tsetValue(min, max) {\n\t\t\t\tlet range = this.items.filter((item) => {\n\t\t\t\t\tconst itemValue = Number(item.value);\n\t\t\t\t\treturn itemValue >= min && itemValue <= max;\n\t\t\t\t});\n\t\t\t\tif (range.length === 0) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlet maxOfRange = range.reduce((max, obj) => {\n\t\t\t\t\treturn Number(obj.value) > Number(max.value) ? obj : max;\n\t\t\t\t}, range[0]);\n\n\t\t\t\tlet minOfRange = range.reduce((min, obj) => {\n\t\t\t\t\treturn Number(obj.value) < Number(min.value) ? obj : min;\n\t\t\t\t}, range[0]);\n\n\t\t\t\tif (maxOfRange) {\n\t\t\t\t\tif (minOfRange) {\n\t\t\t\t\t\tmaxOfRange[\"min\"] = minOfRange.value;\n\t\t\t\t\t\tthis.select(maxOfRange, false);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tselect(property) {\n\t\t\t\tthis.onSelected(property, this.initial);\n\t\t\t},\n\t\t\tgetAllValues() {\n\t\t\t\treturn this.items.map((item) => Number(item.value));\n\t\t\t},\n\t\t\troundMin(num) {\n\t\t\t\tif (num > 100) {\n\t\t\t\t\treturn Math.floor(num \/ 50) * 50;\n\t\t\t\t} else {\n\t\t\t\t\treturn Math.floor(num \/ 10) * 10;\n\t\t\t\t}\n\t\t\t},\n\t\t\troundMax(num) {\n\t\t\t\tif (num > 100) {\n\t\t\t\t\treturn Math.ceil(num \/ 50) * 50;\n\t\t\t\t} else {\n\t\t\t\t\treturn Math.ceil(num \/ 10) * 10;\n\t\t\t\t}\n\t\t\t},\n\t\t}));\n\t});\n<\/script>\n<template id=\"choiceSelectionComponent\">\n  <div class=\"bikefilter-schaltung mb-4\">\n    <fieldset>\n      <template x-for=\"(item, index) in items\">\n        <div class=\"form-check\">\n          <input\n            type=\"radio\"\n            :id=\"item.propertyPath + index\"\n            name=\"drone\"\n            value=\"huey\"\n            x-on:input.change=\"onSelected(item, false)\"\n            class=\"form-check-input\"\n          \/>\n          <label\n            :for=\"item.propertyPath + index\"\n            x-text=\"$store.utils.t(item.context.text)\"\n            class=\"form-check-label\"\n          ><\/label>\n        <\/div>\n      <\/template>\n    <\/fieldset>\n  <\/div>\n<\/template>\n\n<script>\n  document.addEventListener(\"alpine:init\", () => {\n    Alpine.data(\"choiceselection\", ({ items, onSelected }) => ({\n      template: null,\n      items: items,\n      onSelected: onSelected,\n      value: 0,\n      init() {\n        this.setup();\n        this.$nextTick(() => {\n          this.mounted();\n          this.render();\n        });\n      },\n      setup() {\n        this.template = document.getElementById(\"choiceSelectionComponent\");\n      },\n      mounted() {},\n      render() {\n        this.$el.innerHTML = this.template.innerHTML;\n      },\n    }));\n  });\n<\/script>\n<template id=\"multipleChoiceSelectionComponent\">\n  <div class=\"bikefilter-schaltung mb-4\">\n    <fieldset>\n      <template x-for=\"(item, index) in items\">\n        <div class=\"form-check\">\n          <input\n            type=\"checkbox\"\n            :id=\"item.propertyPath + index\"\n            name=\"drone\"\n            value=\"huey\"\n            x-on:input.change=\"onSelected(item, $event.target.checked, false)\"\n            class=\"form-check-input\"\n          \/>\n          <label\n            :for=\"item.propertyPath + index\"\n            x-text=\"$store.utils.t(item.context.text)\"\n            class=\"form-check-label\"\n          ><\/label>\n        <\/div>\n      <\/template>\n    <\/fieldset>\n  <\/div>\n<\/template>\n\n<script>\n  document.addEventListener(\"alpine:init\", () => {\n    Alpine.data(\"multiplechoiceselection\", ({ items, onSelected }) => ({\n      template: null,\n      items: items,\n      onSelected: onSelected,\n      value: 0,\n      init() {\n        this.setup();\n        this.$nextTick(() => {\n          this.mounted();\n          this.render();\n        });\n      },\n      setup() {\n        this.template = document.getElementById(\n          \"multipleChoiceSelectionComponent\"\n        );\n      },\n      mounted() {},\n      render() {\n        this.$el.innerHTML = this.template.innerHTML;\n      },\n    }));\n  });\n<\/script>\n<template id=\"colorSelectionComponent\">\n  <div class=\"color-options mb-4\">\n    <ul class=\"ps-0\">\n      <template x-for=\"(item, index) in items\">\n        <li>\n          <button\n            @click=\"selected(item, index, false)\"\n            :class=\"'btn filter-color-' + item.value.toLowerCase() + ' ' + ((selectedIndex == index) ? 'active' : '')\"\n            data-bs-toggle=\"tooltip\"\n            data-placement=\"top\"\n            :title=\"item.description\"\n          ><\/button>\n        <\/li>\n      <\/template>\n    <\/ul>\n  <\/div>\n<\/template>\n\n<script>\n  document.addEventListener(\"alpine:init\", () => {\n    Alpine.data(\"colorselection\", ({ items, onSelected }) => ({\n      template: null,\n      items: items,\n      onSelected: onSelected,\n      selectedIndex: -1,\n      init() {\n        this.setup();\n        this.$nextTick(() => {\n          this.mounted();\n          this.render();\n        });\n      },\n      setup() {\n        this.template = document.getElementById(\"colorSelectionComponent\");\n      },\n      mounted() {},\n      render() {\n        this.$el.innerHTML = this.template.innerHTML;\n      },\n      selected(item, index, initial) {\n        this.selectedIndex = index;\n        this.onSelected(item, initial);\n      },\n    }));\n  });\n<\/script>\n<template id=\"bikefinderComponent\">\n  <div class=\"bikefinder\">\n    <div class=\"row\">\n      <div class=\"col-md-4 col-lg-3 bikefinder-filter-col\">\n        <button\n          class=\"btn btn-primary filter-toggle d-md-none mb-3\"\n          data-show=\"Filter anzeigen\"\n          data-hide=\"Filter ausblenden\"\n          x-text=\"$store.utils.t($store.utils.translations.showFilter)\"\n        ><\/button>\n\n        <div\n          class=\"bikefinder-filter-content\"\n          x-data=\"filter({ \n            frameFilterProps: uniquePropFrames(), \n            typeFilterProps: model.uniquePropTypes(), \n            batteryFilterProps: uniquePropBatteries(), \n            gearFilterProps: uniquePropGears(),\n            priceFilterProps: uniquePropPrices(),\n            weightFilterProps: uniquePropWeights(),\n            saleFilterProps: model.uniquePropSales(),\n            lastchanceFilterProps: model.uniquePropLastchance(),\n            newbikeFilterProps: model.uniquePropNewbike(),\n            countOfFilteredBikes: state.countOfFilteredBikes,\n            maxBikesCount: state.maxBikesCount,\n            colorFilterProps: uniquePropColors(),\n            selectedFilter: state.selectedFilter,\n            controller: controller\n          })\"\n        ><\/div>\n      <\/div>\n      <div class=\"col-md-8 col-lg-9\">\n        <div class=\"dropdown text-end dropdown-underline\">\n          <button\n            class=\"btn btn-secondary dropdown-toggle p-0 pb-1 me-3 me-md-4\"\n            type=\"button\"\n            id=\"dropdownSort\"\n            data-bs-toggle=\"dropdown\"\n            aria-haspopup=\"true\"\n            aria-expanded=\"false\"\n            x-text=\"$store.utils.t($store.utils.translations.sortBy)\"\n          ><\/button>\n\n          <div\n            class=\"dropdown-menu dropdown-menu-end dropdown-sort\"\n            aria-labelledby=\"dropdownSort\"\n          >\n            <a\n              @click=\"controller.sortNewestAlphaAction()\"\n              class=\"dropdown-item\"\n              :class=\"state.currentSort == 'newestalpha' ? 'active' : ''\"\n              id=\"sort-newest-alpha\"\n              x-text=\"$store.utils.t($store.utils.translations.sortByNewestAlpha)\"\n            ><\/a>\n            <a\n              @click=\"controller.sortAlphaAction()\"\n              class=\"dropdown-item\"\n              :class=\"state.currentSort == 'alpha' ? 'active' : ''\"\n              id=\"sort-alpha\"\n              x-text=\"$store.utils.t($store.utils.translations.sortByAlpha)\"\n            ><\/a>\n            <a\n              @click=\"controller.sortPriceAction()\"\n              class=\"dropdown-item\"\n              :class=\"state.currentSort == 'priceASC' ? 'active' : 'peter'\"\n              id=\"sort-price-asc\"\n              x-text=\"$store.utils.t($store.utils.translations.sortByAsc)\"\n            ><\/a>\n            <a\n              @click=\"controller.sortPriceAction(true)\"\n              class=\"dropdown-item\"\n              :class=\"state.currentSort == 'priceDESC' ? 'active' : 'peter'\"\n              id=\"sort-price-desc\"\n              x-text=\"$store.utils.t($store.utils.translations.sortByDesc)\"\n            ><\/a>\n          <\/div>\n        <\/div>\n        <template x-if=\"showBikeSort &#038;&#038; initialReady\">\n          <div\n            x-data=\"{ bikesByGenerations: state.filteredBikesGroupedByGenerations  }\"\n            class=\"bikefinder-bikes p-md-3 p-lg-4\"\n          >\n            <div\n              x-show=\"state.countOfFilteredBikes.value == 0\"\n              class=\"no-results\"\n            >\n              <span\n                x-text=\"$store.utils.t($store.utils.translations.noResults)\"\n              ><\/span>\n            <\/div>\n            <div class=\"bikefinder-grid\">\n              <template x-for=\"(value, index) in bikesByGenerations\">\n                <div\n                  x-data=\"biketeaser({ frames: bikesByGenerations[index], framesAsGenerations: true, framesMeta: model.frameFilterModel })\"\n                ><\/div>\n              <\/template>\n            <\/div>\n          <\/div>\n        <\/template>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/template>\n\n<script>\n  document.addEventListener(\"alpine:init\", () => {\n    Alpine.data(\n      \"bikefinder\",\n      ({\n        blockId,\n        model,\n        store,\n        state,\n        utils,\n        controller,\n        filterParamsResolver,\n      }) => ({\n        blockId: blockId,\n        model: model,\n        store: store,\n        state: state,\n        utils: utils,\n        controller: controller,\n        filterParamsResolver: filterParamsResolver,\n        showBikeSort: false,\n        initialReady: false,\n        init() {\n          this.setup();\n          this.$nextTick(() => {\n            this.mounted();\n            this.render();\n          });\n        },\n        setup() {\n          this.template = document.getElementById(\"bikefinderComponent\");\n        },\n        mounted() {\n          this.model.variantsToUniqueFramesAndFlattedVariants(\n            this.model.modules[this.blockId].bikes,\n            this.blockId\n          );\n\n          this.$watch(\"state.selectedFilter\", (value) => {\n            this.filter(value);\n          });\n\n          this.$watch(\"state.filteredBikesGroupedByGenerations\", (grouped) => {\n            this.reactiveBikeSort();\n          });\n\n          setTimeout(() => {\n            const { filters } = this.filterParamsResolver.defaultParams;\n            Object.keys(filters).forEach((key) => {\n              this.filterByParams(key, filters[key], true);\n            });\n            \/\/ wait to set all default filter properties - for resetFilterAction() -- to prevent watch updates on state.selectedFilter\n            this.state.defaultFilterProperties = JSON.stringify(\n              this.state.selectedFilter.properties\n            );\n\n            this.initialReady = true;\n          }, 1500);\n        },\n        render() {\n          this.$el.innerHTML = this.template.innerHTML;\n        },\n        filterByParams(key, value, initial) {\n          const propsMap = {\n            category: {\n              getProps: () => this.model.uniquePropTypes(),\n              keyName: \"value\",\n            },\n            primary_basecolour: {\n              getProps: () => this.uniquePropColors(),\n              keyName: \"value\",\n            },\n            frame_type: {\n              getProps: () => this.uniquePropFrames(),\n              keyName: \"value\",\n            },\n            \"bike_specifics.gear.gear_type\": {\n              getProps: () => this.uniquePropGears(),\n              keyName: \"value\",\n            },\n            \"ebike_specifics.battery_range.battery_capacity\": {\n              getProps: () => this.uniquePropBatteries(),\n              keyName: \"value\",\n            },\n          };\n\n          if (key in propsMap) {\n            const mapResult = propsMap[key];\n            const prop = mapResult\n              .getProps()\n              .find((prop) => prop[mapResult[\"keyName\"]] == value);\n            if (prop) {\n              this.controller.filterAddPropertyAction(prop, initial);\n            }\n\n            this.state.selectedFilter.initial = false;\n          }\n        },\n\n        filter(value) {\n          this.model.groupedFrames[this.blockId].forEach((group) => {\n            group.forEach((frame) => {\n              frame.filter(value);\n            });\n          });\n\n          this.state.filteredBikes =\n            this.controller.getOnlyBikesWhereFramesWithVariants(\n              this.model.groupedFrames[this.blockId]\n            );\n\n          const generations = this.controller.getGenerations(\n            this.state.filteredBikes\n          );\n          this.state.filteredBikesGroupedByGenerations = generations;\n\n          const countOfBikes = this.controller.calculateCountOfFilteredBikes(\n            this.blockId\n          );\n          if (this.state.selectedFilter.initial) {\n            this.state.maxBikesCount.value = countOfBikes;\n          }\n\n          this.state.countOfFilteredBikes.value = countOfBikes;\n          this.controller.sortNewestAlphaAction();\n\n          \/\/ Sync Filter\n          this.filterParamsResolver.setFiltersParams(\n            this.filterParamsResolver.getActiveFilters()\n          );\n        },\n        reactiveBikeSort() {\n          this.showBikeSort = false;\n          this.$nextTick(() => {\n            this.showBikeSort = true;\n          });\n        },\n        uniquePropFrames() {\n          return this.model.uniquePropFrames(this.blockId);\n        },\n        uniquePropBatteries() {\n          return this.model.uniquePropBatteries(this.blockId);\n        },\n        uniquePropGears() {\n          return this.model.uniquePropGears(this.blockId);\n        },\n        uniquePropPrices() {\n          return this.model.uniquePropPrices(this.blockId);\n        },\n        uniquePropWeights() {\n          return this.model.uniquePropWeights(this.blockId);\n        },\n        uniquePropColors() {\n          return this.model.uniquePropColors(this.blockId);\n        },\n      })\n    );\n  });\n<\/script>\n\n<style type=\"text\/css\">\n  body.modal-open {\n    padding-right: 0px !important;\n    overflow: auto !important;\n  }\n\n  body {\n    padding-right: 0 !important;\n  }\n\n  body.modal-open header,\n  body.modal-open .content {\n    padding-right: 0 !important;\n  }\n<\/style>\n<div x-data='bikefinder({ \n    blockId: \"1wAG4F\", \n    model: $store.bikefinderModel, \n    store: $store.bikefinderStore, \n    state: $store.bikefinderState, \n    utils: $store.utils, \n    controller: $store.bikefinderController,\n    filterParamsResolver: $store.bikefinderFilterParamsResolver })'>\n<\/div>\n<\/div>\n<\/div>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n<\/div><\/div>\n\n<div class=\"lazyblock-nncontainer-Z1I6h79 wp-block-lazyblock-nncontainer\"><div class=\"section-standard\">\r\n  <div class=\"container\" id=\"container-Z1I6h79\">\r\n    <div class=\"row\">\r\n      <div class=\"col py-4 py-lg-5\">\r\n        <div class=\"lazyblock-inner-blocks\">\n\n<h3 class=\"wp-block-heading\">Hvorfor v\u00e6lge en cykel uden motor fra Diamant?<\/h3>\n\n\n\n<p>Vores motorl\u00f8se cykler er designet til dem, der s\u00e6tter pris p\u00e5 den rene gl\u00e6de ved at tr\u00e6de i pedalerne med egen kraft. Her er, hvad der g\u00f8r vores modeller unikke:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>1x transmission med 11 eller 12 gear<\/strong>: Du beh\u00f8ver kun \u00e9n h\u00e5nd \u2013 det er s\u00e5 enkelt og intuitivt! Vores system med enkelt k\u00e6dehjul er lettere og slider mindre. Op ad bakke fungerer din ops\u00e6tning lige s\u00e5 godt som traditionelle 30-gears ops\u00e6tninger.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Mange monteringsmuligheder<\/strong>: Vores stel har mange fastg\u00f8relsespunkter til tilbeh\u00f8r som flaskeholdere, tasker eller l\u00e5se. M\u00e5ske skal du begynde at dr\u00f8mme, for du er helt sikkert klar til et eventyr.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Robust bagageb\u00e6rer<\/strong>: Clever Rack fra Diamant er stabil og alsidig, udstyret med en rem og kompatibel med cykeltasker og ekstra bagage. Den underst\u00f8tter MIK Side- eller Ortlieb 3.1-systemer for ubesv\u00e6ret integration.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>136 kg v\u00e6gtkapacitet<\/strong>: Vores cykler er designet til tunge laster, h\u00f8jere ryttere eller barnestole og kan nemt klare en systemv\u00e6gt p\u00e5 op til 136 kg.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Robuste stel<\/strong>: Vi l\u00e6gger stor v\u00e6gt p\u00e5 nem vedligeholdelse, standardiserede komponentgr\u00e6nseflader og ekstrem robusthed. Vores stel holder hele livet \u2013 garanteret!<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Forbedrede sikkerhedsfunktioner<\/strong>: Baglygter med standlys, reflekterende d\u00e6kkanter og dynamodrevet lygtesystemer sikrer, at du er synlig og sikker.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Alsidige drevmuligheder<\/strong>: V\u00e6lg mellem vedligeholdelsesfrie remtr\u00e6k med navgear eller klassiske k\u00e6dedrevne gearskiftere.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Hvem b\u00f8r overveje en motorfri Diamant-cykel?<\/h3>\n\n\n\n<p>Vores cykler er ideelle til:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Daglig transport<\/strong>: Moderne transmissioner, vedligeholdelsesvenlige konstruktioner og slankt design g\u00f8r dem perfekte til daglig brug.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Eventyrere<\/strong>: Med masser af monteringsbeslag og holdbare stel er de bygget til udflugter, cykelture og bikepacking-ture.<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Traditionalister<\/strong>: Ingen skal tvinges til at k\u00f8re p\u00e5 en elcykel. Hvis du ikke vil, s\u00e5 lad v\u00e6re. Ikke desto mindre b\u00f8r du drage fordel af innovationer. Vi forts\u00e6tter ogs\u00e5 med at udvikle teknologien inden for cykler uden motor.<\/li>\n<\/ul>\n\n<\/div>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n<\/div><\/div>\n\n\n<div class=\"wp-block-cover is-light\"><img data-dominant-color=\"8a7782\" data-has-transparency=\"false\" loading=\"lazy\" decoding=\"async\" width=\"2560\" height=\"1707\" sizes=\"auto, (max-width: 2560px) 100vw, 2560px\" class=\"wp-block-cover__image-background wp-image-56751 size-full not-transparent\" alt=\"Di 25 mahon lifestyle\" src=\"https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I2798_300-scaled.avif\" style=\"--dominant-color: #8a7782; object-position:43% 50%\" data-object-fit=\"cover\" data-object-position=\"43% 50%\" srcset=\"https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I2798_300-scaled.avif 2560w, https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I2798_300-300x200.avif 300w, https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I2798_300-1024x683.avif 1024w, https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I2798_300-768x512.avif 768w, https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I2798_300-1536x1024.avif 1536w, https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I2798_300-2048x1365.avif 2048w\" \/><span aria-hidden=\"true\" class=\"wp-block-cover__background has-background-dim-0 has-background-dim\"><\/span><div class=\"wp-block-cover__inner-container is-layout-constrained wp-block-cover-is-layout-constrained\">\n<p class=\"has-text-align-center has-large-font-size\"><\/p>\n<\/div><\/div>\n\n\n<div class=\"lazyblock-nncontainer-Z2bvcjN wp-block-lazyblock-nncontainer\"><div class=\"section-standard\">\r\n  <div class=\"container\" id=\"container-Z2bvcjN\">\r\n    <div class=\"row\">\r\n      <div class=\"col py-4 py-lg-5\">\r\n        <div class=\"lazyblock-inner-blocks\">\n\n<h3 class=\"wp-block-heading\">Kan jeg eftermontere en motor p\u00e5 min cykel?<\/h3>\n\n\n\n<p>Vi ser en stigende interesse for at ombygge klassiske cykler til elcykler. Selve ombygningen er lovlig til brug som pedelec (op til 25 km\/t). Det lyder godt, ikke? Men der er nogle forbehold.<\/p>\n\n\n\n<p>Som den person, der foretager ombygningen, p\u00e5tager du dig rollen som producent. Derfor p\u00e5tager du dig produktansvaret. Du skal betale for nogle tests for at sikre, at din ombyggede cykel overholder CE-certificeringsstandarderne.<\/p>\n\n\n\n<p>Hvis du er fristet til at ignorere det, fordi ingen alligevel kontrollerer en cykel: Hvis en tredjepart lider skade som f\u00f8lge af en defekt cykel fra din produktion, er det dig, der er ansvarlig. Og din ansvarsforsikring d\u00e6kker muligvis ikke under disse omst\u00e6ndigheder.<\/p>\n\n\n\n<p>Husk ogs\u00e5, at stel til cykler uden motor ikke er konstrueret til at modst\u00e5 de ekstra kr\u00e6fter, som motors\u00e6t ud\u00f8ver. Eftermontering kan fungere. Det vil vi aldrig love \u2013 og vi kan ikke garantere sikkerheden eller opretholde garantier, hvis der opst\u00e5r problemer.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Kvalitet beskytter milj\u00f8et \u2013 K\u00f8b en cykel for livet<\/h3>\n\n\n\n<p>Vores cykler er designet til lang levetid, lav vedligeholdelse og ressourceeffektivitet. Vi forbedrer l\u00f8bende materialer og produktionsprocesser for at s\u00e6tte h\u00f8jere milj\u00f8standarder \u2013 og vi kr\u00e6ver det samme engagement fra vores leverand\u00f8rer.<\/p>\n\n\n\n<p>Et synligt resultat er vores genanvendelige cykelkasser af pap, der kan genvindes fuldt ud. Det mest virkningsfulde greb er dog cyklen selv: Jo l\u00e6ngere du k\u00f8rer p\u00e5 den, jo mindre bliver dit og vores fodaftryk p\u00e5 milj\u00f8et. Derfor er vores cykler bygget til at holde og forblive kompatible med reservedele i mange \u00e5r fremover.<\/p>\n\n\n\n<p>Med en Diamant-cykel v\u00e6lger du kvalitet og et produkt, der er designet til at give gl\u00e6de selv efter mange \u00e5rs brug.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Hvorfor kalder du det ikke bare cykel?<\/h3>\n\n\n\n<p>Afh\u00e6ngigt af hvilket land du kommer fra, kalder nogle det en biocykel, andre en &#8220;klassisk cykel&#8221;, andre igen en &#8220;akustisk cykel&#8221;, og mange kalder den ganske enkelt en cykel. Og de har ret \u2013 n\u00e5r folk h\u00f8rer ordet &#8220;cykel&#8221;, forestiller de sig ofte en cykel uden motor. Men en elcykel er jo ogs\u00e5 en cykel. Med motor.<\/p>\n\n\n\n<p>Men er det ikke m\u00e6rkeligt at definere det oprindelige koncept for en cykel ud fra det, den mangler? B\u00f8r vi ikke fokusere p\u00e5, hvad den er <em>er<\/em>? Det er her, udtryk som biobike kommer fra, som fremh\u00e6ver dens 100 % menneskedrevne natur. Men selv en pedelec er afh\u00e6ngig af menneskelig indsats for at fungere.<\/p>\n\n\n\n<p>Generelt kalder vi alle cykler for cykler \u2013 uanset om de har motor eller ej. Men denne side skal give dig en intuitiv forst\u00e5else af, hvilke cykler du finder her. Selvom &#8220;cykel uden motor&#8221; ikke er ideelt, er det universelt forst\u00e5eligt. Kald det, hvad du vil \u2013 vi hj\u00e6lper dig med at finde den perfekte motorfri, muskelkraftdrevne akustiske biobike.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong><strong><strong><strong>Din perfekte cykel \u2013 Genfind din bev\u00e6gelse<\/strong><\/strong><\/strong><\/strong><\/h3>\n\n\n\n<p>En cykel uden motor er ren gl\u00e6de og bev\u00e6gelsesfrihed. Med gennemt\u00e6nkt design og f\u00f8rsteklasses materialer beriger vores cykler din hverdag og g\u00f8r dig klar til ethvert eventyr.<\/p>\n\n\n\n<p>Find din perfekte cykel i dag og oplev den lydl\u00f8se, motorfri cykeltur med en Diamant-cykel!<\/p>\n\n<\/div>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n<\/div><\/div>\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":3,"featured_media":66704,"parent":65912,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"slim_seo":{"title":"Cykler uden motor fra Diamant","description":"Oplev motorcyklerne til trekking, sport og byliv \u2013 for m\u00e6nd og kvinder."},"footnotes":""},"class_list":["post-66702","page","type-page","status-publish","has-post-thumbnail","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.diamantrad.com\/en-GB\/wp-json\/wp\/v2\/pages\/66702","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.diamantrad.com\/en-GB\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.diamantrad.com\/en-GB\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.diamantrad.com\/en-GB\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.diamantrad.com\/en-GB\/wp-json\/wp\/v2\/comments?post=66702"}],"version-history":[{"count":3,"href":"https:\/\/www.diamantrad.com\/en-GB\/wp-json\/wp\/v2\/pages\/66702\/revisions"}],"predecessor-version":[{"id":74877,"href":"https:\/\/www.diamantrad.com\/en-GB\/wp-json\/wp\/v2\/pages\/66702\/revisions\/74877"}],"up":[{"embeddable":true,"href":"https:\/\/www.diamantrad.com\/en-GB\/wp-json\/wp\/v2\/pages\/65912"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.diamantrad.com\/en-GB\/wp-json\/wp\/v2\/media\/66704"}],"wp:attachment":[{"href":"https:\/\/www.diamantrad.com\/en-GB\/wp-json\/wp\/v2\/media?parent=66702"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}