{"id":28769,"date":"2026-11-04T18:06:25","date_gmt":"2026-11-04T17:06:25","guid":{"rendered":"https:\/\/www.lukaswojcik.com\/blog\/narzedzia\/gtm-container-orphan-checker-unused-tags-triggers-variables\/"},"modified":"2026-11-04T19:17:23","modified_gmt":"2026-11-04T18:17:23","slug":"gtm-container-orphan-checker-unused-tags-triggers-variables","status":"publish","type":"page","link":"https:\/\/www.lukaswojcik.com\/blog\/pl\/narzedzia\/gtm-container-orphan-checker-unused-tags-triggers-variables\/","title":{"rendered":"Porz\u0105dkowanie kontenera GTM: nieu\u017cywane tagi, regu\u0142y i zmienne"},"content":{"rendered":"<div class=\"lw-go\" id=\"go-wurzel\" style=\"background: var(--bg-panel, #1e1e24); padding: 25px; border-radius: 8px; border: 1px solid var(--border, #2a2a35);\">\n<style>\n.lw-go label.go-feld { display: flex; flex-direction: column; gap: 6px; font-size: 0.84rem; color: var(--text-secondary, #a0a0b0); margin-bottom: 12px; }\n.lw-go textarea { width: 100%; box-sizing: border-box; padding: 9px 10px; 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.84rem; min-height: 220px; resize: vertical; line-height: 1.45; }\n.lw-go .go-reihe { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin: 4px 0 6px; }\n.lw-go button { padding: 9px 16px; border-radius: 6px; border: 1px solid var(--border, #2a2a35); background: var(--bg-body, #14141a); color: var(--text-primary, #e8e8ee); font-size: 0.92rem; cursor: pointer; }\n.lw-go button.go-haupt { background: var(--accent, #38bdf8); border-color: var(--accent, #38bdf8); color: var(--on-accent, #0a0e14); font-weight: 700; }\n.lw-go button:focus-visible, .lw-go input:focus-visible, .lw-go textarea:focus-visible, .lw-go summary:focus-visible { outline: 2px solid var(--accent, #38bdf8); outline-offset: 2px; }\n.lw-go .go-datei { font-size: 0.86rem; color: var(--text-secondary, #a0a0b0); max-width: 100%; }\n.lw-go .go-status { min-height: 1.3em; margin: 10px 0 0; font-size: 0.92rem; color: var(--text-secondary, #a0a0b0); }\n.lw-go .go-status.go-schlecht { color: var(--fail, #ff7b72); }\n.lw-go .go-h { font-weight: 700; color: var(--text-primary, #e8e8ee); font-size: 0.98rem; margin: 26px 0 8px; }\n.lw-go .go-tabelle { overflow-x: auto; }\n.lw-go table { border-collapse: collapse; width: 100%; font-size: 0.88rem; }\n.lw-go th, .lw-go td { text-align: left; padding: 6px 10px; border-bottom: 1px solid var(--border, #2a2a35); vertical-align: top; color: var(--text-primary, #e8e8ee); }\n.lw-go th { color: var(--text-secondary, #a0a0b0); font-weight: 600; font-size: 0.8rem; }\n.lw-go td.go-zahl, .lw-go th.go-zahl { text-align: right; font-variant-numeric: tabular-nums; }\n.lw-go .go-behaelter { margin: 0 0 8px; font-size: 0.9rem; color: var(--text-secondary, #a0a0b0); }\n.lw-go ul.go-liste { list-style: none; margin: 0; padding: 0; }\n.lw-go ul.go-liste > li { display: flex; gap: 10px; align-items: flex-start; padding: 10px 0; border-bottom: 1px solid var(--border, #2a2a35); font-size: 0.9rem; line-height: 1.5; color: var(--text-primary, #e8e8ee); }\n.lw-go .go-marke { flex: 0 0 auto; min-width: 74px; text-align: center; font-size: 0.74rem; font-weight: 700; padding: 2px 6px; border-radius: 4px; border: 1px solid currentColor; }\n.lw-go .go-fehler { color: var(--fail, #ff7b72); }\n.lw-go .go-warnung { color: var(--warn, #f0b429); }\n.lw-go .go-hinweis { color: var(--text-secondary, #a0a0b0); }\n.lw-go .go-gut { color: var(--pass, #3fb950); }\n.lw-go .go-inhalt { flex: 1 1 auto; min-width: 0; }\n.lw-go .go-titel { font-weight: 600; }\n.lw-go .go-hilfe { display: block; font-size: 0.84rem; color: var(--text-secondary, #a0a0b0); margin-top: 2px; line-height: 1.55; }\n.lw-go details { margin-top: 6px; }\n.lw-go summary { cursor: pointer; font-size: 0.84rem; color: var(--accent, #38bdf8); }\n.lw-go ul.go-elemente { list-style: none; margin: 6px 0 0; padding: 0; }\n.lw-go ul.go-elemente li { font-size: 0.84rem; padding: 3px 0; border: 0; display: block; word-break: break-word; }\n.lw-go .go-art { color: var(--text-secondary, #a0a0b0); font-size: 0.76rem; margin-right: 6px; }\n.lw-go .go-nr { font-family: monospace; color: var(--text-secondary, #a0a0b0); font-size: 0.78rem; }\n.lw-go .go-mehr { font-size: 0.82rem; color: var(--text-secondary, #a0a0b0); }\n.lw-go .go-klein { font-size: 0.84rem; color: var(--text-secondary, #a0a0b0); line-height: 1.55; margin: 0 0 6px; }\n.lw-go .go-klein a, .lw-go ul.go-links a { color: var(--accent, #38bdf8); }\n.lw-go ul.go-links { margin: 0 0 10px; padding-left: 1.2em; font-size: 0.86rem; line-height: 1.6; color: var(--text-secondary, #a0a0b0); }\n.lw-go .go-gruppe { margin: 0 0 18px; }\n.lw-go .go-gruppe-kopf { font-weight: 700; color: var(--text-primary, #e8e8ee); font-size: 0.92rem; margin: 0 0 4px; padding: 6px 0; border-bottom: 2px solid var(--accent, #38bdf8); }\n.lw-go .go-gruppe-kopf .go-anzahl { color: var(--text-secondary, #a0a0b0); font-weight: 400; }\n.lw-go table.go-loesch td { word-break: break-word; }\n.lw-go table.go-loesch td.go-n { font-weight: 600; width: 45%; }\n.lw-go table.go-loesch td.go-o { color: var(--text-secondary, #a0a0b0); width: 18%; }\n.lw-go table.go-loesch td.go-g { color: var(--text-secondary, #a0a0b0); font-size: 0.84rem; }\n.lw-go .go-nichts { font-size: 0.9rem; color: var(--pass, #3fb950); margin: 0 0 12px; }\n.lw-go details.go-ueberblick { margin-top: 22px; }\n.lw-go details.go-ueberblick summary { font-weight: 700; color: var(--text-primary, #e8e8ee); font-size: 0.95rem; }\n@media (max-width: 480px) {\n    .lw-go table.go-loesch td.go-o { display: none; }\n    .lw-go table.go-loesch th.go-o { display: none; }\n    .lw-go { padding: 16px !important; }\n    .lw-go .go-marke { min-width: 62px; }\n}\n<\/style>\n<p style=\"color: var(--text-secondary, #a0a0b0); margin-bottom: 18px;\">Kontener ro\u015bnie przez dodawanie, a rzadko przez usuwanie. To sprawdzenie odczytuje w przegl\u0105darce eksport Google Tag Managera i wylicza, co nie jest ju\u017c z niczym po\u0142\u0105czone: tagi bez dzia\u0142aj\u0105cej regu\u0142y (triggera), regu\u0142y i zmienne, do kt\u00f3rych nic si\u0119 nie odwo\u0142uje, pozosta\u0142e szablony i foldery oraz elementy potrzebne tylko wstrzymanym tagom. Uszkodzone odwo\u0142ania (identyfikator regu\u0142y lub {{zmienna}}, kt\u00f3ra nie istnieje) i zduplikowane identyfikatory te\u017c trafiaj\u0105 na list\u0119, bo to w\u0142a\u015bnie one sprawiaj\u0105, \u017ce tag po cichu nic nie wysy\u0142a.<\/p>\n<p>    <label class=\"go-feld\">Eksport kontenera (wklejenie JSON lub wyb\u00f3r pliku)<br \/>\n        <textarea id=\"go-json\" spellcheck=\"false\" autocomplete=\"off\" data-mp-mask placeholder=\"{&quot;exportFormatVersion&quot;: 2, &quot;containerVersion&quot;: {&hellip;}}\"><\/textarea><br \/>\n    <\/label><\/p>\n<p class=\"go-klein\">W Tag Managerze: Administracja \u2192 Eksportuj kontener, dla wersji lub przestrzeni roboczej. Format API wersji kontenera tak\u017ce dzia\u0142a.<\/p>\n<div class=\"go-reihe\">\n        <input id=\"go-datei\" class=\"go-datei\" type=\"file\" accept=\".json,.txt,application\/json,text\/plain\">\n    <\/div>\n<div class=\"go-reihe\">\n        <button type=\"button\" id=\"go-los\" class=\"go-haupt\">Sprawd\u017a kontener<\/button><br \/>\n        <button type=\"button\" id=\"go-beispiel\">Przyk\u0142adowy kontener<\/button><br \/>\n        <button type=\"button\" id=\"go-leeren\">Wyczy\u015b\u0107<\/button>\n    <\/div>\n<p id=\"go-status\" class=\"go-status\" data-mp-mask aria-live=\"polite\">\n<div id=\"go-ergebnis\" data-mp-mask hidden>\n<p id=\"go-behaelter\" class=\"go-behaelter\" data-mp-mask>\n<div class=\"go-h\">Lista do usuni\u0119cia<\/div>\n<p class=\"go-klein\">Wszystko poni\u017cej mo\u017cna usun\u0105\u0107, pogrupowane jak w Tag Managerze. Najlepiej w tej kolejno\u015bci: tagi, regu\u0142y, zmienne, szablony, foldery \u2013 wtedy przy usuwaniu nic ju\u017c nie odwo\u0142uje si\u0119 do elementu. Zmiennych wbudowanych si\u0119 nie usuwa, tylko odznacza w Zmienne \u2192 Konfiguruj. Pozycje z \u201eu\u017cywane tylko przez \u2026\u201d zwalniaj\u0105 si\u0119, gdy wskazane tam elementy znikn\u0105.<\/p>\n<div id=\"go-loeschliste\" data-mp-mask><\/div>\n<div class=\"go-reihe\" id=\"go-export\" hidden>\n            <button type=\"button\" id=\"go-kopieren\">Kopiuj list\u0119 do usuni\u0119cia<\/button><br \/>\n            <button type=\"button\" id=\"go-csv\">Pobierz CSV<\/button>\n        <\/div>\n<div id=\"go-weitere-block\">\n<div class=\"go-h\">B\u0142\u0119dy i uwagi<\/div>\n<p class=\"go-klein\">To nie s\u0105 kandydaci do usuni\u0119cia, lecz b\u0142\u0119dy do naprawy: odwo\u0142ania donik\u0105d, zduplikowane identyfikatory i podobne.<\/p>\n<ul id=\"go-befunde\" class=\"go-liste\" data-mp-mask><\/ul>\n<\/p><\/div>\n<details class=\"go-ueberblick\">\n<summary>Przegl\u0105d<\/summary>\n<div class=\"go-tabelle\">\n<table>\n<thead>\n<tr>\n<th>Element<\/th>\n<th class=\"go-zahl\">W kontenerze<\/th>\n<th class=\"go-zahl\">Kandydaci do usuni\u0119cia<\/th>\n<\/tr>\n<\/thead>\n<tbody id=\"go-zahlen\" data-mp-mask><\/tbody>\n<\/table>\n<\/div>\n<\/details><\/div>\n<div class=\"go-h\">Co jest sprawdzane<\/div>\n<p class=\"go-klein\">Budowa: format eksportu (containerVersion z listami tag\u00f3w, regu\u0142, zmiennych, folder\u00f3w, zmiennych wbudowanych, szablon\u00f3w, stref, klient\u00f3w i transformacji), zduplikowane identyfikatory i nazwy.<\/p>\n<p class=\"go-klein\">Odwo\u0142ania: regu\u0142y uruchamiaj\u0105ce i blokuj\u0105ce, cz\u0142onkowie grup regu\u0142, tagi konfiguracji i czyszczenia wed\u0142ug nazw, ka\u017cda {{zmienna}} w parametrach, filtrach i polach zg\u00f3d, typy w\u0142asnych szablon\u00f3w (cvt_\u2026) oraz identyfikatory folder\u00f3w. Nazwy s\u0105 por\u00f3wnywane dok\u0142adnie, z wielko\u015bci\u0105 liter i spacjami.<\/p>\n<p class=\"go-klein\">Osierocone elementy: tag jest aktywny, gdy nie jest wstrzymany i ma istniej\u0105c\u0105 regu\u0142\u0119 uruchamiaj\u0105c\u0105 albo jest uruchamiany przez aktywny tag. Od aktywnych tag\u00f3w, stref, klient\u00f3w i transformacji \u015bledzone s\u0105 regu\u0142y, zmienne i szablony. To, do czego si\u0119 nie dociera, jest albo nieu\u017cywane (nic si\u0119 do tego nie odwo\u0142uje), albo u\u017cywane tylko przez martwe elementy (odwo\u0142uj\u0105 si\u0119 do tego tylko wstrzymane lub nigdy nieuruchamiane elementy).<\/p>\n<p class=\"go-klein\">Kolejno\u015b\u0107: najpierw uszkodzone odwo\u0142ania, potem nieu\u017cywane elementy, potem punkty warte uwagi.<\/p>\n<div class=\"go-h\">Ograniczenia i prywatno\u015b\u0107<\/div>\n<p class=\"go-klein\">Sprawdzenie opiera si\u0119 na nazwach i identyfikatorach w eksporcie. Niewidoczne s\u0105 nazwa sk\u0142adana w skrypcie jako zwyk\u0142y tekst, element, kt\u00f3rego nadal u\u017cywa inna przestrze\u0144 robocza, oraz tag pozostawiony celowo. Wymieniony element jest kandydatem, a nie wyrokiem: przed usuni\u0119ciem warto por\u00f3wna\u0107 go z histori\u0105 wersji i podgl\u0105dem. Kontenery serwerowe s\u0105 czytane tak samo, a odwo\u0142ania od klient\u00f3w i transformacji licz\u0105 si\u0119 jako aktywne.<\/p>\n<p class=\"go-klein\">JSON kontenera jest odczytywany i analizowany w przegl\u0105darce i nigdzie nie jest wysy\u0142any. Eksporty zawieraj\u0105 identyfikatory tag\u00f3w, identyfikatory pomiar\u00f3w, a czasem kody pikseli lub klucze w niestandardowym HTML; dlatego nic tu nie jest zapisywane ani przesy\u0142ane, a obszary wynik\u00f3w s\u0105 wy\u0142\u0105czone z nagrywania sesji.<\/p>\n<div class=\"go-h\">Powi\u0105zane<\/div>\n<p class=\"go-klein\">Wi\u0119cej narz\u0119dzi do kontener\u00f3w GTM:<\/p>\n<ul class=\"go-links\">\n<li><a href=\"https:\/\/www.lukaswojcik.com\/blog\/pl\/narzedzia\/gtm-duplicates-analyser\/\">Analizator duplikat\u00f3w w GTM<\/a> \u2013 znajduje tagi, regu\u0142y i zmienne, kt\u00f3re robi\u0105 to samo dwa razy.<\/li>\n<li><a href=\"https:\/\/www.lukaswojcik.com\/blog\/pl\/narzedzia\/gtm-naming-convention-auditer\/\">Audyt konwencji nazewnictwa w GTM<\/a> \u2013 por\u00f3wnuje nazwy element\u00f3w z przyj\u0119t\u0105 konwencj\u0105.<\/li>\n<li><a href=\"https:\/\/www.lukaswojcik.com\/blog\/pl\/narzedzia\/gtm-container-history-deep-search-engine\/\">Historia kontenera GTM i wyszukiwanie pog\u0142\u0119bione<\/a> \u2013 znajduje wersj\u0119, w kt\u00f3rej element zosta\u0142 dodany, zmieniony lub usuni\u0119ty.<\/li>\n<li><a href=\"https:\/\/www.lukaswojcik.com\/blog\/pl\/narzedzia\/gtm-datalayer-variable-path-flattener\/\">Generator \u015bcie\u017cek zmiennych dataLayer w GTM<\/a> \u2013 zamienia zagnie\u017cd\u017cony obiekt dataLayer w \u015bcie\u017cki zmiennych do utworzenia.<\/li>\n<li><a href=\"https:\/\/www.lukaswojcik.com\/blog\/pl\/narzedzia\/text-code-diff\/\">Por\u00f3wnanie tekstu i kodu<\/a> \u2013 por\u00f3wnuje dwa eksporty, na przyk\u0142ad przed porz\u0105dkami i po nich.<\/li>\n<\/ul>\n<p class=\"go-klein\">Artyku\u0142y o utrzymywaniu porz\u0105dku w kontenerze:<\/p>\n<ul class=\"go-links\">\n<li><a href=\"https:\/\/www.lukaswojcik.com\/blog\/pl\/digital-analytics-pl\/tutorials-pl\/tutorial-ustalenie-konwencji-nazw-gtm-i-wprowadzenie-jej-w-istniejacym-kontenerze\/\">Tutorial: Ustalenie konwencji nazw GTM i wprowadzenie jej w istniej\u0105cym kontenerze<\/a> \u2013 po nazwach \u0142atwo rozpozna\u0107 osierocone elementy.<\/li>\n<li><a href=\"https:\/\/www.lukaswojcik.com\/blog\/pl\/tworzenie-stron-internetowych\/porownywanie-dwoch-eksportow-kontenera-gtm-normalizacja-przed-diffem-i-czego-nie-pokazuje-porownanie-wierszami\/\">Por\u00f3wnywanie dw\u00f3ch eksport\u00f3w kontenera GTM<\/a> \u2013 tak wida\u0107, \u017ce porz\u0105dki usun\u0119\u0142y tylko to, co mia\u0142y.<\/li>\n<li><a href=\"https:\/\/www.lukaswojcik.com\/blog\/pl\/digital-analytics-pl\/tutorials-pl\/tutorial-znalezienie-wersji-kontenera-w-ktorej-zmienil-sie-tag\/\">Tutorial: Znalezienie wersji kontenera, w kt\u00f3rej zmieni\u0142 si\u0119 tag<\/a> \u2013 na wypadek, gdy usuni\u0119ty element jednak oka\u017ce si\u0119 potrzebny.<\/li>\n<li><a href=\"https:\/\/www.lukaswojcik.com\/blog\/pl\/digital-marketing-pl\/tutorials-pl-digital-marketing-pl\/tutorial-przygotowywanie-i-weryfikacja-zmian-w-google-tag-manager-za-pomoca-claude-code\/\">Tutorial: Przygotowywanie i weryfikacja zmian w Google Tag Manager za pomoc\u0105 Claude Code<\/a> \u2013 sprawdzenie porz\u0105dk\u00f3w przed publikacj\u0105.<\/li>\n<\/ul>\n<\/div>\n<p><script>\n(function () {\n    'use strict';<\/p>\n<p>    const T = {\"einleitung\":\"Kontener ro\u015bnie przez dodawanie, a rzadko przez usuwanie. To sprawdzenie odczytuje w przegl\u0105darce eksport Google Tag Managera i wylicza, co nie jest ju\u017c z niczym po\u0142\u0105czone: tagi bez dzia\u0142aj\u0105cej regu\u0142y (triggera), regu\u0142y i zmienne, do kt\u00f3rych nic si\u0119 nie odwo\u0142uje, pozosta\u0142e szablony i foldery oraz elementy potrzebne tylko wstrzymanym tagom. Uszkodzone odwo\u0142ania (identyfikator regu\u0142y lub {{zmienna}}, kt\u00f3ra nie istnieje) i zduplikowane identyfikatory te\u017c trafiaj\u0105 na list\u0119, bo to w\u0142a\u015bnie one sprawiaj\u0105, \u017ce tag po cichu nic nie wysy\u0142a.\",\"f_json\":\"Eksport kontenera (wklejenie JSON lub wyb\u00f3r pliku)\",\"f_hilfe\":\"W Tag Managerze: Administracja \u2192 Eksportuj kontener, dla wersji lub przestrzeni roboczej. Format API wersji kontenera tak\u017ce dzia\u0142a.\",\"k_pruefen\":\"Sprawd\u017a kontener\",\"k_beispiel\":\"Przyk\u0142adowy kontener\",\"k_leeren\":\"Wyczy\u015b\u0107\",\"k_kopieren\":\"Kopiuj list\u0119 do usuni\u0119cia\",\"k_csv\":\"Pobierz CSV\",\"h_ueberblick\":\"Przegl\u0105d\",\"sp_art\":\"Element\",\"sp_gesamt\":\"W kontenerze\",\"sp_kandidaten\":\"Kandydaci do usuni\u0119cia\",\"h_befunde\":\"B\u0142\u0119dy i uwagi\",\"h_regeln\":\"Co jest sprawdzane\",\"regel_1\":\"Budowa: format eksportu (containerVersion z listami tag\u00f3w, regu\u0142, zmiennych, folder\u00f3w, zmiennych wbudowanych, szablon\u00f3w, stref, klient\u00f3w i transformacji), zduplikowane identyfikatory i nazwy.\",\"regel_2\":\"Odwo\u0142ania: regu\u0142y uruchamiaj\u0105ce i blokuj\u0105ce, cz\u0142onkowie grup regu\u0142, tagi konfiguracji i czyszczenia wed\u0142ug nazw, ka\u017cda {{zmienna}} w parametrach, filtrach i polach zg\u00f3d, typy w\u0142asnych szablon\u00f3w (cvt_\u2026) oraz identyfikatory folder\u00f3w. Nazwy s\u0105 por\u00f3wnywane dok\u0142adnie, z wielko\u015bci\u0105 liter i spacjami.\",\"regel_3\":\"Osierocone elementy: tag jest aktywny, gdy nie jest wstrzymany i ma istniej\u0105c\u0105 regu\u0142\u0119 uruchamiaj\u0105c\u0105 albo jest uruchamiany przez aktywny tag. Od aktywnych tag\u00f3w, stref, klient\u00f3w i transformacji \u015bledzone s\u0105 regu\u0142y, zmienne i szablony. To, do czego si\u0119 nie dociera, jest albo nieu\u017cywane (nic si\u0119 do tego nie odwo\u0142uje), albo u\u017cywane tylko przez martwe elementy (odwo\u0142uj\u0105 si\u0119 do tego tylko wstrzymane lub nigdy nieuruchamiane elementy).\",\"regel_4\":\"Kolejno\u015b\u0107: najpierw uszkodzone odwo\u0142ania, potem nieu\u017cywane elementy, potem punkty warte uwagi.\",\"h_grenzen\":\"Ograniczenia i prywatno\u015b\u0107\",\"grenze\":\"Sprawdzenie opiera si\u0119 na nazwach i identyfikatorach w eksporcie. Niewidoczne s\u0105 nazwa sk\u0142adana w skrypcie jako zwyk\u0142y tekst, element, kt\u00f3rego nadal u\u017cywa inna przestrze\u0144 robocza, oraz tag pozostawiony celowo. Wymieniony element jest kandydatem, a nie wyrokiem: przed usuni\u0119ciem warto por\u00f3wna\u0107 go z histori\u0105 wersji i podgl\u0105dem. Kontenery serwerowe s\u0105 czytane tak samo, a odwo\u0142ania od klient\u00f3w i transformacji licz\u0105 si\u0119 jako aktywne.\",\"datenschutz\":\"JSON kontenera jest odczytywany i analizowany w przegl\u0105darce i nigdzie nie jest wysy\u0142any. Eksporty zawieraj\u0105 identyfikatory tag\u00f3w, identyfikatory pomiar\u00f3w, a czasem kody pikseli lub klucze w niestandardowym HTML; dlatego nic tu nie jest zapisywane ani przesy\u0142ane, a obszary wynik\u00f3w s\u0105 wy\u0142\u0105czone z nagrywania sesji.\",\"h_dazu\":\"Powi\u0105zane\",\"dazu_werkzeuge\":\"Wi\u0119cej narz\u0119dzi do kontener\u00f3w GTM:\",\"dazu_artikel\":\"Artyku\u0142y o utrzymywaniu porz\u0105dku w kontenerze:\",\"w1_titel\":\"Analizator duplikat\u00f3w w GTM\",\"w1_text\":\"znajduje tagi, regu\u0142y i zmienne, kt\u00f3re robi\u0105 to samo dwa razy.\",\"w2_titel\":\"Audyt konwencji nazewnictwa w GTM\",\"w2_text\":\"por\u00f3wnuje nazwy element\u00f3w z przyj\u0119t\u0105 konwencj\u0105.\",\"w3_titel\":\"Historia kontenera GTM i wyszukiwanie pog\u0142\u0119bione\",\"w3_text\":\"znajduje wersj\u0119, w kt\u00f3rej element zosta\u0142 dodany, zmieniony lub usuni\u0119ty.\",\"w4_titel\":\"Generator \u015bcie\u017cek zmiennych dataLayer w GTM\",\"w4_text\":\"zamienia zagnie\u017cd\u017cony obiekt dataLayer w \u015bcie\u017cki zmiennych do utworzenia.\",\"w5_titel\":\"Por\u00f3wnanie tekstu i kodu\",\"w5_text\":\"por\u00f3wnuje dwa eksporty, na przyk\u0142ad przed porz\u0105dkami i po nich.\",\"a1_titel\":\"Tutorial: Ustalenie konwencji nazw GTM i wprowadzenie jej w istniej\u0105cym kontenerze\",\"a1_text\":\"po nazwach \u0142atwo rozpozna\u0107 osierocone elementy.\",\"a2_titel\":\"Por\u00f3wnywanie dw\u00f3ch eksport\u00f3w kontenera GTM\",\"a2_text\":\"tak wida\u0107, \u017ce porz\u0105dki usun\u0119\u0142y tylko to, co mia\u0142y.\",\"a3_titel\":\"Tutorial: Znalezienie wersji kontenera, w kt\u00f3rej zmieni\u0142 si\u0119 tag\",\"a3_text\":\"na wypadek, gdy usuni\u0119ty element jednak oka\u017ce si\u0119 potrzebny.\",\"a4_titel\":\"Tutorial: Przygotowywanie i weryfikacja zmian w Google Tag Manager za pomoc\u0105 Claude Code\",\"a4_text\":\"sprawdzenie porz\u0105dk\u00f3w przed publikacj\u0105.\",\"tausendertrenner\":\" \",\"s_position\":\"(wiersz {zeile}, kolumna {spalte})\",\"s_json\":\"To nie jest poprawny JSON.\",\"s_kein_container\":\"JSON nie wygl\u0105da na kontener Tag Managera: brak containerVersion i brak listy tag\u00f3w, regu\u0142 lub zmiennych.\",\"s_leer\":\"Nie ma jeszcze czego sprawdza\u0107: najpierw nale\u017cy wklei\u0107 eksport lub wybra\u0107 plik.\",\"s_zu_gross\":\"Plik jest wi\u0119kszy ni\u017c 30 MB i nie zosta\u0142 odczytany.\",\"s_lesen\":\"Odczyt pliku \u2026\",\"s_lesefehler\":\"Nie uda\u0142o si\u0119 odczyta\u0107 pliku.\",\"s_ok\":\"Sprawdzono elementy: {n}, czas {ms} ms.\",\"s_beispiel\":\"Wczytano i sprawdzono przyk\u0142adowy kontener.\",\"s_kopiert\":\"Skopiowano list\u0119 porz\u0105dk\u00f3w.\",\"s_kopieren_fehl\":\"Przegl\u0105darka zablokowa\u0142a kopiowanie. Pobranie CSV zawiera t\u0119 sam\u0105 list\u0119.\",\"behaelter_mit_name\":\"Kontener {name} ({id}): odczytano element\u00f3w: {n}, kandydat\u00f3w do usuni\u0119cia: {k}, uszkodzonych odwo\u0142a\u0144 lub zduplikowanych identyfikator\u00f3w: {f}.\",\"behaelter_ohne_name\":\"Odczytano element\u00f3w: {n}, kandydat\u00f3w do usuni\u0119cia: {k}, uszkodzonych odwo\u0142a\u0144 lub zduplikowanych identyfikator\u00f3w: {f}.\",\"zeige_elemente\":\"Poka\u017c elementy\",\"ohne_namen\":\"(bez nazwy)\",\"weitere\":\"\u2026 i {n} kolejnych, wszystkie s\u0105 w pliku CSV.\",\"stufe_fehler\":\"B\u0142\u0105d\",\"stufe_warnung\":\"Nieu\u017cywane\",\"stufe_hinweis\":\"Uwaga\",\"stufe_gut\":\"OK\",\"art_tag\":\"Tagi\",\"art_trigger\":\"Regu\u0142y\",\"art_variable\":\"Zmienne\",\"art_builtin\":\"Zmienne wbudowane (w\u0142\u0105czone)\",\"art_vorlage\":\"W\u0142asne szablony\",\"art_ordner\":\"Foldery\",\"art_zone\":\"Strefy\",\"art_client\":\"Klienci\",\"art_transformation\":\"Transformacje\",\"art_tag_eins\":\"Tag\",\"art_trigger_eins\":\"Regu\u0142a\",\"art_variable_eins\":\"Zmienna\",\"art_builtin_eins\":\"Wbudowana\",\"art_vorlage_eins\":\"Szablon\",\"art_ordner_eins\":\"Folder\",\"art_zone_eins\":\"Strefa\",\"art_client_eins\":\"Klient\",\"art_transformation_eins\":\"Transformacja\",\"d_pausiert\":\"wstrzymany\",\"d_id\":\"ID {x}\",\"d_ordner\":\"folder: {x}\",\"d_id_doppelt\":\"ID {x} wyst\u0119puje wielokrotnie\",\"d_name_doppelt\":\"element\u00f3w o tej nazwie: {x}\",\"d_fehlt_variable\":\"brak: {x}\",\"d_fehlt_trigger\":\"brak regu\u0142y o ID {x}\",\"d_fehlt_tag\":\"brak tagu: {x}\",\"d_fehlt_vorlage\":\"brak szablonu dla {x}\",\"d_fehlt_ordner\":\"brak folderu o ID {x}\",\"d_nur_von\":\"u\u017cywane tylko przez: {x}\",\"csv_art\":\"Rodzaj\",\"csv_name\":\"Nazwa\",\"csv_id\":\"ID\",\"csv_typ\":\"Typ\",\"csv_ordner\":\"Folder\",\"csv_hinweis\":\"Uwaga\",\"b_id_doppelt\":\"Zduplikowane identyfikatory\",\"b_id_doppelt_hilfe\":\"Dwa elementy tego samego rodzaju maj\u0105 ten sam identyfikator. Odwo\u0142anie przez ID nie potrafi ich ju\u017c rozr\u00f3\u017cni\u0107. Zwykle powodem jest r\u0119cznie edytowany JSON lub powtarzane importy.\",\"b_ref_trigger_fehlt\":\"Odwo\u0142ania do regu\u0142, kt\u00f3re nie istniej\u0105\",\"b_ref_trigger_fehlt_hilfe\":\"Tag, grupa regu\u0142 lub strefa wskazuje identyfikator regu\u0142y, kt\u00f3rego nie ma w eksporcie, wi\u0119c nic si\u0119 nie uruchamia. Typowe po usuni\u0119ciu regu\u0142y bez otwarcia tag\u00f3w, kt\u00f3re z niej korzysta\u0142y, albo po cz\u0119\u015bciowym imporcie.\",\"b_ref_variable_fehlt\":\"Odwo\u0142ania do zmiennych, kt\u00f3re nie istniej\u0105\",\"b_ref_variable_fehlt_hilfe\":\"U\u017cyto {{zmiennej}}, ale nie istnieje ani zmienna o tej nazwie, ani w\u0142\u0105czona zmienna wbudowana. Tag Manager rozwi\u0105zuje j\u0105 do undefined. Nazwa musi zgadza\u0107 si\u0119 dok\u0142adnie, z wielko\u015bci\u0105 liter i spacjami.\",\"b_ref_builtin_aus\":\"Zmienne wbudowane u\u017cyte, ale niew\u0142\u0105czone\",\"b_ref_builtin_aus_hilfe\":\"Nazwa nale\u017cy do zmiennej wbudowanej, kt\u00f3ra nie jest w\u0142\u0105czona w tym kontenerze. Po w\u0142\u0105czeniu w Zmienne \u2192 Konfiguruj zmienna ma warto\u015b\u0107; do tego czasu pozostaje undefined.\",\"b_ref_vorlage_fehlt\":\"Brakuj\u0105ce w\u0142asne szablony\",\"b_ref_vorlage_fehlt_hilfe\":\"Element ma typ szablonu (cvt_\u2026), kt\u00f3rego szablonu nie ma w eksporcie. Taki skutek daje import kontenera bez jego szablon\u00f3w. Element nie zadzia\u0142a, dop\u00f3ki szablon nie zostanie dodany ponownie.\",\"b_ref_sequenz_fehlt\":\"Sekwencja tag\u00f3w wskazuje brakuj\u0105cy tag\",\"b_ref_sequenz_fehlt_hilfe\":\"Tag konfiguracji lub czyszczenia jest wskazany w sekwencji tagu, ale tag o tej nazwie nie istnieje. Sekwencja nie mo\u017ce dzia\u0142a\u0107 tak, jak j\u0105 ustawiono.\",\"b_zyklus\":\"Zmienne odwo\u0142uj\u0105ce si\u0119 do siebie w k\u00f3\u0142ko\",\"b_zyklus_hilfe\":\"Zmienna u\u017cywa drugiej, kt\u00f3ra zn\u00f3w u\u017cywa pierwszej albo samej siebie. Tag Manager nie potrafi rozwi\u0105za\u0107 takiego \u0142a\u0144cucha, wi\u0119c warto\u015b\u0107 to undefined.\",\"b_tag_ohne_ausloeser\":\"Tagi, kt\u00f3re nigdy si\u0119 nie uruchomi\u0105\",\"b_tag_ohne_ausloeser_hilfe\":\"Nie przypisano \u017cadnej istniej\u0105cej regu\u0142y uruchamiaj\u0105cej, a \u017caden aktywny tag nie startuje go jako tag konfiguracji lub czyszczenia. Nie jest wstrzymany, wi\u0119c w przestrzeni roboczej wygl\u0105da na aktywny, a mimo to nic nie wysy\u0142a.\",\"b_trigger_ungenutzt\":\"Regu\u0142y, kt\u00f3rych nic nie u\u017cywa\",\"b_trigger_ungenutzt_hilfe\":\"\u017baden tag nie uruchamia si\u0119 na tej regule ani nie jest przez ni\u0105 blokowany, a \u017cadna grupa regu\u0142 ani strefa jej nie zawiera. Usuni\u0119cie jest zwykle bezpieczne, wcze\u015bniejsza wersja nadal j\u0105 zawiera.\",\"b_variable_ungenutzt\":\"Zmienne, kt\u00f3rych nic nie u\u017cywa\",\"b_variable_ungenutzt_hilfe\":\"\u017baden tag, regu\u0142a, zmienna, strefa ani klient nie zawiera odwo\u0142ania {{nazwa}}. Przed usuni\u0119ciem warto sprawdzi\u0107: nazwa sk\u0142adana w skrypcie jako zwyk\u0142y tekst nie jest rozpoznawana, a inna przestrze\u0144 robocza mo\u017ce ju\u017c u\u017cywa\u0107 tej zmiennej.\",\"b_name_doppelt_var\":\"Zmienne o tej samej nazwie\",\"b_name_doppelt_var_hilfe\":\"Dwie zmienne nosz\u0105 jedn\u0105 nazw\u0119, wi\u0119c odwo\u0142anie {{nazwa}} jest niejednoznaczne. Nie nale\u017cy polega\u0107 na tym, kt\u00f3ra z nich wygra.\",\"b_ref_ordner_fehlt\":\"Przypisanie do folderu wskazuje brakuj\u0105cy folder\",\"b_ref_ordner_fehlt_hilfe\":\"Element wskazuje folder, kt\u00f3rego nie ma w eksporcie. Dla uruchamiania nieszkodliwe, ale element le\u017cy poza ka\u017cdym folderem.\",\"b_tag_pausiert\":\"Wstrzymane tagi\",\"b_tag_pausiert_hilfe\":\"Wstrzymane tagi si\u0119 nie uruchamiaj\u0105. Regu\u0142y i zmienne, kt\u00f3rych u\u017cywaj\u0105 tylko one, s\u0105 wymienione osobno. Tag mo\u017cna usun\u0105\u0107 albo zapisa\u0107, dlaczego zostaje.\",\"b_trigger_tot\":\"Regu\u0142y u\u017cywane tylko przez wstrzymane lub nigdy nieuruchamiane tagi\",\"b_trigger_tot_hilfe\":\"Jedyne odwo\u0142ania pochodz\u0105 od tag\u00f3w, kt\u00f3re si\u0119 nie uruchamiaj\u0105. Regu\u0142a staje si\u0119 nieu\u017cywana, gdy tylko te tagi zostan\u0105 usuni\u0119te.\",\"b_variable_tot\":\"Zmienne u\u017cywane tylko przez wstrzymane lub martwe elementy\",\"b_variable_tot_hilfe\":\"Jedyne odwo\u0142ania pochodz\u0105 od element\u00f3w, kt\u00f3re nigdy nie dzia\u0142aj\u0105. Staj\u0105 si\u0119 nieu\u017cywane razem z nimi.\",\"b_vorlage_ungenutzt\":\"W\u0142asne szablony, kt\u00f3rych nic nie u\u017cywa\",\"b_vorlage_ungenutzt_hilfe\":\"\u017baden tag, zmienna ani regu\u0142a nie powsta\u0142a z tego szablonu. Szablony z galerii mo\u017cna p\u00f3\u017aniej doda\u0107 ponownie.\",\"b_vorlage_tot\":\"Szablony u\u017cywane tylko przez martwe elementy\",\"b_vorlage_tot_hilfe\":\"Z szablonu powsta\u0142y tylko wstrzymane lub nigdy nieuruchamiane elementy.\",\"b_builtin_ungenutzt\":\"W\u0142\u0105czone zmienne wbudowane, kt\u00f3rych nic nie u\u017cywa\",\"b_builtin_ungenutzt_hilfe\":\"Nie kosztuj\u0105 nic w czasie dzia\u0142ania, ale lista w edytorze i dane w podgl\u0105dzie si\u0119 wyd\u0142u\u017caj\u0105. Cz\u0119\u015b\u0107 jest w\u0142\u0105czona celowo, by by\u0142a pod r\u0119k\u0105 przy budowie regu\u0142y.\",\"b_ordner_leer\":\"Puste foldery\",\"b_ordner_leer_hilfe\":\"W folderze nie ma ani tagu, ani regu\u0142y, ani zmiennej.\",\"b_name_doppelt\":\"Tagi lub regu\u0142y o tej samej nazwie\",\"b_name_doppelt_hilfe\":\"Dozwolone, ale lista i sekwencja tag\u00f3w wed\u0142ug nazw staj\u0105 si\u0119 niejasne.\",\"b_sauber\":\"Nie znaleziono nieu\u017cywanych ani uszkodzonych element\u00f3w.\",\"b_sauber_hilfe\":\"Ka\u017cdy tag mo\u017ce si\u0119 uruchomi\u0107, a ka\u017cda regu\u0142a, zmienna, szablon i folder jest przywo\u0142ywany przez co\u015b aktywnego.\",\"h_loeschliste\":\"Lista do usuni\u0119cia\",\"loesch_hilfe\":\"Wszystko poni\u017cej mo\u017cna usun\u0105\u0107, pogrupowane jak w Tag Managerze. Najlepiej w tej kolejno\u015bci: tagi, regu\u0142y, zmienne, szablony, foldery \u2013 wtedy przy usuwaniu nic ju\u017c nie odwo\u0142uje si\u0119 do elementu. Zmiennych wbudowanych si\u0119 nie usuwa, tylko odznacza w Zmienne \u2192 Konfiguruj. Pozycje z \u201eu\u017cywane tylko przez \u2026\u201d zwalniaj\u0105 si\u0119, gdy wskazane tam elementy znikn\u0105.\",\"befunde_hilfe\":\"To nie s\u0105 kandydaci do usuni\u0119cia, lecz b\u0142\u0119dy do naprawy: odwo\u0142ania donik\u0105d, zduplikowane identyfikatory i podobne.\",\"sp_name\":\"Nazwa\",\"sp_ordner\":\"Folder\",\"sp_grund\":\"Pow\u00f3d\",\"loesch_tag\":\"Tagi\",\"loesch_trigger\":\"Regu\u0142y\",\"loesch_variable\":\"Zmienne\",\"loesch_vorlage\":\"Szablony\",\"loesch_ordner\":\"Foldery\",\"loesch_builtin\":\"Zmienne wbudowane \u2013 odznaczy\u0107\",\"loesch_nichts\":\"Nie ma nic do usuni\u0119cia: ka\u017cdy tag, regu\u0142a, zmienna, szablon i folder s\u0105 w u\u017cyciu.\",\"g_tag_ohne_ausloeser\":\"brak regu\u0142y, nigdy si\u0119 nie uruchomi\",\"g_tag_pausiert\":\"wstrzymany\",\"g_tag_nur_von\":\"uruchamiany tylko przez: {x}\",\"g_trigger_ungenutzt\":\"\u017caden tag jej nie u\u017cywa\",\"g_trigger_tot\":\"u\u017cywane tylko przez: {x}\",\"g_variable_ungenutzt\":\"nigdzie nieu\u017cywana\",\"g_variable_tot\":\"u\u017cywane tylko przez: {x}\",\"g_vorlage_ungenutzt\":\"\u017caden tag ani zmienna z niego nie korzysta\",\"g_vorlage_tot\":\"u\u017cywane tylko przez: {x}\",\"g_builtin_ungenutzt\":\"nigdzie nieu\u017cywana\",\"g_ordner_leer\":\"pusty\",\"g_ordner_wird_leer\":\"pusty po usuni\u0119ciu pozycji powy\u017cej\",\"hinweis_teilexport\":\"W tym pliku brakuje wielu u\u017cywanych zmiennych. Wygl\u0105da to na eksport cz\u0119\u015bciowy (eksport kontenera tylko z wybranymi elementami). Do listy do usuni\u0119cia potrzebny jest eksport ca\u0142ej przestrzeni roboczej lub wersji.\",\"hinweis_ohne_id\":\"Niekt\u00f3re tagi, regu\u0142y lub zmienne nie maj\u0105 identyfikatora. Eksporty z Tag Managera zawsze je zawieraj\u0105, wi\u0119c plik powsta\u0142 zapewne r\u0119cznie lub w innym narz\u0119dziu, a odwo\u0142a\u0144 przez identyfikatory nie da si\u0119 rzetelnie sprawdzi\u0107.\",\"csv_aktion\":\"Dzia\u0142anie\",\"csv_loeschen\":\"Usu\u0144\",\"csv_deaktivieren\":\"Odznacz\",\"w1_href\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/narzedzia\\\/gtm-duplicates-analyser\\\/\",\"w2_href\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/narzedzia\\\/gtm-naming-convention-auditer\\\/\",\"w3_href\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/narzedzia\\\/gtm-container-history-deep-search-engine\\\/\",\"w4_href\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/narzedzia\\\/gtm-datalayer-variable-path-flattener\\\/\",\"w5_href\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/narzedzia\\\/text-code-diff\\\/\"};<\/p>\n<p>    \/\/ KERN-ANFANG\n    var MAX_BYTES = 31457280;      \/\/ 30 MB\n    var MAX_ZEILEN = 400;          \/\/ Elemente je Befund in der Liste<\/p>\n<p>    var ARTEN = ['tag', 'trigger', 'variable', 'builtin', 'vorlage', 'ordner', 'zone', 'client', 'transformation'];\n    \/\/ Arten, die im Container als Liste stehen: Schluessel im Export, Id-Feld\n    var LISTEN = [\n        { art: 'tag', liste: 'tag', id: 'tagId' },\n        { art: 'trigger', liste: 'trigger', id: 'triggerId' },\n        { art: 'variable', liste: 'variable', id: 'variableId' },\n        { art: 'builtin', liste: 'builtInVariable', id: '' },\n        { art: 'vorlage', liste: 'customTemplate', id: 'templateId' },\n        { art: 'ordner', liste: 'folder', id: 'folderId' },\n        { art: 'zone', liste: 'zone', id: 'zoneId' },\n        { art: 'client', liste: 'client', id: 'clientId' },\n        { art: 'transformation', liste: 'transformation', id: 'transformationId' }\n    ];\n    \/\/ Eingebaute Variablen: Typ im Export -> Name in der Oberflaeche (nur sichere Zuordnungen)\n    var BUILTIN_NAMEN = {\n        CLICK_ELEMENT: 'Click Element', CLICK_CLASSES: 'Click Classes', CLICK_ID: 'Click ID', CLICK_TARGET: 'Click Target', CLICK_URL: 'Click URL',\n        CLICK_TEXT: 'Click Text', ERROR_MESSAGE: 'Error Message', ERROR_URL: 'Error URL', ERROR_LINE: 'Error Line', DEBUG_MODE: 'Debug Mode',\n        FORM_ELEMENT: 'Form Element', FORM_CLASSES: 'Form Classes', FORM_ID: 'Form ID', FORM_TARGET: 'Form Target', FORM_URL: 'Form URL', FORM_TEXT: 'Form Text',\n        HISTORY_SOURCE: 'History Source', NEW_HISTORY_FRAGMENT: 'New History Fragment', OLD_HISTORY_FRAGMENT: 'Old History Fragment',\n        NEW_HISTORY_STATE: 'New History State', OLD_HISTORY_STATE: 'Old History State', PAGE_URL: 'Page URL', PAGE_HOSTNAME: 'Page Hostname',\n        PAGE_PATH: 'Page Path', REFERRER: 'Referrer', SCROLL_DEPTH_THRESHOLD: 'Scroll Depth Threshold', SCROLL_DEPTH_UNITS: 'Scroll Depth Units',\n        SCROLL_DEPTH_DIRECTION: 'Scroll Direction', CONTAINER_ID: 'Container ID', CONTAINER_VERSION: 'Container Version', ENVIRONMENT_NAME: 'Environment Name',\n        EVENT: 'Event', HTML_ID: 'HTML ID', RANDOM_NUMBER: 'Random Number', VIDEO_CURRENT_TIME: 'Video Current Time', VIDEO_DURATION: 'Video Duration',\n        VIDEO_PERCENT: 'Video Percent', VIDEO_PROVIDER: 'Video Provider', VIDEO_STATUS: 'Video Status', VIDEO_TITLE: 'Video Title', VIDEO_URL: 'Video URL',\n        VIDEO_VISIBLE: 'Video Visible'\n    };\n    \/\/ Eingebaute Trigger: feste IDs, die im Export nie als Trigger erscheinen\n    var BUILTIN_TRIGGER = { '2147479553': 'All Pages', '2147479572': 'Consent Initialization - All Pages', '2147479573': 'Initialization - All Pages',\n        '2147479574': 'built-in (server container)' };\n    var BUILTIN_BEKANNT = {};\n    Object.keys(BUILTIN_NAMEN).forEach(function (k) { BUILTIN_BEKANNT[BUILTIN_NAMEN[k]] = true; });<\/p>\n<p>    \/\/ Schluessel, die nie nach Verweisen durchsucht werden (Namen, Notizen, Kennungen)\n    var SPERRE = { name: 1, notes: 1, fingerprint: 1, tagManagerUrl: 1, path: 1, accountId: 1, containerId: 1, containerVersionId: 1, workspaceId: 1,\n        tagId: 1, triggerId: 1, variableId: 1, folderId: 1, templateId: 1, zoneId: 1, clientId: 1, transformationId: 1, parentFolderId: 1,\n        firingTriggerId: 1, blockingTriggerId: 1, customEvaluationTriggerId: 1, setupTag: 1, teardownTag: 1 };<\/p>\n<p>    var ORDNUNG = ['id_doppelt', 'ref_trigger_fehlt', 'ref_variable_fehlt', 'ref_builtin_aus', 'ref_vorlage_fehlt', 'ref_sequenz_fehlt', 'zyklus',\n        'tag_ohne_ausloeser', 'trigger_ungenutzt', 'variable_ungenutzt', 'name_doppelt_var',\n        'ref_ordner_fehlt', 'tag_pausiert', 'trigger_tot', 'variable_tot', 'vorlage_ungenutzt', 'vorlage_tot', 'builtin_ungenutzt', 'ordner_leer', 'name_doppelt'];\n    var STUFE = { id_doppelt: 'fehler', ref_trigger_fehlt: 'fehler', ref_variable_fehlt: 'fehler', ref_builtin_aus: 'fehler', ref_vorlage_fehlt: 'fehler',\n        ref_sequenz_fehlt: 'fehler', zyklus: 'fehler', tag_ohne_ausloeser: 'warnung', trigger_ungenutzt: 'warnung', variable_ungenutzt: 'warnung',\n        name_doppelt_var: 'warnung', ref_ordner_fehlt: 'hinweis', tag_pausiert: 'hinweis', trigger_tot: 'hinweis', variable_tot: 'hinweis',\n        vorlage_ungenutzt: 'hinweis', vorlage_tot: 'hinweis', builtin_ungenutzt: 'hinweis', ordner_leer: 'hinweis', name_doppelt: 'hinweis' };\n    \/\/ Befunde, deren Elemente als Aufraeumkandidaten zaehlen\n    var KANDIDAT = { tag_ohne_ausloeser: 1, tag_pausiert: 1, trigger_ungenutzt: 1, trigger_tot: 1, variable_ungenutzt: 1, variable_tot: 1,\n        vorlage_ungenutzt: 1, vorlage_tot: 1, builtin_ungenutzt: 1, ordner_leer: 1 };<\/p>\n<p>    function s(x) { return x === undefined || x === null ? '' : String(x); }\n    function fmt(vorlage, werte) {\n        return String(vorlage).replace(\/\\{(\\w+)\\}\/g, function (alles, k) { return Object.prototype.hasOwnProperty.call(werte, k) ? werte[k] : alles; });\n    }\n    function zahl(n) { return String(n).replace(\/\\B(?=(\\d{3})+(?!\\d))\/g, T.tausendertrenner || ','); }<\/p>\n<p>    \/\/ --- Verweise aus einem Element einsammeln --------------------------------\n    function sammeln(x, r, tiefe) {\n        if (tiefe > 40 || x === null || x === undefined) { return; }\n        if (typeof x === 'string') {\n            var re = \/\\{\\{([^{}]+?)\\}\\}\/g, m;\n            while ((m = re.exec(x)) !== null) { r.vars.push(m[1]); }\n            return;\n        }\n        if (Array.isArray(x)) { for (var i = 0; i < x.length; i++) { sammeln(x[i], r, tiefe + 1); } return; }\n        if (typeof x !== 'object') { return; }\n        if (x.type === 'TRIGGER_REFERENCE' &#038;&#038; x.value !== undefined) { r.trig.push(s(x.value)); }\n        if (x.type === 'TAG_REFERENCE' &#038;&#038; x.value !== undefined) { r.tags.push(s(x.value)); }\n        for (var k in x) {\n            if (!Object.prototype.hasOwnProperty.call(x, k) || SPERRE[k] === 1) { continue; }\n            sammeln(x[k], r, tiefe + 1);\n        }\n    }\n    function verweise(roh, art) {\n        var r = { vars: [], trig: [], fire: [], tags: [], seq: [], tmpl: '' };\n        if (art === 'vorlage' || art === 'ordner') { return r; }\n        sammeln(roh, r, 0);\n        ['firingTriggerId', 'blockingTriggerId', 'customEvaluationTriggerId'].forEach(function (k) {\n            var a = roh[k];\n            if (!a &#038;&#038; roh.boundary &#038;&#038; k === 'customEvaluationTriggerId') { a = roh.boundary.customEvaluationTriggerId; }\n            if (a !== undefined &#038;&#038; a !== null &#038;&#038; !Array.isArray(a)) { a = [a]; }\n            (a || []).forEach(function (id) { r.trig.push(s(id)); if (k === 'firingTriggerId') { r.fire.push(s(id)); } });\n        });\n        ['setupTag', 'teardownTag'].forEach(function (k) {\n            (Array.isArray(roh[k]) ? roh[k] : []).forEach(function (t) { if (t &#038;&#038; t.tagName !== undefined) { r.seq.push(s(t.tagName)); } });\n        });\n        \/\/ Vorlagentyp: cvt_<Container-ID>_<templateId> fuer eigene, cvt_<Galerie-ID> fuer Galerievorlagen\n        if (\/^cvt_.\/.test(s(roh.type))) { r.tmpl = s(roh.type).slice(4); }\n        return r;\n    }<\/p>\n<p>    \/\/ --- Container finden ------------------------------------------------------\n    function holeContainer(wurzel) {\n        if (!wurzel || typeof wurzel !== 'object' || Array.isArray(wurzel)) { return null; }\n        if (wurzel.containerVersion && typeof wurzel.containerVersion === 'object' && !Array.isArray(wurzel.containerVersion)) { return wurzel.containerVersion; }\n        for (var i = 0; i < LISTEN.length; i++) { if (Array.isArray(wurzel[LISTEN[i].liste])) { return wurzel; } }\n        return null;\n    }\n\n    \/\/ --- Analyse ----------------------------------------------------------------\n    function analysiere(cv) {\n        var el = [], idKarte = {}, nameKarte = { tag: {}, variable: {} }, builtinKarte = {}, galerieKarte = {};\n        ARTEN.forEach(function (a) { idKarte[a] = {}; });\n        var fund = {};\n        function melde(key, e, info) {\n            if (!fund[key]) { fund[key] = []; }\n            fund[key].push({ e: e, info: info || null });\n        }\n\n        \/\/ 1. Elemente anlegen\n        LISTEN.forEach(function (L) {\n            var liste = Array.isArray(cv[L.liste]) ? cv[L.liste] : [];\n            liste.forEach(function (roh) {\n                if (!roh || typeof roh !== 'object') { return; }\n                var e = { n: el.length, art: L.art, roh: roh, id: L.id ? s(roh[L.id]) : '', name: s(roh.name), typ: s(roh.type), ordner: s(roh.parentFolderId),\n                    ein: [], aus: [], pausiert: roh.paused === true };\n                if (L.art === 'builtin') { if (!e.name) { e.name = BUILTIN_NAMEN[e.typ] || e.typ; } }\n                e.ref = verweise(roh, L.art);\n                el.push(e);\n                if (e.id !== '') { (idKarte[L.art][e.id] = idKarte[L.art][e.id] || []).push(e); }\n                if (L.art === 'tag' || L.art === 'variable') { (nameKarte[L.art][e.name] = nameKarte[L.art][e.name] || []).push(e); }\n                if (L.art === 'builtin') { builtinKarte[e.name] = e; }\n                if (L.art === 'vorlage' &#038;&#038; roh.galleryReference &#038;&#038; roh.galleryReference.galleryTemplateId) {\n                    (galerieKarte[s(roh.galleryReference.galleryTemplateId)] = galerieKarte[s(roh.galleryReference.galleryTemplateId)] || []).push(e);\n                }\n            });\n        });\n\n        \/\/ 2. Doppelte Kennungen und Namen\n        ARTEN.forEach(function (a) {\n            Object.keys(idKarte[a]).forEach(function (id) {\n                if (idKarte[a][id].length > 1) { idKarte[a][id].forEach(function (e) { melde('id_doppelt', e, { k: 'd_id_doppelt', x: id }); }); }\n            });\n        });\n        ['tag', 'trigger'].forEach(function (a) {\n            var karte = {};\n            el.forEach(function (e) { if (e.art === a && e.name !== '') { (karte[e.name] = karte[e.name] || []).push(e); } });\n            Object.keys(karte).forEach(function (nm) { if (karte[nm].length > 1) { karte[nm].forEach(function (e) { melde('name_doppelt', e, { k: 'd_name_doppelt', x: String(karte[nm].length) }); }); } });\n        });\n        Object.keys(nameKarte.variable).forEach(function (nm) {\n            var l = nameKarte.variable[nm];\n            if (l.length > 1 && nm !== '') { l.forEach(function (e) { melde('name_doppelt_var', e, { k: 'd_name_doppelt', x: String(l.length) }); }); }\n        });<\/p>\n<p>        \/\/ 3. Kanten aufbauen, defekte Verweise melden\n        var hatOrdner = Array.isArray(cv.folder);\n        function kante(von, ziel, art) {\n            if (ziel === von) { return; }\n            von.aus.push({ t: ziel, k: art });\n            ziel.ein.push({ s: von, k: art });\n        }\n        el.forEach(function (e) {\n            var r = e.ref, seen;\n            \/\/ Variablen\n            seen = {};\n            r.vars.forEach(function (nm) {\n                if (seen[nm]) { return; }\n                seen[nm] = true;\n                var ziele = (nameKarte.variable[nm] || []).slice();\n                if (builtinKarte[nm]) { ziele.push(builtinKarte[nm]); }\n                \/\/ {{_event}} ist der feste Verweis auf die eingebaute Variable \"Event\" und braucht keine eigene Variable\n                if (nm === '_event') { if (builtinKarte.Event) { ziele.push(builtinKarte.Event); } else { return; } }\n                if (!ziele.length) {\n                    melde(BUILTIN_BEKANNT[nm] ? 'ref_builtin_aus' : 'ref_variable_fehlt', e, { k: 'd_fehlt_variable', x: nm });\n                } else { ziele.forEach(function (z) { kante(e, z, 'v'); }); }\n            });\n            \/\/ Ausloeser\n            seen = {};\n            r.trig.forEach(function (id) {\n                if (seen[id]) { return; }\n                seen[id] = true;\n                var ziele = idKarte.trigger[id];\n                if (!ziele && BUILTIN_TRIGGER[id]) { return; }   \/\/ eingebauter Trigger, steht nie im Export\n                if (!ziele) { melde('ref_trigger_fehlt', e, { k: 'd_fehlt_trigger', x: id }); } else { ziele.forEach(function (z) { kante(e, z, 't'); }); }\n            });\n            \/\/ Tag-Verweise (Parameter) und Reihenfolge\n            seen = {};\n            r.tags.forEach(function (nm) {\n                if (seen[nm]) { return; }\n                seen[nm] = true;\n                (nameKarte.tag[nm] || idKarte.tag[nm] || []).forEach(function (z) { kante(e, z, 'r'); });\n            });\n            seen = {};\n            r.seq.forEach(function (nm) {\n                if (seen[nm]) { return; }\n                seen[nm] = true;\n                var ziele = nameKarte.tag[nm];\n                if (!ziele) { melde('ref_sequenz_fehlt', e, { k: 'd_fehlt_tag', x: nm }); } else { ziele.forEach(function (z) { kante(e, z, 'q'); }); }\n            });\n            \/\/ Vorlage\n            if (r.tmpl) {\n                var mv = \/_(\\d+)$\/.exec(r.tmpl);\n                var vt = (mv && idKarte.vorlage[mv[1]]) || galerieKarte[r.tmpl];\n                if (!vt) { melde('ref_vorlage_fehlt', e, { k: 'd_fehlt_vorlage', x: e.typ }); } else { vt.forEach(function (z) { kante(e, z, 'p'); }); }\n            }\n            \/\/ Ordner\n            if (hatOrdner && e.ordner !== '' && e.ordner !== '0' && !idKarte.ordner[e.ordner] && e.art !== 'ordner') {\n                melde('ref_ordner_fehlt', e, { k: 'd_fehlt_ordner', x: e.ordner });\n            }\n        });<\/p>\n<p>        \/\/ 4. Zyklen unter Variablen\n        var farbe = {}, inZyklus = {};\n        function tiefensuche(e, pfad) {\n            farbe[e.n] = 1; pfad.push(e);\n            e.aus.forEach(function (ka) {\n                var z = ka.t;\n                if (ka.k !== 'v' || z.art !== 'variable') { return; }\n                if (farbe[z.n] === 1) {\n                    for (var i = pfad.length - 1; i >= 0; i--) { inZyklus[pfad[i].n] = true; if (pfad[i] === z) { break; } }\n                } else if (!farbe[z.n]) { tiefensuche(z, pfad); }\n            });\n            pfad.pop(); farbe[e.n] = 2;\n        }\n        el.forEach(function (e) { if (e.art === 'variable' && !farbe[e.n]) { tiefensuche(e, []); } });\n        el.forEach(function (e) {\n            if (e.art !== 'variable') { return; }\n            if (inZyklus[e.n]) { melde('zyklus', e, null); return; }\n            e.aus.forEach(function (ka) { if (ka.k === 'v' && ka.t === e) { melde('zyklus', e, null); } });\n        });\n        \/\/ Selbstverweis: kante() legt keine Kante auf sich selbst an, daher gesondert\n        el.forEach(function (e) {\n            if (e.art === 'variable' && e.ref.vars.indexOf(e.name) !== -1 && !inZyklus[e.n]) {\n                var schon = (fund.zyklus || []).some(function (f) { return f.e === e; });\n                if (!schon) { melde('zyklus', e, null); }\n            }\n        });<\/p>\n<p>        \/\/ 5. Tags: wann feuern sie wirklich?\n        var live = {};\n        function vorhandeneAusloeser(e) { var n = 0; e.ref.fire.forEach(function (id) { if (idKarte.trigger[id] || BUILTIN_TRIGGER[id]) { n++; } }); return n; }\n        var geaendert = true;\n        while (geaendert) {\n            geaendert = false;\n            el.forEach(function (e) {\n                if (e.art !== 'tag' || live[e.n] || e.pausiert) { return; }\n                var ok = vorhandeneAusloeser(e) > 0;\n                if (!ok) {\n                    ok = e.ein.some(function (ka) { return ka.s.art === 'tag' && live[ka.s.n] && (ka.k === 'q' || ka.k === 'r'); });\n                }\n                if (ok) { live[e.n] = true; geaendert = true; }\n            });\n        }<\/p>\n<p>        \/\/ 6. Von lebenden Wurzeln aus verfolgen\n        var erreicht = {}, stapel = [];\n        el.forEach(function (e) {\n            if ((e.art === 'tag' && live[e.n]) || e.art === 'zone' || e.art === 'client' || e.art === 'transformation') { erreicht[e.n] = true; stapel.push(e); }\n        });\n        while (stapel.length) {\n            var a = stapel.pop();\n            a.aus.forEach(function (ka) {\n                if (ka.t.art === 'tag' || erreicht[ka.t.n]) { return; }\n                erreicht[ka.t.n] = true; stapel.push(ka.t);\n            });\n        }<\/p>\n<p>        \/\/ 7. Aufraeumkandidaten einordnen\n        function referrer(e) {\n            var namen = [], gesehen = {};\n            e.ein.forEach(function (ka) {\n                var nm = ka.s.name || ka.s.id;\n                if (!gesehen[ka.s.n]) { gesehen[ka.s.n] = true; namen.push(nm + (ka.s.pausiert ? ' (' + T.d_pausiert + ')' : '')); }\n            });\n            var rest = namen.length > 3 ? ' +' + (namen.length - 3) : '';\n            return namen.slice(0, 3).join(', ') + rest;\n        }\n        var benutzteOrdner = {};\n        el.forEach(function (e) { if (e.ordner !== '' && e.art !== 'ordner') { benutzteOrdner[e.ordner] = true; } });\n        el.forEach(function (e) {\n            if (e.art === 'tag') {\n                if (e.pausiert) { melde('tag_pausiert', e, null); }\n                else if (!live[e.n]) { melde('tag_ohne_ausloeser', e, e.ein.length ? { k: 'd_nur_von', x: referrer(e) } : null); }\n            } else if (e.art === 'trigger' || e.art === 'variable' || e.art === 'vorlage' || e.art === 'builtin') {\n                if (erreicht[e.n]) { return; }\n                var wohin = e.art === 'builtin' ? 'variable' : e.art;\n                if (e.ein.length === 0) {\n                    melde(e.art === 'builtin' ? 'builtin_ungenutzt' : wohin + '_ungenutzt', e, null);\n                } else {\n                    melde(wohin + '_tot', e, { k: 'd_nur_von', x: referrer(e) });\n                }\n            }\n        });\n        \/\/ Ordner zuletzt: leer, oder leer, sobald alle Elemente darin von der Loeschliste weg sind\n        var weg = {};\n        Object.keys(fund).forEach(function (key) { if (KANDIDAT[key]) { fund[key].forEach(function (f) { weg[f.e.n] = true; }); } });\n        var bleibt = {};\n        el.forEach(function (e) { if (e.ordner !== '' && e.art !== 'ordner' && !weg[e.n]) { bleibt[e.ordner] = true; } });\n        el.forEach(function (e) {\n            if (e.art !== 'ordner') { return; }\n            if (!benutzteOrdner[e.id]) { melde('ordner_leer', e, null); }\n            else if (!bleibt[e.id]) { melde('ordner_leer', e, { k: 'g_ordner_wird_leer', x: '' }); }\n        });<\/p>\n<p>        \/\/ 8. Ergebnis zusammenstellen\n        var befunde = [];\n        ORDNUNG.forEach(function (key) {\n            if (fund[key] && fund[key].length) { befunde.push({ key: key, stufe: STUFE[key], eintraege: fund[key] }); }\n        });\n        var kand = {}, zaehl = {};\n        ARTEN.forEach(function (a) { zaehl[a] = { gesamt: 0, kandidaten: 0 }; });\n        el.forEach(function (e) { zaehl[e.art].gesamt++; });\n        befunde.forEach(function (b) {\n            if (!KANDIDAT[b.key]) { return; }\n            b.eintraege.forEach(function (f) {\n                if (!kand[f.e.n]) { kand[f.e.n] = true; zaehl[f.e.art].kandidaten++; }\n            });\n        });\n        var fehler = 0, kandidaten = 0;\n        befunde.forEach(function (b) { if (b.stufe === 'fehler') { fehler += b.eintraege.length; } });\n        Object.keys(kand).forEach(function () { kandidaten++; });\n        var ordnerName = {};\n        el.forEach(function (e) { if (e.art === 'ordner') { ordnerName[e.id] = e.name; } });\n        var cont = (cv.container && typeof cv.container === 'object') ? cv.container : {};\n        \/\/ Teilexport: der Tag Manager kann auch nur ausgewaehlte Elemente exportieren, dann fehlen viele Variablen\n        var fehlendeNamen = {};\n        (fund.ref_variable_fehlt || []).forEach(function (f) { fehlendeNamen[f.info.x] = true; });\n        var nFehlend = Object.keys(fehlendeNamen).length;\n        var teilexport = nFehlend >= 10 && nFehlend > zaehl.variable.gesamt * 0.5;\n        \/\/ Elemente ohne ID kommen in Exporten aus dem Tag Manager nicht vor (Datei von Hand oder per Werkzeug erzeugt)\n        var ohneId = el.some(function (e) { return (e.art === 'tag' || e.art === 'trigger' || e.art === 'variable') && e.id === ''; });\n        return { befunde: befunde, zahlen: zaehl, kandidaten: kandidaten, fehler: fehler, elemente: el.length, ordnerName: ordnerName, teilexport: teilexport, ohneId: ohneId,\n            container: { name: s(cont.name), oeffentlich: s(cont.publicId) } };\n    }<\/p>\n<p>    \/\/ --- Text lesen ----------------------------------------------------------------\n    function textLesen(text) {\n        var t = String(text);\n        if (t.charCodeAt(0) === 0xFEFF) { t = t.slice(1); }\n        var wurzel;\n        try { wurzel = JSON.parse(t); }\n        catch (fehler) {\n            var pos = \/position (\\d+)\/.exec(String(fehler && fehler.message));\n            var info = '';\n            if (pos) {\n                var p = parseInt(pos[1], 10), zeile = 1, letzter = -1, idx = -1;\n                while ((idx = t.indexOf('\\n', idx + 1)) !== -1 && idx < p) { zeile++; letzter = idx; }\n                info = fmt(T.s_position, { zeile: zeile, spalte: p - letzter });\n            }\n            return { fehler: 'json', info: info };\n        }\n        var cv = holeContainer(wurzel);\n        if (!cv) { return { fehler: 'container' }; }\n        return { cv: cv };\n    }\n\n    \/\/ --- Ausgabe -----------------------------------------------------------------------\n    function el_(id) { return document.getElementById(id); }\n    function knoten(tag, klasse, text) {\n        var n = document.createElement(tag);\n        if (klasse) { n.className = klasse; }\n        if (text !== undefined) { n.textContent = text; }\n        return n;\n    }\n    function status(text, schlecht) {\n        var n = el_('go-status');\n        if (!n) { return; }\n        n.textContent = text;\n        n.className = 'go-status' + (schlecht ? ' go-schlecht' : '');\n    }\n    function detailText(info, ordnerName, e) {\n        var teile = [];\n        if (e.id !== '') { teile.push(fmt(T.d_id, { x: e.id })); }\n        if (e.typ) { teile.push(e.typ); }\n        if (e.ordner !== '' &#038;&#038; ordnerName[e.ordner]) { teile.push(fmt(T.d_ordner, { x: ordnerName[e.ordner] })); }\n        if (info) { teile.push(fmt(T[info.k], { x: info.x })); }\n        return teile.join(' \u00b7 ');\n    }\n    var letztes = null;\n\n    function zeigen(res) {\n        letztes = res;\n        var c = res.container;\n        el_('go-behaelter').textContent = fmt(c.name ? T.behaelter_mit_name : T.behaelter_ohne_name,\n            { name: c.name, id: c.oeffentlich, n: zahl(res.elemente), k: zahl(res.kandidaten), f: zahl(res.fehler) });\n        if (res.teilexport) {\n            el_('go-behaelter').appendChild(document.createElement('br'));\n            el_('go-behaelter').appendChild(knoten('strong', 'go-warnung', T.hinweis_teilexport));\n        }\n        if (res.ohneId) {\n            el_('go-behaelter').appendChild(document.createElement('br'));\n            el_('go-behaelter').appendChild(knoten('strong', 'go-warnung', T.hinweis_ohne_id));\n        }\n\n        var tb = el_('go-zahlen');\n        tb.textContent = '';\n        ARTEN.forEach(function (a) {\n            var z = res.zahlen[a];\n            if (!z.gesamt) { return; }\n            var tr = document.createElement('tr');\n            tr.appendChild(knoten('td', '', T['art_' + a]));\n            tr.appendChild(knoten('td', 'go-zahl', zahl(z.gesamt)));\n            tr.appendChild(knoten('td', 'go-zahl', zahl(z.kandidaten)));\n            tb.appendChild(tr);\n        });\n\n        \/\/ Loeschliste: je Art eine Tabelle mit Name, Ordner, Grund\n        var lw = el_('go-loeschliste');\n        lw.textContent = '';\n        var gruppen = loeschGruppen(res), gesamt = 0;\n        LOESCH_ARTEN.forEach(function (a) {\n            var liste = gruppen[a];\n            if (!liste.length) { return; }\n            gesamt += liste.length;\n            var g = knoten('div', 'go-gruppe');\n            g.setAttribute('data-art', a);\n            var kopf = knoten('div', 'go-gruppe-kopf', T['loesch_' + a] + ' ');\n            kopf.appendChild(knoten('span', 'go-anzahl', '(' + zahl(liste.length) + ')'));\n            g.appendChild(kopf);\n            var wrap = knoten('div', 'go-tabelle');\n            var tab = knoten('table', 'go-loesch');\n            var th = document.createElement('thead'), trh = document.createElement('tr');\n            trh.appendChild(knoten('th', '', T.sp_name));\n            trh.appendChild(knoten('th', 'go-o', T.sp_ordner));\n            trh.appendChild(knoten('th', '', T.sp_grund));\n            th.appendChild(trh); tab.appendChild(th);\n            var tb2 = document.createElement('tbody');\n            liste.slice(0, MAX_ZEILEN).forEach(function (f) {\n                var tr = document.createElement('tr');\n                tr.appendChild(knoten('td', 'go-n', f.e.name || T.ohne_namen));\n                tr.appendChild(knoten('td', 'go-o', res.ordnerName[f.e.ordner] || '\u2013'));\n                tr.appendChild(knoten('td', 'go-g', grundText(f)));\n                tb2.appendChild(tr);\n            });\n            if (liste.length > MAX_ZEILEN) {\n                var trm = document.createElement('tr'), tdm = knoten('td', 'go-mehr', fmt(T.weitere, { n: zahl(liste.length - MAX_ZEILEN) }));\n                tdm.colSpan = 3; trm.appendChild(tdm); tb2.appendChild(trm);\n            }\n            tab.appendChild(tb2); wrap.appendChild(tab); g.appendChild(wrap);\n            lw.appendChild(g);\n        });\n        if (!gesamt) { lw.appendChild(knoten('p', 'go-nichts', T.loesch_nichts)); }<\/p>\n<p>        \/\/ Fehler und Hinweise, die kein Loeschen bedeuten\n        var weitere = res.befunde.filter(function (b) { return !KANDIDAT[b.key]; });\n        el_('go-weitere-block').hidden = !weitere.length;\n        var ul = el_('go-befunde');\n        ul.textContent = '';\n        weitere.forEach(function (b) {\n            var li = document.createElement('li');\n            li.setAttribute('data-befund', b.key);\n            li.appendChild(knoten('span', 'go-marke go-' + b.stufe, T['stufe_' + b.stufe]));\n            var inh = knoten('div', 'go-inhalt');\n            inh.appendChild(knoten('span', 'go-titel', T['b_' + b.key] + ' (' + zahl(b.eintraege.length) + ')'));\n            inh.appendChild(knoten('span', 'go-hilfe', T['b_' + b.key + '_hilfe']));\n            var d = document.createElement('details');\n            d.appendChild(knoten('summary', '', T.zeige_elemente));\n            var liste = knoten('ul', 'go-elemente');\n            b.eintraege.slice(0, MAX_ZEILEN).forEach(function (f) {\n                var z = document.createElement('li');\n                z.appendChild(knoten('span', 'go-art', T['art_' + f.e.art + '_eins']));\n                z.appendChild(document.createTextNode((f.e.name || T.ohne_namen) + ' '));\n                z.appendChild(knoten('span', 'go-nr', detailText(f.info, res.ordnerName, f.e)));\n                liste.appendChild(z);\n            });\n            if (b.eintraege.length > MAX_ZEILEN) {\n                liste.appendChild(knoten('li', 'go-mehr', fmt(T.weitere, { n: zahl(b.eintraege.length - MAX_ZEILEN) })));\n            }\n            d.appendChild(liste);\n            inh.appendChild(d);\n            li.appendChild(inh);\n            ul.appendChild(li);\n        });\n        el_('go-export').hidden = !res.befunde.length;\n        el_('go-ergebnis').hidden = false;\n    }<\/p>\n<p>    \/\/ Reihenfolge, in der im Tag Manager geloescht werden kann (zuerst, was auf anderes verweist)\n    var LOESCH_ARTEN = ['tag', 'trigger', 'variable', 'vorlage', 'ordner', 'builtin'];\n    var GRUND_RANG = { tag_ohne_ausloeser: 0, trigger_ungenutzt: 0, variable_ungenutzt: 0, vorlage_ungenutzt: 0, builtin_ungenutzt: 0, ordner_leer: 0,\n        tag_pausiert: 1, trigger_tot: 1, variable_tot: 1, vorlage_tot: 1 };\n    function loeschGruppen(res) {\n        var g = {}, gesehen = {};\n        LOESCH_ARTEN.forEach(function (a) { g[a] = []; });\n        res.befunde.forEach(function (b) {\n            if (!KANDIDAT[b.key]) { return; }\n            b.eintraege.forEach(function (f) {\n                if (gesehen[f.e.n] || !g[f.e.art]) { return; }\n                gesehen[f.e.n] = true;\n                g[f.e.art].push({ e: f.e, key: b.key, info: f.info });\n            });\n        });\n        LOESCH_ARTEN.forEach(function (a) {\n            g[a].sort(function (x, y) {\n                return (GRUND_RANG[x.key] - GRUND_RANG[y.key]) || x.e.name.localeCompare(y.e.name);\n            });\n        });\n        return g;\n    }\n    function grundText(f) {\n        if (f.key === 'tag_ohne_ausloeser' && f.info) { return fmt(T.g_tag_nur_von, { x: f.info.x }); }\n        if (f.key === 'ordner_leer' && f.info) { return T.g_ordner_wird_leer; }\n        return fmt(T['g_' + f.key], { x: f.info ? f.info.x : '' });\n    }<\/p>\n<p>    \/\/ --- Export ---------------------------------------------------------------------------\n    function csvZelle(x) {\n        var t = s(x);\n        if (\/^[=+\\-@\\t\\r]\/.test(t)) { t = \"'\" + t; }\n        return '\"' + t.replace(\/\"\/g, '\"\"') + '\"';\n    }\n    function csvBauen(res) {\n        var zeilen = [[T.csv_aktion, T.csv_art, T.csv_name, T.csv_ordner, T.csv_hinweis, T.csv_id, T.csv_typ].map(csvZelle).join(',')];\n        var gr = loeschGruppen(res);\n        LOESCH_ARTEN.forEach(function (a) {\n            gr[a].forEach(function (f) {\n                zeilen.push([a === 'builtin' ? T.csv_deaktivieren : T.csv_loeschen, T['art_' + a + '_eins'], f.e.name, res.ordnerName[f.e.ordner] || '',\n                    grundText(f), f.e.id, f.e.typ].map(csvZelle).join(','));\n            });\n        });\n        res.befunde.forEach(function (b) {\n            if (KANDIDAT[b.key]) { return; }\n            b.eintraege.forEach(function (f) {\n                zeilen.push([T['stufe_' + b.stufe], T['art_' + f.e.art + '_eins'], f.e.name, res.ordnerName[f.e.ordner] || '',\n                    T['b_' + b.key] + (f.info ? ': ' + fmt(T[f.info.k], { x: f.info.x }) : ''), f.e.id, f.e.typ].map(csvZelle).join(','));\n            });\n        });\n        return '\ufeff' + zeilen.join('\\r\\n') + '\\r\\n';\n    }\n    function listeBauen(res) {\n        var aus = [], gr = loeschGruppen(res);\n        LOESCH_ARTEN.forEach(function (a) {\n            if (!gr[a].length) { return; }\n            aus.push(T['loesch_' + a] + ' (' + gr[a].length + ')');\n            gr[a].forEach(function (f) { aus.push('- ' + (f.e.name || T.ohne_namen) + '  (' + grundText(f) + ')'); });\n            aus.push('');\n        });\n        return aus.join('\\n');\n    }\n    function kopieren() {\n        if (!letztes) { return; }\n        var text = listeBauen(letztes);\n        function geschafft() { status(T.s_kopiert, false); }\n        function misslungen() { status(T.s_kopieren_fehl, true); }\n        if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(text).then(geschafft, misslungen); return; }\n        misslungen();\n    }\n    function csvLaden() {\n        if (!letztes) { return; }\n        var blob = new Blob([csvBauen(letztes)], { type: 'text\/csv;charset=utf-8' });\n        var url = URL.createObjectURL(blob);\n        var a = document.createElement('a');\n        a.href = url; a.download = 'gtm-container-cleanup.csv';\n        document.body.appendChild(a); a.click(); document.body.removeChild(a);\n        setTimeout(function () { URL.revokeObjectURL(url); }, 2000);\n    }<\/p>\n<p>    \/\/ --- Ablauf ------------------------------------------------------------------------------\n    function los(text, meldung) {\n        var eingabe = text === undefined ? el_('go-json').value : text;\n        if (!\/\\S\/.test(eingabe)) { el_('go-ergebnis').hidden = true; status(T.s_leer, true); return null; }\n        var t0 = (window.performance && performance.now) ? performance.now() : Date.now();\n        var gelesen = textLesen(eingabe);\n        if (gelesen.fehler === 'json') { el_('go-ergebnis').hidden = true; status(T.s_json + (gelesen.info ? ' ' + gelesen.info : ''), true); return null; }\n        if (gelesen.fehler === 'container') { el_('go-ergebnis').hidden = true; status(T.s_kein_container, true); return null; }\n        var res = analysiere(gelesen.cv);\n        zeigen(res);\n        var ms = Math.max(1, Math.round(((window.performance && performance.now) ? performance.now() : Date.now()) - t0));\n        status(meldung || fmt(T.s_ok, { n: zahl(res.elemente), ms: ms }), false);\n        return res;\n    }\n    function dateiLesen(datei) {\n        if (!datei) { return; }\n        if (datei.size > MAX_BYTES) { el_('go-ergebnis').hidden = true; status(T.s_zu_gross, true); return; }\n        status(T.s_lesen, false);\n        var fr = new FileReader();\n        fr.onload = function () { el_('go-json').value = String(fr.result); los(); };\n        fr.onerror = function () { status(T.s_lesefehler, true); };\n        fr.readAsText(datei);\n    }<\/p>\n<p>    var BEISPIEL = JSON.stringify({\n        exportFormatVersion: 2,\n        exportTime: '2026-11-03 09:00:00',\n        containerVersion: {\n            path: 'accounts\/1\/containers\/2\/versions\/0', accountId: '1', containerId: '2', containerVersionId: '0',\n            container: { accountId: '1', containerId: '2', name: 'example.com', publicId: 'GTM-EXAMPLE', usageContext: ['WEB'] },\n            folder: [{ folderId: '1', name: 'GA4' }, { folderId: '2', name: 'Old campaign' }, { folderId: '3', name: 'Experiments' }],\n            builtInVariable: [{ type: 'PAGE_URL', name: 'Page URL' }, { type: 'CLICK_TEXT', name: 'Click Text' }, { type: 'PAGE_PATH', name: 'Page Path' }],\n            variable: [\n                { variableId: '1', name: 'Const - GA4 ID', type: 'c', parameter: [{ type: 'TEMPLATE', key: 'value', value: 'G-EXAMPLE123' }], parentFolderId: '1' },\n                { variableId: '2', name: 'DLV - currency', type: 'v', parameter: [{ type: 'INTEGER', key: 'dataLayerVersion', value: '2' }, { type: 'TEMPLATE', key: 'name', value: 'ecommerce.currency' }], parentFolderId: '1' },\n                { variableId: '3', name: 'Const - old pixel ID', type: 'c', parameter: [{ type: 'TEMPLATE', key: 'value', value: '1234567890' }], parentFolderId: '2' }\n            ],\n            trigger: [\n                { triggerId: '1', name: 'All Pages', type: 'PAGEVIEW' },\n                { triggerId: '2', name: 'CE - purchase', type: 'CUSTOM_EVENT', customEventFilter: [{ type: 'EQUALS', parameter: [{ type: 'TEMPLATE', key: 'arg0', value: '{{_event}}' }, { type: 'TEMPLATE', key: 'arg1', value: 'purchase' }] }], parentFolderId: '1' },\n                { triggerId: '3', name: 'Click - spring sale banner', type: 'CLICK', filter: [{ type: 'CONTAINS', parameter: [{ type: 'TEMPLATE', key: 'arg0', value: '{{Click Text}}' }, { type: 'TEMPLATE', key: 'arg1', value: 'Spring sale' }] }], parentFolderId: '2' }\n            ],\n            tag: [\n                { tagId: '1', name: 'GA4 - Google tag', type: 'googtag', parameter: [{ type: 'TEMPLATE', key: 'tagId', value: '{{Const - GA4 ID}}' }], firingTriggerId: ['1'], parentFolderId: '1' },\n                { tagId: '2', name: 'GA4 - purchase', type: 'gaawe', parameter: [{ type: 'TEMPLATE', key: 'eventName', value: 'purchase' }, { type: 'TEMPLATE', key: 'measurementIdOverride', value: '{{Const - GA4 ID}}' }], firingTriggerId: ['9'], parentFolderId: '1' },\n                { tagId: '3', name: 'Pixel - old campaign', type: 'html', paused: true, parameter: [{ type: 'TEMPLATE', key: 'html', value: '<script>track(\"{{Const - old pixel ID}}\");<\\\/script>' }], firingTriggerId: ['3'], parentFolderId: '2' },\n                { tagId: '4', name: 'Floodlight - draft', type: 'fls', parameter: [{ type: 'TEMPLATE', key: 'activityTag', value: 'draft' }] },\n                { tagId: '5', name: 'HTML - consent bridge', type: 'html', parameter: [{ type: 'TEMPLATE', key: 'html', value: '<script>window.cmp = \"{{DLV - consent}}\"; var u = \"{{Page URL}}\";<\\\/script>' }], firingTriggerId: ['1'] }\n            ],\n            customTemplate: [{ templateId: '1', name: 'Unused gallery template', fingerprint: '1', templateData: '___INFO___' }]\n        }\n    }, null, 2);<\/p>\n<p>    window.LW_TEST = window.LW_TEST || {};\n    window.LW_TEST.GTMORPHAN = { T: T, analysiere: analysiere, textLesen: textLesen, holeContainer: holeContainer, los: los, csvBauen: csvBauen, listeBauen: listeBauen,\n        BEISPIEL: BEISPIEL, ORDNUNG: ORDNUNG, ARTEN: ARTEN, loeschGruppen: loeschGruppen, BUILTIN_TRIGGER: BUILTIN_TRIGGER };\n    \/\/ KERN-ENDE<\/p>\n<p>    if (!el_('go-wurzel') || !el_('go-json')) { return; }\n    el_('go-los').addEventListener('click', function () { los(); });\n    el_('go-beispiel').addEventListener('click', function () { el_('go-json').value = BEISPIEL; los(BEISPIEL, T.s_beispiel); });\n    el_('go-leeren').addEventListener('click', function () {\n        el_('go-json').value = ''; el_('go-datei').value = ''; el_('go-ergebnis').hidden = true; letztes = null; status('', false);\n    });\n    el_('go-datei').addEventListener('change', function () { dateiLesen(this.files && this.files[0]); });\n    el_('go-kopieren').addEventListener('click', kopieren);\n    el_('go-csv').addEventListener('click', csvLaden);\n})();\n<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Odczytuje w przegl\u0105darce eksport kontenera Google Tag Manager i wylicza, co straci\u0142o po\u0142\u0105czenie: tagi, kt\u00f3re nigdy si\u0119 nie uruchomi\u0105, regu\u0142y i zmienne, kt\u00f3rych nic nie u\u017cywa, pozosta\u0142e szablony i foldery, elementy utrzymywane tylko przez wstrzymane tagi oraz odwo\u0142ania prowadz\u0105ce donik\u0105d. Nic nie jest wysy\u0142ane.<\/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":[92097,92133,92044],"class_list":["post-28769","page","type-page","status-publish","hentry","tag-data-quality-pl","tag-google-tag-manager-pl","tag-tracking-pl"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Porz\u0105dkowanie kontenera GTM: nieu\u017cywane tagi, regu\u0142y i zmienne | Lukas Wojcik<\/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\/gtm-container-orphan-checker-unused-tags-triggers-variables\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Porz\u0105dkowanie kontenera GTM: nieu\u017cywane tagi, regu\u0142y i zmienne | Lukas Wojcik\" \/>\n<meta property=\"og:description\" content=\"Odczytuje w przegl\u0105darce eksport kontenera Google Tag Manager i wylicza, co straci\u0142o po\u0142\u0105czenie: tagi, kt\u00f3re nigdy si\u0119 nie uruchomi\u0105, regu\u0142y i zmienne, kt\u00f3rych nic nie u\u017cywa, pozosta\u0142e szablony i foldery, elementy utrzymywane tylko przez wstrzymane tagi oraz odwo\u0142ania prowadz\u0105ce donik\u0105d. Nic nie jest wysy\u0142ane.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.lukaswojcik.com\/blog\/pl\/narzedzia\/gtm-container-orphan-checker-unused-tags-triggers-variables\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukas Wojcik - Blog\" \/>\n<meta property=\"article:modified_time\" content=\"2026-11-04T18:17:23+00:00\" \/>\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<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"4 minutes\" \/>\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\\\/gtm-container-orphan-checker-unused-tags-triggers-variables\\\/\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/narzedzia\\\/gtm-container-orphan-checker-unused-tags-triggers-variables\\\/\",\"name\":\"Porz\u0105dkowanie kontenera GTM: nieu\u017cywane tagi, regu\u0142y i zmienne | Lukas Wojcik\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"datePublished\":\"2026-11-04T17:06:25+00:00\",\"dateModified\":\"2026-11-04T18:17:23+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/narzedzia\\\/gtm-container-orphan-checker-unused-tags-triggers-variables\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/narzedzia\\\/gtm-container-orphan-checker-unused-tags-triggers-variables\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/pl\\\/narzedzia\\\/gtm-container-orphan-checker-unused-tags-triggers-variables\\\/#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\\\/pl\\\/narzedzia\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Porz\u0105dkowanie kontenera GTM: nieu\u017cywane tagi, regu\u0142y i zmienne\"}]},{\"@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\":\"Lukas Wojcik\",\"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\":\"Lukas Wojcik\"},\"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":"Porz\u0105dkowanie kontenera GTM: nieu\u017cywane tagi, regu\u0142y i zmienne | Lukas Wojcik","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\/gtm-container-orphan-checker-unused-tags-triggers-variables\/","og_locale":"en_US","og_type":"article","og_title":"Porz\u0105dkowanie kontenera GTM: nieu\u017cywane tagi, regu\u0142y i zmienne | Lukas Wojcik","og_description":"Odczytuje w przegl\u0105darce eksport kontenera Google Tag Manager i wylicza, co straci\u0142o po\u0142\u0105czenie: tagi, kt\u00f3re nigdy si\u0119 nie uruchomi\u0105, regu\u0142y i zmienne, kt\u00f3rych nic nie u\u017cywa, pozosta\u0142e szablony i foldery, elementy utrzymywane tylko przez wstrzymane tagi oraz odwo\u0142ania prowadz\u0105ce donik\u0105d. Nic nie jest wysy\u0142ane.","og_url":"https:\/\/www.lukaswojcik.com\/blog\/pl\/narzedzia\/gtm-container-orphan-checker-unused-tags-triggers-variables\/","og_site_name":"Lukas Wojcik - Blog","article_modified_time":"2026-11-04T18:17:23+00:00","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","twitter_misc":{"Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.lukaswojcik.com\/blog\/pl\/narzedzia\/gtm-container-orphan-checker-unused-tags-triggers-variables\/","url":"https:\/\/www.lukaswojcik.com\/blog\/pl\/narzedzia\/gtm-container-orphan-checker-unused-tags-triggers-variables\/","name":"Porz\u0105dkowanie kontenera GTM: nieu\u017cywane tagi, regu\u0142y i zmienne | Lukas Wojcik","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"datePublished":"2026-11-04T17:06:25+00:00","dateModified":"2026-11-04T18:17:23+00:00","breadcrumb":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/pl\/narzedzia\/gtm-container-orphan-checker-unused-tags-triggers-variables\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.lukaswojcik.com\/blog\/pl\/narzedzia\/gtm-container-orphan-checker-unused-tags-triggers-variables\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.lukaswojcik.com\/blog\/pl\/narzedzia\/gtm-container-orphan-checker-unused-tags-triggers-variables\/#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\/pl\/narzedzia\/"},{"@type":"ListItem","position":3,"name":"Porz\u0105dkowanie kontenera GTM: nieu\u017cywane tagi, regu\u0142y i zmienne"}]},{"@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":"Lukas Wojcik","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":"Lukas Wojcik"},"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\/28769","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=28769"}],"version-history":[{"count":4,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/28769\/revisions"}],"predecessor-version":[{"id":28793,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/28769\/revisions\/28793"}],"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=28769"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/tags?post=28769"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}