Nakoupila jsem plíseň za sedm set. Řetězce to nevzrušuje

Sdílet

Autor: Kateřina Čepelíková / Vitalia.cz
Vydali jsme se na testovací nákup ovoce a zeleniny do několika supermarketů. Tolik plísně a hniloby jsme ale nečekali. A co radí inspekce? „Nelíbí se vám to? Běžte nakupovat jinam.“

Jezte víc zeleniny a ovoce, nabádají výživoví poradci, dietologové, lékaři. Dala jsem na jejich rady a vyrazila na nákup vitamínů v té nejpřirozenější formě. Výstavka plodů země, kterou se chlubily řetězce Tesco, Kaufland a Albert Supermarket ale vezme chuť stravovat se zdravě. Tamní zelenina a ovoce doslova tekly pod rukama a zelená plíseň přitahovala pozornost – bohužel jen mou, nikoli těch, kteří mají kvalitu rychle se kazícího zboží na starosti.

Nahlédněte do naší fotogalerie na produkty podřadné kvality, které se běžně dají v regálech našich obchodů najít pod označením I. jakost. Máme pro vás kajícná vyjádření tiskových mluvčích řetězců i reakce vedoucích prodejen na reklamaci zakoupeného zboží. Co na plíseň v obchodech říká tiskový mluvčí dozorové orgánu, tedy Státní zemědělské a potravinářské inspekce (SZPI)? Taky vám jeho prohlášením vyrazí dech?

Během tří dnů jsem navštívila čtyři pražské obchody s potravinami:

  1. Tesco – Zličín
  2. Makro – Stodůlky
  3. Albert Supermarket – Hůrka
  4. Kaufland – Stodůlky

Autor: Kateřina Čepelíková / Vitalia.cz

Plíseň na ovoci a zelenině – v českých obchodech nic výjimečného, bohužel

Scénář byl vždy stejný. Vstoupit a jako běžný zákazník vybrat to nejhorší, co úseky ovoce a zeleniny nabízely. Protože se v obchodech nesmí fotografovat, takové zboží jsem řádně nakoupila, před obchodem nafotila a za asistence odpovědného pracovníka (většinou vedoucího úseku, prodejny…) zboží reklamovala.

Plíseň v obchodech být může

Dříve než vás seznámím s výsledky „inspekcí“, nabízím právní výklad na minimální požadavky na jakost ovoce a zeleninu: „V každé šarži se povoluje odchylka ve výši 10 % početních nebo hmotnostních produktů, které minimální požadavky nesplňují. V rámci této odchylky smí celkem nejvýše 2 % sestávat z produktů postižených hnilobou. Tato odchylka se však nevztahuje na produkt napadený hnilobou nebo postižený zhoršením jakosti do té míry, že je nezpůsobilý ke spotřebě,“ praví se v nařízení Komise EU 543/2011.

Z tohoto legislativního vyjádření lze tedy vyčíst, že plíseň je v malém množství unijními zákony posvěcena. Obávám se ale, že množství námi zakoupené plísně v českých obchodech tuto míru vysoce překročilo. Podívejte se…

Tesco Zličín – osm a půl kila plísně

Moje první kroky směřovaly do velké nákupní zóny na západě Prahy, konkrétně do hypermarketu Tesco. A vzhledem k tomu, že byl pátek třináctého, měla jsem „štěstí“, zrovna tam probíhala rozsáhlá rekonstrukce, za běžného chodu. To ale nemění nic na tom, že kvalita potravin by měla být zachována. Nebyla.

Už při letmém rozhlédnutí bilo do očí hrozno bílé, respektive hnědé. Ani jsem nemusela hledat plevy mezi zrny, veškeré víno ve volném prodeji bylo nahnilé, viz fotogalerie. Za 5 dostává i bezmála kilo a půl zelenou plísní zasažených nektarinek za bratru stovku, no, nekupte to. Kam nedosáhl můj zrak, pomohl čich, tak jako v případě 5 kg sadbových brambor, ve kterých tak moc bujel nový bakteriální život, že už skoro pochodovaly na pole – samy.

Grep už měl také na kahánku, proto skončil ve vozíku hanby, tak jako rajčata „po sezóně“, jahody a citron nehodící se ani do kompostu. Vše v celkové hodnotě 310 Kč a váze zhruba 8,5 kg.

Při markování mě paní pokladní upozornila na hnijící potraviny, které si mohu dojít vyměnit. Neskrývala překvapení, když jsem tuto nabídku odmítla.

Nastala fáze focení v polních podmínkách a reklamace na Informacích. Povolány byly hned dvě vedoucí, které dobrou půlhodinu klopily zrak a nešetřily omluvami. Vina padla, jak jinak, na selhání lidského faktoru, v tomto případě na novou kvalitářku. Obranou pak byly odpovědi, že zbídačelé plody jim mnohdy vozí už z centrály, že všechno ovoce a zeleninu denně několikrát kontrolují a že je jim mého nálezu velmi líto. Tak líto, že do neoznačené obálky vložili poukázku na nákup v Tescu a s rudými líčky mi doslova nutili její převzetí. Vzhledem k tomu, že mým cílem bylo na problém upozornit, ne vydělat, poukázku jsem nepřevzala.

Kontaktovala jsem tiskovou mluvčí společnosti Tesco, Evu Karasovou, která nám k plesnivým a tlejícím potravinám napsala: „Kvalita ovoce a zeleniny představuje pro nás jednu z nejdůležitějších oblastí, na něž se nepřetržitě zaměřujeme. V uvedeném případě došlo k výpadku našeho kontrolního mechanismu na obchodě, pravděpodobně v důsledku probíhajících stavebních změn v rámci modernizace obchodu. Všichni zaměstnanci zodpovědní za oddělení ovoce a zeleniny a kontrolu kvality budou opětovně proškoleni. Tímto postupem se snažíme preventivně předejít obdobné záležitosti v budoucnu.“

Nakoupené a reklamované ovoce a zelenina v Tescu:

rajčata Kumato

5 ks (váha neuvedena)

49,90 Kč

jahody balené

250 g

14,90 Kč

citrony

280 g

7,00 Kč

hrozno bílé

1,046 kg

73,10 Kč

nektarinky skládané

1,382 kg

96,60 Kč

grep červený

330 g

8,20 Kč

brambory sadba

5 kg

59,90 Kč

celkem

cca 8,5 kg

309,60 Kč

Makro Stodůlky – se ztrátou jediné jahůdky

Další návštěvou jsem poctila společnost Makro. Už na první pohled ovoce a zelenina svítila do dáli a i bližší ohledání místa činu pro mě bylo příjemným překvapením. Jedno jablko jako druhé, okurky jak ze soustruhu, pomeranče by mohly sbírat zlaté na Zahradě Čech.

Malou vadou na kráse však způsobil nález dokonale šedivé „chlupaté“ jahody, mezi stovkami jiných úhledných krabiček s dokonalými červenými plody. Po informování vedoucí úseku byly jahody s omluvou odstraněny. Jiná pochybení jsem zde nenašla, ačkoliv množství, různorodost a exotičnost sortimentu k tomu mohla svádět.

Albert Supermarket Hůrka – ovozel není výrobek

Tady jsem se „poměla“ jen za 109 Kč. Úsek ovoce-zelenina nabízel tvrdá nablýskaná jablka, unavené papriky (ale ne plesnivé) a opravdu krásné hroznové víno. Nicméně i zde se o pozornost přihlásily produkty zemědělství, kterými byste už ani tchýni neuctili. Mrkev olivově hnědé barvy, cherry rajčátka s bonusem bílé plísně a jahody, které od vytečení na zem chránila jen fixace slídového přebalu. Vedoucí obchodu se při reklamaci hluboce omlouvala za pochybení, vrátila peníze a spolu s pracovníkem ovoce-zelenina se ujala radikální kontroly celého úseku.

Ředitelka komunikace společnosti Ahold, Judita Urbánková server Vitalia.cz rozsáhle informovala o auditech, dodržování pravidel hygieny prodeje i kontrol v distribučních centrech. Nicméně dodává: „Přes všechny tyto kontroly se může stát, že v průběhu celého distribučního a prodejního procesu dojde ke změně kvality prodávaného zboží – je nutné si uvědomit, že v případě ovoce- zeleniny se nejedná o průmyslové výrobky, ale o živý a často nebalený materiál, který citlivě reaguje na každou změnu podmínek a na případné nešetrné zacházení.“ 

Ano, kilo rajčat v přepravce se nechová stejně způsobně jako televize v regále, to je třeba si uvědomit, ale hlavně z pozice prodejce.

AQ cherry rajčata

2× 250 g

39,80 Kč

AQ rajčata

750 g

34, 90 Kč

mrkev

235 g

4, 00 Kč

jahody

250 g

29, 90 Kč

celkem

1,735 kg

108, 60 Kč

Kaufland – „největší“ kauf

To nejlepší nakonec. I když nejlepší si v tomto případě zaslouží hodně tučné uvozovky. Při probírání se v přepravkách a krabicích jsem třikrát využila papírového kapesníku. Ruce se mi zabořily do silně tlejících pomerančů, Kumquatů (miniaturních pomerančíků) a plísní řádně zasažených bílých paprik, které se kontrole zřejmě úspěšně vyhýbaly po mnoho dní, dost možná i týdnů. Karambola (tzv. čínská hvězdice) svým vzhledem a zápachem budila pozornost už z dálky a ty nejstarší mandarinky jsem z krabice nakonec vylovila jen se sebezapřením. Na samostatnou kapitolu by pak vystačila dvě balení plesnivých ostružin, cca 20 ks za 55 Kč, „chlupatých“ jahod a červených paprik už dlouho volajících po koši.

Zajímavé, že u pokladny se nikdo mému „živému“ nákupu nedivil, přestože „jeté“ papriky zanechaly na páse mnoho stop.

Reklamace v tomto obchodě probíhala, po předchozích zkušenostech, nečekaně. Obhajoba spočívala v házení viny na „ranní směnu“, která provádí kontrolu. Vedoucí prodejny po vybalení prvních z mých jedenácti pytlíků se závadnými potravinami konstatovala: „To je všechno plesnivé.“ Zajímala se, jestli a proč chodím od prodejny nakupovat záměrně plesnivé věci a má odpověď: „Kdybyste to tu neměli, nemohla bych to koupit, ale hlavně jsem vám chtěla ukázat, co prodáváte,“ ji trochu vyvedla z míry. Nechala mi vrátit peníze a s „upřímnými“ díky za upozornění jsme se rozloučily.

Tiskový mluvčí Kauflandu Michael Šperl vyjádřil politování nad mým nálezem a stejně jako v Tescu nabízel poukázku: „Děkujeme za upozornění na tento případ. Naše společnost si prioritně zakládá na prvotřídní kvalitě a čerstvosti zboží, obzvlášť u ovoce a zeleniny, kde nás zákazníci dle četných průzkumů vnímají jako jednoho z nejlepších na trhu.Vámi zakoupené zboží se v žádném případě neslučuje s touto zásadou a je nám velmi líto, že jste takové plody u nás našla.Ovoce a zelenina jsou několikrát denně kontrolovány. Za vzniklé nepříjemnosti se Vám velmi omlouváme. Jako omluvu bychom Vám rádi poskytli dárkovou poukázku v hodnotě 200 Kč.“ 

Nepříjemnosti to jsou spíš pro Kaufland, proto jsem poukázku opět odmítla.

Dost možná jsem tím ale objevila novou formu přivýdělku, najdete plesnivé ovoce a zeleninu, zakoupíte, proběhne reklamace, kde vám vrátí peníze a jako omluvu dostanete poukázku na nákup.

karambola

1 kus

31,90 Kč

paprika žlutá

194 g

10,70 Kč

kumquat

90 g

12,50 Kč

rajčata cherry

250 g

19,90 Kč

jahody

500 g

19,90 Kč

ostružiny balené

2 balení

109,80 Kč

paprika bílá

520 g

36,30 Kč

mandarinky

558 g

15,00 Kč

pomeranče – volné

692 g

18,60 Kč

paprika červená

488 g

29,20 Kč

blumy červené

84 g

5,90 Kč

celkem

cca 3,7 kg

309, 70 Kč

Sbírka plísní a hniloby doznala na konci průzkumu celkové váhy zhruba 14 kg a ty jsem pořídila jen ve třech obchodech. Jak se lze bránit přehrabování mezi tlejícími kusy v honbě za těmi zatím zdravě vypadajícími?

Nelíbí? Běžte jinam

Odpovídá Pavel Kopřiva, mluvčí Státní zemědělské a potravinářské inspekce – dozorujícího orgánu nad zdravotní nezávadností potravin: „Zákazník vždy může podat podnět na SZPI, která se jím bude v nejkratším možném termínu zabývat a situaci na místě prověří. Může tak učinit prostřednictvím emailu: [email protected].“

Z této e-mailové adresy nám však bylo potvrzeno, že na vyřízení každého dotazu mají až 30 dní, takže nahlášení problému na provozovně neznamená, že kontrola SZPI vezme obchod útokem nejpozději ihned.

Další povedenou možnost, jak se bránit plesnivým vitaminovým bombám v potravinách, uvádí opět mluvčí SZPI: „Pokud se problém opakuje, zákazník se, má-li v okolí svého bydliště tu možnost, může vyhnout prodejcům, kteří nabízí nevyhovující zboží a svou spotřebitelskou volbou podporovat poctivé a zodpovědné obchodníky.“ Takže pokud bydlíte na vesnici, kde je jeden supermarket a jedna večerka a kde si hlavu s kvalitou nelámou, tak tam prostě nechoďte. Není nad to nechat si poradit „shora“…

A proč celá tahle anabáze? Ovoce a zeleninu, které aktuálně na pultech ještě vypadají k světu, napadají nežádoucí mikroorganismy z nakažených sousedních kusů. Zvlášť pokud „nakaženého souseda“ odpovědný pracovník obchodu nechává v přepravce v klidu dožít po mnoho dní.
V momentě, kdy v hromadě ovoce či zeleniny vybíráte zdravé kusy, už vlastně můžete nakupovat plody se zárodky plísní, aniž byste to zatím mohli zrakem poznat. Navíc, proč já, jako zákazník mám ztrácet čas přehrabováním se v mnoha přepravkách s hnijícími plody, abych našla deklarovanou I. jakost? Chci do obchodu přijít, nakoupit a jít. 

S laxním přístupem prodejců k našemu zdraví a penězům je třeba pohnout. Ministr zemědělství Petr Bendl minulý týden v pátek k tématu bezpečnosti a kvality potravin v českých obchodech vyzval nás všechny: „Vytrvalý psychologický tlak na výrobce musí vytvářet nejenom dozorové orgány, ale celá spotřebitelská veřejnost.“ Tak tlačme i na prodejce, třeba se ledy pohnou.

Autor článku

Redaktorka serveru Vitalia.cz se zaměřuje zejména na kvalitu potravin a kvalitu jejich prodeje. Věnuje se také zdravotní problematice.

'; document.getElementById('preroll-iframe').onload = function () { setupIframe(); } prerollContainer = document.getElementsByClassName('preroll-container-iframe')[0]; } function setupIframe() { prerollDocument = document.getElementById('preroll-iframe').contentWindow.document; let el = prerollDocument.createElement('style'); prerollDocument.head.appendChild(el); el.innerText = "#adContainer>div:nth-of-type(1),#adContainer>div:nth-of-type(1) > iframe { width: 99% !important;height: 99% !important;max-width: 100%;}#videoContent,body{ width:100vw;height:100vh}body{ font-family:'Helvetica Neue',Arial,sans-serif}#videoContent{ overflow:hidden;background:#000}#adMuteBtn{ width:35px;height:35px;border:0;background:0 0;display:none;position:absolute;fill:rgba(230,230,230,1);bottom:20px;right:25px}"; videoContent = prerollDocument.getElementById('contentElement'); videoContent.style.display = 'none'; videoContent.volume = 1; videoContent.muted = false; const playPromise = videoContent.play(); if (playPromise !== undefined) { playPromise.then(function () { console.log('PREROLL sound allowed'); // setUpIMA(true); videoContent.volume = 1; videoContent.muted = false; setUpIMA(); }).catch(function () { console.log('PREROLL sound forbidden'); videoContent.volume = 0; videoContent.muted = true; setUpIMA(); }); } } function setupDimensions() { prerollWidth = Math.min(iinfoPrerollPosition.offsetWidth, 480); prerollHeight = Math.min(iinfoPrerollPosition.offsetHeight, 320); } function setUpIMA() { google.ima.settings.setDisableCustomPlaybackForIOS10Plus(true); google.ima.settings.setLocale('cs'); google.ima.settings.setNumRedirects(10); // Create the ad display container. createAdDisplayContainer(); // Create ads loader. adsLoader = new google.ima.AdsLoader(adDisplayContainer); // Listen and respond to ads loaded and error events. adsLoader.addEventListener( google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, onAdsManagerLoaded, false); adsLoader.addEventListener( google.ima.AdErrorEvent.Type.AD_ERROR, onAdError, false); // An event listener to tell the SDK that our content video // is completed so the SDK can play any post-roll ads. const contentEndedListener = function () { adsLoader.contentComplete(); }; videoContent.onended = contentEndedListener; // Request video ads. const adsRequest = new google.ima.AdsRequest(); adsRequest.adTagUrl = iinfoVastUrls[iinfoVastUrlIndex]; console.log('Preroll advert: ' + iinfoVastUrls[iinfoVastUrlIndex]); videoContent.muted = false; videoContent.volume = 1; // Specify the linear and nonlinear slot sizes. This helps the SDK to // select the correct creative if multiple are returned. // adsRequest.linearAdSlotWidth = prerollWidth; // adsRequest.linearAdSlotHeight = prerollHeight; adsRequest.nonLinearAdSlotWidth = 0; adsRequest.nonLinearAdSlotHeight = 0; adsLoader.requestAds(adsRequest); } function createAdDisplayContainer() { // We assume the adContainer is the DOM id of the element that will house // the ads. prerollDocument.getElementById('videoContent').style.display = 'none'; adDisplayContainer = new google.ima.AdDisplayContainer( prerollDocument.getElementById('adContainer'), videoContent); } function unmutePrerollAdvert() { adVolume = !adVolume; if (adVolume) { adsManager.setVolume(0.3); prerollDocument.getElementById('adMuteBtn').innerHTML = ''; } else { adsManager.setVolume(0); prerollDocument.getElementById('adMuteBtn').innerHTML = ''; } } function onAdsManagerLoaded(adsManagerLoadedEvent) { // Get the ads manager. const adsRenderingSettings = new google.ima.AdsRenderingSettings(); adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true; adsRenderingSettings.loadVideoTimeout = 12000; // videoContent should be set to the content video element. adsManager = adsManagerLoadedEvent.getAdsManager(videoContent, adsRenderingSettings); // Add listeners to the required events. adsManager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, onAdError); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED, onContentPauseRequested); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED, onContentResumeRequested); adsManager.addEventListener( google.ima.AdEvent.Type.ALL_ADS_COMPLETED, onAdEvent); // Listen to any additional events, if necessary. adsManager.addEventListener(google.ima.AdEvent.Type.LOADED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.STARTED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.COMPLETE, onAdEvent); playAds(); } function playAds() { // Initialize the container. Must be done through a user action on mobile // devices. videoContent.load(); adDisplayContainer.initialize(); // setupDimensions(); try { // Initialize the ads manager. Ad rules playlist will start at this time. adsManager.init(1920, 1080, google.ima.ViewMode.NORMAL); // Call play to start showing the ad. Single video and overlay ads will // start at this time; the call will be ignored for ad rules. adsManager.start(); // window.addEventListener('resize', function (event) { // if (adsManager) { // setupDimensions(); // adsManager.resize(prerollWidth, prerollHeight, google.ima.ViewMode.NORMAL); // } // }); } catch (adError) { // An error may be thrown if there was a problem with the VAST response. // videoContent.play(); } } function onAdEvent(adEvent) { const ad = adEvent.getAd(); console.log('Preroll event: ' + adEvent.type); switch (adEvent.type) { case google.ima.AdEvent.Type.LOADED: if (!ad.isLinear()) { videoContent.play(); } prerollDocument.getElementById('adContainer').style.width = '100%'; prerollDocument.getElementById('adContainer').style.maxWidth = '640px'; prerollDocument.getElementById('adContainer').style.height = '360px'; break; case google.ima.AdEvent.Type.STARTED: window.addEventListener('scroll', onActiveView); if (ad.isLinear()) { intervalTimer = setInterval( function () { // Example: const remainingTime = adsManager.getRemainingTime(); // adsManager.pause(); }, 300); // every 300ms } prerollDocument.getElementById('adMuteBtn').style.display = 'block'; break; case google.ima.AdEvent.Type.ALL_ADS_COMPLETED: if (ad.isLinear()) { clearInterval(intervalTimer); } if (prerollLastError === 303) { playYtVideo(); } break; case google.ima.AdEvent.Type.COMPLETE: if (ad.isLinear()) { clearInterval(intervalTimer); } playYtVideo(); break; } } function onAdError(adErrorEvent) { console.log(adErrorEvent.getError()); prerollLastError = adErrorEvent.getError().getErrorCode(); if (!loadNext()) { playYtVideo(); } } function loadNext() { iinfoVastUrlIndex++; if (iinfoVastUrlIndex < iinfoVastUrls.length) { iinfoPrerollPosition.remove(); playPrerollAd(); } else { return false; } adVolume = 1; return true; } function onContentPauseRequested() { videoContent.pause(); } function onContentResumeRequested() { videoContent.play(); } function onActiveView() { if (prerollContainer) { const containerOffset = prerollContainer.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight/1 && containerOffset.bottom > 0.0) { if (prerollPaused) { adsManager.resume(); prerollPaused = false; } return true; } else { if (!prerollPaused) { adsManager.pause(); prerollPaused = true; } } } return false; } function playYtVideo() { iinfoPrerollPosition.remove(); youtubeIframe.style.display = 'block'; youtubeIframe.src += '&autoplay=1&mute=1'; } }
Upozorníme vás na články, které by vám neměly uniknout (maximálně 2x týdně).
'; document.getElementById('outstream-iframe').onload = function () { setupIframe(); } replayScreen = document.getElementById('iinfoOutstreamReplay'); iinfoOutstreamPosition = document.getElementById('iinfoOutstreamPosition'); outstreamContainer = document.getElementsByClassName('outstream-container')[0]; setupReplayScreen(); } function setupIframe() { outstreamDocument = document.getElementById('outstream-iframe').contentWindow.document; let el = outstreamDocument.createElement('style'); outstreamDocument.head.appendChild(el); el.innerText = "#adContainer>div:nth-of-type(1),#adContainer>div:nth-of-type(1) > iframe { width: 99% !important;height: 99% !important;max-width: 100%;}#videoContent,body{ width:100vw;height:100vh}body{ font-family:'Helvetica Neue',Arial,sans-serif}#videoContent{ overflow:hidden;background:#000}#adMuteBtn{ width:35px;height:35px;border:0;background:0 0;display:none;position:absolute;fill:rgba(230,230,230,1);bottom:-5px;right:25px}"; videoContent = outstreamDocument.getElementById('contentElement'); videoContent.style.display = 'none'; videoContent.volume = 1; videoContent.muted = false; if ( location.href.indexOf('rejstriky.finance.cz') !== -1 || location.href.indexOf('finance-rejstrik') !== -1 || location.href.indexOf('firmy.euro.cz') !== -1 || location.href.indexOf('euro-rejstrik') !== -1 || location.href.indexOf('/rejstrik/') !== -1 || location.href.indexOf('/rejstrik-firem/') !== -1) { outstreamDirectPlayed = true; soundAllowed = true; iinfoVastUrlIndex = 0; } if (!outstreamDirectPlayed) { console.log('OUTSTREAM direct'); setUpIMA(true); } else { if (soundAllowed) { const playPromise = videoContent.play(); if (playPromise !== undefined) { playPromise.then(function () { console.log('OUTSTREAM sound allowed'); setUpIMA(false); }).catch(function () { console.log('OUTSTREAM sound forbidden'); renderBanner(); }); } } else { renderBanner(); } } } function getWrapper() { let articleWrapper = document.querySelector('.rs-outstream-placeholder'); // Outstream Placeholder from RedSys manipulation if (articleWrapper && articleWrapper.style.display !== 'block') { articleWrapper.innerHTML = ""; articleWrapper.style.display = 'block'; } // Don't render OutStream on homepages if (articleWrapper === null) { if (document.querySelector('body.p-index')) { return null; } } if (articleWrapper === null) { articleWrapper = document.getElementById('iinfo-outstream'); } if (articleWrapper === null) { articleWrapper = document.querySelector('.layout-main__content .detail__article p:nth-of-type(6)'); } if (articleWrapper === null) { // Euro, Autobible, Zdravi articleWrapper = document.querySelector('.o-article .o-article__text p:nth-of-type(6)'); } if (articleWrapper === null) { articleWrapper = document.getElementById('sidebar'); } if (!articleWrapper) { console.error("Outstream wrapper of article was not found."); } return articleWrapper; } function setupDimensions() { outstreamWidth = Math.min(iinfoOutstreamPosition.offsetWidth, 480); outstreamHeight = Math.min(iinfoOutstreamPosition.offsetHeight, 320); } /** * Sets up IMA ad display container, ads loader, and makes an ad request. */ function setUpIMA(direct) { google.ima.settings.setDisableCustomPlaybackForIOS10Plus(true); google.ima.settings.setLocale('cs'); google.ima.settings.setNumRedirects(10); // Create the ad display container. createAdDisplayContainer(); // Create ads loader. adsLoader = new google.ima.AdsLoader(adDisplayContainer); // Listen and respond to ads loaded and error events. adsLoader.addEventListener( google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, onAdsManagerLoaded, false); adsLoader.addEventListener( google.ima.AdErrorEvent.Type.AD_ERROR, onAdError, false); // An event listener to tell the SDK that our content video // is completed so the SDK can play any post-roll ads. const contentEndedListener = function () { adsLoader.contentComplete(); }; videoContent.onended = contentEndedListener; // Request video ads. const adsRequest = new google.ima.AdsRequest(); if (direct) { adsRequest.adTagUrl = directVast; console.log('Outstream DIRECT CAMPAING advert: ' + directVast); videoContent.muted = true; videoContent.volume = 0; outstreamDirectPlayed = true; } else { adsRequest.adTagUrl = iinfoVastUrls[iinfoVastUrlIndex]; console.log('Outstream advert: ' + iinfoVastUrls[iinfoVastUrlIndex]); videoContent.muted = false; videoContent.volume = 1; } // Specify the linear and nonlinear slot sizes. This helps the SDK to // select the correct creative if multiple are returned. // adsRequest.linearAdSlotWidth = outstreamWidth; // adsRequest.linearAdSlotHeight = outstreamHeight; adsRequest.nonLinearAdSlotWidth = 0; adsRequest.nonLinearAdSlotHeight = 0; adsLoader.requestAds(adsRequest); } function setupReplayScreen() { replayScreen.addEventListener('click', function () { iinfoOutstreamPosition.remove(); iinfoVastUrlIndex = 0; outstreamInit(); }); } /** * Sets the 'adContainer' div as the IMA ad display container. */ function createAdDisplayContainer() { // We assume the adContainer is the DOM id of the element that will house // the ads. outstreamDocument.getElementById('videoContent').style.display = 'none'; adDisplayContainer = new google.ima.AdDisplayContainer( outstreamDocument.getElementById('adContainer'), videoContent); } function unmuteAdvert() { adVolume = !adVolume; if (adVolume) { adsManager.setVolume(0.3); outstreamDocument.getElementById('adMuteBtn').innerHTML = ''; } else { adsManager.setVolume(0); outstreamDocument.getElementById('adMuteBtn').innerHTML = ''; } } /** * Loads the video content and initializes IMA ad playback. */ function playAds() { // Initialize the container. Must be done through a user action on mobile // devices. videoContent.load(); adDisplayContainer.initialize(); // setupDimensions(); try { // Initialize the ads manager. Ad rules playlist will start at this time. adsManager.init(1920, 1080, google.ima.ViewMode.NORMAL); // Call play to start showing the ad. Single video and overlay ads will // start at this time; the call will be ignored for ad rules. adsManager.start(); // window.addEventListener('resize', function (event) { // if (adsManager) { // setupDimensions(); // adsManager.resize(outstreamWidth, outstreamHeight, google.ima.ViewMode.NORMAL); // } // }); } catch (adError) { // An error may be thrown if there was a problem with the VAST response. // videoContent.play(); } } /** * Handles the ad manager loading and sets ad event listeners. * @param { !google.ima.AdsManagerLoadedEvent } adsManagerLoadedEvent */ function onAdsManagerLoaded(adsManagerLoadedEvent) { // Get the ads manager. const adsRenderingSettings = new google.ima.AdsRenderingSettings(); adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true; adsRenderingSettings.loadVideoTimeout = 12000; // videoContent should be set to the content video element. adsManager = adsManagerLoadedEvent.getAdsManager(videoContent, adsRenderingSettings); // Add listeners to the required events. adsManager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, onAdError); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED, onContentPauseRequested); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED, onContentResumeRequested); adsManager.addEventListener( google.ima.AdEvent.Type.ALL_ADS_COMPLETED, onAdEvent); // Listen to any additional events, if necessary. adsManager.addEventListener(google.ima.AdEvent.Type.LOADED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.STARTED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.COMPLETE, onAdEvent); playAds(); } /** * Handles actions taken in response to ad events. * @param { !google.ima.AdEvent } adEvent */ function onAdEvent(adEvent) { // Retrieve the ad from the event. Some events (for example, // ALL_ADS_COMPLETED) don't have ad object associated. const ad = adEvent.getAd(); console.log('Outstream event: ' + adEvent.type); switch (adEvent.type) { case google.ima.AdEvent.Type.LOADED: // This is the first event sent for an ad - it is possible to // determine whether the ad is a video ad or an overlay. if (!ad.isLinear()) { // Position AdDisplayContainer correctly for overlay. // Use ad.width and ad.height. videoContent.play(); } outstreamDocument.getElementById('adContainer').style.width = '100%'; outstreamDocument.getElementById('adContainer').style.maxWidth = '640px'; outstreamDocument.getElementById('adContainer').style.height = '360px'; break; case google.ima.AdEvent.Type.STARTED: window.addEventListener('scroll', onActiveView); // This event indicates the ad has started - the video player // can adjust the UI, for example display a pause button and // remaining time. if (ad.isLinear()) { // For a linear ad, a timer can be started to poll for // the remaining time. intervalTimer = setInterval( function () { // Example: const remainingTime = adsManager.getRemainingTime(); // adsManager.pause(); }, 300); // every 300ms } outstreamDocument.getElementById('adMuteBtn').style.display = 'block'; break; case google.ima.AdEvent.Type.ALL_ADS_COMPLETED: if (ad.isLinear()) { clearInterval(intervalTimer); } if (outstreamLastError === 303) { if (isBanner) { renderBanner(); } else { replayScreen.style.display = 'flex'; } } break; case google.ima.AdEvent.Type.COMPLETE: // This event indicates the ad has finished - the video player // can perform appropriate UI actions, such as removing the timer for // remaining time detection. if (ad.isLinear()) { clearInterval(intervalTimer); } if (isBanner) { renderBanner(); } else { replayScreen.style.display = 'flex'; } break; } } /** * Handles ad errors. * @param { !google.ima.AdErrorEvent } adErrorEvent */ function onAdError(adErrorEvent) { // Handle the error logging. console.log(adErrorEvent.getError()); outstreamLastError = adErrorEvent.getError().getErrorCode(); if (!loadNext()) { renderBanner(); } } function renderBanner() { if (isBanner) { console.log('Outstream: Render Banner'); iinfoOutstreamPosition.innerHTML = ""; iinfoOutstreamPosition.style.height = "330px"; iinfoOutstreamPosition.appendChild(bannerDiv); } else { console.log('Outstream: Banner is not set'); } } function loadNext() { iinfoVastUrlIndex++; if (iinfoVastUrlIndex < iinfoVastUrls.length) { iinfoOutstreamPosition.remove(); outstreamInit(); } else { return false; } adVolume = 1; return true; } /** * Pauses video content and sets up ad UI. */ function onContentPauseRequested() { videoContent.pause(); // This function is where you should setup UI for showing ads (for example, // display ad timer countdown, disable seeking and more.) // setupUIForAds(); } /** * Resumes video content and removes ad UI. */ function onContentResumeRequested() { videoContent.play(); // This function is where you should ensure that your UI is ready // to play content. It is the responsibility of the Publisher to // implement this function when necessary. // setupUIForContent(); } function onActiveView() { if (outstreamContainer) { const containerOffset = outstreamContainer.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight/1 && containerOffset.bottom > 0.0) { if (outstreamPaused) { adsManager.resume(); outstreamPaused = false; } return true; } else { if (!outstreamPaused) { adsManager.pause(); outstreamPaused = true; } } } return false; } let outstreamInitInterval; if (typeof cpexPackage !== "undefined") { outstreamInitInterval = setInterval(tryToInitializeOutstream, 100); } else { const wrapper = getWrapper(); if (wrapper) { let outstreamInitialized = false; window.addEventListener('scroll', () => { if (!outstreamInitialized) { const containerOffset = wrapper.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight / 1 && containerOffset.bottom > 0.0) { outstreamInit(); outstreamInitialized = true; } } }); } } function tryToInitializeOutstream() { const wrapper = getWrapper(); if (wrapper) { const containerOffset = wrapper.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight / 1 && containerOffset.bottom > 0.0) { if (cpexPackage.adserver.displayed) { clearInterval(outstreamInitInterval); outstreamInit(); } } } else { clearInterval(outstreamInitInterval); } } }
OSZAR »