')
// Remove cookie consent
html = html.replace(/'
// Add annotation data
headhtml += '\n'
// Scrollbar colors
headhtml += '\n'
// Add to
parts = html.split('')
html = parts[0] + '\n' + headhtml + '\n' + parts.slice(1).join('')
return cb(html)
}
},
'spotify': {
'name': 'Spotify',
'scripts': function themeSpotifyScripts () {
const script = []
const onload = []
// Define globals
script.push('var iv458,annotations1234;')
script.push('function removeIfExists (e) { if(e && e.remove) { e.remove() }}')
script.push('function decodeHTML652 (s) { return s.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">") }')
// Hide cookies box function
// script.push('function hideCookieBox458 () {if(document.querySelector(".optanon-allow-all")){document.querySelector(".optanon-allow-all").click(); clearInterval(iv458)}}')
// onload.push('iv458 = window.setInterval(hideCookieBox458, 500)')
// Hide footer
script.push('function hideFooter895 () {let f = document.querySelectorAll(".footer div"); if(f.length){removeIfExists(f[0]);removeIfExists(f[1])}}')
script.push('function hideSecondaryFooter895 () {if(document.querySelector(".footer.footer--secondary")){document.querySelector(".footer.footer--secondary").parentNode.removeChild(document.querySelector(".footer.footer--secondary"))}}')
onload.push('hideFooter895()')
onload.push('hideSecondaryFooter895()')
// Hide other stuff
script.push('function hideStuff235 () {')
script.push(' const grayBox = document.querySelector(".column_layout-column_span-initial_content>.dfp_unit.u-x_large_bottom_margin.dfp_unit--in_read"); removeIfExists(grayBox)')
script.push(' removeIfExists(document.querySelector(".header .header-expand_nav_menu"))')
script.push('}')
onload.push('hideStuff235()')
// Show annotations function
script.push('function showAnnotation1234(ev, id) {')
script.push(' ev.preventDefault()')
script.push(' document.querySelectorAll(".song_body-lyrics .referent--yellow.referent--highlighted").forEach((e) => e.className = e.className.replace(/\\breferent--yellow\\b/, "").replace(/\\breferent--highlighted\\b/, ""))')
script.push(' this.className += " referent--yellow referent--highlighted"')
script.push(' if(typeof annotations1234 == "undefined") {')
script.push(' annotations1234 = JSON.parse(document.getElementById("annotationsdata1234").innerHTML)')
script.push(' }')
script.push(' if(id in annotations1234) {')
script.push(' let annotation = annotations1234[id]')
script.push(' let main = document.querySelector(".annotationbox")')
script.push(' main.innerHTML = ""')
script.push(' main.style.display = "block"')
script.push(' const bodyRect = document.body.getBoundingClientRect()')
script.push(' const elemRect = this.getBoundingClientRect()')
script.push(' const top = elemRect.top - bodyRect.top + elemRect.height')
script.push(' main.style.top = top + "px"')
script.push(' main.style.left = "5px"')
script.push(' const div0 = document.createElement("div")')
script.push(' div0.className = "annotationcontent"')
script.push(' main.appendChild(div0)')
script.push(' html = \'
$author
$body
\';')
script.push(' html = html.replace(/\\$body/g, decodeHTML652(annotation.body.html)).replace(/\\$author/g, decodeHTML652(annotation.created_by.name));')
script.push(' div0.innerHTML = html')
script.push(' targetBlankLinks145 (); // Change link target to _blank')
script.push(' window.setTimeout(function() { document.body.addEventListener("click", hideAnnotationOnClick1234);}, 100); // hide on click')
script.push(' }')
script.push('}')
script.push('function hideAnnotationOnClick1234(ev) {')
script.push(' let target = ev.target')
script.push(' while(target) {')
script.push(' if(target.id == "annotationbox") {')
script.push(' return')
script.push(' }')
script.push(' if(target.className && target.className.indexOf("referent") !== -1) {')
script.push(' let id = parseInt(target.dataset.id)')
script.push(' return showAnnotation1234.call(target, ev, id)')
script.push(' }')
script.push(' target = target.parentNode')
script.push(' }')
script.push(' document.body.removeEventListener("click", hideAnnotationOnClick1234);')
script.push(' let main = document.querySelector(".annotationbox")')
script.push(' main.style.display = "none"')
script.push('}')
onload.push('annotations1234 = JSON.parse(document.getElementById("annotationsdata1234").innerHTML);')
// Make song title clickable
script.push('function clickableTitle037() { ')
script.push(' let url = document.querySelector("meta[property=\'og:url\']").content; ')
script.push(' let h1 = document.querySelector(\'.header_with_cover_art-primary_info-title\'); ')
script.push(' h1.innerHTML = \'
\' + h1.innerHTML + \'\'')
// Featuring and album name
script.push(' let h2 = document.querySelector(\'.header_with_cover_art-primary_info-primary_artist\').parentNode; ')
script.push(' document.querySelectorAll(".metadata_unit-label").forEach(function(el) { ')
script.push(' if(el.innerText.toLowerCase().indexOf("feat") !== -1) ')
script.push(' h1.innerHTML += " "+el.parentNode.innerText.trim(); ')
script.push(' else if(el.innerText.toLowerCase().indexOf("album") !== -1) ')
script.push(' h2.innerHTML = h2.innerHTML + " \u2022 " + el.parentNode.querySelector("a").parentNode.innerHTML.trim(); ')
script.push(' }); ')
// Remove other meta like Producer
script.push(' while(document.querySelector("h3")) { ')
script.push(' document.querySelector("h3").remove() ')
script.push(' } ')
script.push('}')
onload.push('clickableTitle037()')
// Change links to target=_blank
script.push('function targetBlankLinks145 () {')
script.push(' const as = document.querySelectorAll(\'body a:not([href|="#"]):not([target=_blank])\')')
script.push(' as.forEach(function(a) {')
script.push(' a.target = "_blank";')
script.push(' })')
script.push('}')
onload.push('window.setTimeout(targetBlankLinks145, 1000)')
if (!annotationsEnabled) {
// Remove all annotations
script.push('function removeAnnotations135() { ')
script.push(' document.querySelectorAll(".song_body-lyrics .referent").forEach(function(a) { ')
script.push(' while(a.firstChild) { ')
script.push(' a.parentNode.insertBefore(a.firstChild, a)')
script.push(' } ')
script.push(' a.remove()')
script.push(' }) ')
script.push('} ')
onload.push('removeAnnotations135()')
}
// Open real page if not in frame
onload.push('if(top==window) {document.location.href = document.querySelector("meta[property=\'og:url\']").content}')
return [script, onload]
},
'combine': function themeSpotifyXombineGeniusResources (script, onload, song, html, annotations, cb) {
let headhtml = ''
// Make annotations clickable
const regex = /annotation-fragment="(\d+)"/g
html = html.replace(regex, 'onclick="showAnnotation1234.call(this, event, $1)"')
// Remove cookie consent
html = html.replace(/'
// Add annotation data
headhtml += '\n'
// CSS
headhtml += '\n\n'
// Add to
parts = html.split('')
html = parts[0] + '\n' + headhtml + '\n' + parts.slice(1).join('')
return cb(html)
}
}
}
themeKey = Object.keys(themes)[0]
theme = themes[themeKey]
function combineGeniusResources (song, html, annotations, cb) {
const [script, onload] = theme.scripts()
return theme.combine(script, onload, song, html, annotations, cb)
}
function onResize () {
let iframe = document.getElementById('lyricsiframe')
if (iframe) {
iframe.style.width = document.getElementById('lyricscontainer').clientWidth - 1 + 'px'
iframe.style.height = (document.querySelector('.Root__nav-bar .navBar').clientHeight + document.querySelector('.now-playing-bar ').clientHeight - document.querySelector('.lyricsnavbar').clientHeight) + 'px'
}
}
function initResize () {
window.addEventListener('mousemove', onMouseMoveResize)
window.addEventListener('mouseup', stopResize)
window.removeEventListener('resize', onResize)
}
function onMouseMoveResize (e) {
optionCurrentSize = 100 - (e.clientX / document.body.clientWidth * 100)
resizeLeftContainer.style.width = (100 - optionCurrentSize) + '%'
resizeContainer.style.width = optionCurrentSize + '%'
}
function stopResize () {
window.removeEventListener('mousemove', onMouseMoveResize)
window.removeEventListener('mouseup', stopResize)
window.addEventListener('resize', onResize)
onResize()
GM.setValue('optioncurrentsize', optionCurrentSize)
}
function getCleanLyricsContainer () {
const topContainer = document.querySelector('.Root__top-container')
if (!document.getElementById('lyricscontainer')) {
topContainer.style.width = (100 - optionCurrentSize) + '%'
topContainer.style.float = 'left'
resizeContainer = document.createElement('div')
resizeContainer.id = 'lyricscontainer'
resizeContainer.style = 'min-height: 100%; width: ' + optionCurrentSize + '%; position: relative; z-index: 1; float:left'
topContainer.parentNode.insertBefore(resizeContainer, topContainer.nextSibling)
} else {
resizeContainer = document.getElementById('lyricscontainer')
resizeContainer.innerHTML = ''
}
resizeLeftContainer = topContainer
return document.getElementById('lyricscontainer')
}
function hideLyrics () {
if (document.getElementById('lyricscontainer')) {
document.getElementById('lyricscontainer').parentNode.removeChild(document.getElementById('lyricscontainer'))
const topContainer = document.querySelector('.Root__top-container')
topContainer.style.width = '100%'
topContainer.style.removeProperty('float')
}
addLyricsButton()
}
function showLyrics (song, searchresultsLengths) {
const container = getCleanLyricsContainer()
const separator = document.createElement('span')
separator.setAttribute('class', 'second-line-separator')
separator.setAttribute('style', 'padding:0px 3px')
separator.appendChild(document.createTextNode('•'))
const bar = document.createElement('div')
bar.setAttribute('class', 'lyricsnavbar')
bar.style.fontSize = '0.7em'
container.appendChild(bar)
// Resize button
const resizeButton = document.createElement('span')
resizeButton.style.fontSize = '1.8em'
resizeButton.style.cursor = 'ew-resize'
resizeButton.style.color = 'white'
resizeButton.appendChild(document.createTextNode('⇹'))
resizeButton.addEventListener('mousedown', initResize)
bar.appendChild(resizeButton)
bar.appendChild(separator.cloneNode(true))
// Hide button
const hideButton = document.createElement('a')
hideButton.href = '#'
hideButton.appendChild(document.createTextNode('Hide'))
hideButton.addEventListener('click', function hideButtonClick (ev) {
ev.preventDefault()
optionAutoShow = false // Temporarily disable showing lyrics automatically on song change
clearInterval(mainIv)
hideLyrics()
})
bar.appendChild(hideButton)
bar.appendChild(separator.cloneNode(true))
// Config button
const configButton = document.createElement('a')
configButton.href = '#'
configButton.appendChild(document.createTextNode('Options'))
configButton.addEventListener('click', function configButtonClick (ev) {
ev.preventDefault()
config()
})
bar.appendChild(configButton)
bar.appendChild(separator.cloneNode(true))
// Wrong lyrics
const wrongLyricsButton = document.createElement('a')
wrongLyricsButton.href = '#'
wrongLyricsButton.appendChild(document.createTextNode('Wrong lyrics'))
wrongLyricsButton.addEventListener('click', function wrongLyricsButtonClick (ev) {
ev.preventDefault()
forgetLyricsSelection(currentTitle, currentArtists, this.dataset.hit)
showSearchField(currentArtists + ' ' + currentTitle)
})
bar.appendChild(wrongLyricsButton)
// Back button
if (searchresultsLengths) {
bar.appendChild(separator.cloneNode(true))
const backbutton = document.createElement('a')
backbutton.href = '#'
if (searchresultsLengths === true) {
backbutton.appendChild(document.createTextNode('Back to search results'))
} else {
backbutton.appendChild(document.createTextNode('Back to search (' + (searchresultsLengths - 1) + ' other result' + (searchresultsLengths === 2 ? '' : 's') + ')'))
}
backbutton.addEventListener('click', function backbuttonClick (ev) {
ev.preventDefault()
addLyrics(true)
})
bar.appendChild(backbutton)
}
const iframe = document.createElement('iframe')
iframe.id = 'lyricsiframe'
container.appendChild(iframe)
const spinner = '
'
if (isFirefox) {
iframe.src = 'data:text/html;charset=utf-8,' + encodeURIComponent(spinner)
} else {
iframe.src = emptySpotifyURL + '?405#html,' + encodeURIComponent(spinner)
}
iframe.style.width = container.clientWidth - 1 + 'px'
iframe.style.height = (document.querySelector('.Root__nav-bar .navBar').clientHeight + document.querySelector('.now-playing-bar ').clientHeight - bar.clientHeight) + 'px'
loadGeniusSong(song, function loadGeniusSongCb (html) {
if (annotationsEnabled) {
loadGeniusAnnotations(song, html, function loadGeniusAnnotationsCb (song, html, annotations) {
combineGeniusResources(song, html, annotations, function combineGeniusResourcesCb (html) {
if (isFirefox) {
iframe.src = 'data:text/html;charset=utf-8,' + encodeURIComponent(html)
} else {
iframe.src = emptySpotifyURL+'#html:scripts,' + encodeURIComponent(html)
}
iframe.style.position = 'fixed'
})
})
} else {
combineGeniusResources(song, html, {}, function combineGeniusResourcesCb (html) {
if (isFirefox) {
iframe.src = 'data:text/html;charset=utf-8,' + encodeURIComponent(html)
} else {
iframe.src = emptySpotifyURL+'#html:scripts,' + encodeURIComponent(html)
}
iframe.style.position = 'fixed'
})
}
})
}
function listSongs (hits, container, query) {
if (!container) {
container = getCleanLyricsContainer()
}
// Back to search button
const backToSearchButton = document.createElement('a')
backToSearchButton.href = '#'
backToSearchButton.appendChild(document.createTextNode('Back to search'))
backToSearchButton.addEventListener('click', function backToSearchButtonClick (ev) {
ev.preventDefault()
if (query) {
showSearchField(query)
} else if (currentArtists) {
showSearchField(currentArtists + ' ' + currentTitle)
} else {
showSearchField()
}
})
const separator = document.createElement('span')
separator.setAttribute('class', 'second-line-separator')
separator.setAttribute('style', 'padding:0px 3px')
separator.appendChild(document.createTextNode('•'))
// Hide button
const hideButton = document.createElement('a')
hideButton.href = '#'
hideButton.appendChild(document.createTextNode('Hide'))
hideButton.addEventListener('click', function hideButtonClick (ev) {
ev.preventDefault()
hideLyrics()
})
// List search results
const trackhtml = '
'
container.innerHTML = '
'
container.insertBefore(hideButton, container.firstChild)
container.insertBefore(separator, container.firstChild)
container.insertBefore(backToSearchButton, container.firstChild)
const ol = container.querySelector('ol.tracklist')
const searchresultsLengths = hits.length
const title = currentTitle
const artists = currentArtists
const onclick = function onclick () {
rememberLyricsSelection(title, artists, this.dataset.hit)
showLyrics(JSON.parse(this.dataset.hit), searchresultsLengths)
}
hits.forEach(function forEachHit (hit) {
let li = document.createElement('li')
li.setAttribute('class', 'tracklist-row')
li.setAttribute('role', 'button')
li.innerHTML = trackhtml.replace(/\$title/g, hit.result.title_with_featured).replace(/\$artist/g, hit.result.primary_artist.name).replace(/\$lyrics_state/g, hit.result.lyrics_state).replace(/\$stats\.pageviews/g, "pageviews" in hit.result.stats ? metricPrefix(hit.result.stats.pageviews, 1) : ' - ')
li.dataset.hit = JSON.stringify(hit)
li.addEventListener('click', onclick)
ol.appendChild(li)
})
}
function addLyrics (force, beLessSpecific) {
let songTitle = document.querySelector('.track-info__name.ellipsis-one-line').innerText
let feat = songTitle.indexOf(' (feat')
if (feat !== -1) {
songTitle = songTitle.substring(0, feat).trim()
}
const musicIsPlaying = document.querySelector('.now-playing-bar .player-controls__buttons .control-button.control-button--circled').className.toLowerCase().indexOf('pause') !== -1
const songArtistsArr = []
document.querySelector('.track-info__artists.ellipsis-one-line').querySelectorAll('a[href^="/artist/"]').forEach((e) => songArtistsArr.push(e.innerText))
let songArtists = songArtistsArr.join(' ')
if (force || (!document.hidden && musicIsPlaying && (currentTitle !== songTitle || currentArtists !== songArtists))) {
currentTitle = songTitle
currentArtists = songArtists
const firstArtist = songArtistsArr[0]
let simpleTitle = songTitle = songTitle.replace(/\s*-\s*.+?$/, '') // Remove anything following the last dash
if (beLessSpecific) {
songArtists = firstArtist
songTitle = simpleTitle
}
let hitFromCache = getLyricsSelection(songTitle, songArtists)
if (!force && hitFromCache) {
showLyrics(hitFromCache, true)
} else {
geniusSearch(songTitle + ' ' + songArtists, function geniusSearchCb (r) {
const hits = r.response.sections[0].hits
if (hits.length === 0) {
hideLyrics()
if (!beLessSpecific && (firstArtist !== songArtists || simpleTitle !== songTitle)) {
// Try again with only the first artist or the simple title
addLyrics(!!force, true)
} else if (force) {
showSearchField()
}
} else if (hits.length === 1) {
showLyrics(hits[0])
} else {
listSongs(hits)
}
})
}
}
}
function searchByQuery (query, container) {
geniusSearch(query, function geniusSearchCb (r) {
const hits = r.response.sections[0].hits
if (hits.length === 0) {
alert('No search results')
} else {
listSongs(hits, container, query)
}
})
}
function showSearchField (query) {
const b = getCleanLyricsContainer()
b.appendChild(document.createTextNode('Search genius.com'))
b.style.paddingRight = '15px'
const input = b.appendChild(document.createElement('input'))
input.className = 'SearchInputBox__input'
input.placeholder = 'Search genius.com...'
if (query) {
input.value = query
} else if (currentArtists) {
input.value = currentArtists
}
input.addEventListener('change', function onSearchLyricsButtonClick () {
if (input.value) {
searchByQuery(input.value, b)
}
})
input.addEventListener('keyup', function onSearchLyricsKeyUp (ev) {
if (ev.keyCode === 13) {
ev.preventDefault()
if (input.value) {
searchByQuery(input.value, b)
}
}
})
document.body.appendChild(b)
input.focus()
}
function addLyricsButton () {
if (document.getElementById('showlyricsbutton')) {
return
}
const b = document.createElement('div')
b.setAttribute('id', 'showlyricsbutton')
b.setAttribute('style', 'position:absolute; top: 0px; right:0px; color:#ffff64; cursor:pointer')
b.setAttribute('title', 'Load lyrics from genius.com')
b.appendChild(document.createTextNode('🅖'))
b.addEventListener('click', function onShowLyricsButtonClick () {
optionAutoShow = true // Temporarily enable showing lyrics automatically on song change
mainIv = window.setInterval(main, 2000)
addLyrics(true)
})
document.body.appendChild(b)
}
function config () {
loadCache()
// Blur background
if (document.querySelector('.Root__top-container')) {
document.querySelector('.Root__top-container').style.filter = 'blur(4px)';
}
if (document.getElementById('lyricscontainer')) {
document.getElementById('lyricscontainer').style.filter = 'blur(1px)';
}
const win = document.createElement('div')
win.setAttribute('id', 'myconfigwin39457845')
win.setAttribute('style', 'position:absolute; top: 10px; right:10px; padding:15px; background:white; border-radius:10%; border:2px solid black; color:black; z-index:10')
let style = win.appendChild(document.createElement('style'))
style.innerHTML += '#myconfigwin39457845 div {margin:2px 0; padding:5px;border-radius: 5px;background-color: #EFEFEF;}'
document.body.appendChild(win)
const h1 = document.createElement('h1')
win.appendChild(h1).appendChild(document.createTextNode('Options'))
const a = document.createElement('a')
a.href = 'https://github.com/cvzi/Spotify-Genius-Lyrics-userscript/issues'
a.style = 'color:blue'
win.appendChild(a).appendChild(document.createTextNode('Report problem: github.com/cvzi/Spotify-Genius-Lyrics-userscript'))
// Switch: Show automatically
let div = win.appendChild(document.createElement('div'))
const checkAutoShow = div.appendChild(document.createElement('input'))
checkAutoShow.type = 'checkbox'
checkAutoShow.id = 'checkAutoShow748'
checkAutoShow.checked = optionAutoShow === true
const onAutoShow = function onAutoShowListener () {
GM.setValue('optionautoshow', checkAutoShow.checked === true)
}
checkAutoShow.addEventListener('click', onAutoShow)
checkAutoShow.addEventListener('change', onAutoShow)
let label = div.appendChild(document.createElement('label'))
label.setAttribute('for', 'checkAutoShow748')
label.appendChild(document.createTextNode(' Automatically show lyrics when new song starts'))
div.appendChild(document.createElement('br'))
div.appendChild(document.createTextNode('(if you disable this, a small button will appear in the top right corner to show the lyrics)'))
// Select: Theme
div = win.appendChild(document.createElement('div'))
div.appendChild(document.createTextNode('Theme: '))
const selectTheme = div.appendChild(document.createElement('select'))
for (let key in themes) {
const option = selectTheme.appendChild(document.createElement('option'))
option.value = key
if (themeKey === key) {
option.selected = true
}
option.appendChild(document.createTextNode(themes[key].name))
}
const onSelectTheme = function onSelectThemeListener () {
if (themeKey !== selectTheme.selectedOptions[0].value) {
theme = themes[selectTheme.selectedOptions[0].value]
addLyrics(true)
}
themeKey = selectTheme.selectedOptions[0].value
GM.setValue('theme', themeKey)
}
selectTheme.addEventListener('change', onSelectTheme)
// Switch: Show annotations
div = win.appendChild(document.createElement('div'))
const checkAnnotationsEnabled = div.appendChild(document.createElement('input'))
checkAnnotationsEnabled.type = 'checkbox'
checkAnnotationsEnabled.id = 'checkAnnotationsEnabled748'
checkAnnotationsEnabled.checked = annotationsEnabled === true
const onAnnotationsEnabled = function onAnnotationsEnabledListener () {
if (checkAnnotationsEnabled.checked !== annotationsEnabled) {
annotationsEnabled = checkAnnotationsEnabled.checked === true
addLyrics(true)
GM.setValue('annotationsenabled', annotationsEnabled)
}
}
checkAnnotationsEnabled.addEventListener('click', onAnnotationsEnabled)
checkAnnotationsEnabled.addEventListener('change', onAnnotationsEnabled)
label = div.appendChild(document.createElement('label'))
label.setAttribute('for', 'checkAnnotationsEnabled748')
label.appendChild(document.createTextNode(' Show annotations'))
// Buttons
div = win.appendChild(document.createElement('div'))
const closeButton = div.appendChild(document.createElement('button'))
closeButton.appendChild(document.createTextNode('Close'))
closeButton.style.color = 'black'
closeButton.addEventListener('click', function onCloseButtonClick () {
win.parentNode.removeChild(win)
// Un-blur background
if(document.querySelector('.Root__top-container')) {
document.querySelector('.Root__top-container').style.filter = '';
}
if (document.getElementById('lyricscontainer')) {
document.getElementById('lyricscontainer').style.filter = '';
}
})
const bytes = metricPrefix(JSON.stringify(selectionCache).length + JSON.stringify(requestCache).length, 2, 1024) + 'Bytes'
const clearCacheButton = div.appendChild(document.createElement('button'))
clearCacheButton.appendChild(document.createTextNode('Clear cache (' + bytes + ')'))
clearCacheButton.style.color = 'black'
clearCacheButton.addEventListener('click', function onClearCacheButtonClick () {
Promise.all([GM.setValue('selectioncache', '{}'), GM.setValue('requestcache', '{}')]).then(function () {
clearCacheButton.innerHTML = 'Cleared'
})
})
}
function main () {
if (document.querySelector('.now-playing')) {
if (optionAutoShow) {
addLyrics()
} else {
addLyricsButton()
}
}
}
(function () {
Promise.all([
GM.getValue('theme', themeKey),
GM.getValue('annotationsenabled', annotationsEnabled)
]).then(function (values) {
if (themes.hasOwnProperty(values[0])) {
themeKey = values[0]
} else {
console.log('Invalid value for theme key: GM.getValue("theme") = ' + values[0])
themeKey = Object.keys(themes)[0]
}
theme = themes[themeKey]
annotationsEnabled = !!values[1]
if (!isFirefox && document.location.href.startsWith(emptySpotifyURL + '#html:scripts,')) {
const [script, onload] = theme.scripts()
document.write(decodeURIComponent(document.location.hash.split('#html:scripts,')[1]))
window.setTimeout(function () {
eval(script.join('\n') + '\n' + onload.join('\n'))
}, 1000)
} else if (!isFirefox && document.location.href.startsWith(emptySpotifyURL + '?405#html,')) {
document.write(decodeURIComponent(document.location.hash.split('#html,')[1]))
} else {
loadCache()
mainIv = window.setInterval(main, 2000)
window.addEventListener('resize', onResize)
}
})
})()