(function (){
'use strict';
var ROOT_SELECTOR='.ep-yt-playlist';
var INFINITE_SCROLL_PX=120;
var INIT_FLAG='epYtPlaylistInit';
var SELECTORS={
queue: {
iframe:     '.ep-yt-queue__iframe',
list:       '.ep-yt-queue__items',
item:       '.ep-yt-queue__item',
activeItem: '.ep-yt-queue__item.is-active',
loader:     '.ep-yt-queue__loader',
loopBtn:    '.ep-yt-queue__loop',
shuffleBtn: '.ep-yt-queue__shuffle',
posCurrent: '.ep-yt-queue__position-current',
scrollAxis: 'y'
},
theatre: {
iframe:     '.ep-yt-theatre__iframe',
list:       '.ep-yt-theatre__strip',
item:       '.ep-yt-theatre__card',
activeItem: '.ep-yt-theatre__card.is-active',
loader:     '.ep-yt-theatre__loader',
loopBtn:    '.ep-yt-theatre__loop',
shuffleBtn: '.ep-yt-theatre__shuffle',
posCurrent: '.ep-yt-theatre__position-current',
navPrev:    '.ep-yt-theatre__nav--prev',
navNext:    '.ep-yt-theatre__nav--next',
scrollAxis: 'x'
},
library: {
iframe:     '.ep-yt-library__modal-iframe',
list:       '.ep-yt-library__grid',
item:       '.ep-yt-library__card',
activeItem: '.ep-yt-library__card.is-active',
loader:     '.ep-yt-library__loader',
modal:      '.ep-yt-library__modal',
modalClose: '.ep-yt-library__modal-close',
posCurrent: '.ep-yt-library__position-current',
scrollAxis: 'y'
},
spotlight: {
iframe:     '.ep-yt-spotlight__iframe',
list:       '.ep-yt-spotlight__rail',
item:       '.ep-yt-spotlight__rail-card',
activeItem: '.ep-yt-spotlight__rail-card.is-active',
loader:     '.ep-yt-spotlight__loader',
loopBtn:    '.ep-yt-spotlight__loop',
shuffleBtn: '.ep-yt-spotlight__shuffle',
posCurrent: '.ep-yt-spotlight__position-current',
heroTitle:  '.ep-yt-spotlight__hero-title',
heroDesc:   '.ep-yt-spotlight__hero-desc',
scrollAxis: 'y'
},
cinema: {
iframe:     '.ep-yt-cinema__iframe',
list:       '.ep-yt-cinema__items',
item:       '.ep-yt-cinema__item',
activeItem: '.ep-yt-cinema__item.is-active',
loader:     '.ep-yt-cinema__loader',
loopBtn:    '.ep-yt-cinema__loop',
shuffleBtn: '.ep-yt-cinema__shuffle',
posCurrent: '.ep-yt-cinema__position-current',
playPrev:     '.ep-yt-cinema__prev',
playNext:     '.ep-yt-cinema__next',
overlayOpen:  '.ep-yt-cinema__open-queue',
overlayClose: '.ep-yt-cinema__close-queue',
overlay:      '.ep-yt-cinema__overlay',
scrollAxis: 'y'
},
magazine: {
iframe:     '.ep-yt-magazine__iframe',
list:       '.ep-yt-magazine__rail',
item:       '.ep-yt-magazine__rail-item',
activeItem: '.ep-yt-magazine__rail-item.is-active',
loader:     '.ep-yt-magazine__loader',
loopBtn:    '.ep-yt-magazine__loop',
shuffleBtn: '.ep-yt-magazine__shuffle',
posCurrent: '.ep-yt-magazine__position-current',
heroTitle:  '.ep-yt-magazine__hero-title',
heroDesc:   '.ep-yt-magazine__hero-desc',
readMore:   '.ep-yt-magazine__readmore',
scrollAxis: 'y'
}};
function ready(fn){
if(document.readyState!=='loading') fn();
else document.addEventListener('DOMContentLoaded', fn);
}
function $$(root, sel){ return Array.prototype.slice.call(root.querySelectorAll(sel)); }
function $(root, sel){ return root.querySelector(sel); }
function getLayout(root){
var l=root.getAttribute('data-layout')||'queue';
return SELECTORS[l] ? l:'queue';
}
function swapVideoId(iframe, vid){
if(!iframe||!vid) return;
try {
var src=iframe.src;
var next=src.replace(/(\/embed\/)([^?&"'>]+)(.*)?/, '$1' + vid + '$3');
if(/[?&]autoplay=0/.test(next)){
next=next.replace(/([?&])autoplay=0/, '$1autoplay=1');
}else if(next.indexOf('autoplay=')===-1){
next +=(next.indexOf('?')===-1 ? '?':'&') + 'autoplay=1';
}
iframe.src=next;
} catch (err){  }}
function setActive(root, sel, item){
$$(root, sel.activeItem).forEach(function (el){ el.classList.remove('is-active'); });
if(item){
item.classList.add('is-active');
var list=$(root, sel.list);
if(list&&typeof item.scrollIntoView==='function'){
var listRect=list.getBoundingClientRect();
var itemRect=item.getBoundingClientRect();
var off=sel.scrollAxis==='x'
? (itemRect.left < listRect.left||itemRect.right > listRect.right)
: (itemRect.top < listRect.top||itemRect.bottom > listRect.bottom);
if(off){
item.scrollIntoView({ block: 'nearest', inline: 'nearest', behavior: 'smooth' });
}}
}}
function updateCounter(root, sel){
var current=$(root, sel.posCurrent);
var active=$(root, sel.activeItem);
if(current&&active){
current.textContent=active.getAttribute('data-index')||'';
}}
function playByIndex(root, sel, index, state){
var items=$$(root, sel.item);
if(!items.length) return;
if(index >=items.length){
if(state.loop) index=0;
else return;
}
if(index < 0) index=0;
var item=items[index];
var iframe=$(root, sel.iframe);
var vid=item.getAttribute('data-vid');
if(!vid||!iframe) return;
swapVideoId(iframe, vid);
setActive(root, sel, item);
updateCounter(root, sel);
}
function visualIndex(root, sel, item){
var items=$$(root, sel.item);
return items.indexOf(item);
}
function attachClickToSwap(root, sel, state){
var list=$(root, sel.list);
if(!list) return;
list.addEventListener('click', function (event){
var item=event.target.closest(sel.item);
if(!item||!list.contains(item)) return;
event.preventDefault();
state.cursor=visualIndex(root, sel, item);
playByIndex(root, sel, state.cursor, state);
if(sel.heroTitle||sel.heroDesc){
var titleEl=sel.heroTitle ? $(root, sel.heroTitle):null;
var descEl=sel.heroDesc  ? $(root, sel.heroDesc):null;
if(titleEl){
var t=item.getAttribute('data-title')||'';
if(t) titleEl.textContent=t;
}
if(descEl){
var d=item.getAttribute('data-description')||'';
if(d!=='') descEl.textContent=d;
}}
if(sel.modal&&state.layout==='library'){
var modal=$(root, sel.modal);
if(modal) modal.hidden=false;
}});
}
function attachLayoutExtras(root, sel, state){
if(state.layout==='cinema'){
var openBtn=$(root, sel.overlayOpen);
var closeBtn=$(root, sel.overlayClose);
var overlay=$(root, sel.overlay);
if(openBtn&&overlay) openBtn.addEventListener('click', function (){ overlay.classList.add('is-open'); });
if(closeBtn&&overlay) closeBtn.addEventListener('click', function (){ overlay.classList.remove('is-open'); });
}
if(state.layout==='library'){
var modal=$(root, sel.modal);
var close=$(root, sel.modalClose);
if(close&&modal) close.addEventListener('click', function (){ modal.hidden=true; });
if(modal) modal.addEventListener('click', function (event){
if(event.target===modal) modal.hidden=true;
});
}
if(state.layout==='magazine'){
var more=$(root, sel.readMore);
var desc=$(root, sel.heroDesc);
if(more&&desc) more.addEventListener('click', function (){
desc.classList.toggle('is-expanded');
more.textContent=desc.classList.contains('is-expanded')
? (more.getAttribute('data-collapse-label')||'Show less')
: (more.getAttribute('data-expand-label')||'Read more');
});
}}
function attachLoopShuffle(root, sel, state){
var loopBtn=$(root, sel.loopBtn);
var shuffleBtn=$(root, sel.shuffleBtn);
if(loopBtn){
loopBtn.addEventListener('click', function (){
state.loop = !state.loop;
loopBtn.setAttribute('aria-pressed', String(state.loop));
});
}
if(shuffleBtn){
shuffleBtn.addEventListener('click', function (){
state.shuffle = !state.shuffle;
shuffleBtn.setAttribute('aria-pressed', String(state.shuffle));
if(state.shuffle) shuffleOrder(root, sel, state);
else restoreOrder(root, sel, state);
});
}}
function shuffleOrder(root, sel, state){
var list=$(root, sel.list);
if(!list) return;
var items=$$(root, sel.item);
if(!state.originalOrder){
state.originalOrder=items.map(function (i){ return i.getAttribute('data-vid'); });
}
var shuffled=items.slice();
for (var i=shuffled.length - 1; i > 0; i--){
var j=Math.floor(Math.random() * (i + 1));
var tmp=shuffled[i]; shuffled[i]=shuffled[j]; shuffled[j]=tmp;
}
shuffled.forEach(function (el){ list.appendChild(el); });
var active=$(root, sel.activeItem);
state.cursor=visualIndex(root, sel, active);
}
function restoreOrder(root, sel, state){
if(!state.originalOrder) return;
var list=$(root, sel.list);
if(!list) return;
var byVid={};
$$(root, sel.item).forEach(function (el){
byVid[el.getAttribute('data-vid')]=el;
});
state.originalOrder.forEach(function (vid){
if(byVid[vid]) list.appendChild(byVid[vid]);
});
var active=$(root, sel.activeItem);
state.cursor=visualIndex(root, sel, active);
}
function attachInfiniteScroll(root, sel, state){
var list=$(root, sel.list);
if(!list) return;
list.addEventListener('scroll', function (){
if(state.loadingNext||!state.nextPageToken) return;
var remaining=sel.scrollAxis==='x'
? list.scrollWidth - list.scrollLeft - list.clientWidth
: list.scrollHeight - list.scrollTop - list.clientHeight;
if(remaining < INFINITE_SCROLL_PX){
fetchNextPage(root, sel, state);
}});
var fillRounds=0;
function fillUntilScrollable(){
if(!state.nextPageToken||state.loadingNext) return;
if(fillRounds >=3) return;
var room=sel.scrollAxis==='x'
? list.scrollWidth <=list.clientWidth + 8
: list.scrollHeight <=list.clientHeight + 8;
if(room){
fillRounds++;
fetchNextPage(root, sel, state).then(function (){
setTimeout(fillUntilScrollable, 50);
});
}}
setTimeout(fillUntilScrollable, 50);
}
function attachPlaybackNavButtons(root, sel, state){
var prev=sel.playPrev ? $(root, sel.playPrev):null;
var next=sel.playNext ? $(root, sel.playNext):null;
function step(delta){
var items=$$(root, sel.item);
if(!items.length) return;
var active=$(root, sel.activeItem);
state.cursor=active ? visualIndex(root, sel, active):state.cursor;
var target=state.cursor + delta;
if(target >=items.length) target=state.loop ? 0:items.length - 1;
if(target < 0) target=state.loop ? items.length - 1:0;
state.cursor=target;
playByIndex(root, sel, target, state);
}
if(prev) prev.addEventListener('click', function (){ step(-1); });
if(next) next.addEventListener('click', function (){ step(1); });
}
function attachTheatreNavButtons(root, sel){
var prev=$(root, sel.navPrev);
var next=$(root, sel.navNext);
var list=$(root, sel.list);
if(!list) return;
function pageBy(dir){
list.scrollBy({ left: dir * list.clientWidth * 0.8, behavior: 'smooth' });
}
if(prev) prev.addEventListener('click', function (){ pageBy(-1); });
if(next) next.addEventListener('click', function (){ pageBy(1); });
}
function fetchNextPage(root, sel, state){
if(state.loadingNext||!state.nextPageToken) return Promise.resolve();
state.loadingNext=true;
var loader=$(root, sel.loader);
if(loader) loader.hidden=false;
var data=window.embedpressFrontendData||{};
var restUrl=(data.rest_url||'/wp-json/') + 'embedpress/v1/youtube-playlist-items';
var params=new URLSearchParams({
playlist_id: state.playlistId,
page_token:  state.nextPageToken,
page_size:   String(state.pageSize),
offset:      String($$(root, sel.item).length),
layout:      state.layout
});
var headers={ 'Accept': 'application/json' };
if(data.rest_nonce) headers['X-WP-Nonce']=data.rest_nonce;
return fetch(restUrl + '?' + params.toString(), { headers: headers, credentials: 'same-origin' })
.then(function (r){ return r.ok ? r.json():Promise.reject(r); })
.then(function (payload){
if(payload&&payload.html){
var list=$(root, sel.list);
list.insertAdjacentHTML('beforeend', payload.html);
}
state.nextPageToken=payload&&payload.next_page_token ? payload.next_page_token:'';
root.setAttribute('data-next-page-token', state.nextPageToken);
if(state.shuffle){
shuffleOrder(root, sel, state);
}else{
state.originalOrder=$$(root, sel.item).map(function (i){
return i.getAttribute('data-vid');
});
}})
.catch(function (){ state.nextPageToken=''; })
.finally(function (){
state.loadingNext=false;
if(loader) loader.hidden=true;
});
}
function attachEndedListener(root, sel, state){
var iframe=$(root, sel.iframe);
if(!iframe) return;
try {
iframe.contentWindow.postMessage(JSON.stringify({
event: 'listening',
id:    state.id
}), '*');
} catch (e){  }}
function handleEnded(state){
var root=state.root;
var sel=SELECTORS[state.layout];
if(state.shuffle){
var items=$$(root, sel.item);
if(items.length <=1) return;
var next=state.cursor;
for (var attempt=0; attempt < 5; attempt++){
next=Math.floor(Math.random() * items.length);
if(next!==state.cursor) break;
}
state.cursor=next;
playByIndex(root, sel, next, state);
}else{
state.cursor++;
playByIndex(root, sel, state.cursor, state);
}}
function bindGlobalMessageRouter(){
if(window[INIT_FLAG + 'MsgBound']) return;
window[INIT_FLAG + 'MsgBound']=true;
window.addEventListener('message', function (event){
if(typeof event.data!=='string') return;
if(event.origin.indexOf('youtube.com')===-1&&event.origin.indexOf('youtube-nocookie.com')===-1) return;
var data;
try { data=JSON.parse(event.data); } catch (e){ return; }
if(data&&data.event==='onStateChange'&&data.info===0){
$$(document, ROOT_SELECTOR).forEach(function (root){
var sel=SELECTORS[getLayout(root)];
var iframe=$(root, sel.iframe);
if(iframe&&iframe.contentWindow===event.source){
var state=root[INIT_FLAG + 'State'];
if(state) handleEnded(state);
}});
}});
}
function initOne(root){
if(root[INIT_FLAG]) return;
root[INIT_FLAG]=true;
var layout=getLayout(root);
var sel=SELECTORS[layout];
var active=$(root, sel.activeItem)||$(root, sel.item);
var state={
root:           root,
layout:         layout,
id:             'epyp-' + Math.random().toString(36).slice(2, 9),
playlistId:     root.getAttribute('data-playlist-id')||'',
pageSize:       parseInt(root.getAttribute('data-pagesize'), 10)||6,
nextPageToken:  root.getAttribute('data-next-page-token')||'',
cursor:         active ? visualIndex(root, sel, active):0,
loop:           false,
shuffle:        false,
loadingNext:    false,
originalOrder:  null
};
root[INIT_FLAG + 'State']=state;
attachClickToSwap(root, sel, state);
attachLoopShuffle(root, sel, state);
attachInfiniteScroll(root, sel, state);
attachEndedListener(root, sel, state);
attachLayoutExtras(root, sel, state);
attachPlaybackNavButtons(root, sel, state);
if(layout==='theatre') attachTheatreNavButtons(root, sel);
}
function init(){
bindGlobalMessageRouter();
$$(document, ROOT_SELECTOR).forEach(initOne);
if(typeof window.MutationObserver==='function'){
var obs=new MutationObserver(function (mutations){
mutations.forEach(function (m){
Array.prototype.forEach.call(m.addedNodes||[], function (node){
if(node.nodeType!==1) return;
if(node.matches&&node.matches(ROOT_SELECTOR)) initOne(node);
if(node.querySelectorAll){
Array.prototype.forEach.call(node.querySelectorAll(ROOT_SELECTOR), initOne);
}});
});
});
obs.observe(document.body, { childList: true, subtree: true });
}}
ready(init);
})();