{"id":10231,"date":"2026-08-15T00:05:26","date_gmt":"2026-08-14T22:05:26","guid":{"rendered":"https:\/\/www.lukaswojcik.com\/blog\/narzedzia\/tcf-consent-string-decoder\/"},"modified":"2026-08-15T00:05:26","modified_gmt":"2026-08-14T22:05:26","slug":"tcf-consent-string-decoder","status":"publish","type":"page","link":"https:\/\/www.lukaswojcik.com\/blog\/pl\/narzedzia\/tcf-consent-string-decoder\/","title":{"rendered":"Dekoder ci\u0105g\u00f3w zgody TCF v2.2"},"content":{"rendered":"<div class=\"gtm-analyser-container\" style=\"background: var(--bg-panel, #1e1e24); padding: 25px; border-radius: 8px; border: 1px solid var(--border, #2a2a35);\">\n<p style=\"color: var(--text-secondary, #a0a0b0); margin-bottom: 20px;\">Ci\u0105g TC z pliku cookie euconsent-v2 albo z odpowiedzi __tcfapi zostaje tu odczytany bit po bicie w przegl\u0105darce. Nic nie opuszcza strony.<\/p>\n<p>    <label for=\"tcf-eingabe\" style=\"color: var(--text-secondary, #a0a0b0); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Ci\u0105g TC<\/label><br \/>\n    <textarea id=\"tcf-eingabe\" class=\"form-control\" style=\"width: 100%; height: 110px; padding: 12px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; font-family: monospace; font-size: 0.85rem; box-sizing: border-box;\" placeholder=\"CQVLVAAQ...\"><\/textarea><\/p>\n<p>    <label for=\"tcf-gvl\" style=\"color: var(--text-secondary, #a0a0b0); display: block; font-size: 0.85rem; margin: 15px 0 5px;\">Global Vendor List w formacie JSON (opcjonalnie, dla nazw dostawc\u00f3w)<\/label><br \/>\n    <textarea id=\"tcf-gvl\" class=\"form-control\" style=\"width: 100%; height: 70px; padding: 12px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; font-family: monospace; font-size: 0.8rem; box-sizing: border-box;\" placeholder=\"Zawarto\u015b\u0107 vendor-list.json - bez niej widoczne s\u0105 wy\u0142\u0105cznie numery dostawc\u00f3w\"><\/textarea><\/p>\n<div style=\"display: flex; gap: 10px; flex-wrap: wrap; margin: 18px 0 0;\">\n        <button id=\"tcf-btn\" class=\"button\" style=\"background: var(--accent, #7ee787); color: #0b1114; border: none; padding: 12px 24px; border-radius: 6px; font-weight: 700; cursor: pointer;\">Dekoduj<\/button><br \/>\n        <button id=\"tcf-beispiel\" class=\"button\" type=\"button\" style=\"background: transparent; color: var(--text-primary, #e8e8ee); border: 1px solid var(--border, #2a2a35); padding: 12px 20px; border-radius: 6px; font-weight: 700; cursor: pointer;\">Wczytaj przyk\u0142ad<\/button>\n    <\/div>\n<div id=\"tcf-ergebnis\" style=\"margin-top: 22px;\"><\/div>\n<\/div>\n<p><script>\n(function () {\n    'use strict';<\/p>\n<p>    const T = {\"einleitung\":\"Ci\u0105g TC z pliku cookie euconsent-v2 albo z odpowiedzi __tcfapi zostaje tu odczytany bit po bicie w przegl\u0105darce. Nic nie opuszcza strony.\",\"label_string\":\"Ci\u0105g TC\",\"ph_string\":\"CQVLVAAQ...\",\"label_gvl\":\"Global Vendor List w formacie JSON (opcjonalnie, dla nazw dostawc\u00f3w)\",\"ph_gvl\":\"Zawarto\u015b\u0107 vendor-list.json - bez niej widoczne s\u0105 wy\u0142\u0105cznie numery dostawc\u00f3w\",\"knopf\":\"Dekoduj\",\"beispiel\":\"Wczytaj przyk\u0142ad\",\"fehler_leer\":\"Nie podano ci\u0105gu TC.\",\"fehler_zeichen\":\"Ci\u0105g zawiera znaki spoza bezpiecznego dla sieci alfabetu Base64.\",\"fehler_kurz\":\"Ci\u0105g ko\u0144czy si\u0119, zanim segment g\u0142\u00f3wny jest kompletny.\",\"fehler_version\":\"Wersja %s to nie TCF v2 - tutaj mo\u017cna odczyta\u0107 wy\u0142\u0105cznie ci\u0105gi wersji 2.\",\"h_ueberblick\":\"Nag\u0142\u00f3wek\",\"h_zwecke\":\"Cele\",\"h_merkmale\":\"Cechy szczeg\u00f3lne\",\"h_anbieter\":\"Dostawcy\",\"h_beschraenkungen\":\"Ograniczenia wydawcy\",\"h_verleger\":\"Segment wydawcy\",\"h_segmente\":\"Segmenty\",\"h_warnungen\":\"Ustalenia\",\"l_version\":\"Wersja\",\"l_erstellt\":\"Utworzono\",\"l_geaendert\":\"Ostatnia zmiana\",\"l_cmp\":\"Numer CMP\",\"l_cmpversion\":\"Wersja CMP\",\"l_bildschirm\":\"Ekran zgody\",\"l_sprache\":\"J\u0119zyk zgody\",\"l_gvl\":\"Wersja listy dostawc\u00f3w\",\"l_richtlinie\":\"Wersja polityki TCF\",\"l_dienst\":\"Specyficzne dla us\u0142ugi\",\"l_stapel\":\"Niestandardowe zestawy\",\"l_zweckeins\":\"Szczeg\u00f3lne traktowanie celu 1\",\"l_land\":\"Kraj wydawcy\",\"ja\":\"tak\",\"nein\":\"nie\",\"s_zweck\":\"Cel\",\"s_zustimmung\":\"Zgoda\",\"s_li\":\"Uzasadniony interes\",\"s_nicht_erlaubt\":\"Uzasadniony interes nie jest ju\u017c dopuszczalny dla tego celu od TCF 2.2.\",\"a_zustimmung\":\"zgoda\",\"a_li\":\"uzasadniony interes\",\"a_anzahl\":\"Ustawieni dostawcy\",\"a_max\":\"Najwy\u017cszy numer dostawcy\",\"a_kodierung\":\"Kodowanie\",\"a_bitfeld\":\"pole bitowe\",\"a_bereich\":\"zakresy\",\"a_keine\":\"W tej sekcji nie ustawiono \u017cadnego dostawcy.\",\"a_mehr\":\"oraz %s kolejnych\",\"b_zweck\":\"Cel\",\"b_keine\":\"Wydawca nie ograniczy\u0142 \u017cadnego celu.\",\"b_art0\":\"niedozwolony\",\"b_art1\":\"wymagana zgoda\",\"b_art2\":\"wymagany uzasadniony interes\",\"b_art3\":\"nieprzypisane\",\"v_zwecke\":\"Cele ze zgod\u0105\",\"v_zweckeLI\":\"Cele z uzasadnionym interesem\",\"v_eigene\":\"Cele w\u0142asne\",\"v_keine\":\"brak\",\"seg_kern\":\"Segment g\u0142\u00f3wny\",\"seg_offengelegt\":\"Ujawnieni dostawcy\",\"seg_erlaubt\":\"Dozwoleni dostawcy (usuni\u0119te w TCF 2.2)\",\"seg_verleger\":\"Dane wydawcy\",\"seg_unbekannt\":\"Nieznany segment\",\"seg_bits\":\"%s bit\u00f3w\",\"w_richtlinie\":\"Wersja polityki %s jest ni\u017csza ni\u017c 4, ci\u0105g powsta\u0142 wi\u0119c wed\u0142ug zasad sprzed TCF 2.2.\",\"w_li_verboten\":\"Dla cel\u00f3w %s ustawiono uzasadniony interes, czego TCF 2.2 ju\u017c nie dopuszcza.\",\"w_unbekannt\":\"Ustawiono bity dla cel\u00f3w %s, kt\u00f3re w TCF 2.2 nie istniej\u0105.\",\"w_reihenfolge\":\"Znacznik zmiany jest wcze\u015bniejszy ni\u017c znacznik utworzenia.\",\"w_gvl0\":\"Wersja listy dostawc\u00f3w wynosi zero, co wskazuje na ci\u0105g testowy albo wype\u0142niacz.\",\"w_alt\":\"Ostatnia zmiana mia\u0142a miejsce oko\u0142o %s miesi\u0119cy temu, czyli poza zwyczajowymi trzynastoma miesi\u0105cami.\",\"w_keine_anbieter\":\"\u017baden dostawca nie ma zgody, na tej podstawie nic nie mo\u017ce si\u0119 uruchomi\u0107.\",\"w_zweckeins\":\"Ustawiono szczeg\u00f3lne traktowanie celu 1: w tej jurysdykcji cel 1 jest regulowany poza ci\u0105giem.\",\"hinweis_namen\":\"Widoczne s\u0105 wy\u0142\u0105cznie numery dostawc\u00f3w. Nazwy pochodz\u0105 z Global Vendor List, kt\u00f3ra celowo nie jest tu pobierana, aby strona obywa\u0142a si\u0119 bez zapyta\u0144 na zewn\u0105trz.\",\"hinweis_gvl_kaputt\":\"Listy dostawc\u00f3w nie uda\u0142o si\u0119 odczyta\u0107 jako JSON, dlatego brakuje nazw.\",\"zweck1\":\"Przechowywanie informacji na urz\u0105dzeniu lub dost\u0119p do nich\",\"zweck2\":\"Wykorzystanie ograniczonych danych do wyboru reklam\",\"zweck3\":\"Tworzenie profili na potrzeby spersonalizowanych reklam\",\"zweck4\":\"Wykorzystanie profili do wyboru spersonalizowanych reklam\",\"zweck5\":\"Tworzenie profili w celu personalizacji tre\u015bci\",\"zweck6\":\"Wykorzystanie profili do wyboru spersonalizowanych tre\u015bci\",\"zweck7\":\"Pomiar skuteczno\u015bci reklam\",\"zweck8\":\"Pomiar skuteczno\u015bci tre\u015bci\",\"zweck9\":\"Poznawanie odbiorc\u00f3w na podstawie statystyk lub po\u0142\u0105czenia danych z r\u00f3\u017cnych \u017ar\u00f3de\u0142\",\"zweck10\":\"Rozwijanie i ulepszanie us\u0142ug\",\"zweck11\":\"Wykorzystanie ograniczonych danych do wyboru tre\u015bci\",\"merkmal1\":\"Wykorzystanie dok\u0142adnych danych geolokalizacyjnych\",\"merkmal2\":\"Aktywne skanowanie cech urz\u0105dzenia w celu identyfikacji\"};<\/p>\n<p>    \/\/ --- reine Entschluesselung, ohne jeden Zugriff auf das Dokument ---<\/p>\n<p>    const ZEICHEN = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';<\/p>\n<p>    \/\/ Zwecke und Sondermerkmale nach TCF 2.2. Zwecke 12 bis 24 sind im\n    \/\/ Format vorgesehen, aber nicht vergeben - gesetzte Bits dort sind ein\n    \/\/ Befund und keine Zweckangabe.\n    const ZWECKE = [\n        T.zweck1, T.zweck2, T.zweck3, T.zweck4, T.zweck5, T.zweck6,\n        T.zweck7, T.zweck8, T.zweck9, T.zweck10, T.zweck11\n    ];\n    const MERKMALE = [T.merkmal1, T.merkmal2];<\/p>\n<p>    \/\/ Berechtigtes Interesse ist seit TCF 2.2 fuer diese Zwecke nicht mehr\n    \/\/ zulaessig - ein gesetztes Bit deutet auf einen alten String oder eine\n    \/\/ fehlerhafte Erzeugung hin.\n    const LI_VERBOTEN = [1, 3, 4, 5, 6];<\/p>\n<p>    const ARTEN = [T.b_art0, T.b_art1, T.b_art2, T.b_art3];<\/p>\n<p>    function bitsAus(text) {\n        let bits = '';\n        for (let i = 0; i < text.length; i++) {\n            const wert = ZEICHEN.indexOf(text.charAt(i));\n            if (wert < 0) {\n                return null;\n            }\n            let teil = wert.toString(2);\n            while (teil.length < 6) { teil = '0' + teil; }\n            bits += teil;\n        }\n        return bits;\n    }\n\n    function leser(bits) {\n        let pos = 0;\n        return {\n            rest: function () { return bits.length - pos; },\n            stelle: function () { return pos; },\n            zahl: function (anzahl) {\n                if (pos + anzahl > bits.length) { throw new Error(T.fehler_kurz); }\n                const teil = bits.substr(pos, anzahl);\n                pos += anzahl;\n                return parseInt(teil, 2);\n            },\n            bit: function () {\n                if (pos + 1 > bits.length) { throw new Error(T.fehler_kurz); }\n                const wert = bits.charAt(pos) === '1';\n                pos += 1;\n                return wert;\n            },\n            datum: function () {\n                \/\/ 36 Bit Zehntelsekunden seit dem 1. Januar 1970.\n                if (pos + 36 > bits.length) { throw new Error(T.fehler_kurz); }\n                const teil = bits.substr(pos, 36);\n                pos += 36;\n                return parseInt(teil, 2) * 100;\n            },\n            buchstaben: function (anzahl) {\n                let text = '';\n                for (let i = 0; i < anzahl; i++) {\n                    text += String.fromCharCode(65 + this.zahl(6));\n                }\n                return text;\n            },\n            feld: function (anzahl) {\n                \/\/ Bitfeld: Bit n steht fuer die Nummer n, gezaehlt ab eins.\n                const treffer = [];\n                for (let i = 1; i <= anzahl; i++) {\n                    if (this.bit()) { treffer.push(i); }\n                }\n                return treffer;\n            }\n        };\n    }\n\n    function anbieterLesen(l) {\n        const raus = { maxId: 0, kodierung: 'bitfeld', ids: [], bereiche: [] };\n        raus.maxId = l.zahl(16);\n        const bereichKodiert = l.bit();\n        if (!bereichKodiert) {\n            raus.kodierung = 'bitfeld';\n            for (let i = 1; i <= raus.maxId; i++) {\n                if (l.bit()) { raus.ids.push(i); }\n            }\n            return raus;\n        }\n        raus.kodierung = 'bereich';\n        const anzahl = l.zahl(12);\n        for (let i = 0; i < anzahl; i++) {\n            const istBereich = l.bit();\n            const start = l.zahl(16);\n            if (istBereich) {\n                const ende = l.zahl(16);\n                raus.bereiche.push([start, ende]);\n                \/\/ Sehr grosse Bereiche nicht aufloesen, sonst waechst die\n                \/\/ Liste ins Unermessliche; die Anzeige nutzt ohnehin Bereiche.\n                if (ende - start <= 5000) {\n                    for (let v = start; v <= ende; v++) { raus.ids.push(v); }\n                }\n            } else {\n                raus.bereiche.push([start, start]);\n                raus.ids.push(start);\n            }\n        }\n        return raus;\n    }\n\n    function beschraenkungenLesen(l) {\n        const liste = [];\n        const anzahl = l.zahl(12);\n        for (let i = 0; i < anzahl; i++) {\n            const eintrag = { zweck: l.zahl(6), art: l.zahl(2), anbieter: [] };\n            const posten = l.zahl(12);\n            for (let p = 0; p < posten; p++) {\n                const istBereich = l.bit();\n                const start = l.zahl(16);\n                if (istBereich) {\n                    eintrag.anbieter.push([start, l.zahl(16)]);\n                } else {\n                    eintrag.anbieter.push([start, start]);\n                }\n            }\n            liste.push(eintrag);\n        }\n        return liste;\n    }\n\n    function kernLesen(bits) {\n        const l = leser(bits);\n        const k = {};\n        k.version = l.zahl(6);\n        if (k.version !== 2) {\n            throw new Error(T.fehler_version.replace('%s', String(k.version)));\n        }\n        k.erstellt = l.datum();\n        k.geaendert = l.datum();\n        k.cmpId = l.zahl(12);\n        k.cmpVersion = l.zahl(12);\n        k.bildschirm = l.zahl(6);\n        k.sprache = l.buchstaben(2);\n        k.gvlVersion = l.zahl(12);\n        k.richtlinie = l.zahl(6);\n        k.dienstspezifisch = l.bit();\n        k.nichtStandard = l.bit();\n        k.merkmale = l.feld(12);\n        k.zwecke = l.feld(24);\n        k.zweckeLI = l.feld(24);\n        k.zweckEins = l.bit();\n        k.land = l.buchstaben(2);\n        k.anbieter = anbieterLesen(l);\n        k.anbieterLI = anbieterLesen(l);\n        k.beschraenkungen = beschraenkungenLesen(l);\n        k.bits = bits.length;\n        return k;\n    }\n\n    function verlegerLesen(l) {\n        const v = {};\n        v.zwecke = l.feld(24);\n        v.zweckeLI = l.feld(24);\n        const anzahl = l.zahl(6);\n        v.anzahlEigene = anzahl;\n        v.eigene = anzahl > 0 ? l.feld(anzahl) : [];\n        v.eigeneLI = anzahl > 0 ? l.feld(anzahl) : [];\n        return v;\n    }<\/p>\n<p>    function warnungenSammeln(kern, segmente, jetzt) {\n        const warnungen = [];<\/p>\n<p>        if (kern.richtlinie < 4) {\n            warnungen.push(T.w_richtlinie.replace('%s', String(kern.richtlinie)));\n        }\n        const verboten = [];\n        LI_VERBOTEN.forEach(function (nummer) {\n            if (kern.zweckeLI.indexOf(nummer) !== -1) { verboten.push(nummer); }\n        });\n        if (verboten.length) {\n            warnungen.push(T.w_li_verboten.replace('%s', verboten.join(', ')));\n        }\n        const unbekannt = kern.zwecke.concat(kern.zweckeLI).filter(function (n) { return n > 11; });\n        if (unbekannt.length) {\n            warnungen.push(T.w_unbekannt.replace('%s', unbekannt.sort(function (a, b) { return a - b; }).join(', ')));\n        }\n        if (kern.geaendert < kern.erstellt) {\n            warnungen.push(T.w_reihenfolge);\n        }\n        if (kern.gvlVersion === 0) {\n            warnungen.push(T.w_gvl0);\n        }\n        \/\/ Dreizehn Monate sind die uebliche Obergrenze fuer die Gueltigkeit\n        \/\/ einer Einwilligung; darueber ist der String erneuerungsbeduerftig.\n        const dreizehnMonate = 13 * 30.5 * 24 * 60 * 60 * 1000;\n        if (jetzt &#038;&#038; kern.geaendert > 0 && (jetzt - kern.geaendert) > dreizehnMonate) {\n            warnungen.push(T.w_alt.replace('%s', String(Math.floor((jetzt - kern.geaendert) \/ (30.5 * 24 * 60 * 60 * 1000)))));\n        }\n        if (kern.anbieter.ids.length === 0 && kern.anbieter.bereiche.length === 0) {\n            warnungen.push(T.w_keine_anbieter);\n        }\n        if (kern.zweckEins) {\n            warnungen.push(T.w_zweckeins);\n        }\n        return warnungen;\n    }<\/p>\n<p>    function gvlLesen(text) {\n        if (!text || !String(text).trim()) { return null; }\n        let roh;\n        try {\n            roh = JSON.parse(text);\n        } catch (e) {\n            return { fehler: true };\n        }\n        if (!roh || typeof roh !== 'object' || !roh.vendors) { return { fehler: true }; }\n        const namen = {};\n        Object.keys(roh.vendors).forEach(function (schluessel) {\n            const eintrag = roh.vendors[schluessel];\n            if (eintrag && eintrag.name) { namen[String(eintrag.id || schluessel)] = String(eintrag.name); }\n        });\n        return { namen: namen, version: roh.vendorListVersion || 0, anzahl: Object.keys(namen).length };\n    }<\/p>\n<p>    function dekodieren(text, gvlText, jetzt) {\n        const ergebnis = { ok: false, fehler: '', kern: null, segmente: [], warnungen: [], gvl: null };<\/p>\n<p>        const roh = String(text === undefined || text === null ? '' : text).trim();\n        if (roh === '') {\n            ergebnis.fehler = T.fehler_leer;\n            return ergebnis;\n        }<\/p>\n<p>        const teile = roh.split('.');\n        const bits = bitsAus(teile[0]);\n        if (bits === null) {\n            ergebnis.fehler = T.fehler_zeichen;\n            return ergebnis;\n        }\n        if (bits.length < 213) {\n            ergebnis.fehler = T.fehler_kurz;\n            return ergebnis;\n        }\n\n        try {\n            ergebnis.kern = kernLesen(bits);\n        } catch (e) {\n            ergebnis.fehler = e &#038;&#038; e.message ? e.message : T.fehler_kurz;\n            return ergebnis;\n        }\n\n        ergebnis.segmente.push({ art: 0, name: T.seg_kern, bits: bits.length });\n\n        for (let i = 1; i < teile.length; i++) {\n            if (teile[i] === '') { continue; }\n            const sBits = bitsAus(teile[i]);\n            if (sBits === null || sBits.length < 3) {\n                ergebnis.segmente.push({ art: -1, name: T.seg_unbekannt, bits: sBits ? sBits.length : 0 });\n                continue;\n            }\n            const l = leser(sBits);\n            let art = 0;\n            try {\n                art = l.zahl(3);\n                if (art === 1 || art === 2) {\n                    ergebnis.segmente.push({\n                        art: art,\n                        name: art === 1 ? T.seg_offengelegt : T.seg_erlaubt,\n                        bits: sBits.length,\n                        anbieter: anbieterLesen(l)\n                    });\n                } else if (art === 3) {\n                    ergebnis.segmente.push({\n                        art: 3,\n                        name: T.seg_verleger,\n                        bits: sBits.length,\n                        verleger: verlegerLesen(l)\n                    });\n                } else {\n                    ergebnis.segmente.push({ art: art, name: T.seg_unbekannt, bits: sBits.length });\n                }\n            } catch (e) {\n                ergebnis.segmente.push({ art: art, name: T.seg_unbekannt, bits: sBits.length, fehler: true });\n            }\n        }\n\n        ergebnis.gvl = gvlLesen(gvlText);\n        ergebnis.warnungen = warnungenSammeln(ergebnis.kern, ergebnis.segmente, jetzt);\n        ergebnis.ok = true;\n        return ergebnis;\n    }\n\n    function bereicheKuerzen(ids) {\n        \/\/ Aus einer Nummernliste zusammenhaengende Bereiche machen, damit aus\n        \/\/ 900 Zahlen ein lesbarer Ausdruck wird.\n        const sortiert = ids.slice().sort(function (a, b) { return a - b; });\n        const raus = [];\n        let start = null;\n        let vorher = null;\n        for (let i = 0; i < sortiert.length; i++) {\n            const wert = sortiert[i];\n            if (start === null) { start = wert; vorher = wert; continue; }\n            if (wert === vorher + 1) { vorher = wert; continue; }\n            raus.push(start === vorher ? String(start) : start + '-' + vorher);\n            start = wert;\n            vorher = wert;\n        }\n        if (start !== null) {\n            raus.push(start === vorher ? String(start) : start + '-' + vorher);\n        }\n        return raus;\n    }\n\n    function datumText(ms) {\n        if (!isFinite(ms) || ms <= 0) { return '-'; }\n        const d = new Date(ms);\n        function zwei(n) { return (n < 10 ? '0' : '') + n; }\n        return d.getUTCFullYear() + '-' + zwei(d.getUTCMonth() + 1) + '-' + zwei(d.getUTCDate())\n            + ' ' + zwei(d.getUTCHours()) + ':' + zwei(d.getUTCMinutes()) + ':' + zwei(d.getUTCSeconds()) + ' UTC';\n    }\n\n    if (typeof window !== 'undefined') {\n        window.LW_TEST = window.LW_TEST || {};\n        window.LW_TEST.TCF = {\n            dekodieren: dekodieren,\n            bitsAus: bitsAus,\n            leser: leser,\n            bereicheKuerzen: bereicheKuerzen,\n            datumText: datumText\n        };\n    }\n\n    \/\/ --- Anbindung an das Dokument ---\n\n    const btn = document.getElementById('tcf-btn');\n    const out = document.getElementById('tcf-ergebnis');\n    const feld = document.getElementById('tcf-eingabe');\n    const gvlFeld = document.getElementById('tcf-gvl');\n    const beispielBtn = document.getElementById('tcf-beispiel');\n    if (!btn || !out || !feld || !gvlFeld || !beispielBtn) { return; }\n\n    const KASTEN = 'background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); border-radius: 6px; padding: 14px; margin-bottom: 18px;';\n    const UEBERSCHRIFT = 'color: var(--text-primary, #e8e8ee); font-weight: 700; margin-bottom: 8px;';\n\n    function el(tag, css, text) {\n        const knoten = document.createElement(tag);\n        if (css) { knoten.setAttribute('style', css); }\n        if (text !== undefined &#038;&#038; text !== null) { knoten.textContent = text; }\n        return knoten;\n    }\n\n    function zeile(kasten, name, wert, hervor) {\n        const z = el('div', 'display: flex; justify-content: space-between; gap: 14px; flex-wrap: wrap; padding: 5px 0;');\n        z.appendChild(el('span', 'color: var(--text-secondary, #a0a0b0);', name));\n        z.appendChild(el('span', 'color: ' + (hervor ? 'var(--accent, #7ee787)' : 'var(--text-primary, #e8e8ee)') + '; font-family: monospace; text-align: right; word-break: break-all;', wert));\n        kasten.appendChild(z);\n    }\n\n    function meldung(text) {\n        out.textContent = '';\n        out.appendChild(el('div', 'background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); border-left: 3px solid var(--accent, #7ee787); color: var(--text-secondary, #a0a0b0); padding: 14px; border-radius: 6px;', text));\n    }\n\n    function anbieterKasten(titel, anbieter, namen) {\n        const kasten = el('div', KASTEN);\n        zeile(kasten, T.a_anzahl, String(anbieter.ids.length));\n        zeile(kasten, T.a_max, String(anbieter.maxId));\n        zeile(kasten, T.a_kodierung, anbieter.kodierung === 'bereich' ? T.a_bereich : T.a_bitfeld);\n        if (anbieter.ids.length === 0) {\n            kasten.appendChild(el('div', 'color: var(--text-secondary, #a0a0b0); padding-top: 6px;', T.a_keine));\n            return kasten;\n        }\n        const kurz = bereicheKuerzen(anbieter.ids).join(', ');\n        const feldText = el('div', 'color: var(--text-primary, #e8e8ee); font-family: monospace; font-size: 0.82rem; line-height: 1.6; padding-top: 8px; word-break: break-all;', kurz);\n        kasten.appendChild(feldText);\n\n        if (namen) {\n            const liste = el('div', 'padding-top: 10px;');\n            const gezeigt = anbieter.ids.slice(0, 40);\n            gezeigt.forEach(function (id) {\n                const name = namen[String(id)];\n                liste.appendChild(el('div', 'color: var(--text-secondary, #a0a0b0); font-size: 0.85rem; padding: 2px 0;', id + '  ' + (name ? name : '?')));\n            });\n            if (anbieter.ids.length > gezeigt.length) {\n                liste.appendChild(el('div', 'color: var(--text-secondary, #a0a0b0); font-size: 0.85rem; padding-top: 4px;', T.a_mehr.replace('%s', String(anbieter.ids.length - gezeigt.length))));\n            }\n            kasten.appendChild(liste);\n        }\n        return kasten;\n    }<\/p>\n<p>    function zweckeKasten(kern) {\n        const kasten = el('div', KASTEN);\n        const kopf = el('div', 'display: flex; gap: 10px; padding: 4px 0 8px; border-bottom: 1px solid var(--border, #2a2a35); font-size: 0.8rem; color: var(--text-secondary, #a0a0b0);');\n        kopf.appendChild(el('span', 'flex: 1;', T.s_zweck));\n        kopf.appendChild(el('span', 'width: 110px; text-align: center;', T.s_zustimmung));\n        kopf.appendChild(el('span', 'width: 110px; text-align: center;', T.s_li));\n        kasten.appendChild(kopf);<\/p>\n<p>        for (let i = 1; i <= ZWECKE.length; i++) {\n            const hatZ = kern.zwecke.indexOf(i) !== -1;\n            const hatL = kern.zweckeLI.indexOf(i) !== -1;\n            const z = el('div', 'display: flex; gap: 10px; align-items: center; padding: 6px 0; border-bottom: 1px solid var(--border, #2a2a35);');\n            z.appendChild(el('span', 'flex: 1; color: var(--text-primary, #e8e8ee); font-size: 0.88rem;', i + '. ' + ZWECKE[i - 1]));\n            z.appendChild(el('span', 'width: 110px; text-align: center; font-family: monospace; color: ' + (hatZ ? 'var(--accent, #7ee787)' : 'var(--text-secondary, #a0a0b0)') + ';', hatZ ? T.ja : T.nein));\n            const liText = LI_VERBOTEN.indexOf(i) !== -1 &#038;&#038; !hatL ? '-' : (hatL ? T.ja : T.nein);\n            const liFarbe = hatL &#038;&#038; LI_VERBOTEN.indexOf(i) !== -1 ? '#ffb86c' : (hatL ? 'var(--accent, #7ee787)' : 'var(--text-secondary, #a0a0b0)');\n            const liFeld = el('span', 'width: 110px; text-align: center; font-family: monospace; color: ' + liFarbe + ';', liText);\n            if (hatL &#038;&#038; LI_VERBOTEN.indexOf(i) !== -1) { liFeld.title = T.s_nicht_erlaubt; }\n            z.appendChild(liFeld);\n            kasten.appendChild(z);\n        }\n        return kasten;\n    }\n\n    function zeigen(erg) {\n        out.textContent = '';\n        const kern = erg.kern;\n\n        if (erg.warnungen.length) {\n            out.appendChild(el('div', UEBERSCHRIFT, T.h_warnungen));\n            const kasten = el('div', 'background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); border-left: 3px solid #ffb86c; border-radius: 6px; padding: 14px; margin-bottom: 18px;');\n            erg.warnungen.forEach(function (w) {\n                kasten.appendChild(el('div', 'color: var(--text-secondary, #a0a0b0); padding: 4px 0; font-size: 0.9rem;', w));\n            });\n            out.appendChild(kasten);\n        }\n\n        out.appendChild(el('div', UEBERSCHRIFT, T.h_ueberblick));\n        const ueberblick = el('div', KASTEN);\n        zeile(ueberblick, T.l_version, String(kern.version));\n        zeile(ueberblick, T.l_erstellt, datumText(kern.erstellt));\n        zeile(ueberblick, T.l_geaendert, datumText(kern.geaendert));\n        zeile(ueberblick, T.l_cmp, String(kern.cmpId), true);\n        zeile(ueberblick, T.l_cmpversion, String(kern.cmpVersion));\n        zeile(ueberblick, T.l_bildschirm, String(kern.bildschirm));\n        zeile(ueberblick, T.l_sprache, kern.sprache);\n        zeile(ueberblick, T.l_gvl, String(kern.gvlVersion), true);\n        zeile(ueberblick, T.l_richtlinie, String(kern.richtlinie) + (kern.richtlinie >= 4 ? '  (TCF 2.2)' : ''));\n        zeile(ueberblick, T.l_land, kern.land);\n        zeile(ueberblick, T.l_dienst, kern.dienstspezifisch ? T.ja : T.nein);\n        zeile(ueberblick, T.l_stapel, kern.nichtStandard ? T.ja : T.nein);\n        zeile(ueberblick, T.l_zweckeins, kern.zweckEins ? T.ja : T.nein);\n        out.appendChild(ueberblick);<\/p>\n<p>        out.appendChild(el('div', UEBERSCHRIFT, T.h_zwecke));\n        out.appendChild(zweckeKasten(kern));<\/p>\n<p>        out.appendChild(el('div', UEBERSCHRIFT, T.h_merkmale));\n        const merkmale = el('div', KASTEN);\n        for (let i = 1; i <= MERKMALE.length; i++) {\n            zeile(merkmale, i + '. ' + MERKMALE[i - 1], kern.merkmale.indexOf(i) !== -1 ? T.ja : T.nein, kern.merkmale.indexOf(i) !== -1);\n        }\n        out.appendChild(merkmale);\n\n        const namen = erg.gvl &#038;&#038; erg.gvl.namen ? erg.gvl.namen : null;\n        out.appendChild(el('div', UEBERSCHRIFT, T.h_anbieter + ' - ' + T.a_zustimmung));\n        out.appendChild(anbieterKasten(T.a_zustimmung, kern.anbieter, namen));\n        out.appendChild(el('div', UEBERSCHRIFT, T.h_anbieter + ' - ' + T.a_li));\n        out.appendChild(anbieterKasten(T.a_li, kern.anbieterLI, namen));\n\n        if (!namen) {\n            out.appendChild(el('div', 'color: var(--text-secondary, #a0a0b0); font-size: 0.85rem; margin: -8px 0 18px;', T.hinweis_namen));\n        } else if (erg.gvl.fehler) {\n            out.appendChild(el('div', 'color: #ffb86c; font-size: 0.85rem; margin: -8px 0 18px;', T.hinweis_gvl_kaputt));\n        }\n\n        out.appendChild(el('div', UEBERSCHRIFT, T.h_beschraenkungen));\n        const beschr = el('div', KASTEN);\n        if (!kern.beschraenkungen.length) {\n            beschr.appendChild(el('div', 'color: var(--text-secondary, #a0a0b0);', T.b_keine));\n        } else {\n            kern.beschraenkungen.forEach(function (b) {\n                const name = b.zweck >= 1 && b.zweck <= ZWECKE.length ? ZWECKE[b.zweck - 1] : '?';\n                const bereiche = b.anbieter.map(function (p) { return p[0] === p[1] ? String(p[0]) : p[0] + '-' + p[1]; }).join(', ');\n                zeile(beschr, T.b_zweck + ' ' + b.zweck + ': ' + name, (ARTEN[b.art] || '?') + '  [' + bereiche + ']');\n            });\n        }\n        out.appendChild(beschr);\n\n        const verleger = erg.segmente.filter(function (s) { return s.art === 3 &#038;&#038; s.verleger; });\n        if (verleger.length) {\n            out.appendChild(el('div', UEBERSCHRIFT, T.h_verleger));\n            const kasten = el('div', KASTEN);\n            const v = verleger[0].verleger;\n            zeile(kasten, T.v_zwecke, v.zwecke.length ? v.zwecke.join(', ') : T.v_keine);\n            zeile(kasten, T.v_zweckeLI, v.zweckeLI.length ? v.zweckeLI.join(', ') : T.v_keine);\n            zeile(kasten, T.v_eigene, v.anzahlEigene ? (v.eigene.join(', ') || T.v_keine) : T.v_keine);\n            out.appendChild(kasten);\n        }\n\n        out.appendChild(el('div', UEBERSCHRIFT, T.h_segmente));\n        const segmente = el('div', KASTEN);\n        erg.segmente.forEach(function (s) {\n            zeile(segmente, s.name, T.seg_bits.replace('%s', String(s.bits)));\n        });\n        out.appendChild(segmente);\n    }\n\n    btn.addEventListener('click', function () {\n        const erg = dekodieren(feld.value, gvlFeld.value, Date.now());\n        if (!erg.ok) {\n            meldung(erg.fehler);\n            return;\n        }\n        zeigen(erg);\n    });\n\n    beispielBtn.addEventListener('click', function () {\n        \/\/ Ein selbst erzeugter, gueltiger String nach TCF 2.2 mit Kernsegment\n        \/\/ und Verlagssegment - siehe beispiel_bauen.js neben dieser Quelle.\n        feld.value = 'CQoSKcgQoSKcgAfAJBDETfEgAPLgAEPgAAYgJYQBoAAgAYADQAJgAWwF5wMgAywEsIAYAAgAaQCAAIwAEdABgDIAPA.eFAAACgAAA';\n        gvlFeld.value = '';\n        btn.click();\n    });\n})();\n<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dekodowanie ci\u0105gu zgody IAB TCF v2.2 w ca\u0142o\u015bci w przegl\u0105darce: CMP, cele, uzasadniony interes, dostawcy, ograniczenia wydawcy oraz kontrole zaostrzone w TCF 2.2.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":9284,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"template-tool-base.php","meta":{"footnotes":""},"tags":[92127,92151],"class_list":["post-10231","page","type-page","status-publish","hentry","tag-consent-management-pl","tag-prywatnosc-danych-pl-pl"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Dekoder ci\u0105g\u00f3w zgody TCF v2.2 - Lukas Wojcik - Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.lukaswojcik.com\/blog\/pl\/narzedzia\/tcf-consent-string-decoder\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Dekoder ci\u0105g\u00f3w zgody TCF v2.2 - Lukas Wojcik - Blog\" \/>\n<meta property=\"og:description\" content=\"Dekodowanie ci\u0105gu zgody IAB TCF v2.2 w ca\u0142o\u015bci w przegl\u0105darce: CMP, cele, uzasadniony interes, dostawcy, ograniczenia wydawcy oraz kontrole zaostrzone w TCF 2.2.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.lukaswojcik.com\/blog\/pl\/narzedzia\/tcf-consent-string-decoder\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukas Wojcik - Blog\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/og-default.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/narzedzia\\\/tcf-consent-string-decoder\\\/\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/narzedzia\\\/tcf-consent-string-decoder\\\/\",\"name\":\"Dekoder ci\u0105g\u00f3w zgody TCF v2.2 - Lukas Wojcik - Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"datePublished\":\"2026-08-14T22:05:26+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/narzedzia\\\/tcf-consent-string-decoder\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/narzedzia\\\/tcf-consent-string-decoder\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/narzedzia\\\/tcf-consent-string-decoder\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Toolbox\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/toolbox-3\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Dekoder ci\u0105g\u00f3w zgody TCF v2.2\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\",\"name\":\"Lukas Wojcik - Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\",\"name\":\"luky\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"width\":424,\"height\":636,\"caption\":\"luky\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\"},\"sameAs\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Dekoder ci\u0105g\u00f3w zgody TCF v2.2 - Lukas Wojcik - Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.lukaswojcik.com\/blog\/pl\/narzedzia\/tcf-consent-string-decoder\/","og_locale":"en_US","og_type":"article","og_title":"Dekoder ci\u0105g\u00f3w zgody TCF v2.2 - Lukas Wojcik - Blog","og_description":"Dekodowanie ci\u0105gu zgody IAB TCF v2.2 w ca\u0142o\u015bci w przegl\u0105darce: CMP, cele, uzasadniony interes, dostawcy, ograniczenia wydawcy oraz kontrole zaostrzone w TCF 2.2.","og_url":"https:\/\/www.lukaswojcik.com\/blog\/pl\/narzedzia\/tcf-consent-string-decoder\/","og_site_name":"Lukas Wojcik - Blog","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/og-default.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.lukaswojcik.com\/blog\/pl\/narzedzia\/tcf-consent-string-decoder\/","url":"https:\/\/www.lukaswojcik.com\/blog\/pl\/narzedzia\/tcf-consent-string-decoder\/","name":"Dekoder ci\u0105g\u00f3w zgody TCF v2.2 - Lukas Wojcik - Blog","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"datePublished":"2026-08-14T22:05:26+00:00","breadcrumb":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/pl\/narzedzia\/tcf-consent-string-decoder\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.lukaswojcik.com\/blog\/pl\/narzedzia\/tcf-consent-string-decoder\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.lukaswojcik.com\/blog\/pl\/narzedzia\/tcf-consent-string-decoder\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.lukaswojcik.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Toolbox","item":"https:\/\/www.lukaswojcik.com\/blog\/toolbox-3\/"},{"@type":"ListItem","position":3,"name":"Dekoder ci\u0105g\u00f3w zgody TCF v2.2"}]},{"@type":"WebSite","@id":"https:\/\/www.lukaswojcik.com\/blog\/#website","url":"https:\/\/www.lukaswojcik.com\/blog\/","name":"Lukas Wojcik - Blog","description":"","publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.lukaswojcik.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9","name":"luky","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","width":424,"height":636,"caption":"luky"},"logo":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg"},"sameAs":["https:\/\/www.lukaswojcik.com\/blog"]}]}},"_links":{"self":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/10231","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/comments?post=10231"}],"version-history":[{"count":0,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/10231\/revisions"}],"up":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/9284"}],"wp:attachment":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media?parent=10231"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/tags?post=10231"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}