V ČR chybí důležité léky. Které jsou nedostupné a proč?

29. 6. 2022

Sdílet

Autor: Depositphotos
Jít s receptem do lékárny se v některých případech začíná podobat loterii. Některé léky opět nejsou k dostání, ačkoli náhrada za ně není.

Dřív lékárníci drželi zásoby léků na měsíc, dnes ví, že u některých položek se vyplatí mít je i na tři měsíce předem. Jejich dodávky jsou totiž nestabilní a žádné jednoznačné vysvětlení pro to často neexistuje. Které léky jsou aktuálně nedostupné a proč?

Co se dozvíte v článku
  1. Na trhu chybí oční antibiotika
  2. Jak zjistit dostupnost léků
  3. Co dělat, když váš lék není na trhu
  4. V ČR chybí lék důležitý při infarktu či mrtvici
  5. Za výpadky může i panika, tvrdí ministerstvo
  6. Kvůli výpadkům lékárny nakupují nové suroviny
  7. Příčin potíží s dostupností léků je více

Na trhu chybí oční antibiotika

„Vracíme se zpátky před rok 1989 a držíme dokonce tříměsíční zásoby, protože výpadky jsou časté a dlouhodobé, ačkoliv jde o základní, život zachraňující léky,“ říká vedoucí lékárník Ústavní lékárny Fakultní nemocnice Královské Vinohrady Lukáš Láznička.

Aktuálně pacienti pociťují například výpadek očních antibiotických kapek a masti Tobrex. Jde o léčivo, které se používá při bakteriálních infekcích povrchu oka, jakou je např. zánět spojivek. „Předepsala bych vám něco jiného, ale ani to nedostanete,“ krčí rameny dětská lékařka, kterou navštěvuje autorka tohoto textu se svými dětmi. „Napíšu vám ho, ale musíte zkoušet obvolávat lékárny. Co vím, tak ještě minulý týden měli několik balení v Nemocnici Na Homolce,“ dodává jedinou radu, která v současné situaci může pomoci. Sehnat léčivo se autorce reportáže nakonec podařilo ve 4. lékárně, byť místo původně předepsaných očních kapek dostala mast.

Antibiotika chyběla přitom už na podzim. Tehdy šlo zejména o sirupy pro nejmenší děti napříč značkami. Tato forma je pro malé pacienty důležitá, protože tablety ještě nedokáží spolknout. 

I Tobrex hlásil výpadky již před několika měsíci. V minulosti chyběly na trhu opakovaně antibiotické masti Framykoin či Ophthalmo-Septonex. Tyto léky podle lékárníků chybí pravidelně, výpadky se ale lékárny naučily pokrývat tak, že nakoupí suroviny a masti lidem namíchají.

Jak zjistit dostupnost léků

  • Dostupnost léku si může ověřit každý v Databázi léčiv na webu SÚKL (zadáte název léčiva a následně se podíváte do záložky Dostupnost), kde ústav zveřejňuje případné přerušení dodávek. Ty musí výrobce povinně hlásit. Tato cesta ale není zcela spolehlivá, protože do databáze se nepropisuje každý výpadek a ne vždy výrobce povinnost splní.
  • Informaci o tom, že lék na trhu chybí, můžete získat od lékaře, který vám jej předepisuje. Ani lékař ji ale nemusí mít, protože se ji nemusí dozvědět.
  • Místo, kde se o výpadku léčiva dozvíte zcela jistě, je lékárna. Ale ani lékárníci nemusí vědět, proč k výpadku došlo, jak dlouho potrvá a kdy lék opět bude na trhu.

Co dělat, když váš lék není na trhu

  • Pokud lék chybí, můžete se poradit se svým lékařem, zda pro vás existuje jiná volba, kterou v lékárně seženete, a tento náhradní lék si nechat předepsat.
  • Jak jsme již dříve upozorňovali na webu Finance.cz, pomoci může i lékárník. Pokud je na trhu jiný lék se stejnou účinnou látkou, může vám vydat ten, který je dostupný.
  • Pokud je lék nenahraditelný, musíte buď čekat (ale pozor, běžný recept má platnost 14 dnů), nebo obíhat či obtelefonovávat lékárny, zda jej někde přece jen nemají. U volně prodejných léků vám může pomoci internet a sortiment online lékáren, u léků na předpis zase to, že část lékárníků vidí do skladových zásob svých kolegů v jiných provozovnách. Tuto možnost serveru Vitalia.cz potvrdil například Michal Petrov, mluvčí sítě lékáren Dr. Max.

V ČR chybí lék důležitý při infarktu či mrtvici

S výpadky se nepotýkají jen pacienti s eRecepty, léky chybí také nemocnicím. Aktuálně například ten s názvem Actilyse. V injekční formě rozpouští krevní sraženiny, takže se používá u pacientů postižených akutním infarktem myokardu či cévní mozkovou příhodou například ve specializovaných tzv. iktových centrech. Jde tedy o lék zachraňující životy. Žádná náhrada za něj neexistuje.

V jeho distribuci jsou potíže téměř pravidelné a táhnou se roky. Už v roce 2013 ministerstvo zdravotnictví na čas rozhodlo, že tento lék nesmí být přeprodán do zahraničí, protože v ČR by pacientům chyběl.

„Do ČR se dodávalo velmi omezené množství. Třeba 200 ampulí pro celou zemi, což je de facto spotřeba jen našeho iktového centra. Už loni byly kráceny dodávky, od letošního jara se ho ale dodává minimální množství a nemáme výhled, že by se situace měla brzy zlepšit,“ podotýká farmaceut Lukáš Láznička.

Web Státního ústavu pro kontrolu léčiv (SÚKL) žádné aktuálně nahlášené výpadky ze strany výrobce neeviduje. Z jeho databáze lze ale vyčíst, že držitel rozhodnutí o registraci informoval o omezené dostupnosti. Ministerstvo zdravotnictví (MZ) ohledně Actilyse letos nevydalo žádné mimořádné opatření, které by omezovalo či zakazovalo jeho vývoz z ČR do zahraničí, tzv. reexport.

Za výpadky může i panika, tvrdí ministerstvo

Podle MZ před časem výrobce oznámil omezení dodávek Actilyse z kapacitních a výrobních důvodů, a to nejen pro ČR. Rezort ale tvrdí, že se daří léčivo do ČR dostávat, a to v počtech někdy lehce převyšujících loňské dodávky. Přesto úřad potvrzuje, že lék chybí.

„Ačkoli doposud nedošlo k žádnému reálnému snížení dodávek léčivých přípravků Actilyse do ČR, evidujeme řadu podnětů odborné veřejnosti ohledně toho, že mají nedostatek těchto léčivých přípravků,“ podotýká mluvčí ministerstva Ondřej Jakob

Jak je tedy možné, že dodávky jsou, a lék přesto chybí? „Současná situace velmi pravděpodobně vznikla v důsledku paniky na trhu ve formě zvýšeného předzásobování z důvodu výše uvedeného oznámení o výrazném snížení dodávek ze strany držitele rozhodnutí o registraci,“ domnívá se mluvčí MZ.

Podobně hovoří SÚKL. „Výpadek léčiva Actilyse hlášen není, protože držitel rozhodnutí o registraci uvádí, že dodává kontinuálně, pouze ve sníženém množství,“ uvádí mluvčí SÚKL Klára Brunclíková. „V letošním roce bylo prozatím na trh dodáno přibližně stejné množství tohoto léčivého přípravku jako v odpovídajícím období loni. Nedostupnost pro jednotlivá zdravotnická zařízení je tedy způsobena spíše nervozitou na úrovni distribuce,“ dodává.

Podle Lukáš Lázničky může být důvodem i to, že se rozšířila síť iktových center, která se specializují na léčbu lidí po infarktu či mrtvici. Navíc interval podávání léku byl zkrácen a lék mohou dostat i pacienti, kteří na něj dříve neměli nárok. Ondřej Jakob na dotazy Vitalia.cz ovšem uvedl, že u Actilyse se indikační kritéria nijak v minulých letech neměnila.

Držitel registrace léku, což je výrobce Boehringer Ingelheim, na základě výzvy MZ a SÚKL nyní dokončuje práce na takovém distribučním modelu, který by měl „optimalizovat dodávky léčivých přípravků Actilyse a umožnit pružně reagovat na požadavky poskytovatelů zdravotních služeb provozujících centra vysoce specializované péče o pacienty s iktem v ČR“. A Ondřej Jakob dodává: „Věříme, že se situace stabilizuje s ohledem na naše aktivity již v následujících týdnech.“ 

Kvůli výpadkům lékárny nakupují nové suroviny

Jenže ČR se nepotýká jen s nedostatky výše jmenovaných léků. Jen za měsíc červen MZ vydalo zatím čtyři mimořádná rozhodnutí, která se týkají reexportů. Konkrétně Sabrilu k léčbě epilepsie, Unasinu na infekční onemocnění horních dýchacích cest a záněty dolních dýchacích cest, léku Cetrotide, jenž se používá u pacientek připravujících se na odběr vajíček, a léku Ultibro Breezhaler pro pacienty s chronickou obstrukční plicní nemocí. Tato mimořádná opatření v podobě zákazu prodeje do zahraničí nebo jeho povinného oznamování přicházejí ve chvíli, kdy MZ obdrží od SÚKL varování, že na trhu hrozí absence důležitého léku.

Z informací od lékárníků a distributorů léčiv vyplývá, že se trh prakticky neustále potýká s nedostatkem různých léčiv. U části z nich se výpadky opakují. „V dnešní době jsou, bohužel, výpadky normální. Pokud je možnost generické záměny léku, je situace jednoduchá. Pokud ji pacient akceptuje, dostane lék jiného názvu, ale se stejnou účinnou látkou. Výpadky se ale týkají i léků, které jsou nenahraditelné a u nich pacientovi říkáme, že nezbývá nic jiného, než obtelefonovat či obejít více lékáren. Případně se spojit s lékařem a hledat takové řešení, aby terapie nebyla přerušena. Jen lékař může pacienta podle jeho zdravotního stavu převést na jinou účinnou látku či jinou aplikační formu,“ vysvětluje prezident České lékárnické komory Aleš Krebs.

Lékárníci malou část těchto potíží dokáží obejít například tím, že lék pacientovi individuálně připraví. Jde to třeba u některých mastí. Zatímco dříve suroviny k jejich výrobě ve větším množství skladem nedrželi, opakovaná nedostupnost některých léčiv to změnila a nyní už se lékárny více předzásobují nejen některými léky, ale i surovinami na jejich výrobu přímo v lékárně.

„Tím, že výpadků je v současné době vyšší množství, než jsme byli zvyklí, tak skupina léků, kterou nahrazujeme individuální přípravou, narůstá a dynamicky se mění. Snažíme se a žádáme o to, aby na trhu byly dostupné i takové suroviny, které tu dříve vůbec nebyly. A to proto, abychom byli schopní nahradit oblíbené a hojně předepisované léky, jež kvůli výpadku dočasně chybí,“ potvrzuje farmaceut Lukáš Láznička.

Takto se ale chovají spíše větší lékárny. V nich často pacient na výrobu takového léčiva nemusí ani čekat, protože lékárny jej připraví předem. Pokud totiž z trhu dočasně zmizí hojně žádaný lék, nemusí mít lékárník obavy, že jeho individuálně vyrobenou náhradu neudá. Ta má kvůli absenci konzervačních látek velmi krátkou expiraci.

Příčin potíží s dostupností léků je více

Proč k výpadkům dochází a jak jim předejít, je velmi složité říci. Žádný jeden hlavní důvod neexistuje. To tedy znamená, že není snadné výpadkům předcházet.

„Příčin může být celá řada a nedá se říci, která z nich je dominantní. Navíc výpadky probíhají velmi dynamicky. Například my lék už nedokážeme objednat, ale pro systém SÚKL to ještě výpadek není. Navíc někdy výrobci výpadek nehlásí, ačkoli tuto povinnosti mají,“ podotýká prezident lékárnické komory.

Za výpadkem můžou být výrobní příčiny, tedy to, že léku nebylo vyrobeno dost nebo se nepotkal se spotřebou. „To se v zimě stalo u antibiotik, protože se sezóna akutních respiračních onemocnění nepotkala s obdobím obvyklé spotřeby. To znamená, že respirační onemocnění obvykle probíhají do února a března, přičemž letos byla protažena do dubna a května, ale to už byly zásoby v ČR vyčerpané a výrobci s distributory je nestíhali rychle doplnit,“ uvádí příklad Aleš Krebs.

Problémy s dodávkami se prohloubily v době, kdy se svět začal potýkat s pandemií nemoci covid-19. Ta mimo jiné přinesla potíže s přepravou zboží z Asie, kde se vyrábí značná část surovin i léčiv. A když už nechybí látky pro výrobu, mohou chybět suroviny, z nichž se vyrábí např. obal. Celosvětová krize žene ceny nahoru, válka na Ukrajině ještě více narušila dodávky např. papíru, a tak se může stát, že vyrobený lék musí čekat třeba na krabičku.

Navíc pokud je výroba léčiva či jeho důležité součásti soustředěna do jednoho či dvou míst ve světě, jakmile dojde k poškození výroby či výrobě chybné šarže, výpadek u účinné látky či léčiva je pak rozsáhlý a zasáhne řadu zemí.

Farmaceutické společnosti zase léta opakují, že úhradové stropy jsou v ČR nastaveny tak nízko, že část produkce raději výrobci dodají jinam. Důvod je logický – v zahraničí mají z prodeje vyšší zisky.

Potíž nastává i v tom, že v době prudkého růstu cen ČR nemá žádný mechanismus automatické valorizace úhradových stropů, tedy maxim vyplácených za lék z veřejného zdravotního pojištění. Ačkoliv výroba a přeprava léku může být teoreticky nákladnější, obchodníci musí počítat se stejnými cenami a maržemi, které byly zafixovány třeba před lety při dohadování, zda lék bude hrazen z veřejných peněz, či nikoli.

Setkali jste se v poslední době s tím, že nebyl k sehnání lék, který jste nutně potřebovali?

Odborná spolupráce:

Mgr. Aleš Krebs, Ph.D.

Prezident České lékárnické komory, předseda Vzdělávací rady farmaceutů, jež působí pod ministerstvem zdravotnictví. Provozuje lékárnu ve Slatinicích na Olomoucku.


PharmDr. Lukáš Láznička

Vedoucí lékárník Ústavní lékárny Fakultní nemocnice Královské Vinohrady, člen představenstva České lékárnické komory.

Autor článku

Redaktorka Vitalia.cz. Vystudovala žurnalistiku a češtinu na Univerzitě Palackého v Olomouci, pracovala v Deníku, na webu TV Nova a iDNES.cz. Píše o zdravotnictví. Je držitelkou novinářských cen Psychiatrické společností ČLS JEP za rok 2021 a 2022. 

'; 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 »