{"product_id":"druckvorlage-bigledup","title":"Druckvorlage BigLedup","description":"{% assign vis24_system_name = 'BIG LEDUP' %}\n{% assign vis24_order_url = '' %}\n\n\u003cdiv class=\"vis24-big-ledup-pdf\" data-vis24-big-ledup-pdf data-system=\"{{ vis24_system_name | escape }}\" data-order-url=\"{{ vis24_order_url | escape }}\"\u003e\n  \u003cdetails class=\"cc-accordion-item\"\u003e\n    \u003csummary class=\"cc-accordion-item__title\"\u003e\n      \u003ch3\u003ePDF-Druckvorlage für {{ vis24_system_name | escape }} erstellen\u003c\/h3\u003e\n    \u003c\/summary\u003e\n\n    \u003cdiv class=\"cc-accordion-item__panel\"\u003e\n      \u003cp\u003e\n        Für rechteckige Textilgrafiken von BIG LEDUP Stele, BIG LEDUP und REAL BIG LEDUP.\n        Für Sonderteile bitte die Herstellervorlagen für\n        \u003ca href=\"https:\/\/www.best-systems.com\/assets\/bigledupbridgecutting-templatedeen2026-10.pdf\"\u003eBRIDGE\u003c\/a\u003e\n        und\n        \u003ca href=\"https:\/\/www.best-systems.com\/assets\/bigledupdoorcutting-templatedeen2026-10.pdf\"\u003eDOOR\u003c\/a\u003e\n        verwenden.\n      \u003c\/p\u003e\n\n      \u003cdiv class=\"vis24-big-ledup-pdf__box\"\u003e\n        \u003cdiv class=\"vis24-big-ledup-pdf__fields\"\u003e\n          \u003clabel\u003e\n            Aufbau\n            \u003cselect data-layout\u003e\n              \u003coption value=\"single\"\u003eEinzelner Rahmen\u003c\/option\u003e\n              \u003coption value=\"row\"\u003eMehrere Rahmen nebeneinander\u003c\/option\u003e\n            \u003c\/select\u003e\n          \u003c\/label\u003e\n\n          \u003clabel data-count-field hidden\u003e\n            Anzahl Rahmen\n            \u003cselect data-count\u003e\u003c\/select\u003e\n          \u003c\/label\u003e\n\n          \u003clabel\u003e\n            Maßstab\n            \u003cselect data-scale\u003e\n              \u003coption value=\"1\"\u003e1:1 – Originalgröße\u003c\/option\u003e\n              \u003coption value=\"2\"\u003e1:2\u003c\/option\u003e\n              \u003coption value=\"10\" selected\u003e1:10\u003c\/option\u003e\n            \u003c\/select\u003e\n          \u003c\/label\u003e\n        \u003c\/div\u003e\n\n        \u003cdiv data-frames\u003e\u003c\/div\u003e\n\n        \u003cfigure class=\"vis24-big-ledup-pdf__preview\" data-preview hidden\u003e\n          \u003cfigcaption\u003e\u003cstrong\u003eVorschau von vorne\u003c\/strong\u003e\u003c\/figcaption\u003e\n          \u003cdiv class=\"vis24-big-ledup-pdf__drawing\" data-drawing aria-hidden=\"true\"\u003e\u003c\/div\u003e\n          \u003cp class=\"vis24-big-ledup-pdf__note\"\u003e\n            Die Rahmen stehen unten bündig. Mit den Pfeiltasten unter den\n            Rahmenmaßen ändern Sie die Reihenfolge von links nach rechts.\n          \u003c\/p\u003e\n        \u003c\/figure\u003e\n\n        \u003cp class=\"vis24-big-ledup-pdf__format\" data-format aria-live=\"polite\"\u003e\u003c\/p\u003e\n\n        \u003cdiv data-table hidden\u003e\n          \u003ctable aria-label=\"Produktionsmaße je Rahmen im Originalformat\"\u003e\n            \u003cthead\u003e\n              \u003ctr\u003e\n                \u003cth scope=\"col\"\u003eNr.\u003c\/th\u003e\n                \u003cth scope=\"col\"\u003eEndformat\u003c\/th\u003e\n                \u003cth scope=\"col\"\u003eMit Beschnitt\u003c\/th\u003e\n                \u003cth scope=\"col\"\u003eSicherheits\u003cwbr\u003ebereich\u003c\/wbr\u003e\n\u003c\/th\u003e\n              \u003c\/tr\u003e\n            \u003c\/thead\u003e\n            \u003ctbody data-sizes\u003e\u003c\/tbody\u003e\n          \u003c\/table\u003e\n        \u003c\/div\u003e\n\n        \u003cp class=\"vis24-big-ledup-pdf__note\" data-status\u003e\u003c\/p\u003e\n        \u003cp class=\"vis24-big-ledup-pdf__note\" data-announcement aria-live=\"polite\"\u003e\u003c\/p\u003e\n        \u003cp class=\"vis24-big-ledup-pdf__error\" data-warning aria-live=\"polite\" hidden\u003e\u003c\/p\u003e\n        \u003cp class=\"vis24-big-ledup-pdf__error\" data-error role=\"alert\" hidden\u003e\u003c\/p\u003e\n\n        \u003cbutton class=\"vis24-big-ledup-pdf__download\" type=\"button\" data-download disabled\u003e\n          PDF-Druckvorlagen herunterladen\n        \u003c\/button\u003e\n\n        \u003cp class=\"vis24-big-ledup-pdf__note\"\u003e\n          Entfernen Sie die Hilfslinien und Beschriftungen vor dem Export Ihrer Druckdateien.\n        \u003c\/p\u003e\n\n        {% if vis24_order_url != blank %}\n          \u003cdiv class=\"vis24-big-ledup-pdf__order\"\u003e\n            \u003cbutton class=\"vis24-big-ledup-pdf__download\" type=\"button\" data-order disabled\u003e\n              Ersatzdrucke für diese Rahmen bestellen\n            \u003c\/button\u003e\n            \u003col data-order-links hidden\u003e\u003c\/ol\u003e\n          \u003c\/div\u003e\n        {% endif %}\n      \u003c\/div\u003e\n    \u003c\/div\u003e\n  \u003c\/details\u003e\n\u003c\/div\u003e\n\n\u003cstyle\u003e\n  .vis24-big-ledup-pdf {\n    margin: 20px 0;\n    min-width: 0;\n  }\n\n  .vis24-big-ledup-pdf [hidden] {\n    display: none !important;\n  }\n\n  .vis24-big-ledup-pdf summary {\n    padding: .75rem 0;\n    cursor: pointer;\n  }\n\n  .vis24-big-ledup-pdf h3 {\n    margin: 0;\n    font-size: 1.25rem;\n  }\n\n  .vis24-big-ledup-pdf__box {\n    min-width: 0;\n    padding: clamp(10px, 3vw, 18px);\n    border: 1px solid #ddd;\n    border-radius: 12px;\n    background: #eee;\n    color: #222;\n  }\n\n  .vis24-big-ledup-pdf__fields,\n  .vis24-big-ledup-pdf__dimensions {\n    display: grid;\n    gap: 12px;\n  }\n\n  .vis24-big-ledup-pdf__fields {\n    grid-template-columns: repeat(auto-fit, minmax(min(100%, 150px), 1fr));\n    margin-bottom: 14px;\n  }\n\n  .vis24-big-ledup-pdf__dimensions {\n    grid-template-columns: repeat(2, minmax(0, 1fr));\n  }\n\n  .vis24-big-ledup-pdf__frame {\n    min-width: 0;\n    margin: 0 0 14px;\n    padding: 0;\n    border: 0;\n  }\n\n  .vis24-big-ledup-pdf__frame legend {\n    margin-bottom: 5px;\n    padding: 0;\n    font-weight: 700;\n  }\n\n  .vis24-big-ledup-pdf label {\n    min-width: 0;\n    font-weight: 600;\n  }\n\n  .vis24-big-ledup-pdf select,\n  .vis24-big-ledup-pdf input {\n    box-sizing: border-box;\n    display: block;\n    width: 100%;\n    min-width: 0;\n    min-height: 44px;\n    margin-top: 5px;\n    padding: 10px;\n    border: 1px solid #ccc;\n    border-radius: 8px;\n    background: #fff;\n    color: #222;\n    font-size: 16px;\n  }\n\n  .vis24-big-ledup-pdf__move {\n    display: flex;\n    flex-wrap: wrap;\n    gap: 8px;\n    margin-top: 8px;\n  }\n\n  .vis24-big-ledup-pdf__move button {\n    min-height: 44px;\n    padding: 7px 12px;\n    border: 1px solid #999;\n    border-radius: 8px;\n    background: #fff;\n    color: #222;\n    cursor: pointer;\n  }\n\n  .vis24-big-ledup-pdf__preview {\n    margin: 18px 0;\n    padding: 14px;\n    border: 1px solid #ccc;\n    border-radius: 8px;\n    background: #fff;\n  }\n\n  .vis24-big-ledup-pdf__drawing {\n    position: relative;\n    margin: 12px auto 0;\n    box-shadow: 0 2px #24487b;\n  }\n\n  .vis24-big-ledup-pdf__panel {\n    position: absolute;\n    bottom: 0;\n    box-sizing: border-box;\n    display: grid;\n    place-items: center;\n    overflow: hidden;\n    border: 1px solid #24487b;\n    background: #dbe8fb;\n    color: #173763;\n    font-size: clamp(9px, 2vw, 14px);\n    font-weight: 700;\n  }\n\n  .vis24-big-ledup-pdf__panel:nth-child(even) {\n    background: #edf3fc;\n  }\n\n  .vis24-big-ledup-pdf__format,\n  .vis24-big-ledup-pdf__error {\n    color: #b00020;\n    font-weight: 700;\n  }\n\n  .vis24-big-ledup-pdf__format {\n    margin: 16px 0 10px;\n    font-size: 22px;\n  }\n\n  .vis24-big-ledup-pdf__error {\n    margin: 12px 0;\n    font-size: 17px;\n  }\n\n  .vis24-big-ledup-pdf table {\n    width: 100%;\n    max-width: 100%;\n    min-width: 0;\n    margin: 0;\n    table-layout: fixed;\n    border-collapse: collapse;\n    font-size: clamp(12px, 2vw, 14px);\n  }\n\n  .vis24-big-ledup-pdf th,\n  .vis24-big-ledup-pdf td {\n    padding: 6px 4px;\n    border-bottom: 1px solid #d2d2d2;\n    text-align: left;\n    vertical-align: top;\n    white-space: normal;\n    overflow-wrap: anywhere;\n  }\n\n  .vis24-big-ledup-pdf thead th:first-child {\n    width: 12%;\n  }\n\n  .vis24-big-ledup-pdf__note {\n    margin: 12px 0;\n    color: #555;\n    font-size: 14px;\n  }\n\n  .vis24-big-ledup-pdf [data-announcement]:empty,\n  .vis24-big-ledup-pdf [data-status]:empty {\n    margin: 0;\n  }\n\n  .vis24-big-ledup-pdf__download {\n    box-sizing: border-box;\n    width: 100%;\n    padding: 13px 20px;\n    border: 1px solid transparent;\n    border-radius: 999px;\n    background: linear-gradient(90deg, #ff5a00, #e6007e);\n    color: #fff;\n    font-weight: 700;\n    cursor: pointer;\n  }\n\n  .vis24-big-ledup-pdf button:disabled {\n    opacity: .55;\n    cursor: not-allowed;\n  }\n\n  .vis24-big-ledup-pdf__order {\n    margin-top: 16px;\n  }\n\n  .vis24-big-ledup-pdf__order a {\n    color: #a0001c;\n    text-decoration: underline;\n  }\n\u003c\/style\u003e\n\n\u003cscript\u003e\n(function () {\n  \"use strict\";\n\n  const BLEED = 20;\n  const SAFETY = 20;\n  const WIDTHS = [\n    880, 1000, 1300, 1400, 1500, 1750, 1850, 2000, 2350, 2500, 2600, 2700,\n    2750, 2850, 3000, 3100, 3200, 3250, 3300, 3350, 3450, 3500, 3550, 3600,\n    3700, 3750, 3850, 4000, 4050, 4100, 4200, 4250, 4300, 4350, 4400, 4450,\n    4500, 4550, 4600, 4700, 4750, 4850, 4950, 5000, 5500, 5750, 5850, 6000,\n    6250, 6350, 6500, 6600, 6700, 6750, 6850, 7000, 7100, 7200, 7250, 7350,\n    7450, 7500, 7550, 7600, 7700, 7750, 7850, 7950, 8000, 8050, 8100, 8200,\n    8300, 8350, 8400, 8450, 8500, 8550, 8600, 8700, 8750, 8850, 8950, 9000,\n    9050, 9100, 9200, 9250, 9300, 9350, 9550, 9600, 9700, 9750, 9850, 10000\n  ];\n  const HEIGHTS = [2000, 2300, 2480, 2980];\n  const MAX_PDF_SIDE = 5080;\n  const SCALES = [1, 2, 10];\n  const POINTS_PER_MM = 72 \/ 25.4;\n  const number = new Intl.NumberFormat(\"de-DE\", {\n    maximumFractionDigits: 1,\n    useGrouping: false\n  });\n\n  function size(width, height) {\n    return number.format(width) + \" × \" + number.format(height) + \" mm\";\n  }\n\n  function show(element, message) {\n    element.textContent = message;\n    element.hidden = !message;\n  }\n\n  function boundsOf(frames) {\n    return {\n      width: frames.reduce((sum, frame) =\u003e sum + frame.width, 0),\n      height: Math.max(...frames.map(frame =\u003e frame.height))\n    };\n  }\n\n  function fitsPdf(bounds, scale) {\n    return (Math.max(bounds.width, bounds.height) + 2 * BLEED) \/ scale \u003c= MAX_PDF_SIDE;\n  }\n\n  function hasHeightPeak(frames) {\n    return frames.some((frame, index) =\u003e\n      index \u003e 0 \u0026\u0026 index \u003c frames.length - 1 \u0026\u0026\n      frame.height \u003e frames[index - 1].height \u0026\u0026\n      frame.height \u003e frames[index + 1].height\n    );\n  }\n\n  function loadPdfLib() {\n    if (window.PDFLib) return Promise.resolve(window.PDFLib);\n\n    if (!window.vis24BigLedupPdfLibrary) {\n      window.vis24BigLedupPdfLibrary = new Promise((resolve, reject) =\u003e {\n        const script = document.createElement(\"script\");\n        script.src = \"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/pdf-lib\/1.17.1\/pdf-lib.min.js\";\n        script.onload = () =\u003e window.PDFLib ? resolve(window.PDFLib) : reject();\n        script.onerror = () =\u003e {\n          script.remove();\n          reject();\n        };\n        document.head.appendChild(script);\n      }).catch(() =\u003e {\n        window.vis24BigLedupPdfLibrary = null;\n        throw new Error(\"Die PDF-Bibliothek konnte nicht geladen werden. Bitte versuchen Sie es erneut.\");\n      });\n    }\n\n    return window.vis24BigLedupPdfLibrary;\n  }\n\n  function drawCentered(page, font, text, sizePt, x, y, maxWidth, color) {\n    const width = font.widthOfTextAtSize(text, sizePt);\n    const fitted = sizePt * Math.min(1, maxWidth \/ width);\n\n    page.drawText(text, {\n      x: x - font.widthOfTextAtSize(text, fitted) \/ 2,\n      y,\n      size: fitted,\n      font,\n      color\n    });\n  }\n\n  function addOverview(pdf, font, config, system, colors) {\n    const page = pdf.addPage([842, 595]);\n    const { width, height } = config.bounds;\n    const diagramScale = Math.min(746 \/ width, 245 \/ height);\n    const baseline = 170;\n    let left = (842 - width * diagramScale) \/ 2;\n\n    const lines = [\n      [system + \" - Übersicht der Rahmen\", 24, 540],\n      [\"Gesamtbreite × maximale Höhe: \" + size(width, height), 14, 510],\n      [\"Vorderansicht von links nach rechts. Rahmen unten bündig.\", 11, 486],\n      [\"Einzelvorlagen im Maßstab 1:\" + config.scale + \".\", 11, 465],\n      [\"Jeder Rahmen erhält umlaufend 20 mm Beschnitt im Originalformat.\", 11, 125],\n      [\"An Rahmenstößen das Motiv in den Beschnitt der Einzelvorlage weiterführen.\", 11, 105]\n    ];\n\n    lines.forEach(([text, fontSize, y]) =\u003e\n      drawCentered(page, font, text, fontSize, 421, y, 746, colors.text)\n    );\n\n    config.frames.forEach((frame, index) =\u003e {\n      const w = frame.width * diagramScale;\n      const h = frame.height * diagramScale;\n\n      page.drawRectangle({\n        x: left,\n        y: baseline,\n        width: w,\n        height: h,\n        color: colors.fill,\n        borderColor: colors.blue,\n        borderWidth: 1\n      });\n\n      drawCentered(page, font, \"Rahmen \" + (index + 1), Math.min(13, h \/ 5),\n        left + w \/ 2, baseline + h * .53, w * .88, colors.text);\n      drawCentered(page, font, size(frame.width, frame.height), Math.min(11, h \/ 6),\n        left + w \/ 2, baseline + h * .3, w * .88, colors.text);\n\n      left += w;\n    });\n  }\n\n  function addTemplate(pdf, font, frames, scale, title, colors) {\n    const { width, height } = boundsOf(frames);\n    const points = POINTS_PER_MM \/ scale;\n    const bleed = BLEED * points;\n    const safety = SAFETY * points;\n    const pageWidth = (width + 2 * BLEED) * points;\n    const pageHeight = (height + 2 * BLEED) * points;\n    const line = 1.2 * points;\n    const page = pdf.addPage([pageWidth, pageHeight]);\n    const combined = frames.length \u003e 1;\n\n    page.setBleedBox(0, 0, pageWidth, pageHeight);\n    page.setTrimBox(bleed, bleed, width * points, height * points);\n\n    page.drawRectangle({\n      x: line \/ 2,\n      y: line \/ 2,\n      width: pageWidth - line,\n      height: pageHeight - line,\n      borderColor: colors.red,\n      borderWidth: line\n    });\n\n    const firstWidth = frames[0].width * points;\n    const firstHeight = frames[0].height * points;\n    const titleSize = Math.min(firstWidth, firstHeight) * .065;\n    const detailSize = titleSize * .55;\n    const gap = titleSize * 1.25;\n    let left = bleed;\n\n    frames.forEach((frame, index) =\u003e {\n      const w = frame.width * points;\n      const h = frame.height * points;\n\n      page.drawRectangle({\n        x: left,\n        y: bleed,\n        width: w,\n        height: h,\n        borderColor: colors.blue,\n        borderWidth: line\n      });\n\n      page.drawRectangle({\n        x: left + safety,\n        y: bleed + safety,\n        width: w - 2 * safety,\n        height: h - 2 * safety,\n        borderColor: colors.green,\n        borderWidth: line\n      });\n\n      if (combined) {\n        const labelSize = Math.min(titleSize, h * .08);\n        drawCentered(page, font, \"Rahmen \" + (index + 1), labelSize,\n          left + w \/ 2, bleed + h * .35, w * .85, colors.text);\n        drawCentered(page, font, size(frame.width, frame.height), labelSize * .55,\n          left + w \/ 2, bleed + h * .35 - labelSize * 1.25, w * .85, colors.text);\n      }\n\n      left += w;\n    });\n\n    let join = bleed;\n    frames.slice(0, -1).forEach((frame, index) =\u003e {\n      join += frame.width * points;\n\n      page.drawLine({\n        start: { x: join, y: bleed },\n        end: {\n          x: join,\n          y: bleed + Math.min(frame.height, frames[index + 1].height) * points\n        },\n        thickness: line * 1.5,\n        dashArray: [5.5 * points, 3.5 * points],\n        color: colors.split\n      });\n    });\n\n    const labels = [\n      [title, titleSize, colors.text],\n      [\"Maßstab 1:\" + scale + \" | Maße im Originalformat\", detailSize, colors.text],\n      [combined ? \"BLAU - Sichtfläche je Rahmen\" :\n        \"BLAU - Endformat: \" + size(width, height), detailSize, colors.blue],\n      [\"ROT - Dateiformat inkl. Beschnitt: \" +\n        size(width + 2 * BLEED, height + 2 * BLEED), detailSize, colors.red],\n      [combined ? \"GRÜN - Sicherheitsbereich je Rahmen\" :\n        \"GRÜN - Sicherheitsbereich: \" +\n        size(width - 2 * SAFETY, height - 2 * SAFETY), detailSize, colors.green]\n    ];\n\n    if (combined) {\n      labels.push([\"VIOLETT GESTRICHELT - Rahmenstoß\", detailSize, colors.split]);\n    }\n\n    const headingY = combined ? bleed + firstHeight * .85 : pageHeight \/ 2 + 2 * gap;\n\n    labels.forEach(([text, fontSize, color], index) =\u003e {\n      drawCentered(page, font, text, fontSize, bleed + firstWidth \/ 2,\n        headingY - index * gap, (firstWidth - 2 * safety) * .88, color);\n    });\n  }\n\n  function savePdf(bytes, filename) {\n    const url = URL.createObjectURL(new Blob([bytes], { type: \"application\/pdf\" }));\n    const link = document.createElement(\"a\");\n\n    link.href = url;\n    link.download = filename;\n    document.body.appendChild(link);\n    link.click();\n    link.remove();\n\n    window.setTimeout(() =\u003e URL.revokeObjectURL(url), 30000);\n  }\n\n  function init(root) {\n    if (root.dataset.initialized) return;\n    root.dataset.initialized = \"true\";\n\n    const find = selector =\u003e root.querySelector(selector);\n    const system = root.dataset.system || \"Textildisplay\";\n    \/\/ Helvetica in pdf-lib verwendet WinAnsi.\n    const pdfSystem = system.replace(\/[–—]\/g, \"-\").replace(\/[^\\u0020-\\u007e\\u00a0-\\u00ff]\/g, \"\");\n    const layout = find(\"[data-layout]\");\n    const count = find(\"[data-count]\");\n    const scale = find(\"[data-scale]\");\n    const framesBox = find(\"[data-frames]\");\n    const preview = find(\"[data-preview]\");\n    const drawing = find(\"[data-drawing]\");\n    const table = find(\"[data-table]\");\n    const sizes = find(\"[data-sizes]\");\n    const status = find(\"[data-status]\");\n    const warning = find(\"[data-warning]\");\n    const error = find(\"[data-error]\");\n    const download = find(\"[data-download]\");\n    const announcement = find(\"[data-announcement]\");\n    const order = find(\"[data-order]\");\n    const orderLinks = find(\"[data-order-links]\");\n    const frames = [{ width: 2000, height: 2480 }];\n    let generating = false;\n\n    for (let quantity = 2; quantity \u003c= 12; quantity += 1) {\n      count.add(new Option(String(quantity), String(quantity)));\n    }\n\n    function readConfig() {\n      const multiple = layout.value === \"row\";\n      const quantity = multiple ? Number(count.value) : 1;\n      const activeFrames = frames.slice(0, quantity).map(frame =\u003e ({\n        width: frame.width,\n        height: frame.height\n      }));\n      const valid = activeFrames.every(frame =\u003e\n        WIDTHS.includes(frame.width) \u0026\u0026 HEIGHTS.includes(frame.height)\n      );\n      const selectedScale = Number(scale.value);\n      const bounds = valid ? boundsOf(activeFrames) : null;\n\n      return {\n        frames: activeFrames,\n        multiple,\n        valid,\n        bounds,\n        scale: selectedScale,\n        peak: valid \u0026\u0026 hasHeightPeak(activeFrames),\n        totalFits: valid \u0026\u0026 fitsPdf(bounds, selectedScale),\n        individualFits: valid \u0026\u0026 activeFrames.every(frame =\u003e fitsPdf(frame, selectedScale))\n      };\n    }\n\n    function makeField(labelText, key, options, value) {\n      const label = document.createElement(\"label\");\n      const field = document.createElement(\"select\");\n\n      label.textContent = labelText;\n      field.dataset[key] = \"\";\n      options.forEach(option =\u003e field.add(new Option(String(option), String(option))));\n      field.value = String(value);\n      label.appendChild(field);\n\n      return label;\n    }\n\n    function makeMoveButton(index, direction, disabled) {\n      const button = document.createElement(\"button\");\n      const left = direction \u003c 0;\n\n      button.type = \"button\";\n      button.textContent = left ? \"← Nach links\" : \"Nach rechts →\";\n      button.dataset.move = String(direction);\n      button.setAttribute(\"aria-label\", \"Rahmen \" + (index + 1) +\n        (left ? \" nach links\" : \" nach rechts\"));\n      button.disabled = disabled;\n\n      return button;\n    }\n\n    function renderFrames() {\n      const multiple = layout.value === \"row\";\n      const quantity = multiple ? Number(count.value) : 1;\n\n      while (frames.length \u003c quantity) {\n        frames.push({ width: frames[0].width, height: frames[0].height });\n      }\n\n      find(\"[data-count-field]\").hidden = !multiple;\n      framesBox.replaceChildren();\n\n      frames.slice(0, quantity).forEach((frame, index) =\u003e {\n        const fieldset = document.createElement(\"fieldset\");\n        const legend = document.createElement(\"legend\");\n        const fields = document.createElement(\"div\");\n\n        fieldset.className = \"vis24-big-ledup-pdf__frame\";\n        fieldset.dataset.frameIndex = String(index);\n        legend.textContent = multiple ? \"Rahmen \" + (index + 1) : \"Rahmenmaße\";\n        fields.className = \"vis24-big-ledup-pdf__dimensions\";\n\n        fields.append(\n          makeField(\"Breite (mm)\", \"width\", WIDTHS, frame.width),\n          makeField(\"Höhe (mm)\", \"height\", HEIGHTS, frame.height)\n        );\n        fieldset.append(legend, fields);\n\n        if (multiple) {\n          const controls = document.createElement(\"div\");\n          controls.className = \"vis24-big-ledup-pdf__move\";\n          controls.append(\n            makeMoveButton(index, -1, index === 0),\n            makeMoveButton(index, 1, index === quantity - 1)\n          );\n          fieldset.appendChild(controls);\n        }\n\n        framesBox.appendChild(fieldset);\n      });\n    }\n\n    function renderPreview(config) {\n      preview.hidden = !config.valid || !config.multiple;\n      drawing.replaceChildren();\n      if (preview.hidden) return;\n\n      const { width, height } = config.bounds;\n      drawing.style.width = \"min(100%, \" + (240 * width \/ height) + \"px)\";\n      drawing.style.aspectRatio = width + \" \/ \" + height;\n      let left = 0;\n\n      config.frames.forEach((frame, index) =\u003e {\n        const panel = document.createElement(\"div\");\n\n        panel.className = \"vis24-big-ledup-pdf__panel\";\n        panel.style.left = (100 * left \/ width) + \"%\";\n        panel.style.width = (100 * frame.width \/ width) + \"%\";\n        panel.style.height = (100 * frame.height \/ height) + \"%\";\n        panel.textContent = String(index + 1);\n        panel.title = \"Rahmen \" + (index + 1) + \" · \" + size(frame.width, frame.height);\n\n        drawing.appendChild(panel);\n        left += frame.width;\n      });\n    }\n\n    function update() {\n      const config = readConfig();\n      const format = find(\"[data-format]\");\n\n      download.disabled = generating || !config.individualFits;\n\n      if (order) {\n        order.disabled = !config.valid;\n        orderLinks.hidden = true;\n        orderLinks.replaceChildren();\n      }\n\n      renderPreview(config);\n      table.hidden = !config.valid;\n      sizes.replaceChildren();\n      format.textContent = \"\";\n      status.textContent = \"\";\n      show(warning, \"\");\n\n      if (!config.valid) {\n        status.textContent = \"Bitte die sichtbare Breite und Höhe aller Rahmen in mm auswählen.\";\n        return;\n      }\n\n      const { width, height } = config.bounds;\n      const mixed = config.frames.some(frame =\u003e frame.height !== height);\n      format.textContent = mixed\n        ? \"Gesamtbreite \" + number.format(width) + \" mm · maximale Höhe \" + number.format(height) + \" mm\"\n        : \"Sichtfläche \" + size(width, height);\n\n      config.frames.forEach((frame, index) =\u003e {\n        const row = sizes.insertRow();\n        const heading = document.createElement(\"th\");\n\n        heading.scope = \"row\";\n        heading.textContent = String(index + 1);\n        row.appendChild(heading);\n        row.insertCell().textContent = size(frame.width, frame.height);\n        row.insertCell().textContent = size(frame.width + 2 * BLEED, frame.height + 2 * BLEED);\n        row.insertCell().textContent = size(frame.width - 2 * SAFETY, frame.height - 2 * SAFETY);\n      });\n\n      status.textContent = \"Maßstab 1:\" + config.scale +\n        \" · \" + number.format(BLEED \/ config.scale) + \" mm Beschnitt und \" +\n        number.format(SAFETY \/ config.scale) + \" mm Sicherheitsabstand je Kante in der Einzelvorlage.\";\n\n      if (!config.individualFits) {\n        const next = SCALES.find(candidate =\u003e\n          config.frames.every(frame =\u003e fitsPdf(frame, candidate))\n        );\n\n        show(warning, next\n          ? \"Mindestens eine Einzelvorlage überschreitet die PDF-Seitengröße. Bitte Maßstab 1:\" + next + \" wählen.\"\n          : \"Mindestens eine Einzelvorlage überschreitet auch bei 1:10 die PDF-Seitengröße.\");\n      } else if (config.peak) {\n        show(warning, \"Ein Rahmen ist höher als seine beiden Nachbarn. Die PDF enthält die Übersicht und die nummerierten Einzelvorlagen.\");\n      } else if (config.multiple \u0026\u0026 !config.totalFits) {\n        const next = SCALES.find(candidate =\u003e fitsPdf(config.bounds, candidate));\n\n        show(warning, \"Die Gesamtfläche passt bei diesem Maßstab nicht auf eine PDF-Seite. \" +\n          \"Die PDF enthält die Übersicht und die Einzelvorlagen.\" +\n          (next ? \" Für die Gesamtfläche wählen Sie bitte 1:\" + next + \".\" : \"\"));\n      }\n    }\n\n    download.addEventListener(\"click\", async () =\u003e {\n      const config = readConfig();\n      if (generating || !config.individualFits) return;\n\n      show(error, \"\");\n      generating = true;\n      download.disabled = true;\n\n      try {\n        const { PDFDocument, StandardFonts, rgb } = await loadPdfLib();\n        const pdf = await PDFDocument.create();\n        const font = await pdf.embedFont(StandardFonts.HelveticaBold);\n        const colors = {\n          text: rgb(.13, .13, .13),\n          red: rgb(.75, .02, .12),\n          blue: rgb(.02, .23, .75),\n          green: rgb(0, .48, .18),\n          split: rgb(.48, .12, .68),\n          fill: rgb(.92, .95, 1)\n        };\n\n        pdf.setTitle(\"VIS24 \" + system + \" - Druckvorlagen 1:\" + config.scale);\n\n        if (config.multiple) {\n          addOverview(pdf, font, config, pdfSystem, colors);\n        }\n\n        config.frames.forEach((frame, index) =\u003e {\n          addTemplate(pdf, font, [frame], config.scale,\n            pdfSystem + \" - Rahmen \" + (index + 1) + \" von \" + config.frames.length, colors);\n        });\n\n        if (config.multiple \u0026\u0026 !config.peak \u0026\u0026 config.totalFits) {\n          addTemplate(pdf, font, config.frames, config.scale, pdfSystem + \" - Gesamtfläche\", colors);\n        }\n\n        const slug = system.replace(\/[^a-zA-Z0-9]+\/g, \"-\").replace(\/^-|-$\/g, \"\") || \"Textildisplay\";\n        savePdf(await pdf.save(), \"VIS24_\" + slug + \"_Druckvorlagen_\" +\n          config.frames.length + \"-Rahmen_1zu\" + config.scale + \".pdf\");\n      } catch (exception) {\n        console.error(\"VIS24 Textildisplay PDF\", exception);\n        show(error, exception.message?.startsWith(\"Die PDF-Bibliothek\")\n          ? exception.message\n          : \"Die PDF konnte nicht erstellt werden. Bitte versuchen Sie es erneut.\");\n      } finally {\n        generating = false;\n        download.disabled = !readConfig().individualFits;\n      }\n    });\n\n    order?.addEventListener(\"click\", () =\u003e {\n      const config = readConfig();\n      if (!config.valid) return;\n\n      orderLinks.replaceChildren();\n\n      config.frames.forEach((frame, index) =\u003e {\n        const item = document.createElement(\"li\");\n        const link = document.createElement(\"a\");\n\n        link.href = root.dataset.orderUrl;\n        link.textContent = \"Rahmen \" + (index + 1) + \" · \" + size(frame.width, frame.height) +\n          \" – Ersatzdruck öffnen\";\n        item.appendChild(link);\n        orderLinks.appendChild(item);\n      });\n\n      orderLinks.hidden = false;\n    });\n\n    framesBox.addEventListener(\"change\", event =\u003e {\n      const field = event.target;\n      if (!field.matches(\"[data-width], [data-height]\")) return;\n\n      const index = Number(field.closest(\"[data-frame-index]\").dataset.frameIndex);\n      const key = field.matches(\"[data-width]\") ? \"width\" : \"height\";\n\n      frames[index][key] = Number(field.value);\n      announcement.textContent = \"\";\n      show(error, \"\");\n      update();\n    });\n\n    root.addEventListener(\"change\", event =\u003e {\n      if (event.target === layout || event.target === count) {\n        renderFrames();\n      } else if (event.target !== scale) {\n        return;\n      }\n\n      announcement.textContent = \"\";\n      show(error, \"\");\n      update();\n    });\n\n    framesBox.addEventListener(\"click\", event =\u003e {\n      const button = event.target.closest(\"[data-move]\");\n      if (!button || button.disabled) return;\n\n      const index = Number(button.closest(\"[data-frame-index]\").dataset.frameIndex);\n      const target = index + Number(button.dataset.move);\n      [frames[index], frames[target]] = [frames[target], frames[index]];\n\n      renderFrames();\n      show(error, \"\");\n      update();\n\n      announcement.textContent = \"Rahmen steht jetzt an Position \" + (target + 1) + \".\";\n      const row = framesBox.querySelector('[data-frame-index=\"' + target + '\"]');\n      const same = row.querySelector('[data-move=\"' + button.dataset.move + '\"]');\n      (same.disabled ? row.querySelector(\"[data-move]:not(:disabled)\") : same)?.focus();\n    });\n\n    renderFrames();\n    update();\n  }\n\n  const selector = \"[data-vis24-big-ledup-pdf]\";\n  document.querySelectorAll(selector).forEach(init);\n\n  if (!window.vis24BigLedupPdfSectionHandler) {\n    window.vis24BigLedupPdfSectionHandler = true;\n    document.addEventListener(\"shopify:section:load\", event =\u003e {\n      event.target.querySelectorAll(selector).forEach(init);\n    });\n  }\n})();\n\u003c\/script\u003e","brand":"VIS24","offers":[{"title":"Default Title","offer_id":57565292593417,"sku":null,"price":0.0,"currency_code":"EUR","in_stock":false}],"url":"https:\/\/vis24.de\/products\/druckvorlage-bigledup","provider":"VIS24","version":"1.0","type":"link"}