There are 22 previous versions of this script.
the source is over 100KB, syntax highlighting in the browser is too slow
// ==UserScript==
// @name YouTube Lyrics by Rob W
// @description Instant Lyrics for YouTube, Grooveshark and Spotify. Multiple sources and a manual search form ensure that most lyrics are found. To configure this script, visit https://rob.lekensteyn.nl/youtubelyrics/
// @author Rob W <gwnRob@gmail.com>
// @namespace Rob W
// @version 3.5.1
// @website http://userscripts.org/scripts/show/112070
// @updateURL http://userscripts.org/scripts/source/112070.meta.js
// @downloadURL http://userscripts.org/scripts/source/112070.user.js
// @include http://www.youtube.com/*
// @include https://www.youtube.com/*
// @include http://grooveshark.com/*
// @include http://html5.grooveshark.com/*
// @include http://retro.grooveshark.com/*
// @include http://play.spotify.com/*
// @include https://play.spotify.com/*
// @include http://rob.lekensteyn.nl/youtubelyrics/*
// @include https://rob.lekensteyn.nl/youtubelyrics/*
// @icon https://rob.lekensteyn.nl/youtubelyrics/icons/32.png
// @run-at document-start
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_deleteValue
// @grant GM_listValues
// @grant GM_xmlhttpRequest
// ==/UserScript==
/**
* (c) 2013 Rob W <gwnRob@gmail.com>
* Website: https://rob.lekensteyn.nl/youtubelyrics/
*
* Distributed under the MIT license (http://opensource.org/licenses/MIT)
*
* Milestones:
* 4 sep 2011 - Initial release of version 1 and 2 branches
* 8 jan 2013 - Public release of version 3 branch - new features and a modular codebase
* 9 jan 2013 - Released Safari extension
* 10 jan 2013 - Released Opera extension
* 11 jan 2013 - Released Firefox add-on
* 5 feb 2013 - Published Internet Explorer extension
* 12 feb 2013 - Grooveshark support (13 Feb: added support for HTML5 and Retro Grooveshark)
*
* Websites:
* - https://rob.lekensteyn.nl/youtubelyrics/
* - http://userscripts.org/scripts/show/112070
* - https://chrome.google.com/webstore/detail/lifkpflabnobkgbjpcmocmgcajlecbcp
* - https://addons.mozilla.org/firefox/addon/youtube-lyrics-by-rob-w/
* - https://addons.opera.com/en/extensions/details/youtube-lyrics-by-rob-w/
*
* Contact:
* - Rob W <gwnRob@gmail.com>
*
* Distributed in the following forms:
* - Chrome extension
* - Firefox add-on
* - Safari extension
* - Opera extension
* - Internet Explorer extension (32 and 64 bits)
* - Hybrid userscript (Greasemonkey / NinjaKit / Tampermonkey / Opera)
*
* A full list plus links to the distributed versions can be found at
* https://rob.lekensteyn.nl/youtubelyrics/#get-extension
*
* Change log:
* https://rob.lekensteyn.nl/youtubelyrics/CHANGELOG
*/
(function() {
var e, t, r;
(function(n) {
function o(e, t) {
return S.call(e, t);
}
function i(e, t) {
var r, n, o, i, s, a, c, l, u, p, d = t && t.split("/"), f = v.map, h = f && f["*"] || {};
if (e && "." === e.charAt(0)) if (t) {
for (d = d.slice(0, d.length - 1), e = d.concat(e.split("/")), l = 0; e.length > l; l += 1) if (p = e[l],
"." === p) e.splice(l, 1), l -= 1; else if (".." === p) {
if (1 === l && (".." === e[2] || ".." === e[0])) break;
l > 0 && (e.splice(l - 1, 2), l -= 2);
}
e = e.join("/");
} else 0 === e.indexOf("./") && (e = e.substring(2));
if ((d || h) && f) {
for (r = e.split("/"), l = r.length; l > 0; l -= 1) {
if (n = r.slice(0, l).join("/"), d) for (u = d.length; u > 0; u -= 1) if (o = f[d.slice(0, u).join("/")],
o && (o = o[n])) {
i = o, s = l;
break;
}
if (i) break;
!a && h && h[n] && (a = h[n], c = l);
}
!i && a && (i = a, s = c), i && (r.splice(0, s, i), e = r.join("/"));
}
return e;
}
function s(e, t) {
return function() {
return f.apply(n, L.call(arguments, 0).concat([ e, t ]));
};
}
function a(e) {
return function(t) {
return i(t, e);
};
}
function c(e) {
return function(t) {
g[e] = t;
};
}
function l(e) {
if (o(y, e)) {
var t = y[e];
delete y[e], b[e] = !0, d.apply(n, t);
}
if (!o(g, e) && !o(b, e)) throw Error("No " + e);
return g[e];
}
function u(e) {
var t, r = e ? e.indexOf("!") : -1;
return r > -1 && (t = e.substring(0, r), e = e.substring(r + 1, e.length)), [ t, e ];
}
function p(e) {
return function() {
return v && v.config && v.config[e] || {};
};
}
var d, f, h, m, g = {}, y = {}, v = {}, b = {}, S = Object.prototype.hasOwnProperty, L = [].slice;
h = function(e, t) {
var r, n = u(e), o = n[0];
return e = n[1], o && (o = i(o, t), r = l(o)), o ? e = r && r.normalize ? r.normalize(e, a(t)) : i(e, t) : (e = i(e, t),
n = u(e), o = n[0], e = n[1], o && (r = l(o))), {
f: o ? o + "!" + e : e,
n: e,
pr: o,
p: r
};
}, m = {
require: function(e) {
return s(e);
},
exports: function(e) {
var t = g[e];
return t !== void 0 ? t : g[e] = {};
},
module: function(e) {
return {
id: e,
uri: "",
exports: g[e],
config: p(e)
};
}
}, d = function(e, t, r, i) {
var a, u, p, d, f, v, S = [];
if (i = i || e, "function" == typeof r) {
for (t = !t.length && r.length ? [ "require", "exports", "module" ] : t, f = 0; t.length > f; f += 1) if (d = h(t[f], i),
u = d.f, "require" === u) S[f] = m.require(e); else if ("exports" === u) S[f] = m.exports(e),
v = !0; else if ("module" === u) a = S[f] = m.module(e); else if (o(g, u) || o(y, u) || o(b, u)) S[f] = l(u); else {
if (!d.p) throw Error(e + " missing " + u);
d.p.load(d.n, s(i, !0), c(u), {}), S[f] = g[u];
}
p = r.apply(g[e], S), e && (a && a.exports !== n && a.exports !== g[e] ? g[e] = a.exports : p === n && v || (g[e] = p));
} else e && (g[e] = r);
}, e = t = f = function(e, t, r, o, i) {
return "string" == typeof e ? m[e] ? m[e](t) : l(h(e, t).f) : (e.splice || (v = e,
t.splice ? (e = t, t = r, r = null) : e = n), t = t || function() {}, "function" == typeof r && (r = o,
o = i), o ? d(n, e, t, r) : setTimeout(function() {
d(n, e, t, r);
}, 15), f);
}, f.config = function(e) {
return v = e, f;
}, r = function(e, t, r) {
t.splice || (r = t, t = []), o(g, e) || o(y, e) || (y[e] = [ e, t, r ]);
}, r.amd = {
jQuery: !0
};
})(), r("config-greasemonkey", [], function() {
var e = {};
return e.getItem = function(e, t) {
setTimeout(function() {
var r = GM_getValue(e);
"string" == typeof r && (r = JSON.parse(r)), t(r);
}, 0);
}, e.setItem = function(e, t, r) {
t = JSON.stringify(t), setTimeout(function() {
GM_setValue(e, t), r(!0);
}, 0);
}, e.removeItem = function(e, t) {
setTimeout(function() {
GM_deleteValue(e), t(!0);
}, 0);
}, e.clear = function(e) {
setTimeout(function() {
for (var t = GM_listValues(), r = 0; t.length > r; r++) GM_deleteValue(t[r]);
e(!0);
}, 0);
}, e.init = function() {}, e;
}), r("config-userscript", [], function() {
var e = function(e, t, r) {
console && console.log(e + ": " + r);
}, t = {}, r = "rwYTL.", n = "robw_ytl", o = "/robots.txt#lyrics-settings", i = [ "http://www.youtube.com", "https://www.youtube.com" ], s = i.concat("https://rob.lekensteyn.nl", "http://rob.lekensteyn.nl");
return t.getItem = function(t, n) {
var o = localStorage.getItem(r + t);
if ("string" == typeof o) try {
o = JSON.parse(o);
} catch (i) {
e("config.getItem error: " + i), o = void 0;
}
n(o);
}, t.setItem = function(t, n, o) {
var i = !1;
try {
localStorage.setItem(r + t, JSON.stringify(n)), i = !0;
} catch (s) {
e("config.setItem error: " + s);
}
o(i);
}, t.removeItem = function(e, t) {
localStorage.removeItem(r + e), t(!0);
}, t.clear = function(e) {
for (var t = [], n = localStorage.length - 1; n >= 0; --n) {
var o = localStorage.key(n);
o && 0 === o.indexOf(r) && t.push(o);
}
t.forEach(function(e) {
localStorage.removeItem(e);
}), e(!0);
}, t.init = function() {
function r() {
return (location.protocol + "//" + location.host).toLowerCase();
}
function a() {
return (location.pathname + location.hash).toLowerCase();
}
if (-1 !== i.indexOf(r()) && a() === o && (addEventListener("message", function(e) {
if (-1 !== s.indexOf(e.origin) && "string" == typeof e.data) {
var r = e.data.match(/^(@(\D+)\d+)(getItem|setItem|removeItem|clear)(\[[\S\s]*\])$/);
if (r) {
var o = r[1], i = r[2];
if (n === i) {
var a = r[3], c = JSON.parse(r[4]);
c.push(function() {
var t = [].slice.call(arguments), r = o + "callback" + JSON.stringify(t);
e.source.postMessage(r, e.origin);
}), t[a].apply(t, c);
}
}
}
}, !0), parent.postMessage("Hello", "*")), -1 !== s.indexOf(r()) && a() !== o) {
var c = {}, l = {}, u = {};
i.forEach(function(e) {
u[e] = {
frame: null,
queue: [],
useless: null
};
}), addEventListener("message", function(t) {
if (-1 !== s.indexOf(t.origin) && "string" == typeof t.data) if ("Hello" !== t.data) {
var r = t.data.match(/^(@(\D+)\d+)callback(\[[\S\s]*\])$/);
if (r) {
var o = r[1], i = r[2];
if (i === n) {
var a = JSON.parse(r[3]);
l[o] ? l[o](a) : e("Callback not found for ID " + o);
}
}
} else {
clearTimeout(c[t.origin]), u[t.origin].useless = !1;
for (var p; p = u[t.origin].queue.shift(); ) p(t.source);
}
}, !0);
var p = function(e, t, r, i) {
var s = "@" + n + (0 | 1e9 * Math.random()), a = s + t + JSON.stringify(r), p = u[e];
if (l[s] = function(e) {
delete l[s], i.apply(this, e);
}, null !== p.useless) p.useless ? l[s]([]) : p.frame.contentWindow.postMessage(a, e); else if (p.queue.push(function(t) {
t.postMessage(a, e);
}), !p.frame) {
p.frame = document.createElement("iframe"), p.frame.style.cssText = "border:0;margin:0;width:1px;height:1px;pointer-events: none;",
p.frame.src = e + o;
var d = function() {
p.useless !== !1 && (p.useless = !0), p.frame.removeEventListener("error", d, !0),
l[s] && l[s]([]);
};
p.frame.addEventListener("error", d, !0);
var f = function() {
p.frame.removeEventListener("load", f, !0), p.useless !== !1 && (c[e] = setTimeout(d, 2e3));
};
p.frame.addEventListener("load", f, !0), (document.body || document.documentElement).appendChild(p.frame);
}
}, d = function(e, r) {
var n = t[e], o = "getItem" === e;
t[e] = function() {
var s = [].slice.call(arguments), a = s.pop(), c = o ? null : !0, l = 0, u = function(e) {
o ? (null === c || void 0 === c) && (c = e) : c = c && e, ++l === i.length && a(c);
};
n.apply(t, s.concat(u));
for (var d = 0; i.length > d; d++) {
var f = i[d];
f !== r && p(f, e, s, u);
}
};
};
-1 !== i.indexOf(r()) ? (d("setItem", r()), d("removeItem", r()), d("clear", r())) : (d("setItem"),
d("getItem"), d("removeItem"), d("clear"));
}
}, t;
}), r("config", [ "config-greasemonkey", "config-userscript" ], function(e, t) {
return "function" == typeof GM_getValue && "function" == typeof GM_setValue && "function" == typeof GM_listValues && (t = e),
t.init(), t;
}), r("setwmode", [], function() {
function e(e) {
if (!/^opaque$/i.test(e.getAttribute("wmode"))) {
var t, r;
t = e.parentNode, r = e.nextSibling, t.removeChild(e), e.setAttribute("wmode", "opaque"),
t.insertBefore(e, r);
}
}
function t() {
var t = !1;
setTimeout(function() {
t = !0;
}, 6e4);
var r = setInterval(function() {
var n = document.getElementsByTagName("embed")[0];
n ? (clearInterval(r), e(n)) : t && clearInterval(r);
}, 50);
}
return function() {
if (!(0 > Object.prototype.toString.call(window.HTMLElement).indexOf("Constructor") || /mac/i.test(navigator.platform))) {
var r = document.getElementsByTagName("embed")[0];
r ? e(r) : t();
}
};
}), r("domready", [], function() {
function e() {
clearInterval(r);
for (var e; e = n.shift(); ) e();
}
function t() {
r = setInterval(function() {
"complete" === document.readyState && e();
}, 50), document.addEventListener("DOMContentLoaded", e, !0);
}
var r, n = [];
return function(e) {
e && ("complete" === document.readyState ? e() : (void 0 === r && t(), n.push(e)));
};
}), r("processRequest-greasemonkey", [ "require", "exports", "module" ], function(e, t) {
function r(e) {
var t = e.url, r = {
url: t,
abort: function() {
o && o.abort();
}
}, o = GM_xmlhttpRequest({
method: e.method || "GET",
url: t,
headers: e.headers,
onload: function(i) {
var s = i.status, a = i.responseText;
r.abort = n, o = null, s >= 200 && 300 > s || 304 === s ? e.found({
url: t,
responseText: a
}) : e.fail({
url: t
});
},
onerror: function() {
r.abort = n, o = null, e.fail({
url: t
});
},
data: e.payload
});
o && e.afterSend(r);
}
var n = function() {};
t.processRequest = r;
}), r("processRequest-cors", [ "require", "exports", "module" ], function(e, t) {
function r(e, t) {
var i = e.url, s = new XMLHttpRequest(), a = {
url: i,
abort: function() {
s && s.abort();
}
}, c = "http:" === location.protocol ? "http:" : "https:";
if (s.open(e.method || "GET", c + "//cors-anywhere.herokuapp.com/" + i, !0), s.setRequestHeader("X-Requested-With", "XMLHttpRequest"),
e.headers) for (var l = Object.keys(e.headers), u = 0; l.length > u; u++) {
var p = l[u];
if (n.call(e.headers, p)) {
var d = e.headers[p];
s.setRequestHeader(p, d);
}
}
return s.onload = function() {
var n = s.status, c = s.statusText, l = s.responseText, u = 333 === n && s.getResponseHeader("Location");
if (i = s.getResponseHeader("X-Request-URL") || i, a.abort = o, s = null, 333 === n) if (t = +t ? +t + 1 : 1,
u && 5 >= t) {
var p = +/\d+/.exec(c);
307 !== p && 308 !== p && (e.method = "GET", e.payload = null), e.url = u;
var d = r(e, t);
a.url = d.url, a.abort = d.abort, d = null;
} else e.fail({
url: i
}); else n >= 200 && 300 > n || 304 === n ? e.found({
url: i,
responseText: l
}) : e.fail({
url: i
});
}, s.onerror = function() {
a.abort = o, s = null, e.fail({
url: i
});
}, s.send(e.payload), s && e.afterSend(a), a;
}
var n = Object.prototype.hasOwnProperty, o = function() {};
t.processRequest = r;
}), r("processRequest", [ "processRequest-greasemonkey", "processRequest-cors" ], function(e, t) {
return "function" == typeof GM_xmlhttpRequest ? e : t;
}), r("ScrapedSource", [ "require", "exports", "module" ], function(e, t) {
function r(e) {
return this instanceof r ? (this.parseOptions(e), this.validate(), void 0) : (n("ScrapedSource", "invalid_constructor_call", 'Constructor cannot be called as a function. Use "new ScrapedSource(options)" instead of "ScrapedSource(options)"'),
void 0);
}
var n = function(e, t, r) {
var n = Error(e + ": " + r);
throw n.type = t, n;
}, o = /^\$[A-Za-z]+$/, i = /\$\{([A-Za-z]+)\}|\$([A-Za-z]+)/g;
r.Scheme = {
identifier: "string",
disabled: [ "undefined", "boolean" ],
url_result: [ "string", "function" ],
method_result: [ "undefined", "string" ],
payload_result: [ "undefined", "string", "function" ],
headers_result: [ "undefined", "object" ],
process_result: "function",
url_search: [ "string", "function" ],
method_search: [ "undefined", "string" ],
payload_search: [ "undefined", "string", "function" ],
headers_search: [ "undefined", "object" ],
process_search: "function"
}, r.StrictScheme = !1, r.prototype.disabled = !1, r.prototype.validate = function() {
var e = this;
return Object.keys(this.constructor.Scheme).every(function(t) {
return e.validateKey(t, e[t]);
});
}, r.prototype.validateKey = function(e, t) {
if (!this.constructor || !this.constructor.Scheme) return n("ScrapedSource::validateKey", "scheme_not_found", 'The caller\'s constructor must have a property "Scheme"!'),
!1;
var r = this.constructor.Scheme[e];
if (!r) {
if (!o.test(e)) return this.constructor.StrictScheme ? (n("ScrapedSource::validateKey", "unknown_key", "Unknown key " + e + ", forbidden by strict scheme!"),
!1) : !0;
r = "function";
}
Array.isArray(r) || (r = [ r ]);
var i = typeof t;
return -1 === r.indexOf(i) ? (n("ScrapedSource::validateKey", "type_mismatch", 'typeof "' + e + '" must be "' + r + '"! Actual type: "' + i + '"'),
!1) : !0;
}, r.prototype.parseOptions = function(e) {
if ("object" != typeof e) return n("ScrapedSource::parseOptions", "type_mismatch", "Argument options is required and must be an object!"),
!1;
var t = this;
return Object.keys(e).every(function(r) {
var n = t.validateKey(r, e[r]);
return n && (t[r] = e[r]), n;
});
}, r.prototype.get_url = function(e, t) {
var r = this, o = r["url_" + e];
"function" == typeof o && (o = o.call(r, t)), "string" != typeof o && n("ScrapedSource::get_url", "type_mismatch", "url_" + e + " is not a string.");
var s = !0;
return o = o.replace(i, function(e, o, i) {
return o = "$" + (o || i), "function" == typeof r[o] ? r[o](t) : (n("ScrapedSource::get_url", "invalid_parameter", "No function found for " + o),
s = !1, void 0);
}), s ? o : null;
}, r.prototype.getMethod = function(e) {
var t = this["method_" + e];
return "string" == typeof t ? t : null;
}, r.prototype.getHeaders = function(e, t) {
var r = this, n = r["headers_" + e];
return "function" == typeof n && n.call(r, t), !n || "object" != typeof n || n instanceof Array ? null : n;
}, r.prototype.getPayload = function(e, t) {
var r = this, o = r["payload_" + e];
if ("function" == typeof o && o.call(r, t), "string" != typeof o) return null;
var s = !0;
return o = o.replace(i, function(e, o, i) {
return o = "$" + (o || i), "function" == typeof r[o] ? r[o](t) : (n("ScrapedSource::getPayload", "invalid_parameter", "No function found for " + o),
s = !1, void 0);
}), s ? o : null;
}, t.ScrapedSource = r;
}), r("InfoProvider", [ "require", "exports", "module", "processRequest", "ScrapedSource" ], function(e, t) {
function r(e) {
this.parseSources(e);
}
var n = e("processRequest").processRequest, o = e("ScrapedSource").ScrapedSource, i = Object.prototype.hasOwnProperty, s = function(e, t, r) {
var n = Error(e + ": " + r);
throw n.type = t, n;
}, a = function(e, t) {
if (t) {
for (var r in t) i.call(t, r) && (e[r] = t[r]);
return e;
}
}, c = function(e, t) {
var r = [].slice.call(arguments, 2);
return function() {
return e.apply(t, r);
};
};
r.prototype.parseSources = function(e) {
if (!(e instanceof Array)) return s("InfoProvider::parseSources", "type_mismatch", "The only argument must be an array of ScrapedSource instances!"),
void 0;
var t = [];
e.forEach(function(e, r) {
e instanceof o ? t.push(e) : s("InfoProvider::parseSources", "type_mismatch", "Source " + r + " is not a ScrapedSource instance!");
}), this.sources = t, this.sourceCount = e.length;
}, r.prototype.query = function(e, t, r, o) {
function i(e, r) {
if (++w > 7) return v(), s("InfoProvider::query:_processURL", "redirect_loop", "Too many redirects"),
void 0;
var o = {
url: e.redir,
afterSend: S,
fail: v,
found: function(e) {
e.tempData = r, l(e);
}
}, i = "result", a = d.getMethod(i, t);
a && "GET" !== a.toUpperCase() && (o.payload = d.getPayload(i, t), o.headers = d.getHeaders(i, t)),
n(o);
}
function l(e) {
g.url = e.url, d.process_result(e.responseText, {
fail: v,
found: function(e) {
e.redir ? i(e, e.tempData) : b(e);
}
}, {
url: e.url,
query: t,
tempData: e.tempData
});
}
function u(e) {
g.url = e.redir || e.url, d.process_search(e.responseText, {
fail: v,
found: i
}, {
url: e.url,
query: t,
tempData: e.tempData
});
}
var p = this;
if (p.abort(), "function" != typeof r || !t || !e) return s("InfoProvider::query", "invalid_args", "Usage: function( String type, object query, function callback(result) )"),
void 0;
o = +o || 0;
var d = p.sources[o], f = !1, h = p.lastTimeAborted, m = a({}, t), g = {
sourceIndex: o,
sourceCount: p.sourceCount,
sourceIdentifier: "<unknown>",
searchTerms: t.searchTerms,
url: "",
retry: c(p.query, p, e, m, r, o),
query: t,
abort: null
};
p.sourceCount > o + 1 ? g.next = c(p.query, p, e, m, r, o + 1) : g.restart = c(p.query, p, e, m, r);
var y = function(e, t, n) {
if (!f && p.lastTimeAborted === h) {
f = n;
var o = {};
a(o, g), a(o, t), o.type = e, r(o);
}
}, v = function(e) {
y("fail", e, !0);
}, b = function(e) {
y("found", e, !0);
}, S = function(e) {
p._abort = e.abort, y("fetching", e, !1);
};
if (!d) return v(), void 0;
d.$SEARCHTERMS && (g.searchTerms = d.$SEARCHTERMS(t));
var L = d.get_url(e, t);
if (g.url = L, g.sourceIdentifier = d.identifier, !L) return v(), void 0;
var w = 0, x = {
url: L,
afterSend: S,
fail: v,
found: function(t) {
f || ("search" === e ? u(t) : l(t));
}
}, A = d.getMethod(e, t);
A && (x.method = A, "GET" !== A.toUpperCase() && (x.payload = d.getPayload(e, t),
x.headers = d.getHeaders(e, t))), n(x);
}, r.prototype.lastTimeAborted = 0, r.prototype.abort = function() {
this.lastTimeAborted++;
var e = this._abort;
e && (this._abort = null, e());
}, t.InfoProvider = r;
}), r("normalize_accents", [ "require", "exports", "module" ], function(e, t) {
var r = Object.prototype.hasOwnProperty, n = {
a: [ "ª", "à", "á", "â", "ã", "ä", "å", "ā", "ă", "ą", "ǎ", "ȁ", "ȃ", "ȧ", "ᵃ", "ḁ", "ẚ", "ạ", "ả", "ₐ", "a" ],
A: [ "À", "Á", "Â", "Ã", "Ä", "Å", "Ā", "Ă", "Ą", "Ǎ", "Ȁ", "Ȃ", "Ȧ", "ᴬ", "Ḁ", "Ạ", "Ả", "A" ],
b: [ "ᵇ", "ḃ", "ḅ", "ḇ", "b" ],
B: [ "ᴮ", "Ḃ", "Ḅ", "Ḇ", "B" ],
c: [ "ç", "ć", "ĉ", "ċ", "č", "ᶜ", "ⅽ", "c" ],
C: [ "Ç", "Ć", "Ĉ", "Ċ", "Č", "Ⅽ", "C" ],
d: [ "ď", "ᵈ", "ḋ", "ḍ", "ḏ", "ḑ", "ḓ", "ⅾ", "d" ],
D: [ "Ď", "ᴰ", "Ḋ", "Ḍ", "Ḏ", "Ḑ", "Ḓ", "Ⅾ", "D" ],
e: [ "è", "é", "ê", "ë", "ē", "ĕ", "ė", "ę", "ě", "ȅ", "ȇ", "ȩ", "ᵉ", "ḙ", "ḛ", "ẹ", "ẻ", "ẽ", "ₑ", "e" ],
E: [ "È", "É", "Ê", "Ë", "Ē", "Ĕ", "Ė", "Ę", "Ě", "Ȅ", "Ȇ", "Ȩ", "ᴱ", "Ḙ", "Ḛ", "Ẹ", "Ẻ", "Ẽ", "E" ],
f: [ "ᶠ", "ḟ", "f" ],
F: [ "Ḟ", "℉", "F" ],
g: [ "ĝ", "ğ", "ġ", "ģ", "ǧ", "ǵ", "ᵍ", "ḡ", "g" ],
G: [ "Ĝ", "Ğ", "Ġ", "Ģ", "Ǧ", "Ǵ", "ᴳ", "Ḡ", "G" ],
h: [ "ĥ", "ȟ", "ʰ", "ḣ", "ḥ", "ḧ", "ḩ", "ḫ", "ẖ", "ℎ", "h" ],
H: [ "Ĥ", "Ȟ", "ᴴ", "Ḣ", "Ḥ", "Ḧ", "Ḩ", "Ḫ", "H" ],
i: [ "ì", "í", "î", "ï", "ĩ", "ī", "ĭ", "į", "ǐ", "ȉ", "ȋ", "ᵢ", "ḭ", "ỉ", "ị", "ⁱ", "i" ],
I: [ "Ì", "Í", "Î", "Ï", "Ĩ", "Ī", "Ĭ", "Į", "İ", "Ǐ", "Ȉ", "Ȋ", "ᴵ", "Ḭ", "Ỉ", "Ị", "I" ],
j: [ "ĵ", "ǰ", "ʲ", "j" ],
J: [ "Ĵ", "ᴶ", "J" ],
k: [ "ķ", "ǩ", "ᵏ", "ḱ", "ḳ", "ḵ", "k" ],
K: [ "Ķ", "Ǩ", "ᴷ", "Ḱ", "Ḳ", "Ḵ", "K", "K" ],
l: [ "ĺ", "ļ", "ľ", "ˡ", "ŀ", "ḷ", "ḻ", "ḽ", "ⅼ", "l" ],
L: [ "Ĺ", "Ļ", "Ľ", "ᴸ", "Ḷ", "Ḻ", "Ḽ", "Ⅼ", "L" ],
m: [ "ᵐ", "ḿ", "ṁ", "ṃ", "ⅿ", "m" ],
M: [ "ᴹ", "Ḿ", "Ṁ", "Ṃ", "Ⅿ", "M" ],
n: [ "ñ", "ń", "ņ", "ň", "ʼn", "ṅ", "ṇ", "ṉ", "ṋ", "n" ],
N: [ "Ñ", "Ń", "Ņ", "Ň", "ᴺ", "Ṅ", "Ṇ", "Ṉ", "Ṋ", "N" ],
o: [ "º", "ò", "ó", "ô", "õ", "ö", "ō", "ŏ", "ő", "ǒ", "ǫ", "ȍ", "ȏ", "ȯ", "ᵒ", "ọ", "ỏ", "o" ],
O: [ "Ò", "Ó", "Ô", "Ö", "Õ", "Ō", "Ŏ", "Ő", "Ǒ", "Ǫ", "Ȍ", "Ȏ", "Ȯ", "ᴼ", "Ọ", "Ỏ", "O" ],
p: [ "ᵖ", "ṕ", "ṗ", "p" ],
P: [ "ᴾ", "Ṕ", "Ṗ", "P" ],
q: [ "q" ],
Q: [ "Q" ],
r: [ "ŕ", "ŗ", "ř", "ȑ", "ȓ", "ʳ", "ᵣ", "ṙ", "Ṛ", "ṛ", "ṟ", "r" ],
R: [ "Ŕ", "Ŗ", "Ř", "Ȑ", "Ȓ", "ᴿ", "Ṙ", "Ṟ", "R" ],
s: [ "ś", "ŝ", "ş", "š", "ș", "ṡ", "ṣ", "s" ],
S: [ "Ś", "Ŝ", "Ş", "Š", "Ș", "Ṡ", "Ṣ", "S" ],
t: [ "ţ", "ť", "ț", "ᵗ", "ṫ", "ṭ", "ṯ", "ṱ", "ẗ", "t" ],
T: [ "Ţ", "Ť", "Ț", "ᵀ", "Ṫ", "Ṭ", "Ṯ", "Ṱ", "T" ],
u: [ "ù", "ú", "û", "ü", "ũ", "ū", "ŭ", "ů", "ű", "ư", "ǔ", "ȕ", "ȗ", "ᵘ", "ᵤ", "ṳ", "ṵ", "ṷ", "ụ", "ủ", "u" ],
U: [ "Ù", "Ú", "Ü", "Û", "Ũ", "Ū", "Ŭ", "Ů", "Ű", "Ų", "Ư", "Ǔ", "Ȕ", "Ȗ", "ᵁ", "Ṳ", "Ṵ", "Ṷ", "Ụ", "Ủ", "U" ],
v: [ "ṽ", "ṿ", "ᵛ", "ᵥ", "v" ],
V: [ "Ṽ", "Ṿ", "ⱽ", "V" ],
w: [ "ŵ", "ʷ", "ẁ", "ẃ", "ẅ", "ẇ", "ẉ", "ẘ", "w" ],
W: [ "Ŵ", "ᵂ", "Ẁ", "Ẃ", "Ẅ", "Ẇ", "Ẉ", "W" ],
x: [ "ˣ", "ẋ", "ẍ", "ₓ", "x" ],
X: [ "Ẋ", "Ẍ", "X" ],
y: [ "ý", "ÿ", "ŷ", "ȳ", "ʸ", "ẏ", "ẙ", "ỳ", "ỵ", "ỷ", "ỹ", "y" ],
Y: [ "Ý", "Ŷ", "Ÿ", "Ȳ", "Ẏ", "Ỳ", "Ỵ", "Ỷ", "Ỹ", "Y" ],
z: [ "ź", "ż", "ž", "ẑ", "ẓ", "ẕ", "z" ],
Z: [ "Ź", "Ż", "Ž", "Ẑ", "Ẓ", "Ẕ", "Z" ]
}, o = {}, i = "";
for (var s in n) if (r.call(n, s)) for (var a = n[s], c = 0; a.length > c; c++) o[a[c]] = s,
i += a[c];
i = RegExp("[" + i + "]", "gi"), t.normalize_accents = function(e) {
return e ? e.replace(i, function(e) {
return r.call(o, e) ? o[e] : e;
}) : e;
};
}), r("SourceScraperUtils", [ "require", "exports", "module", "normalize_accents" ], function(e, t) {
var r = e("normalize_accents").normalize_accents, n = function(e, t, r) {
console && console.log(e + ": " + r);
}, o = {};
o.toStringArray = function(e, t) {
if (!e || !(e = e.firstChild)) return [];
t || (t = {});
var r = {};
for (r.tags = t.tags || /^(?:[bui]|strong|em)$/i, r.flushBefore = t.flushBefore || /^br$/i,
r.flushAfter = t.flushAfter, r.lineAfterFlush = t.lineAfterFlush, r.isEndNode = t.isEndNode,
r.tmpLine = "", r.lines = [], i(e, r), r.tmpLine && r.lines.push(r.tmpLine); r.lines.length && !r.lines[0].trim(); ) r.lines.shift();
for (var n = r.lines.length; --n > 0 && !r.lines[n].trim(); ) r.lines.pop();
return r.lines;
};
var i = function(e, t) {
if (e) do {
if (t.isEndNode && t.isEndNode(e)) return;
if (3 === e.nodeType) t.tmpLine += e.nodeValue; else if (1 === e.nodeType) {
var r = e.tagName;
t.flushBefore && t.flushBefore.test(r) && (t.lines.push(t.tmpLine), t.tmpLine = ""),
t.tags && t.tags.test(r) && i(e.firstChild, t), t.flushAfter && t.flushAfter.test(r) && (t.tmpLine && (t.lines.push(t.tmpLine),
t.tmpLine = ""), t.lineAfterFlush && t.lineAfterFlush.test(r) && t.lines.push(""));
}
} while (e = e.nextSibling);
};
try {
new DOMParser().parseFromString("", "text/html").body, o.toDOM = function(e) {
return new DOMParser().parseFromString(e, "text/html");
};
} catch (s) {
if (o.toDOM = function(e) {
var t = document.implementation.createHTMLDocument("");
return e && !/^\s+$/.test(e) && (t.open(), t.write(e + "</html>"), t.close()), t;
}, window.opera) o.toDOM = function(e) {
var t = document.implementation.createHTMLDocument("");
return e = e.replace(/<img\s/gi, "<img src "), t.documentElement.innerHTML = e,
t;
}; else try {
if (!o.toDOM("<body><p></p></body>").querySelector("p")) return o.toDOM = function(e) {
var t = document.implementation.createHTMLDocument("");
return t.documentElement.innerHTML = e, t;
}, void 0;
} catch (s) {
o.toDOM = function(e) {
var t = /<title\b[^>]*>([\S\s]+)<\/title/i.exec(e);
if (t) {
var r = document.createElement("div");
t = t[1].split(/<\/textarea/i)[0], r.innerHTML = "<textarea>" + t + "</textarea>",
t = r.firstChild.value, r = null;
} else t = "";
e = e.replace(/^\s*<!doctype[^>]*>/i, ""), e = e.replace(/<(link|image)\b/gi, "$& href=data: "),
e = e.replace(/<(img|script|style|video|audio|source|bgsound)\b/gi, "$& src=data: "),
e = e.replace(/<\/?(object|applet)\b/gi, "$&dp"), e = e.replace(/<style\b/gi, "$& disabled "),
e = e.replace(/\bo([Nn])/g, "o$1").replace(/\bO([Nn])/g, "O$1"), e = e.replace(/\b(style\s*=)/gi, "s$1");
var n;
e = e.replace(/<body\b/i, "<s tub></s>$&"), document.implementation.createHTMLDocument ? n = document.implementation.createHTMLDocument(t) : (n = document.createElement("html"),
n.documentElement = n, n.getElementById = function(e) {
return n.querySelector("#" + ("" + e).replace(/\W/g, "\\$&"));
}, n.head = n.appendChild(document.createElement("head")), n.title = t, n.body = n.appendChild(document.createElement("body"))),
n.body.innerHTML = e;
var o = n.body.querySelector("s[tub]");
if (o && o.parentNode === n.body) {
for (var i; (i = n.body.firstChild) != o; ) n.head.appendChild(i);
n.body.removeChild(o);
}
return n;
};
}
}
o.normalize_accents = r, o.search = {}, o.search.isSearchURL = function(e) {
return /^https?:\/\/m\.bing\.com\//.test(e);
}, o.search.get_url = function(e) {
var t = "http://m.bing.com/search?q=", r = e.query;
return e.site && (r = "site:" + e.site + " " + r), t += encodeURIComponent(r);
}, o.search.getResultsFromResponse = function(e) {
if (!e || "string" != typeof e) return [];
for (var t, r = [], o = /<a href="(\/ins\?[^"]*?&url=([A-Za-z0-9+\/=_]+)&[^"]+)/g; null !== (t = o.exec(e)); ) {
var i, s = t[2];
try {
for (var a = s.split("_"), c = 0; a.length > c; ++c) 0 === c ? i = "" : i += 1 === c ? "?" : "&",
i += window.atob(a[c]);
} catch (l) {
n("SourceScraperUtils:search:getResultsFromResponse", "atob_error", "Failed to decode the URL, " + l),
i = t[1].replace(/&/g, "&");
}
r.push(i);
}
return r;
}, t.SourceScraperUtils = o;
}), r("LyricsSource", [ "require", "exports", "module", "ScrapedSource", "SourceScraperUtils" ], function(e, t) {
function r(e) {
o.call(this, e);
}
function n(e, t) {
return t && t.keepAccents || (e = i.normalize_accents(e)), e;
}
var o = e("ScrapedSource").ScrapedSource, i = e("SourceScraperUtils").SourceScraperUtils;
r.prototype = Object.create(o.prototype), r.prototype.constructor = r, r.Scheme = {
identifier: "string",
disabled: [ "undefined", "boolean" ],
homepage: "string",
description: [ "undefined", "string" ],
url_result: [ "string", "function" ],
method_result: [ "undefined", "string" ],
payload_result: [ "undefined", "string", "function" ],
headers_result: [ "undefined", "object" ],
process_result: "function",
url_search: [ "string", "function" ],
method_search: [ "undefined", "string" ],
payload_search: [ "undefined", "string", "function" ],
headers_search: [ "undefined", "object" ],
process_search: "function"
}, r.prototype.handleSearch = function(e, t) {
return this.process_lyrics(e, t);
}, r.prototype.$ARTIST$SONG = function(e, t) {
return e += "", e = e.replace(/\([^)]*\)/g, ""), e = e.replace(/\[[^\]]*\]/g, ""),
e = n(e, t), e = e.replace(/ +/g, " "), e = e.trim();
}, r.prototype.$ARTIST = function(e, t) {
return this.$ARTIST$SONG(e.artist + "", t);
}, r.prototype.$SONG = function(e, t) {
return this.$ARTIST$SONG(e.song + "", t);
}, r.prototype.$SEARCHTERMS = function(e, t) {
if (!e.videotitle) {
if (e.searchTerms) return e.searchTerms;
if (e.artist && e.song) return e.artist + " - " + e.song;
}
var r = e.videotitle + "";
return r = r.replace(/\([^)]*\)/g, " "), r = r.replace(/\[[^\]]*\]/g, " "), r = r.replace(/\b(ft|feat)\b[^\-]+/i, ""),
r = r.replace(/\bhd\b/i, ""), r = r.replace(/(?:w.(?:th)? ?)?((?:on)?.?screen ?)?lyrics?/i, ""),
r = r.replace(/\b(?:(?:piano|guitar|drum|acoustic|instrument(?:al)?) ?)?cover( by [^ )\]]+)?/i, ""),
r = r.replace(/\b(?:recorded )?live (?:at|@|on).+$/i, ""), r = r.replace(/\b\d{1,2}[\-.\/]\d{1,2}[\-.\/](?:(?:1[789]|20)\d{2}|\d{2})\b/, ""),
r = r.replace(/[(\[][^\])]*(?:20|19)\d{2}[^\])]*[)\]]/, ""), r = r.replace(/\b1[789]\d{2}|20\d{2}\b/, ""),
r = r.replace(/\bYouTube\b/gi, ""), r = r.replace(/\bre.?uploaded\b/i, ""), r = r.replace(/\bhigh[\- ]?quality\b/i, ""),
r = r.replace(/\boffici?al\b/i, ""), r = r.replace(/\b(minecraft|rsmv|mmv|(?:(?:naruto|bleach|avatar|toradora|final ?fantasy ?\d{0,2})[^a-z0-9]+)?amv)/i, ""),
r = r.replace(/\b(?:full )?music\b/gi, ""), r = r.replace(/\bdemo\b/i, ""), r = r.replace(/\bfan(?:[\- ]?(?:video|made))?\b/i, ""),
r = r.replace(/\b(videos?|audio|acoustic)/gi, ""), r = r.replace(/\b(on ?)?iTunes\b/i, ""),
r = r.replace(/(^|[^a-z0-9])(?:240|360|480)p\b/i, ""), r = r.replace(/\.(3gp?[2p]|as[fx]|avi|flv|m[4o]v|mpe?g?[34]|rm|webm|wmv)\s*$/i, ""),
r = n(r, t), r = r.replace(/(?:^|\s)([^a-z0-9 ])(\1+)(?=\s|$)/gi, " "), r = r.replace(/^[\s\-']+|[\s\-']+$/g, ""),
r = r.replace(/\s{2,}/g, " ");
}, r.prototype.$encSEARCHTERMS = function(e, t) {
return encodeURIComponent(this.$SEARCHTERMS(e), t);
}, t.LyricsSource = r;
}), r("sources/lyrics.wikia.com", [ "require", "exports", "module", "LyricsSource", "SourceScraperUtils" ], function(e, t) {
var r = e("LyricsSource").LyricsSource, n = e("SourceScraperUtils").SourceScraperUtils;
t.source = new r({
disabled: !1,
identifier: "lyrics.wikia.com",
homepage: "http://lyrics.wikia.com/",
description: "The biggest lyrics database, containing millions of lyrics in several languages.",
url_result: "http://lyrics.wikia.com/$ARTIST:$SONG",
url_search: function(e) {
return n.search.get_url({
site: "lyrics.wikia.com",
query: '"This song is performed by" ' + this.$SEARCHTERMS(e)
});
},
process_result: function(e, t) {
var r = n.toDOM(e), o = r.querySelector(".lyricbox");
if (!o) {
var i = r.querySelector(".redirectText a[href]");
if (i && (i = i.getAttribute("href") || "", "/" === i.charAt(0) && (i = "http://lyrics.wikia.com" + i),
i)) return t.found({
url: i
}), void 0;
}
var s = n.toStringArray(o);
if (s.length) {
var a = r.title.split(" Lyrics - Lyric Wiki")[0].replace(":", " - ");
t.found({
lyrics: s,
title: a
});
} else t.fail();
},
process_search: function(e, t) {
for (var r = n.search.getResultsFromResponse(e), o = 0; r.length > o; o++) {
var i = r[o];
if (/^https?:\/\/lyrics\.wikia\.com\/(?!Category:)(?!User:)(?!Special:)[^:]+:./i.test(i)) return t.found({
redir: i
}), void 0;
}
t.fail();
},
$ARTIST$SONG: function(e, t) {
return (t || (t = {})).keepAccents = !0, e = r.prototype.$ARTIST$SONG.call(this, e, t),
e = e.replace(/ /g, "_"), e = e.replace(/^_+|_+$/g, ""), e = e.replace(/(_|^)(.)/g, function(e, t, r) {
return t + r.toUpperCase();
});
},
$ARTIST: function(e, t) {
var n = r.prototype.$ARTIST.call(this, e, t);
return /^(Category|User|Special)$/i.test(n) && (n += "_(Artist)"), n;
}
});
}), r("sources/lyrics.com", [ "require", "exports", "module", "LyricsSource", "SourceScraperUtils" ], function(e, t) {
var r = e("LyricsSource").LyricsSource, n = e("SourceScraperUtils").SourceScraperUtils;
t.source = new r({
disabled: !1,
identifier: "lyrics.com",
homepage: "http://www.lyrics.com/",
description: "Millions of lyrics in several languages.",
url_result: "http://www.lyrics.com/$SONG-lyrics-$ARTIST.html",
method_search: "POST",
headers_search: {
"Content-Type": "application/x-www-form-urlencoded"
},
payload_search: "what=all&keyword=$encSEARCHTERMS",
url_search: "http://www.lyrics.com/search.php?what=all&keyword=$encSEARCHTERMS",
process_result: function(e, t) {
var r = n.toDOM(e), o = r.querySelector("#lyrics,#lyric_space"), i = o && o.querySelector("a[href]");
if (i && /^\s*Submit Lyrics\s*$/i.test(i.textContent)) return t.fail(), void 0;
var s = n.toStringArray(o, {
tags: /^(?:[buiap]|div|strong|em)$/i,
flushBefore: /^(p|br|div)$/i,
flushAfter: /^(p|br|div)$/i
});
if (s.length) {
var a = r.title.replace(/\s+Lyrics$/, "");
t.found({
lyrics: s,
title: a
});
} else t.fail();
},
process_search: function(e, t) {
var r = n.toDOM(e), o = r.querySelector('a[href^="http://www.lyrics.com/search.php?what=rd"][href*="&rd="][href*="-lyrics-"]'), i = o && /&rd=([^&#]+)/.exec(o.getAttribute("href"));
i ? (i = "http://www.lyrics.com/" + i[1], t.found({
redir: i
})) : t.fail();
},
$ARTIST$SONG: function(e, t) {
return e = r.prototype.$ARTIST$SONG.call(this, e, t), e = e.toLowerCase(), e = e.replace(/[^a-z0-9\- ]/g, ""),
e = e.replace(/ /g, "-"), e = e.replace(/-{2,}/, "-"), e = e.replace(/^-|-$/, "");
}
});
}), r("sources/metrolyrics.com", [ "require", "exports", "module", "LyricsSource", "SourceScraperUtils" ], function(e, t) {
var r = e("LyricsSource").LyricsSource, n = e("SourceScraperUtils").SourceScraperUtils;
t.source = new r({
disabled: !1,
identifier: "metrolyrics.com",
homepage: "http://www.metrolyrics.com/",
description: "Millions of lyrics in several languages.",
url_result: "http://m.metrolyrics.com/$SONG-lyrics-$ARTIST.html",
url_search: function(e) {
return n.search.get_url({
site: "metrolyrics.com",
query: this.$SEARCHTERMS(e)
});
},
process_result: function(e, t, r) {
var o = n.toDOM(e), i = o.querySelector(".lyricsbody,.gnlyricsbody"), s = n.toStringArray(i);
if (s.length) {
var a = o.title.replace(/\s+Lyrics$/, ""), c = r.url.replace(/^(https?:\/\/)m\./, "$1www.");
t.found({
lyrics: s,
title: a,
url: c
});
} else t.fail();
},
process_search: function(e, t) {
for (var r = n.search.getResultsFromResponse(e), o = 0; r.length > o; o++) {
var i = r[o];
if (/^https?:\/\/(m|www)\.metrolyrics\.com\/[a-z0-9\-]+-lyrics-[a-z0-9\-]+\.html$/i.test(i)) return i = i.replace(/^(https?:\/\/)www\./, "$1m."),
t.found({
redir: i
}), void 0;
}
t.fail();
},
$ARTIST$SONG: function(e, t) {
return e = r.prototype.$ARTIST$SONG.call(this, e, t), e = e.toLowerCase(), e = e.replace(/([a-z])!([a-z])/g, "$1i$2"),
e = e.replace(/[^a-z0-9+\- ]/g, ""), e = e.replace(/[\- ]+/g, "-"), e = e.replace(/^-+|-+$/g, "");
}
});
}), r("sources/lyricsmania.com", [ "require", "exports", "module", "LyricsSource", "SourceScraperUtils" ], function(e, t) {
var r = e("LyricsSource").LyricsSource, n = e("SourceScraperUtils").SourceScraperUtils;
t.source = new r({
disabled: !0,
identifier: "lyricsmania.com",
homepage: "http://www.lyricsmania.com/",
description: "Millions of English, French, German, Spanish and Italian lyrics (and others).",
url_result: "http://www.lyricsmania.com/$SONG_lyrics_$ARTIST.html",
url_search: function(e) {
return n.search.get_url({
site: "lyricsmania.com",
query: this.$SEARCHTERMS(e)
});
},
process_result: function(e, t) {
var r = n.toDOM(e), o = r.querySelector("#songlyrics_h,#songlyrics"), i = n.toStringArray(o);
if (i.length) {
var s = r.title.replace(/\s+Lyrics$/, "");
t.found({
lyrics: i,
title: s
});
} else t.fail();
},
process_search: function(e, t) {
for (var r = n.search.getResultsFromResponse(e), o = 0; r.length > o; o++) {
var i = r[o];
if (/^https?:\/\/www\.lyricsmania\.com\/.+_lyrics_.+\.html$/i.test(i)) return t.found({
redir: i
}), void 0;
}
t.fail();
},
$ARTIST$SONG: function(e, t) {
return e = r.prototype.$ARTIST$SONG.call(this, e, t), e = e.toLowerCase(), e = e.replace(/&/g, "and"),
e = e.replace("[ost]", "_soundtrack_"), e = e.replace(/[ \/]/g, "_"), e = e.replace(/[^a-z0-9!,_\-@*:$°]/g, "");
}
});
}), r("sources/azlyrics.com", [ "require", "exports", "module", "LyricsSource", "SourceScraperUtils" ], function(e, t) {
var r = e("LyricsSource").LyricsSource, n = e("SourceScraperUtils").SourceScraperUtils;
t.source = new r({
disabled: !1,
identifier: "azlyrics.com",
homepage: "http://www.azlyrics.com/",
description: "Hundred thousands of mostly English lyrics.",
url_result: "http://www.azlyrics.com/lyrics/$ARTIST/$SONG.html",
method_search: "GET",
url_search: "http://search.azlyrics.com/search.php?q=$encSEARCHTERMS",
process_result: function(e, t) {
var r = n.toDOM(e), o = r.querySelector('div[style="margin-left:10px;margin-right:10px;"]'), i = n.toStringArray(o);
if (i.length) {
var s = r.title.split("LYRICS -");
s[0] = s[0].replace(/([A-Z])(\S*)/g, function(e, t, r) {
return t.toUpperCase() + r.toLowerCase();
}), s = s.join("-"), t.found({
lyrics: i,
title: s
});
} else t.fail();
},
process_search: function(e, t) {
var r = n.toDOM(e), o = r.querySelector('a[href^="http://www.azlyrics.com/lyrics/"]');
o ? t.found({
redir: o.href
}) : t.fail();
},
$ARTIST$SONG: function(e, t) {
return e = r.prototype.$ARTIST$SONG.call(this, e, t), e = e.toLowerCase(), e = e.replace(/([a-z])!([a-z])/g, "$1i$2"),
e = e.replace(/[^a-z0-9]/g, "");
},
$SEARCHTERMS: function(e, t) {
var n = r.prototype.$SEARCHTERMS.call(this, e, t);
return e.videotitle && (n = n.replace(/\s+-\s+/g, " ")), n;
}
});
}), r("sources/lyricstime.com", [ "require", "exports", "module", "LyricsSource", "SourceScraperUtils" ], function(e, t) {
var r = e("LyricsSource").LyricsSource, n = e("SourceScraperUtils").SourceScraperUtils;
t.source = new r({
disabled: !1,
identifier: "lyricstime.com",
homepage: "http://www.lyricstime.com/",
description: "Millions of lyrics in several languages.",
url_result: "http://www.lyricstime.com/$ARTIST-$SONG-lyrics.html",
url_search: function(e) {
return n.search.get_url({
site: "lyricstime.com",
query: this.$SEARCHTERMS(e)
});
},
process_result: function(e, t) {
var r = n.toDOM(e), o = r.querySelector("#songlyrics > p"), i = n.toStringArray(o);
if (i.length) {
var s = r.title.replace(/\s+Lyrics$/, "");
t.found({
lyrics: i,
title: s
});
} else t.fail();
},
process_search: function(e, t) {
for (var r = n.search.getResultsFromResponse(e), o = 0; r.length > o; o++) {
var i = r[o];
if (/^https?:\/\/www\.lyricstime\.com\/.+-lyrics\.html$/i.test(i)) return t.found({
redir: i
}), void 0;
}
t.fail();
},
$ARTIST$SONG: function(e, t) {
return (t || (t = {})).keepAccents = !0, e = r.prototype.$ARTIST$SONG.call(this, e, t),
e = e.toLowerCase(), e = e.replace(/([a-z])!([a-z])/g, "$1i$2"), e = e.replace(/[^a-z0-9]/g, "-"),
e = e.replace(/-{2,}/g, "-"), e = e.replace(/^-+|-+$/g, "");
}
});
}), r("sources/lyricsmode.com", [ "require", "exports", "module", "LyricsSource", "SourceScraperUtils" ], function(e, t) {
var r = e("LyricsSource").LyricsSource, n = e("SourceScraperUtils").SourceScraperUtils;
t.source = new r({
disabled: !1,
identifier: "lyricsmode.com",
homepage: "http://www.lyricsmode.com/",
description: "Millions of lyrics in many languages.",
url_result: "http://m.lyricsmode.com/lyrics/$ARTISTFIRSTLETTER/$ARTIST/$SONG.html",
url_search: function(e) {
return n.search.get_url({
site: "lyricsmode.com",
query: this.$SEARCHTERMS(e)
});
},
process_result: function(e, t, r) {
var o = n.toDOM(e), i = o.querySelector("#songlyrics"), s = n.toStringArray(i);
if (s.length) {
var a = o.title.replace(/\s+Lyrics\s*(\| LyricsMode\.com Mobile)?$/i, ""), c = r.url.replace(/^(https?:\/\/)m\./, "$1www.");
t.found({
lyrics: s,
title: a,
url: c
});
} else t.fail();
},
process_search: function(e, t) {
for (var r = n.search.getResultsFromResponse(e), o = 0; r.length > o; o++) {
var i = r[o];
if (/^https?:\/\/(m|www)\.lyricsmode\.com\/lyrics\/(.)\/\2[^\/]+\/.+\.html$/i.test(i)) return i = i.replace(/^(https?:\/\/)www\./, "$1m."),
t.found({
redir: i
}), void 0;
}
t.fail();
},
$ARTIST$SONG: function(e, t) {
return e = r.prototype.$ARTIST$SONG.call(this, e, t), e = e.toLowerCase(), e = e.replace(/[ \-]/g, "_"),
e = e.replace(/([a-z])!([a-z])/g, "$1i$2"), e = e.replace(/[^a-z0-9_\-]/g, ""),
e = e.replace(/_{2,}/g, "_"), e = e.replace(/^_+|_+$/g, "");
},
$ARTISTFIRSTLETTER: function(e) {
return this.$ARTIST(e).charAt(0);
}
});
}), r("sources/magistrix.de", [ "require", "exports", "module", "LyricsSource", "SourceScraperUtils" ], function(e, t) {
var r = e("LyricsSource").LyricsSource, n = e("SourceScraperUtils").SourceScraperUtils;
t.source = new r({
disabled: !0,
identifier: "magistrix.de",
homepage: "http://magistrix.de/lyrics/",
description: "German source with hundred thousands of lyrics (German, English and others).",
url_result: function(e) {
return n.search.get_url({
site: "magistrix.de/lyrics",
query: "SONGTEXT " + this.$ARTIST(e) + " " + this.$SONG(e)
});
},
url_search: function(e) {
return n.search.get_url({
site: "magistrix.de/lyrics",
query: "SONGTEXT " + this.$SEARCHTERMS(e)
});
},
process_result: function(e, t, r) {
if (!/^https?:\/\/www\.magistrix\.de\//.test(r.url)) return this.process_search(e, t, r);
var o = n.toDOM(e), i = o.querySelector("#songtext"), s = n.toStringArray(i, {
tags: /^([buip]|strong|em)$/i,
flushBefore: /^(br|p)$/i,
flushAfter: /^p$/i,
lineAfterFlush: /^p$/i
});
if (s.length) {
var a = o.title.replace("Songtext:", "").replace(/Lyrics\s*$/, "").trim();
if (!a) {
var c, l, u = o.querySelector("div[data-artist][data-song]");
u ? (c = u.getAttribute("data-artist"), l = u.getAttribute("data-song")) : (l = o.querySelector("h1 .headline"),
c = o.querySelector(".artistlink"), c && l ? (c = c.textContent, l = l.textContent.replace(/\s*Lyrics$/, "")) : c = l = ""),
a = c + " - " + l;
}
t.found({
lyrics: s,
title: a
});
} else t.fail();
},
process_search: function(e, t) {
for (var r, o = n.search.getResultsFromResponse(e), i = 0; o.length > i; i++) {
var s = o[i];
if (/^http:\/\/www\.magistrix\.de\/lyrics\/[^\/]+\/[^\/]+-\d+\.html/i.test(s)) {
if (!s.match(/\bUebersetzung-\d+\.html$/i, "")) return t.found({
redir: s
}), void 0;
r || (r = s);
}
}
return r ? (t.found({
redir: r
}), void 0) : (t.fail(), void 0);
}
});
}), r("sources/leoslyrics.com", [ "require", "exports", "module", "LyricsSource", "SourceScraperUtils" ], function(e, t) {
var r = e("LyricsSource").LyricsSource, n = e("SourceScraperUtils").SourceScraperUtils;
t.source = new r({
disabled: !0,
identifier: "leoslyrics.com",
homepage: "http://www.leoslyrics.com/",
description: "Hundred thousands of lyrics in many languages, popular among Idian users.",
url_result: "http://www.leoslyrics.com/$ARTIST/$SONG-lyrics/",
url_search: function(e) {
return n.search.get_url({
site: "leoslyrics.com",
query: this.$SEARCHTERMS(e)
});
},
process_result: function(e, t) {
var r = n.toDOM(e), o = r.querySelector(".song > div"), i = n.toStringArray(o);
if (i.length) {
var s = r.querySelector(".title-header h2 + ul > li a");
s = s && s.textContent.replace(/\s*Lyrics\s*$/i, "").trim();
var a = r.querySelector(".title-header h2");
a = a && a.textContent.replace(/\s*Lyrics\s*$/i, "").trim();
var c = s && a ? s + " - " + a : r.title.replace(/\sLYRICS$/i, "");
t.found({
lyrics: i,
title: c
});
} else t.fail();
},
process_search: function(e, t) {
for (var r = n.search.getResultsFromResponse(e), o = 0; r.length > o; o++) {
var i = r[o];
if (/^https?:\/\/www\.leoslyrics\.com\/[^\/]+\/.+-lyrics\/?$/i.test(i)) return t.found({
redir: i
}), void 0;
}
t.fail();
},
$ARTIST$SONG: function(e, t) {
return e = r.prototype.$ARTIST$SONG.call(this, e, t), e = e.toLowerCase(), e = e.replace(/[.' +]/g, "-"),
e = e.replace(/[^a-z0-9!\-]/g, ""), e = e.replace(/-{2,}/g, "-");
}
});
}), r("sources/vagalume.com.br", [ "require", "exports", "module", "LyricsSource", "SourceScraperUtils" ], function(e, t) {
var r = e("LyricsSource").LyricsSource, n = e("SourceScraperUtils").SourceScraperUtils;
t.source = new r({
disabled: !0,
identifier: "vagalume.com.br",
homepage: "http://www.vagalume.com.br/",
description: "Brazilian site providing millions of lyrics in many languages.",
url_result: "http://www.vagalume.com.br/$ARTIST/$SONG.html",
url_search: function(e) {
return n.search.get_url({
site: "vagalume.com.br",
query: this.$SEARCHTERMS(e)
});
},
process_result: function(e, t) {
var r = n.toDOM(e), o = r.querySelector("#lyr_original div"), i = n.toStringArray(o, {
tags: /^(?:[buip]|strong|em|span)$/i,
flushBefore: /^(?:br|p)$/i,
flushAfter: /^p$/i
});
if (i.length) {
var s = r.title.replace(/ - VAGALUME$/i, "");
t.found({
lyrics: i,
title: s
});
} else t.fail();
},
process_search: function(e, t) {
for (var r = n.search.getResultsFromResponse(e), o = 0; r.length > o; o++) {
var i = /^http:\/\/(www|m)(\.vagalume\.com\.br\/(?!(my|top100|especiais|news|plugin|facebook|browse|playlisteiros)\/).*?\/(?!(discografia|fotos|popularidade|relacionados|news)\b).*?)$/i.exec(r[o]);
if (i) return i = "http://www" + i[2], i = i.replace(/-cifrada(\.html)?$/i, "$1"),
t.found({
redir: i
}), void 0;
}
t.fail();
},
$ARTIST$SONG: function(e, t) {
return e = r.prototype.$ARTIST$SONG.call(this, e, t), e = e.toLowerCase(), e = e.replace(/([a-z])!([a-z])/g, "$1i$2"),
e = e.replace(/[ .]/g, "-"), e = e.replace(/[^a-z0-9\-]/g, ""), e = e.replace(/-{2,}/g, "-"),
e = e.replace(/^-|-$/g, "");
}
});
}), r("sources/letras.mus.br", [ "require", "exports", "module", "LyricsSource", "SourceScraperUtils" ], function(e, t) {
var r = e("LyricsSource").LyricsSource, n = e("SourceScraperUtils").SourceScraperUtils;
t.source = new r({
disabled: !0,
identifier: "letras.mus.br",
homepage: "http://letras.mus.br/",
description: "A big Brazilian source with millions of lyrics (also in many other languages).",
url_result: "http://letras.mus.br/$ARTIST/$SONG/",
url_search: function(e) {
return n.search.get_url({
site: "letras.mus.br",
query: this.$SEARCHTERMS(e)
});
},
process_result: function(e, t) {
var r = n.toDOM(e), o = r.querySelector("#div_letra,#letra_original"), i = n.toStringArray(o, {
tags: /^(?:[buip]|strong|em|div)$/i,
flushBefore: /^(?:br|p|div)$/i,
flushAfter: /^(?:p|div)$/i,
lineAfterFlush: /^p$/i
});
if (i.length) {
var s, a = r.querySelector("#identificador_musica"), c = r.querySelector("#identificador_artista");
s = a && c ? a.textContent + " - " + c.textContent : r.title.replace(/\([^)]+\)/g, ""),
t.found({
lyrics: i,
title: s
});
} else t.fail();
},
process_search: function(e, t) {
for (var r = n.search.getResultsFromResponse(e), o = 0; r.length > o; o++) {
var i = r[o];
if (/^http:\/\/letras\.mus\.br\/.*?\/.*?\//i.test(i)) return t.found({
redir: i
}), void 0;
}
t.fail();
},
$ARTIST$SONG: function(e, t) {
return e = r.prototype.$ARTIST$SONG.call(this, e, t), e = e.toLowerCase(), e = e.replace(/[_ ]/g, "-"),
e = e.replace(/[^a-z0-9\-]/g, ""), e = e.replace(/-{2,}/g, "-"), e = e.replace(/^-+|-+$/g, "");
}
});
}), r("algorithms", [ "require", "exports", "module", "normalize_accents" ], function(e, t) {
function r(e, t) {
e += "", t || (e = e.toLocaleLowerCase(), e = s(e), e = e.replace(/[.,?\/"':;|\\\]\[\{\}\(\)\-_=+!@#$%\^&*~`]/g, " ")),
e = (" " + e + " ").replace(/\s+/g, " ");
for (var r = {}, n = -1, o = e.length - 1; o > ++n; ) {
var i = e.substr(n, 2);
r[i] = r[i] ? r[i] + 1 : 1;
}
return {
length: o,
hash: r
};
}
function n(e, t, n) {
var o = r(e, n), i = r(t, n), s = 0, a = o.length + i.length;
if (!o.length || !i.length) return a ? 0 : 1;
var c, l;
i.length > o.length ? (c = o.hash, l = i.hash) : (c = i.hash, l = o.hash);
for (var u = Object.keys(c), p = 0; u.length > p; ++p) {
var d = u[p];
l[d] && (s += c[d] > l[d] ? l[d] : c[d]);
}
return 2 * s / a;
}
function o(e) {
if (-1 == e.indexOf("-")) return null;
e = e.match(/^(.+?)\s-\s(.+)/) || e.match(/^(.+?)\s-(.+)/) || e.match(/^(.+?)-\s(.+)/) || e.match(/^(.+?)-(.+)/);
var t = e[1].trim(), r = e[2].trim();
return t && r ? [ t, r ] : null;
}
function i(e, t, r) {
r = !isNaN(r) && isFinite(r) ? +r : .3;
var i = o(e), s = o(t);
return i && s ? n(i[0], s[0]) > r && n(i[1], s[1]) > r : n(e, t) > r;
}
var s = e("normalize_accents").normalize_accents;
t.getSimilarityCoefficient = n, t.splitSongTitle = o, t.isTitleSimilar = i;
}), r("sources/darklyrics.com", [ "require", "exports", "module", "LyricsSource", "SourceScraperUtils", "algorithms" ], function(e, t) {
function r(e) {
return e.replace(/[^a-z0-9'. ]/i, " ").replace(/\s+/, " ").trim();
}
function n(e) {
return e && e.replace(/^\s*\d+\./, "").trim() || "";
}
function o(e, t) {
for (var r, o = -1/0, i = 0; e.length > i; i++) {
var s = e[i], c = n(s.textContent).toLowerCase(), l = a.getSimilarityCoefficient(c, t);
l > o && (o = l, r = s);
}
return o > .3 ? r : null;
}
var i = e("LyricsSource").LyricsSource, s = e("SourceScraperUtils").SourceScraperUtils, a = e("algorithms");
t.source = new i({
disabled: !0,
identifier: "darklyrics.com",
homepage: "http://www.darklyrics.com/",
description: "Dark Lyrics is provides Metal lyrics for 4500+ bands.",
url_result: function(e) {
return "http://www.darklyrics.com/search?q=" + encodeURIComponent(r(this.$ARTIST(e)) + " " + r(this.$SONG(e)));
},
url_search: function(e) {
return "http://www.darklyrics.com/search?q=" + encodeURIComponent(r(this.$SEARCHTERMS(e)));
},
process_result: function(e, t, r) {
if (/^https?:\/\/www\.darklyrics\.com\/search/.test(r.url)) return this.process_search(e, t, r);
var i = s.toDOM(e), a = i.querySelectorAll("h3 > a");
if (!a) return t.fail(), void 0;
var c = i.title.split(/\sLyrics\s/i, 1)[0].toLowerCase(), l = r.query.song && this.$SONG(r.query);
l || (l = this.$SEARCHTERMS(r.query) || "", l = l.toLowerCase().replace(c, " "),
l = l.replace(/\s+/, " ").replace(/^[\s\-]+|[\s\-]+$/g, ""));
var u = o(a, l);
if (!u || !u.parentNode) return t.fail(), void 0;
var p = s.toStringArray({
firstChild: u.parentNode.nextSibling
}, {
isEndNode: function(e) {
return "H3" === e.nodeName.toUpperCase();
}
});
if (p.length) {
c = c.replace(/([a-z])(\S*)/g, function(e, t, r) {
return t.toUpperCase() + r.toLowerCase();
}), l = n(u.textContent);
var d = c + " - " + l;
t.found({
lyrics: p,
title: d,
url: r.url.replace(/(#\d*)?$/, "#" + u.name)
});
} else t.fail();
},
process_search: function(e, t, r) {
var n = s.toDOM(e), i = n.querySelectorAll('a[href*="lyrics/"][href*=".html#"]'), a = o(i, this.$SEARCHTERMS(r.query)), c = a && a.getAttribute("href").replace(/^(?!http)/i, "http://www.darklyrics.com/");
return /^http:\/\/www\.darklyrics\.com\/lyrics\//i.test(c) ? (t.found({
redir: c
}), void 0) : (t.fail(), void 0);
}
});
}), r("sources/metal-archives.com", [ "require", "exports", "module", "LyricsSource", "SourceScraperUtils", "algorithms" ], function(e, t) {
function r(e, t, r) {
if (e) {
for (var n = -1, o = -1/0, s = 0; e.length > s; s++) {
var a = r(e[s]);
if (a) {
var c = i.getSimilarityCoefficient(a, t);
if (c > o && (n = s, o = c, 1 == c)) break;
}
}
return o > .3 ? n : -1;
}
}
var n = e("LyricsSource").LyricsSource, o = e("SourceScraperUtils").SourceScraperUtils, i = e("algorithms"), s = /^https?:\/\/www\.metal-archives\.com\/search\/ajax-advanced\/searching\/songs\/\?songTitle=(.*?)&bandName=(.*)/, a = /^https?:\/\/www\.metal-archives\.com\/albums\/([^\/]+)\/([^\/]+).*/i, c = /"https?:\/\/www\.metal-archives\.com\/albums\/([^\/]+)\/([^\/]+).*?"/i;
t.source = new n({
disabled: !0,
identifier: "metal-archives.com",
homepage: "http://www.metal-archives.com/",
description: "The Metal Archives is an extensive database (90k+ bands) of metal lyrics.",
url_result: function(e) {
return "http://www.metal-archives.com/search/ajax-advanced/searching/songs/?songTitle=" + encodeURIComponent(this.$SONG(e)) + "&bandName=" + encodeURIComponent(this.$ARTIST(e));
},
url_search: function(e) {
return o.search.get_url({
site: "metal-archives.com/albums",
query: this.$SEARCHTERMS(e)
});
},
process_result: function(e, t, r) {
if (s.test(r.url) || a.test(r.url)) return this.process_search(e, t, r);
if (/^\s*(<[^>]*>)?\(lyrics not available\)/i.test(e)) return t.fail(), void 0;
var n = o.toDOM(e), i = n.querySelectorAll("h3 > a");
if (!i) return t.fail(), void 0;
var c = o.toStringArray(n.body);
c.length ? t.found({
lyrics: c,
title: r.tempData && r.tempData.song_title || "(N/A)",
url: r.tempData && r.tempData.song_url || r.url
}) : t.fail();
},
process_search: function(e, t, n) {
if (!/^https?:\/\/www\.metal-archives\.com\//.test(n.url)) {
for (var i = o.search.getResultsFromResponse(e), l = 0; i.length > l; l++) {
var u = i[l];
if (a.test(u)) return t.found({
redir: u
}), void 0;
}
return t.fail(), void 0;
}
var p, d, f, h, m, g;
if (s.exec(n.url), s.test(n.url)) try {
var y = JSON.parse(e);
if (p = this.$ARTIST(n.query), d = this.$SONG(n.query), !y || !y.aaData || !y.aaData.length) return t.fail(),
void 0;
if (h = r(y.aaData, p + "/" + d, function(e) {
var t = e[1] && c.exec(e[1]);
return t ? t[1] + "/" + t[2] : void 0;
}), -1 === h) return t.fail(), void 0;
var v = y.aaData[h];
m = c.exec(v[1]), f = m[0], p = v[0].match(/[^><]+(?=<\/a>)/i), p = p && p[0].trim() || decodeURIComponent(m[1]).replace(/_/, " "),
d = v[3], g = /lyricsLink_(\d+)/.exec(v[4]), g = g ? g[1] : 0;
} catch (b) {
return t.fail(), void 0;
} else if (a.test(n.url)) {
var S = o.toDOM(e), L = S.querySelectorAll("tr[id^=song]");
p = S.querySelector(".band_name"), p ? p = p.textContent.trim() : (m = a.match(n.url),
p = decodeURIComponent(m[1]).replace(/_/, " ")), d = n.query.song && this.$SONG(n.query);
var w = "";
if (d || (d = this.$SEARCHTERMS(n.query), w = p), d = d.toLowerCase(), h = r(L, d, function(e) {
return /\d/.test(e.id) ? (e = e.previousElementSibling, e && e.cells && e.cells[1] ? w + " " + e.cells[1].textContent.trim().toLowerCase() : void 0) : void 0;
}), -1 === h) return t.fail(), void 0;
var x = L[h];
f = n.url, d = x.previousElementSibling.cells[1].textContent.trim(), g = x.id.replace(/\D+/, "");
}
t.found({
redir: "http://www.metal-archives.com/release/ajax-view-lyrics/id/" + g,
tempData: {
song_url: f,
song_title: p + " - " + d
}
});
}
});
}), r("sources/musica.com", [ "require", "exports", "module", "LyricsSource", "SourceScraperUtils" ], function(e, t) {
var r = e("LyricsSource").LyricsSource, n = e("SourceScraperUtils").SourceScraperUtils;
t.source = new r({
disabled: !0,
identifier: "musica.com",
homepage: "http://www.musica.com/",
description: "Spanish site with 800k lyrics.",
url_result: function(e) {
return n.search.get_url({
site: "musica.com",
query: '"letras.asp?letra=" "Letra de" "' + this.$SONG(e) + '"' + ' de "' + this.$ARTIST(e) + '"'
});
},
url_search: function(e) {
return n.search.get_url({
site: "musica.com",
query: '"Letra de" "letras.asp?letra=" ' + this.$SEARCHTERMS(e)
});
},
process_result: function(e, t, r) {
if (!/^https?:\/\/www\.musica\.com\/letras\.asp/.test(r.url)) return this.process_search(e, t, r);
var o, i, s, a = n.toDOM(e), c = a.querySelector('font[style*="line-height"][style*=family]');
if (!c || 2 !== (s = a.querySelectorAll('h1 a[href*="letras.asp?letra"]')).length || !(i = s[0].textContent.trim()) || !(o = s[1].textContent.replace(/\([^)]*\)\s*$/, "").trim())) return t.fail(),
void 0;
var l = n.toStringArray(c);
l.length ? t.found({
lyrics: l,
title: i + " - " + o
}) : t.fail();
},
process_search: function(e, t) {
for (var r = n.search.getResultsFromResponse(e), o = 0; r.length > o; o++) {
var i = r[o];
if (/^https?:\/\/www\.musica\.com\/letras\.asp\?.*?letra=\d+/i.test(i)) return t.found({
redir: i
}), void 0;
}
t.fail();
},
$ARTIST$SONG: function(e, t) {
return e = r.prototype.$ARTIST$SONG.call(this, e, t), e = e.replace(/([a-z])!([a-z])/gi, "$1i$2"),
e = e.replace(/[":']/g, " "), e = e.replace(/ +/, " ");
}
});
}), r("sources/shironet.mako.co.il", [ "require", "exports", "module", "LyricsSource", "SourceScraperUtils" ], function(e, t) {
var r = e("LyricsSource").LyricsSource, n = e("SourceScraperUtils").SourceScraperUtils, o = function(e) {
return /[\u0590-\u05FF]/.test(e);
};
t.source = new r({
disabled: !0,
identifier: "shironet.mako.co.il",
homepage: "http://shironet.mako.co.il/",
description: "The best source for Hebrew lyrics.",
url_result: function(e) {
return this.url_search(e);
},
url_search: function(e) {
return e = this.$SEARCHTERMS(e), o(e) ? "http://shironet.mako.co.il/searchSongs?type=lyrics&q=" + encodeURIComponent(e) : "";
},
process_result: function(e, t, r) {
if (/^https?:\/\/shironet\.mako\.co\.il\/searchSongs/.test(r.url)) return this.process_search(e, t, r);
var o = n.toDOM(e), i = o.querySelector(".artist_lyrics_text"), s = n.toStringArray(i);
if (s.length) {
var a = o.querySelector(".artist_singer_title");
a = a && a.textContent.trim();
var c = o.querySelector(".artist_song_name_txt");
c = c && c.textContent.trim();
var l = a + " - " + c;
t.found({
lyrics: s,
title: l
});
} else t.fail();
},
process_search: function(e, t) {
var r = n.toDOM(e), o = r.querySelector('a[href*="/artist?type=lyrics"][class*="search"]'), i = o && o.getAttribute("href").replace(/^\//i, "http://shironet.mako.co.il/");
i ? t.found({
redir: i
}) : t.fail();
},
$ARTIST$SONG: function(e, t) {
return (t || (t = {})).keepAccents = !0, e = r.prototype.$ARTIST$SONG.call(this, e, t),
e = e.replace(/[^\u0590-\u05FF\d\-]+/g, " "), e = e.replace(/^[ \-]+|[ \-]+$/g, ""),
e = e.replace(/ +/g, " ");
},
$SEARCHTERMS: function(e, t) {
var r, n = function(e) {
return e = e.replace(/[^\u0590-\u05FF\d\-]+/g, " "), e = e.replace(/(מילים לשיר|עם מילים|עם כתוביות|קאבר|אקוסטי|בהופעה)/g, " "),
e = e.replace(/^[ \-]+|[ \-]+$/g, ""), e = e.replace(/ +/g, " ");
};
if (!e.videotitle && (r = e.searchTerms, !r)) {
var o = this.$ARTIST(e, t), i = this.$SONG(e, t);
o && i && (r = n(o + " - " + i));
}
return !r && e.videotitle && (r = e.videotitle, r = r.replace(/\([^)]*\)/g, " "),
r = r.replace(/\[[^\]]*\]/g, " "), r = n(r), r || (r = n(e.videotitle))), r;
}
});
}), r("sources/angolotesti.it", [ "require", "exports", "module", "LyricsSource", "SourceScraperUtils" ], function(e, t) {
var r = e("LyricsSource").LyricsSource, n = e("SourceScraperUtils").SourceScraperUtils;
t.source = new r({
disabled: !0,
identifier: "angolotesti.it",
homepage: "http://www.angolotesti.it/",
description: "The largest lyrics provider of Italy, with hundred thousands of lyrics.",
url_result: function(e) {
return n.search.get_url({
site: "angolotesti.it",
query: this.$SONG(e) + " Testo " + this.$ARTIST(e)
});
},
url_search: function(e) {
return n.search.get_url({
site: "angolotesti.it",
query: this.$SEARCHTERMS(e) + " Testo"
});
},
process_result: function(e, t, r) {
if (n.search.isSearchURL(r.url)) return this.process_search(e, t, r);
var o = n.toDOM(e), i = o.querySelector(".testo"), s = n.toStringArray(i);
if (s.length) {
var a = o.title.replace(/^(.+?) Testo (.+?)$/, "$2 - $1");
t.found({
lyrics: s,
title: a
});
} else t.fail();
},
process_search: function(e, t) {
for (var r = n.search.getResultsFromResponse(e), o = 0; r.length > o; o++) {
var i = r[o];
if (/^https?:\/\/(www\.)?angolotesti\.it\/(0-9|[a-z])\/[^\/]*\d\/[^\/]*\d/i.test(i)) return t.found({
redir: i
}), void 0;
}
t.fail();
}
});
}), r("sources/lyrics", [ "require", "exports", "module", "config", "sources/lyrics.wikia.com", "sources/lyrics.com", "sources/metrolyrics.com", "sources/lyricsmania.com", "sources/azlyrics.com", "sources/lyricstime.com", "sources/lyricsmode.com", "sources/magistrix.de", "sources/leoslyrics.com", "sources/vagalume.com.br", "sources/letras.mus.br", "sources/darklyrics.com", "sources/metal-archives.com", "sources/musica.com", "sources/shironet.mako.co.il", "sources/angolotesti.it" ], function(e, t) {
for (var r = e("config"), n = function(e, t, r) {
console && console.log(e + ": " + r);
}, o = [ e("sources/lyrics.wikia.com").source, e("sources/lyrics.com").source, e("sources/metrolyrics.com").source, e("sources/lyricsmania.com").source, e("sources/azlyrics.com").source, e("sources/lyricstime.com").source, e("sources/lyricsmode.com").source, e("sources/magistrix.de").source, e("sources/leoslyrics.com").source, e("sources/vagalume.com.br").source, e("sources/letras.mus.br").source, e("sources/darklyrics.com").source, e("sources/metal-archives.com").source, e("sources/musica.com").source, e("sources/shironet.mako.co.il").source, e("sources/angolotesti.it").source ], i = 0; o.length > i; ++i) o[i]._disabled = o[i].disabled;
var s = function(e, t) {
for (var r = 0; e.length > r; r++) if (e[r].identifier === t) return r;
return -1;
}, a = function(e, t) {
if (e) for (var r = e.length - 1; r >= 0; --r) {
var o = e[r], i = s(t, o);
i >= 0 ? t.unshift(t.splice(i, 1)[0]) : n("getLyricsSources", "id_unknown", 'Unknown identifier found in the "order" preference.');
}
}, c = function(e, t, r) {
if (e) for (var n = r.length - 1; n >= 0; --n) {
var o = r[n].identifier;
r[n].disabled = -1 !== e.indexOf(o) ? !0 : t && -1 !== t.indexOf(o) ? !1 : r[n]._disabled;
}
}, l = function(e) {
for (var t = e.length - 1; t >= 0; --t) e[t].disabled === !0 && e.splice(t, 1);
}, u = function(e, t) {
r.getItem("lyricsSourcePreferences", function(r) {
for (var n = o.slice(0), i = n.length, s = 0, u = i - 1; u >= 0; --u) n[u].disabled = n[u]._disabled;
r && (r.order && (s = r.order.length), a(r.order, n), c(r.blacklist, r.whitelist, n)),
e && l(n), n.stats = {
old: s,
"new": i - s,
total: i
}, t(n);
});
}, p = function(e) {
u(!1, e);
}, d = function(e) {
u(!0, e);
};
t.getAllLyricsSources = p, t.getLyricsSources = d;
}), r("SimpleTemplating", [ "require", "exports", "module" ], function(e, t) {
function r(e) {
return this instanceof r ? (this.useTemplate(e), void 0) : new r(e);
}
function n(e, t, r) {
var n = /^on(.+)$/.exec(r);
if (!n) return e[r] = t[r], void 0;
var o = n[1], i = "data-robw-" + o, s = e[i], a = t[r];
s && (e.removeEventListener(o, s, !1), delete e[i]), "function" == typeof a && (e.addEventListener(o, a, !1),
e[i] = a);
}
var o = function(e, t, r) {
console && console.log(e + ": " + r);
}, i = function(e, t, r) {
var n = Error(e + ": " + r);
throw n.type = t, n;
};
r.prototype.useTemplate = function(e) {
var t = e.tagName;
if (t && e.cloneNode) return this.element = e, this;
t || (t = "div");
var r = document.createElement(t);
return Object.keys(e).forEach(function(t) {
"tagName" !== t && (r[t] = e[t]);
}), this.element = r, this;
}, r.prototype.getElement = function() {
return this.element || i("SimpleTemplating::getElement", "invalid_state", "Cannot use getElement() before an element has been defined! Construct the base element using useTemplate(template)"),
this.element;
}, r.prototype.update = function(e) {
var t = this.getElement();
return Object.keys(e).forEach(function(r) {
var i = t.querySelectorAll(r);
if (i.length) for (var s = e[r], a = s._pre, c = s._post, l = i.length - 1; l >= 0; --l) {
var u = i[l], p = {};
"function" == typeof a && a(u, p);
for (var d = Object.keys(s), f = 0; d.length > f; ++f) {
var h = d[f];
"_pre" !== h && "_post" !== h && n(u, s, h);
}
"function" == typeof c && c(u, p);
} else o("SimpleTemplating::update", "no_nodes", "No matching nodes found for " + r);
}), this;
}, t.SimpleTemplating = r;
}), r("text", {
load: function(e) {
throw Error("Dynamic load not allowed: " + e);
}
}), r("text!style/lyricsPanel.css", [], function() {
return '.L759-overlay{position:fixed;bottom:0;right:0;width:100%;height:100%;background-color:transparent !important;z-index:9999}\n.L759-overlay,.L759-container,.L759-container *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}\n.L759-container{position:fixed;top:2px;right:2px;width:275px;z-index:10000;font-family:arial,sans-serif;overflow:hidden;background-color:#fff !important;color:#000 !important;border:1px solid #bbe !important;padding:5px 1px 1px 5px;display:block;border-radius:5px 5px 5px 0;line-height:15px;font-size:14px;min-height:25px;min-width:67px;-webkit-box-shadow:1px 1px 4px lightGrey;box-shadow:1px 1px 4px lightGrey}.L759-container.boxsizingbug{min-height:17px;min-width:59px}\n.L759-container *{color:inherit !important}\n.L759-container button,.L759-container input{display:inline-block;height:20px;margin:0;border:0;background-color:transparent !important;padding:0;line-height:1.2em;font-size:13px;color:#000 !important}\n.L759-container .L759-buttons button{background-color:#ccc !important;cursor:pointer;padding:0 5px;font-size:16px;color:#333 !important}\n.L759-container a,.L759-container .L759-link-style{cursor:pointer;color:#438bc5 !important;text-decoration:none}\n.L759-container a:hover,.L759-container .L759-link-style:hover{text-decoration:underline;background-color:transparent !important}\n.L759-container .L759-title{border-bottom:3px double #99f !important;font-size:17px;height:22px;margin-right:25px;overflow:hidden;cursor:move;white-space:nowrap;text-overflow:ellipsis}\n.L759-container .L759-close{overflow:visible}\n.L759-container .L759-close,.L759-container .L759-close:before{position:absolute;height:25px;width:25px;top:0;right:0;z-index:50;cursor:pointer;background-color:#f50 !important;display:block}\n.L759-container .L759-close:before{content:"";background:transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAYAAABy6+R8AAAA0klEQVQokWNggIKrV69yv3r1ypUBC3jz5o3906dPhVAEQRrevn17AIj/vH79OgJZDmiQB1D8BxCfg2uEaXj37t1/EAZpBJociawBSQ6i8eXLlzpAznuYBEwjEPcga4Dir0CDrGBuNgYqeIemAB1/BapzQvcsPo2YGmAAGAiF2DQBDevAqgHd0+h+hAUOURqQNcKjA+oXjFACiuWi+xEaqs4MZ86cYQEKrMbmaaiByNGxC6ieE2wbkkaMUALyTaAaERpgAKQR6GYDbIH04sULbWQNADXdoxVKiraqAAAAAElFTkSuQmCC") center no-repeat !important;opacity:1}\n.L759-container .L759-close:hover:before{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAYAAABy6+R8AAAAzElEQVQokWNggIJXr15x//nzx5UBCwCK23/69EkIRRCk4d+/fweA+M/fv38j0DR4AMV/APE5uEaYhv9QANUYiawBSQ6i8devXzpAzvv/SACkEYh7kDVAxb/+/v3bCmwbkGEMFHj3Hw8AaQDa7ITiL3wasWqAAaBfCnFo6sCqAd3T6H6EBQ5RGtA0RiD7BSOUgApy0f0I0ggEzgxnzpxhAXJWY/M01MD3SHK7nj17xgm2DaYRWygBNZqANKJogAGQRmBEG2ALJKC4NrIGAGjtuqnt84LiAAAAAElFTkSuQmCC") !important}\n.L759-container .L759-content{overflow:auto;word-wrap:break-word}.L759-container .L759-content .L759-link-container{border:0;border-bottom:1px solid #759 !important;text-align:center}\n.L759-container .L759-content .L759-info{display:none;border:0;border-bottom:1px solid #759 !important;min-height:40px;padding-left:40px;background:2px 2px no-repeat url("https://rob.lekensteyn.nl/youtubelyrics/icons/32.png") !important}.L759-container .L759-content .L759-info.L759-http{background-image:url("http://rob.lekensteyn.nl/youtubelyrics/icons/32.png") !important}\n.L759-container .L759-content .L759-info .L759-song-title{font-style:italic}\n.L759-container .L759-content .L759-info .L759-link-to-found-source{font-weight:bold}\n.L759-container .L759-content>div{padding-top:2px}\n.L759-container .L759-content .L759-lyrics-line{min-height:15px;padding-left:1em;text-indent:-1em}\n.L759-container .L759-content .L759-result[dir=rtl] .L759-lyrics-line{padding-left:0;padding-right:1.2em}\n.L759-container .L759-searchbox{padding-left:12px;width:100%}.L759-container .L759-searchbox .L759-searchterms{width:100%;float:left;margin:0 -30px 0 0;padding:0 30px 0 0;border:1px solid lightGrey !important}.L759-container .L759-searchbox .L759-searchterms:-moz-placeholder{color:#cacaca !important}\n.L759-container .L759-searchbox .L759-searchterms::-moz-placeholder{color:#cacaca !important}\n.L759-container .L759-searchbox .L759-searchterms::-webkit-input-placeholder{color:#cacaca !important}\n.L759-container .L759-searchbox .L759-searchterms:focus:-moz-placeholder{color:transparent !important}\n.L759-container .L759-searchbox .L759-searchterms:focus::-moz-placeholder{color:transparent !important}\n.L759-container .L759-searchbox .L759-searchterms:focus::-webkit-input-placeholder{color:transparent !important}\n.L759-container .L759-searchbox .L759-dosearch{width:30px;background:#fafafa url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAYAAABy6+R8AAAAe0lEQVQoz62RwQmAMBAEE3zZX57BWtKJ4D0D1mAXdpAyjBvch4YTNbgwn9sMHBdjjljgQQSJRM6sUVKGAeQbgiZ6lhsQ4IhwlvnmkshClC2EXayLxMIpkmOXfpGa1ntziOHryQsj6DSx/twZrE+ilh4sJ3F6I2mibxHNDkVQQZxWN/WxAAAAAElFTkSuQmCC") center no-repeat !important;opacity:.6;border:1px solid lightGrey !important;height:20px;cursor:default}.L759-container .L759-searchbox .L759-dosearch:hover,.L759-container .L759-searchbox .L759-dosearch:focus,.L759-container .L759-searchbox .L759-dosearch:active{opacity:1}\n.L759-container .L759-searchbox .L759-dosearch:active{background-color:#eee !important}\n.L759-container .L759-searchbox .L759-searchterms,.L759-container .L759-searchbox .L759-dosearch{border-bottom-right-radius:5px}\n.L759-container .L759-resizer{position:absolute;left:0;bottom:0;width:17px;height:17px;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAYAAAA7bUf6AAAAKklEQVQ4jWMIDQ39z0ApABkyahCmRooNwqZppBtEjCaCBhGradSgATAIAGuTiXfwFGCyAAAAAElFTkSuQmCC") !important;cursor:sw-resize}\n.L759-skin-dark{background-color:#000 !important;color:#ccc !important;border-color:#888 !important;-webkit-box-shadow:1px 1px 4px #777;box-shadow:1px 1px 4px #777}.L759-skin-dark button,.L759-skin-dark input{background-color:transparent !important;color:#ccc !important}\n.L759-skin-dark .L759-buttons button{background-color:#333 !important;color:#999 !important}\n.L759-skin-dark a,.L759-skin-dark .L759-link-style{color:#8dd !important}\n.L759-skin-dark .L759-title{border-bottom-color:#aaa !important}\n.L759-skin-dark .L759-close{background-color:#555 !important}.L759-skin-dark .L759-close:before{opacity:.6}\n.L759-skin-dark .L759-content .L759-link-container{border-bottom-color:#aaa !important}\n.L759-skin-dark .L759-content .L759-info{background-image:url("https://rob.lekensteyn.nl/youtubelyrics/icons/32-dark.png") !important;border-bottom-color:#aaa !important}.L759-skin-dark .L759-content .L759-info.L759-http{background-image:url("http://rob.lekensteyn.nl/youtubelyrics/icons/32-dark.png") !important}\n.L759-skin-dark .L759-searchbox .L759-searchterms{border-color:#444 !important}.L759-skin-dark .L759-searchbox .L759-searchterms:-moz-placeholder{color:#cacaca !important}\n.L759-skin-dark .L759-searchbox .L759-searchterms::-moz-placeholder{color:#cacaca !important}\n.L759-skin-dark .L759-searchbox .L759-searchterms::-webkit-input-placeholder{color:#cacaca !important}\n.L759-skin-dark .L759-searchbox .L759-dosearch{background-color:#aaa !important;border-color:#444 !important}.L759-skin-dark .L759-searchbox .L759-dosearch:active{background-color:#999 !important}\n';
}), r("text!templates/lyricsPanel.html", [], function() {
return '<div class="L759-title"></div>\n<button class="L759-close"></button>\n<div class="L759-content">\n <div class="L759-fetching">\n <div class="L759-buttons">\n <button class="L759-b-abort">Abort</button>\n <button class="L759-b-retry">Retry</button>\n <button class="L759-b-next">Next</button>\n </div>\n <div class="L759-status">\n Loading <a class="L759-link-to-fetched-source" target="_blank" rel="noreferrer">nothing</a>.\n <br><br>\n » <a class="L759-settings-link" href="https://rob.lekensteyn.nl/youtubelyrics/#config" target="_blank">Settings for \'YouTube Lyrics\'</a>\n </div>\n </div>\n <div class="L759-done">\n <div class="L759-link-container">\n <span class="L759-switch-source L759-link-style">\n » Different source (<span class="L759-sourceindex"></span> / <span class="L759-sourcecount"></span>)\n </span>\n <span class="L759-toggle-info L759-link-style">» Info</span>\n </div>\n <div class="L759-info">\n <div class="L759-song-info">\n The lyrics for <span class="L759-song-title"></span> were retrieved from <a class="L759-link-to-found-source" target="_blank" rel="noreferrer"></a>.\n </div>\n <br>\n » <a class="L759-settings-link" href="https://rob.lekensteyn.nl/youtubelyrics/#config" target="_blank">Settings for \'YouTube Lyrics\'</a>\n </div>\n <div class="L759-result"></div>\n </div>\n</div>\n<div class="L759-searchbox">\n <input type="text" class="L759-searchterms" placeholder=" artist - song">\n <button class="L759-dosearch"></button>\n</div>\n<div class="L759-resizer"></div>';
}), r("text!style/pageAction.css", [], function() {
return ".YouTubeLyricsByRobWPageActionIcon {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n position: fixed;\n top: 50px;\n right: 0; \n z-index: 99999;\n display: inline-block;\n height: 30px;\n width: 30px;\n margin: 0;\n border: 1px solid #999;\n padding: 0;\n background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAGDgAABg4BKbET0gAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAPwSURBVEjH7VbtL2RXGJ//gg/ig29V2W5TbUT4gLbbWXbHS1JMLBWqKRUr9AOJotFSKlJGvaSZbKTEFyVCWBKrpuItMVrT7CwSYb2Eced9xsxc49d5Hpm7pqXYZJt+2F9ycs+593nO75zfeZ7nXBn+Y8heE16Gk+fbcM9q4P7tiuazIduXJvQszOPoTjwOb71xo0Y+5CsrKyuDyWTiyahvNpsvZ/N6Icg/+NeJDe/ehiHyrQu/ka9sY2MDBQUF6O/vh1qthkajQWVlJWZnZ5mjt7eXn7u7u3gyOQlTthKiXg/v4QHE9TXYGr4JmNSh/gn2lu8vXRBL2tLSgtTUVNjtdmRlZcHtdkOpVOL4+Bg5OTlMuLKygubGRsnRe3QEQZEIxyM1LGUlsH33LWyN9Uzo+eN3eFa0MH/+KYxpCrgej8M1+RjGlHtnhHNzc6iuroZWq0VdXR0T0Fin00mECwsLFxIeD/0C61eVcHT9CEeHiglpEeaiz+DWzMDZ9/PZArTLcPY8CiQ8PT1FSkoKhoaGkJyczETl5eUYGBhAfn7+hYR21Q88sfhMLxGKf+p4R9S3VHwJ969PYP26GpaHX5wRWiwWbG5uMgHJOTMzA4/Hw2NRFDE1NYWtrS08396GMfU+E9JZGt57G4fv3IIp/xMI9+9C+Oh9CHc/hHBPDlPuAxzefvMsWJLusLymB5k3TwtRtwqj8mPfZBHXTwufLfmQ70sn/qndxtEq6p9e0fRs+/8pbXSGY2NjUjG4LpaWlqScvTbh2toa8vLy0NXV5Ssq3hsRzs/PY3p6+vqEJycniIuLg8vl+ocRRTF9J9hsNkkJKhQ7Ozvc/7siBoNBinQCzWs0Gl8QUklTKBSBN4KPpLOzE6GhoZweVAgoTwcHBxEWFobMzEyEh4ejvb0dERERkh9JS4tvaGjg8cTEBOd5aWnpC8La2lq0trYGpoCPZHV1FQkJCTxubm5GfX0974gIaYdOp5OrUHp6Otv09fWho6MDVquV/QlRUVHY398PlFQul+PIVz3Og4x6enpQVVXF46SkJD4rKvhk70d3dzdUKhX309LSsL6+HjBPTU0N4uPjOS6YkM6BtnwetGoKgsLCQi5tFLkhISGSzE1NTZJtdnY2l8fl5WUEBQWxAnTNjYyMYHx8nH2io6M5FmR0JcXExHCtpJaRkYHY2FjWm0BnRu+p3CUmJvK73NxcltqPyMhIlJSUcKCQ1NQfHh7mBQQHB6OtrQ2jo6MX5yHpTudyProIJK1/V/6z8YOuMT8cDkdASgmCwJfCjStNcXEx9vb2Xu1PVEVFBV/ERUVFWFxcfPV/bQcHB3wtnZfk9Y/wVfgLrni+tLJdUScAAAAASUVORK5CYII=') center no-repeat !important;\n cursor: pointer;\n}\n.YouTubeLyricsByRobWPageActionIcon:hover {\n border-color: #000;\n}\n/*YouTube*/\n#watch-headline-title .YouTubeLyricsByRobWPageActionIcon {\n position: absolute;\n top: 1px;\n right: 0;\n}\n/*Grooveshark*/\n#player .YouTubeLyricsByRobWPageActionIcon {\n position: relative;\n top: 8px;\n right: 30px;\n float: left;\n}\n/*Grooveshark Retro*/\n#footer > #player .YouTubeLyricsByRobWPageActionIcon {\n position: relative;\n top: 5px;\n right: -7px;\n float: left;\n}\n#footer > #player .YouTubeLyricsByRobWPageActionIcon ~ #player_controls_seeking {\n margin-left: 220px; /* was 190px */\n}\n/*Grooveshark HTML5*/\n#page-header .YouTubeLyricsByRobWPageActionIcon {\n position: absolute;\n top: 6px;\n left: 50px;\n right: auto;\n}\n\n/*Spotify Web client*/\n#wrapper > .YouTubeLyricsByRobWPageActionIcon {\n position: absolute;\n top: 0;\n right: 0;\n opacity: 0.6;\n}\n#wrapper > .YouTubeLyricsByRobWPageActionIcon:hover {\n opacity: 1;\n}";
}), r("eventBridge", [ "text!style/pageAction.css" ], function(e) {
var t, r = {}, n = [], o = function(e, t) {
var o = r[e] ? r[e].slice(0) : [];
if (n.push({
data: t,
callbacks: o
}), 1 === n.length) for (;n.length > 0; ) {
t = n.shift(), o = t.callbacks, t = t.data;
for (var i = 0; o.length > i; i++) o[i](t);
}
}, i = function(e, t) {
if ("function" != typeof t) throw Error("Callback must be a function!");
(r[e] || (r[e] = [])).push(t);
}, s = function() {
if (!t) {
var r = document.createElement("style");
r.appendChild(document.createTextNode(e)), (document.head || document.documentElement).appendChild(r),
t = document.createElement("div"), t.className = "YouTubeLyricsByRobWPageActionIcon",
t.title = "Click to show the Lyrics panel.\nPress CTRL and click to hide this button.",
t.addEventListener("click", function(e) {
a(), e.ctrlKey || o("toggle");
});
}
(document.body || document.documentElement).appendChild(t), o("iconinserted", t);
}, a = function() {
t && t.parentNode && t.parentNode.removeChild(t);
};
i("attached", a), i("detached", s);
return {
dispatchEvent: o,
listenEvent: i
};
}), r("touch2mouse", [], function() {
function e(e) {
return function(t) {
var r = t.changedTouches;
r && (r = r[0], t.preventDefault(), t = document.createEvent("MouseEvents"), t.initMouseEvent(e, !0, !0, document.defaultView, 1, r.screenX, r.screenY, r.clientX, r.clientY, r.ctrlKey, r.altKey, r.shiftKey, r.metaKey, 0, null),
r.target.dispatchEvent(t));
};
}
var t = "ontouchend" in document.documentElement, r = {}, n = {}, o = function(t, o) {
r[o] = t, n[t] = e(o);
};
o("touchstart", "mousedown"), o("touchmove", "mousemove"), o("touchend", "mouseup");
var i = {
events: n,
supportsTouch: t,
addTouchListener: function(e, t) {
if (i.supportsTouch) {
var o = r[t];
o && e.addEventListener(o, n[o], !1);
}
},
removeTouchListener: function(e, t) {
if (i.supportsTouch) {
var o = r[t];
o && e.removeEventListener(o, n[o], !1);
}
}
};
return i;
}), r("LyricsPanel", [ "require", "exports", "module", "InfoProvider", "LyricsSource", "sources/lyrics", "SimpleTemplating", "text!style/lyricsPanel.css", "text!templates/lyricsPanel.html", "eventBridge", "config", "algorithms", "touch2mouse" ], function(e, t) {
var r = e("InfoProvider").InfoProvider, n = e("LyricsSource").LyricsSource, o = e("sources/lyrics").getLyricsSources, i = e("SimpleTemplating").SimpleTemplating, s = e("text!style/lyricsPanel.css"), a = e("text!templates/lyricsPanel.html"), c = e("eventBridge"), l = e("config"), u = e("algorithms"), p = e("touch2mouse"), d = "";
/youtube/i.test(location.host) ? d = ".youtube" : /grooveshark/i.test(location.host) ? d = ".grooveshark" : /spotify/i.test(location.host) && (d = ".spotify"),
a = {
className: "L759-container",
tagName: "div",
innerHTML: a
};
var f = Object.prototype.hasOwnProperty, h = function(e, t, r) {
console && console.log(e + ": " + r);
}, m = function(e, t, r) {
var n = Error(e + ": " + r);
throw n.type = t, n;
}, g = function(e, t) {
if (t) {
for (var r in t) f.call(t, r) && (e[r] = t[r]);
return e;
}
}, y = function(e) {
return !(!e || !(document.documentElement.contains ? document === e || document.documentElement.contains(e) : 16 & document.compareDocumentPosition(e)));
}, v = {}, b = {};
b.panelElement = null, b.getCurrentStyle = function() {
return document.defaultView.getComputedStyle(b.panelElement);
}, b.infoProvider = null, b.runQueuedQuery = null, b.minWidth = 0, b.minHeight = 0,
b.boxsizingbug = !1, b.boxsizingcomputedstylebug = !1, b.runQuery = function(e, t) {
e = g({}, e);
var n = "";
if (e.song && e.artist) n = "result"; else {
if (e.searchTerms || (e.searchTerms = e.videotitle), !e.searchTerms) return;
n = "search";
}
if (b.runQueuedQuery = function() {
b.runQueuedQuery = null, b.infoProvider.query(n, e, b.queryCallback, t);
}, b.infoProvider) b.runQueuedQuery(); else {
if (0 === b.infoProvider) return;
b.infoProvider = 0, o(function(e) {
v = e.stats, b.infoProvider = new r(e), b.runQueuedQuery();
});
}
}, b.abortQuery = function() {
b.runQueuedQuery && (S = b.runQueuedQuery, b.runQueuedQuery = null), b.infoProvider && b.infoProvider.abort();
};
var S;
b.resumeQuery = function() {
S && S();
}, b.queryCallback = function(e) {
switch (b.attachPanel(), S = null, e.type) {
case "fetching":
b.render.fetchingLyrics(e), S = e.retry;
break;
case "fail":
e.next ? e.next() : b.render.notFound(e);
break;
case "found":
if (e.restart) {
var t = {
type: "fail",
sourceIndex: e.sourceIndex,
sourceCount: e.sourceCount,
searchTerms: e.searchTerms,
restart: e.restart
};
e.restart = function() {
b.queryCallback(t);
};
}
b.render.foundLyrics(e);
break;
case "message":
b.render.showMessage(e);
break;
default:
return m("YTL:queryCallback", "unknown_type", "Unknown type " + type + '. Expected one of "fetching", "fail" or "found"!'),
void 0;
}
b.panelHelpers.dimensions.adaptPanelToResult();
}, b.detachPanel = function() {
b.abortQuery(), y(b.panelElement) && (b.render.unbindInitialEvents(), b.panelElement.parentNode.removeChild(b.panelElement)),
y(b.styleSheet) && b.styleSheet.parentNode.removeChild(b.styleSheet), clearInterval(L),
b.panelHelpers.mover.end(), b.panelHelpers.resizer.end(), b.panelHelpers.overlay.detach(),
h("YTL:detachPanel", "detached", "Removed Lyrics panel."), c.dispatchEvent("detached");
}, b.attachPanel = function() {
var e = !b.panelElement;
b.styleSheet || (b.styleSheet = document.createElement("style"), b.styleSheet.appendChild(document.createTextNode(s))),
e && (b.panelElement = i(a).getElement(), b.panelElement.dir = "ltr", b.panelElement.style.top = b.savedOffsets.top + "px",
b.panelElement.style.right = b.savedOffsets.right + "px", b.panelElement.style.width = b.savedOffsets.width + "px"),
y(b.styleSheet) || (document.head || document.documentElement).appendChild(b.styleSheet),
y(b.panelElement) || (b.activateTheme(), (document.body || document.documentElement).appendChild(b.panelElement),
"fixed" != b.getCurrentStyle().position && b.pollPanelCSSActivation(), b.panelHelpers.dimensions.fixBoxSizing(),
b.render.bindInitialEvents(), b.panelHelpers.dimensions.enforcePosition(), e ? b.panelHelpers.dimensions.adaptPanelToResult() : b.panelHelpers.dimensions.enforceDimensions(),
b.panelHelpers.dimensions.enforcePosition() && b.panelHelpers.dimensions.enforceDimensions(),
b.resumeQuery(), c.dispatchEvent("attached"));
};
var L;
b.pollPanelCSSActivation = function() {
var e = Date.now(), t = setInterval(function() {
"fixed" == b.getCurrentStyle().position ? (clearInterval(t), b.panelHelpers.dimensions.adaptPanelToResult()) : Date.now() - e > 2e4 && clearInterval(t);
}, 50);
}, b.activateTheme = function() {
var e = function(e) {
var t = b.panelElement || a;
t.className = t.className.replace(/L759-skin-\S+/, "") + (e && "default" != e ? " L759-skin-" + e : "");
}, t = function(e) {
var t = e && document.defaultView.getComputedStyle(e);
return t && /^rgba?\(\d{1,2},\s*\d{1,2},\s*\d{1,2}(,\s*(?!0)\d*)?\)$/.test(t.backgroundColor);
};
l.getItem("theme" + d, function(r) {
"dark" == r || "default" == r ? e(r) : ".youtube" == d && t(document.body) || ".grooveshark" == d && t(document.getElementById("page-inner")) ? e("dark") : e("");
});
}, b.activateTheme();
var w = "panelOffsets" + d;
b.savedOffsets = {
top: 2,
right: 2,
width: 275,
maxHeight: 600
};
var x, A = 1, E = 2;
b.saveOffsets = function(e) {
if (!b.panelElement || !y(b.panelElement)) return h("LyricsPanel.saveOffsets", "not_rendered", "Lyric panel cannot be found within the document!"),
void 0;
var t = b.savedOffsets, r = b.getCurrentStyle(), n = function(e, r) {
r = parseFloat(r), !isNaN(r) && isFinite(r) && (t[e] = r);
};
e & A && (n("top", r.top), n("right", r.right)), e & E && (b.boxsizingcomputedstylebug ? (n("width", b.panelElement.style.width),
n("maxHeight", b.panelElement.style.height)) : (n("width", r.width), n("maxHeight", r.height))),
clearTimeout(x), x = setTimeout(function() {
l.setItem(w, t, function(e) {
e ? h("LyricsPanel.saveOffsets", "", "Saved Lyric panel's position and dimensions!") : h("LyricsPanel.saveOffsets", "", "Failed to save the Lyric panel's position and dimensions!");
});
}, 200);
};
var T = 0, k = [];
b.loadOffsets = function(e) {
2 == T ? e(b.savedOffsets) : 1 == T ? k.push(e) : (T = 1, k.push(e), l.getItem(w, function(t) {
if (t) {
var r = function(e) {
f.call(t, e) && (b.savedOffsets[e] = t[e]);
};
r("top"), r("right"), r("width"), r("maxHeight");
}
for (;e = k.shift(); ) e(b.savedOffsets);
T = 2;
}));
}, b.panelHelpers = {}, b.panelHelpers.show = function(e) {
e.style.display = "";
}, b.panelHelpers.hide = function(e) {
e.style.display = "none";
}, b.panelHelpers.doSearch = function() {
var e = b.panelElement.querySelector(".L759-searchterms").value, t = u.splitSongTitle(e);
t ? b.runQuery({
searchTerms: e,
artist: t[0],
song: t[1]
}) : b.runQuery({
searchTerms: e
});
}, b.panelHelpers.dimensions = {}, b.panelHelpers.dimensions.getViewportDimensions = function() {
var e = b.panelHelpers.overlay.isAttached();
b.panelHelpers.overlay.attach();
var t = b.overlayElement.getBoundingClientRect(), r = t.right, n = t.bottom;
return e || b.panelHelpers.overlay.detach(), {
width: r,
height: n
};
};
var C;
b.panelHelpers.dimensions.fixBoxSizing = function() {
if (!C) {
C = 1;
var e = document.createElement("div");
e.style.cssText = "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;top:-999px;position:absolute;min-height:6px;padding:1px;border:0;",
document.documentElement.appendChild(e);
var t = b.getCurrentStyle();
b.minHeight = parseFloat(t.minHeight) || 25, b.minWidth = parseFloat(t.minWidth) || 25,
8 == e.scrollHeight && (b.boxsizingbug = !0, b.panelElement.className += " boxsizingbug"),
e.style.height = "8px", "8px" != window.getComputedStyle(e).height && (b.boxsizingcomputedstylebug = !0),
e.parentNode.removeChild(e), e = null;
}
}, b.panelHelpers.dimensions.enforceDimensions = function() {
var e, t, r = b.getCurrentStyle(), n = b.panelElement.offsetWidth, o = b.panelElement.offsetHeight, i = parseFloat(r.top), s = parseFloat(r.right), a = b.minWidth, c = b.minHeight, l = b.panelHelpers.dimensions.getViewportDimensions(), u = l.width - s, p = l.height - i;
n > u && (e = u), a > n && (e = a), o > p && (t = p), c > o && (t = c), e && (b.panelElement.style.width = e + "px"),
t && (b.panelElement.style.height = t + "px"), b.panelHelpers.dimensions.enforceContentHeight();
}, b.panelHelpers.dimensions.enforcePosition = function() {
var e = b.getCurrentStyle(), t = parseFloat(e.top) || 0, r = parseFloat(e.right) || 0, n = b.panelHelpers.dimensions.getViewportDimensions(), o = n.height, i = n.width;
b.boxsizingcomputedstylebug ? (o -= parseFloat(b.panelElement.style.height) || b.minHeight,
i -= parseFloat(b.panelElement.style.width) || b.minWidth) : (o -= parseFloat(e.height) || b.minHeight,
i -= parseFloat(e.width) || b.minWidth);
var s = !1;
return t > o && (s = !0, b.panelElement.style.top = Math.max(0, o) + "px"), 0 > t && (s = !0,
b.panelElement.style.top = "0"), r > i && (s = !0, b.panelElement.style.right = Math.max(0, i) + "px"),
0 > r && (s = !0, b.panelElement.style.right = "0"), s;
}, b.panelHelpers.dimensions.getFixedNonContentHeight = function() {
var e = b.getCurrentStyle(), t = parseFloat(e.borderTopWidth) || 0, r = parseFloat(e.borderBottomWidth) || 0, n = parseFloat(e.paddingTop) || 0, o = parseFloat(e.paddingBottom) || 0, i = b.panelElement.querySelector(".L759-title").offsetHeight, s = b.panelElement.querySelector(".L759-searchbox").offsetHeight;
return _cached_fixedNonContentHeight = t + r + n + o + i + s;
}, b.panelHelpers.dimensions.enforceContentHeight = function() {
var e = Math.max(b.panelElement.offsetHeight, b.minHeight), t = b.panelHelpers.dimensions.getFixedNonContentHeight(), r = e - t;
b.panelElement.querySelector(".L759-content").style.height = 0 > r ? 0 : r + "px";
}, b.panelHelpers.dimensions.adaptPanelToResult = function() {
var e = b.panelElement.querySelector(".L759-result"), t = b.panelElement.querySelector(".L759-content");
t.style.overflow = "scroll";
var r = e.scrollHeight, n = 0;
t.style.overflow = "", t = null, r ? (n = b.panelElement.querySelector(".L759-link-container").offsetHeight,
n += b.panelElement.querySelector(".L759-info").offsetHeight, r += n) : r = b.panelElement.querySelector(".L759-fetching").scrollHeight,
r += 2;
var o = b.panelHelpers.dimensions.getFixedNonContentHeight(), i = o + r, s = o + n;
i > b.savedOffsets.maxHeight && (i = b.savedOffsets.maxHeight), s > i && (i = s),
b.panelElement.style.height = i + "px", b.panelHelpers.dimensions.enforceDimensions();
};
var R;
b.panelHelpers.dimensions.togglePanelHeight = function() {
var e = b.panelElement.offsetHeight;
b.getCurrentStyle();
var t = b.minHeight, r = 10;
r > e - t ? (b.resumeQuery(), R ? (b.panelElement.style.height = R, b.panelHelpers.dimensions.enforceDimensions()) : b.panelHelpers.dimensions.adaptPanelToResult()) : (b.abortQuery(),
R = b.panelElement.style.height, b.panelElement.style.height = t + "px", b.panelHelpers.dimensions.enforceDimensions());
}, b.panelHelpers.overlay = {}, b.panelHelpers.overlay.isAttached = function() {
return !(!b.overlayElement || !y(b.overlayElement));
}, b.panelHelpers.overlay.attach = function() {
b.overlayElement || (b.overlayElement = document.createElement("div"), b.overlayElement.className = "L759-overlay"),
y(b.overlayElement) || ((document.body || document.documentElement).appendChild(b.overlayElement),
b.panelHelpers.dimensions.getViewportDimensions());
}, b.panelHelpers.overlay.detach = function() {
b.panelHelpers.overlay.isAttached() && b.overlayElement.parentNode.removeChild(b.overlayElement);
}, b.panelHelpers.mover = {}, b.panelHelpers.mover.globalMouseMove = null, b.panelHelpers.mover.moverMouseDown = function(e) {
if (2 != e.button && (e.stopPropagation(), e.preventDefault(), !b.panelHelpers.mover.globalMouseMove)) {
var t = b.getCurrentStyle(), r = parseFloat(t.top) || 0, n = parseFloat(t.right) || 0, o = e.clientX, i = e.clientY, s = 0, a = 0, c = b.panelHelpers.dimensions.getViewportDimensions(), l = c.height - b.minHeight, u = c.width - b.minWidth;
b.panelHelpers.mover.globalMouseMove = function(e) {
if (e.preventDefault(), !y(b.panelElement)) return b.panel.mover.end(), void 0;
var t = r - i + e.clientY;
t > l && (t = l), s > t && (t = s);
var c = n + o - e.clientX;
c > u && (c = u), a > c && (c = a), b.panelElement.style.top = t + "px", b.panelElement.style.right = c + "px";
}, b.panelHelpers.overlay.attach(), document.addEventListener("mousemove", b.panelHelpers.mover.globalMouseMove, !0),
document.addEventListener("mouseup", b.panelHelpers.mover.globalMouseUp, !0), p.addTouchListener(document, "mousemove"),
p.addTouchListener(document, "mouseup");
}
}, b.panelHelpers.mover.globalMouseUp = function(e) {
e.preventDefault(), e.stopPropagation(), b.panelHelpers.dimensions.enforceDimensions(),
b.panelHelpers.mover.end();
}, b.panelHelpers.mover.end = function() {
b.panelHelpers.mover.globalMouseMove && (document.removeEventListener("mousemove", b.panelHelpers.mover.globalMouseMove, !0),
p.removeTouchListener(document, "mousemove"), b.panelHelpers.mover.globalMouseMove = null,
document.removeEventListener("mouseup", b.panelHelpers.mover.globalMouseUp, !0),
p.removeTouchListener(document, "mouseup"), b.panelHelpers.overlay.detach(), b.saveOffsets(A));
}, b.panelHelpers.resizer = {}, b.panelHelpers.resizer.globalMouseMove = null, b.panelHelpers.resizer.resizerMouseDown = function(e) {
if (!b.panelHelpers.resizer.globalMouseMove) {
e.preventDefault(), e.stopPropagation();
var t = b.panelElement.offsetWidth, r = b.panelElement.offsetHeight, n = e.clientX, o = e.clientY, i = b.getCurrentStyle(), s = b.minWidth, a = b.panelHelpers.dimensions.getViewportDimensions(), c = a.width - (parseFloat(i.right) || 0), l = b.minHeight, u = a.height - (parseFloat(i.top) || 0);
b.panelHelpers.resizer.globalMouseMove = function(e) {
if (e.preventDefault(), !y(b.panelElement)) return b.panel.resizer.end(), void 0;
var i = t + n - e.clientX;
i > c && (i = c), s > i && (i = s);
var a = r - o + e.clientY;
a > u && (a = u), l > a && (a = l), b.panelElement.style.width = i + "px", b.panelElement.style.height = a + "px",
b.panelHelpers.dimensions.enforceContentHeight();
}, document.addEventListener("mousemove", b.panelHelpers.resizer.globalMouseMove, !0),
document.addEventListener("mouseup", b.panelHelpers.resizer.end, !0), p.addTouchListener(document, "mousemove"),
p.addTouchListener(document, "mouseup"), b.panelHelpers.overlay.attach();
}
}, b.panelHelpers.resizer.end = function() {
b.panelHelpers.resizer.globalMouseMove && (document.removeEventListener("mousemove", b.panelHelpers.resizer.globalMouseMove, !0),
p.removeTouchListener(document, "mousemove"), b.panelHelpers.resizer.globalMouseMove = null,
document.removeEventListener("mouseup", b.panelHelpers.resizer.end, !0), p.removeTouchListener(document, "mouseup"),
b.panelHelpers.overlay.detach(), b.saveOffsets(E));
}, b.panelHelpers.stayWithinViewport = function() {
b.panelHelpers.dimensions.enforcePosition() && b.panelHelpers.dimensions.enforceDimensions();
};
var H, _ = 0;
b.panelHelpers.globalResize = function() {
var e = 333, t = Date.now(), r = t - _;
r > e ? (setTimeout(b.panelHelpers.stayWithinViewport, 4), _ = t) : (_ = t, clearTimeout(H),
H = setTimeout(b.panelHelpers.stayWithinViewport, e));
}, b.render = {}, b.render.bindInitialEvents = function() {
i(b.panelElement).update({
".L759-resizer": {
onmousedown: b.panelHelpers.resizer.resizerMouseDown,
ontouchstart: p.events.touchstart
},
".L759-title": {
onmousedown: b.panelHelpers.mover.moverMouseDown,
ontouchstart: p.events.touchstart,
ondblclick: b.panelHelpers.dimensions.togglePanelHeight
},
".L759-close": {
onclick: b.detachPanel
},
".L759-info": {
className: "L759-info " + ("https:" === location.protocol ? "" : "L759-http")
},
".L759-toggle-info": {
onclick: function(e) {
e.preventDefault();
var t = b.panelElement.querySelector(".L759-info");
t.style.display = t.offsetHeight ? "none" : "block", b.panelHelpers.dimensions.adaptPanelToResult();
}
},
".L759-searchbox .L759-searchterms": {
onkeydown: function(e) {
(13 === e.keyCode || "Enter" === e.keyIdentifier) && (e.preventDefault(), e.stopPropagation(),
b.panelHelpers.doSearch());
}
},
".L759-searchbox .L759-dosearch": {
onclick: b.panelHelpers.doSearch
},
"a.L759-settings-link": {
_post: function() {
("rob.lekensteyn.nl" === location.host || /^(chrome-extension|widget)/.test(location.protocol)) && (this.href = "#config",
this.target = "");
}
}
});
window.addEventListener("resize", b.panelHelpers.globalResize, !0);
}, b.render.unbindInitialEvents = function() {
i(b.panelElement).update({
".L759-resizer": {
onmousedown: null,
ontouchstart: null
},
".L759-title": {
onmousedown: null,
ontouchstart: null,
ondblclick: null
},
".L759-close": {
onclick: null
},
".L759-toggle-info": {
onclick: null
},
".L759-searchbox .L759-searchterms": {
onkeydown: null
},
".L759-searchbox .L759-dosearch": {
onclick: null
}
}), window.removeEventListener("resize", b.panelHelpers.globalResize, !0);
}, b.render.showMessage = function(e) {
var t = {
dir: ""
};
t[e.html ? "innerHTML" : "textContent"] = e.message, i(b.panelElement).update({
".L759-title": {
textContent: e.title || "YouTube Lyrics",
title: ""
},
".L759-fetching, .L759-link-container, .L759-info .L759-song-info": {
_post: b.panelHelpers.hide
},
".L759-result": t
});
}, b.render.fetchingLyrics = function(e) {
i(b.panelElement).update({
".L759-title": {
textContent: "Searching...",
title: ""
},
".L759-fetching": {
_post: b.panelHelpers.show
},
".L759-fetching .L759-buttons .L759-b-abort": {
onclick: e.abort,
_post: b.panelHelpers["function" == typeof e.abort ? "show" : "hide"]
},
".L759-fetching .L759-buttons .L759-b-retry": {
onclick: e.retry,
_post: b.panelHelpers["function" == typeof e.retry ? "show" : "hide"]
},
".L759-fetching .L759-buttons .L759-b-next": {
onclick: e.next,
_post: b.panelHelpers["function" == typeof e.next ? "show" : "hide"]
},
".L759-done": {
_post: b.panelHelpers.hide
},
".L759-link-to-fetched-source": {
href: e.url,
textContent: decodeURI(e.url)
}
});
}, b.render.notFound = function(e) {
i(b.panelElement).update({
".L759-title": {
textContent: "Not found",
title: ""
},
".L759-fetching": {
_post: b.panelHelpers.hide
},
".L759-done, .L759-link-container": {
_post: b.panelHelpers.show
},
".L759-done .L759-result": {
dir: "ltr",
innerHTML: "Cannot find lyrics (" + (+e.sourceCount || 0) + "x) for:<br>" + '<span class="YTL-notFound"></span>' + '<br>• <a class="YTL-notFound-search-link" target="_blank" rel="noreferrer"></a>' + '<br>• <span title="Enable or disable lyric providers.\n ' + +v.total + ' sources are available.">' + '<a href="https://rob.lekensteyn.nl/youtubelyrics/#config" target="_blank">Edit sources</a>' + (v.new ? " (" + +v.new + " new)" : "") + "</span><br>"
},
".L759-info .L759-song-info": {
_post: b.panelHelpers.hide
}
});
var t = n.prototype.$SEARCHTERMS(e.query, {
keepAccents: !0
});
/\blyrics\b/i.test(t) || (t += " lyrics"), t = encodeURIComponent(t);
var r = "https://encrypted.google.com/search?q=" + t;
i(b.panelElement).update({
".YTL-notFound": {
textContent: e.searchTerms
},
".YTL-notFound-search-link": {
href: r,
textContent: "Try Google (new window)"
}
}), b.render.updateSwitchSourceLink(e);
}, b.render.foundLyrics = function(e) {
var t = /^[^A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02B8\u0300-\u0590\u0800-\u1FFF\u2C00-\uFB1C\uFDFE-\uFE6F\uFEFD-\uFFFF]*[\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC]/, r = t.test(e.lyrics[0]) ? "rtl" : "ltr";
i(b.panelElement).update({
".L759-title": {
textContent: e.title,
title: e.title + "\n\nSource: " + e.sourceIdentifier
},
".L759-fetching": {
_post: b.panelHelpers.hide
},
".L759-done, .L759-link-container": {
_post: b.panelHelpers.show
},
".L759-info .L759-song-info": {
_post: b.panelHelpers.show
},
".L759-info .L759-song-title": {
textContent: e.title,
title: e.title
},
".L759-info .L759-link-to-found-source": {
href: e.url,
textContent: e.sourceIdentifier
},
".L759-done .L759-result": {
dir: r,
textContent: ""
}
}), b.render.updateSwitchSourceLink(e);
var n = document.createDocumentFragment(), o = document.createElement("div");
o.className = "L759-lyrics-line";
for (var s = 0; e.lyrics.length > s; s++) {
var a = o.cloneNode(!1);
a.textContent = e.lyrics[s].trim(), n.appendChild(a);
}
b.panelElement.querySelector(".L759-done .L759-result").appendChild(n);
}, b.render.updateSwitchSourceLink = function(e) {
i(b.panelElement).update({
".L759-done .L759-switch-source": {
onclick: e.next || e.restart,
title: "Click to search for lyrics at a different source.\nCurrent query: " + e.searchTerms
},
".L759-done .L759-switch-source .L759-sourceindex": {
textContent: e.sourceCount && e.sourceIndex + 1
},
".L759-done .L759-switch-source .L759-sourcecount": {
textContent: e.sourceCount
}
});
}, b.init = function() {
b.init = function() {}, c.listenEvent("toggle", function() {
b.panelElement && (y(b.panelElement) ? b.detachPanel() : b.attachPanel());
});
}, t.LyricsPanel = b;
}), r("YouTubeLyrics", [ "require", "exports", "module", "LyricsPanel", "eventBridge", "config" ], function(e, t) {
var r = e("LyricsPanel").LyricsPanel, n = e("eventBridge"), o = e("config"), i = function(e, t, r) {
console && console.log(e + ": " + r);
}, s = {};
s.LyricsPanel = r, s.getQuery = function() {
var e = "", t = "", r = "", n = document.querySelector(".channels-featured-video-details h3.title a");
return n ? r = n.textContent.trim() : (n = document.querySelector(".video-detail .title a")) ? r = n.title : document.getElementById("watch-headline-title") ? (n = document.title.replace(/\-\s*YouTube\s*$/, "").trim(),
r = n, n = document.querySelector('a[href^="/artist/"]'), n || (n = document.querySelector(".metadata-info-title+*")),
n && (t = n.textContent.trim()), n = document.querySelector('a[onmousedown*="metadata"]'),
n = n && n.parentNode, n = n && n.previousElementSibling, n = n && n.textContent.trim(),
n && (n = n.match(/^[^"]*"([\S\s]+)"[^"]*$/) || n.match(/^[^„]*„([\S\s]+)”[^”]*$/) || n.match(/^[^„]*„([\S\s]+)“[^“]*$/) || n.match(/^[^«]*«([\S\s]+)»[^»]*$/) || n.match(/^[^']*'([\S\s]+)'[^']*$/) || n.match(/^Koupit skladbu ([\S\s]+) na$/) || n.match(/^K\xFApi\u0165 skladbu ([\S\s]+) v slu\u017Ebe$/) || n.match(/^Osta ([\S\s]+) myym\xE4l\xE4st\xE4$/) || n.match(/^K\xF6p ([\S\s]+) p\xE5:$/) || n.match(/^([\S\s]+) \u0B90 \u0B87\u0BA4\u0BBF\u0BB2\u0BCD \u0BB5\u0BBE\u0B99\u0BCD\u0B95\u0BC1\u0B95$/) || n.match(/^[^\u300A]*\u300A([\S\s]+)\u300B[^\u300B]*$/) || n.match(/^[^\u300C]*\u300C([\S\s]+)\u300D[^\u300D]*$/),
n && (e = n[1]))) : document.querySelector("h1#vt") && (r = document.title.replace(/^YouTube\s*-\s*$/, "").trim()),
{
song: e,
artist: t,
videotitle: r
};
}, s.watchNavigationChanges = function() {};
var a = {};
s.checkContext = function() {
var e = s.getQuery();
return e.song || e.artist || e.videotitle ? a.song === e.song && a.artist === e.artist && a.videotitle === e.videotitle ? (i("YTL:checkContext", "query_not_modified", "Query did not change. Did not initiate a new query."),
void 0) : (a = e, s.LyricsPanel.runQuery(e), void 0) : (i("YTL:checkContext", "query_empty", "Query was empty."),
void 0);
}, s.putTinyButton = function(e) {
var t = document.getElementById("watch-headline-title");
t && e.parentNode !== t && t.appendChild(e);
}, s.launchPanel = function() {
s.launchPanel = function() {}, r.loadOffsets(function() {
s.LyricsPanel.init(), s.checkContext(), s.watchNavigationChanges();
});
}, s.init = function() {
i("YTL:init", "init", "Initializing YouTube Lyrics.");
var e = s.getQuery();
(e.song || e.artist || e.videotitle) && (n.listenEvent("iconinserted", s.putTinyButton),
o.getItem("youtube-autolaunch", function(t) {
n.dispatchEvent("detached"), t !== !1 ? (s.launchPanel(), e = null) : n.listenEvent("toggle", function() {
e && (s.launchPanel(), e = null);
});
}));
}, t.YTL = s, t.init = s.init;
}), r("GroovesharkLyrics", [ "require", "exports", "module", "LyricsPanel", "eventBridge", "config" ], function(e, t) {
var r = e("LyricsPanel").LyricsPanel, n = e("eventBridge"), o = e("config"), i = function(e, t, r) {
console && console.log(e + ": " + r);
}, s = {};
s.LyricsPanel = r;
var a = function() {
var e, t = document.getElementById("little-queue"), r = "", n = "";
return t && (e = t.querySelector(".little-queue-title"), e && (r = e.textContent),
e = t.querySelector(".little-queue-meta"), e && (n = e.textContent.split(" - ")[0])),
t = e = null, {
song: r,
artist: n
};
}, c = "now-playing-metadata";
s.getQuery = function() {
var e = document.getElementById(c);
if (null === e) if (e = document.getElementById("playerDetails_nowPlaying")) c = "playerDetails_nowPlaying"; else if (document.getElementById("little-queue")) return s.getQuery = a,
a();
var t, r = "", n = "";
return e && (t = e.querySelector(".song"), t && (r = t.title), t = e.querySelector(".artist"),
t && (n = t.title)), e = t = null, {
song: r,
artist: n
};
};
var l;
s.watchNavigationChanges = function() {
clearInterval(l), l = setInterval(s.checkContext, 200);
}, s.unwatchNavigationChanges = function() {
clearInterval(l);
};
var u = {};
s.checkContext = function() {
var e = s.getQuery();
(e.song || e.artist) && (u.song !== e.song || u.artist !== e.artist) && (u = e,
s.LyricsPanel.runQuery(e));
}, s.putTinyButton = function(e) {
var t = document.getElementById("player") || document.getElementById("page-header");
t && e.parentNode !== t && t.insertBefore(e, t.firstChild);
}, s.launchPanel = function() {
s.launchPanel = function() {};
var e = document.querySelector("#player-wrapper,#footer");
e && (s.LyricsPanel.panelHelpers.dimensions.getViewportDimensions = function() {
var t = e.getBoundingClientRect();
return {
width: t.right,
height: t.top
};
}), s.LyricsPanel.loadOffsets(function() {
s.LyricsPanel.init(), r.queryCallback({
type: "message",
html: !0,
title: "Lyrics for Grooveshark",
message: 'Play a song or use the search box to get lyrics.<br><br>Hit the close button to hide the panel.<br>» <a href="https://rob.lekensteyn.nl/youtubelyrics/#config" target="_blank">Preferences</a>'
}), s.checkContext(), s.watchNavigationChanges();
});
}, s.init = function() {
i("GSL:init", "init", "Initializing Grooveshark Lyrics."), n.listenEvent("attached", s.watchNavigationChanges),
n.listenEvent("detached", s.unwatchNavigationChanges), n.listenEvent("iconinserted", s.putTinyButton),
o.getItem("grooveshark-autolaunch", function(e) {
if (n.dispatchEvent("detached"), e !== !1) s.launchPanel(); else {
var t = !0;
n.listenEvent("toggle", function() {
t && (s.launchPanel(), t = !1);
});
}
});
}, t.GSL = s, t.init = s.init;
}), r("SpotifyLyrics", [ "require", "exports", "module", "LyricsPanel", "eventBridge", "config", "algorithms" ], function(e, t) {
var r = e("LyricsPanel").LyricsPanel, n = e("eventBridge"), o = e("config"), i = e("algorithms"), s = function(e, t, r) {
console && console.log(e + ": " + r);
}, a = {};
a.LyricsPanel = r, a.getQuery = function() {
var e = "", t = "", r = document.title.replace(/\s*-?\s*Spotify\s*$/i, "").replace(/^[\u25b6\s]+/, ""), n = r.replace(/\([^)]*\)|\[[^\]]*\]/g, " ");
return -1 == n.indexOf(" - ") && (n = r), n = n.split(" - "), 2 == n.length ? (e = n[0],
t = n[1]) : n.length > 2 && (t = n.pop(), e = .7 > i.getSimilarityCoefficient(t, n[0]) ? n[0] : n[1]),
{
song: e,
artist: t
};
};
var c;
a.watchNavigationChanges = function() {
clearInterval(c), c = setInterval(a.checkContext, 200);
}, a.unwatchNavigationChanges = function() {
clearInterval(c);
};
var l = {};
a.checkContext = function() {
var e = a.getQuery();
(e.song || e.artist) && (l.song !== e.song || l.artist !== e.artist) && (l = e,
a.LyricsPanel.runQuery(e));
}, a.putTinyButton = function(e) {
var t = document.getElementById("wrapper");
t && t.appendChild(e);
}, a.launchPanel = function() {
a.launchPanel = function() {}, a.LyricsPanel.loadOffsets(function() {
a.LyricsPanel.init(), r.queryCallback({
type: "message",
html: !0,
title: "Lyrics for Spotify",
message: 'Play a song or use the search box to get lyrics.<br><br>Hit the close button to hide the panel.<br>» <a href="https://rob.lekensteyn.nl/youtubelyrics/#config" target="_blank">Preferences</a>'
}), a.checkContext(), a.watchNavigationChanges();
});
}, a.init = function() {
s("SPL:init", "init", "Initializing Spotify Lyrics."), n.listenEvent("attached", a.watchNavigationChanges),
n.listenEvent("detached", a.unwatchNavigationChanges), n.listenEvent("iconinserted", a.putTinyButton),
o.getItem("spotify-autolaunch", function(e) {
if (n.dispatchEvent("detached"), e !== !1) a.launchPanel(); else {
var t = !0;
n.listenEvent("toggle", function() {
t && (a.launchPanel(), t = !1);
});
}
});
}, t.SPL = a, t.init = a.init;
}), r("LyricsPanel-demo", [ "require", "exports", "module", "LyricsPanel" ], function(e, t) {
function r() {
n.init(), n.infoProvider = null, n.queryCallback({
type: "message",
html: !0,
message: i
});
}
var n = e("LyricsPanel").LyricsPanel, o = /^https?:\/\/rob\.lekensteyn\.nl\/youtubelyrics/i.test(location.href) || /^(chrome-extension|widget):$/.test(location.protocol) ? "" : "https://rob.lekensteyn.nl/youtubelyrics/", i = 'Hi there,<br><br>Whenever you visit a <b>YouTube</b> video or play a song on <b>Grooveshark</b> or <b>Spotify</b>\'s Web Player, lyrics will be displayed in this box.If you want to see other lyrics, click on "Different source", or use the search box below.<br><br>» <a href="' + o + '#quick-guide">More information</a><br><br>';
t.init = r;
}), r("dragndrop-nodes", [ "require", "exports", "module" ], function(e, t) {
function r() {
if (a) {
a.style.display = i;
var e = c.parentNode;
e && e.removeChild(c), a = null, s = null, c = null;
}
}
function n(e, t, r) {
var n = e[l + t];
n && (e.removeEventListener(t, n, !1), e[l + t] = null), r && (e.addEventListener(t, r, !1),
e[l + t] = r);
}
function o(e, t, o) {
function l(e) {
e.stopPropagation(), e.preventDefault();
}
if (t && !t.contains(e)) throw Error("The dragged node must be the moved node or a child of the moved node!");
t = t || e;
var u = function(e) {
t.dragDrop(), l(e);
};
n(e, "mouseover", function() {
"draggable" in t ? t.draggable = !0 : t.dragDrop && n(t, "selectstart", u);
}), n(e, "mouseout", function() {
t.draggable ? t.draggable = !1 : n(t, "selectstart");
}), n(t, "dragstart", function(e) {
a = t, s = a.previousSibling, c = document.createElement(a.tagName), c.draggable = !0,
c.className = "drag-drop-placeholder", c.style.height = a.offsetHeight + "px", n(c, "dragover", l),
n(c, "drop", function(e) {
l(e), c.parentNode.insertBefore(a, c), o && a.previousSibling !== s && o(), r();
});
try {
e.dataTransfer.effectAllowed = "move", e.dataTransfer.setData("text/plain", "");
} catch (i) {}
}), n(t, "dragenter", function(e) {
if (a && e.target === t) {
var r = e.target;
if ("none" !== a.style.display) return a.parentNode.insertBefore(c, a), i = a.style.display,
a.style.display = "none", void 0;
if (r !== c) {
var n = r.parentNode;
0 === (2 & c.compareDocumentPosition(r)) && (r = r.nextSibling), n.insertBefore(c, r);
}
}
}), n(t, "dragover", l), n(t, "drop", l), n(t, "dragend", r);
}
var i, s, a, c, l = "dndEvent" + Math.random();
t.bindDnD = o;
}), r("text!style/config.css", [], function() {
return '.drag-drop-placeholder {\n outline: 1px dashed #AAA;\n}\n.pref-sources, .pref-item {\n width: 390px;\n list-style-type: none;\n margin: 0;\n padding: 0;\n}\n.pref-sources {\n position: relative;\n margin: 5px 0 0;\n}\n.pref-sources *,\n.config-site-box {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n.pref-item {\n height: 24px;\n padding: 2px 0;\n line-height: 20px;\n font-size: 18px;\n}\n.pref-item.source-disabled {\n opacity: 0.4;\n}\n.pref-item.source-disabled:hover {\n opacity: 0.8;\n}\n.pref-item .anchor {\n display: inline-block;\n width: 30px;\n text-align: center;\n cursor: move;\n}\n.pref-item .description {\n padding: 0 10px;\n}\n.pref-item input[type=checkbox] {\n display: none;\n}\n.pref-item input[type=checkbox] + span {\n display: inline-block;\n width: 4ex;\n height: 20px;\n border: 1px solid #BBB;\n background-color: #fff;\n vertical-align: middle;\n line-height: 1em;\n font-size: 16px;\n text-align: center;\n cursor: default;\n}\n.pref-item input[type=checkbox] + span:hover {\n border-color: #000;\n}\n.pref-item input[type=checkbox] + span:before {\n content: \'Off\';\n}\n.pref-item input[type=checkbox]:checked + span:before {\n content: \'On\';\n}\n\n/* Description of source */\n.pref-item.sd-highlight:hover,\n.source-item-description:hover ~ .pref-item.sd-highlight {\n outline: 1px solid #888;\n}\n.source-item-description {\n position: absolute;\n top: 0;\n left: 400px;\n display: none;\n width: 300px;\n height: 100%;\n border-left: 3px solid #99C;\n padding: 7px;\n font-size: 16px;\n}\n.source-item-description.sd-visible {\n display: block;\n}\n.sd-source-header {\n font-weight: bold;\n margin: 0 0 0.5em 0;\n}\n\n\n.config-site-box {\n display: inline-block;\n border: 1px solid transparent;\n width: 32%;\n min-height: 2em;\n padding: 0.5em;\n background-color: #EEFAEE;\n border-radius: 3px;\n vertical-align: top;\n}\n.config-site-box:hover {\n border-color: #CCF;\n}\n.config-site-box label:hover {\n background-color: #FED;\n}\n.config-site-box.site-disabled {\n background-color: #FAEEEE;\n}\n.config-site-box .config-site-items {\n position: relative;\n}\n.config-site-box .btn-enable-site,\n.config-site-box.site-disabled:hover .btn-disable-site,\n.config-site-box .btn-disable-site {\n display: none;\n}\n.config-site-box:hover .btn-disable-site,\n.config-site-box.site-disabled .btn-enable-site {\n display: block;\n}\n.config-site-box.site-disabled .config-site-items > div {\n visibility: hidden;\n}\ninput[type="button"].btn-disable-site {\n position: absolute;\n right: 0;\n top: -2em;\n height: 1.5em;\n padding-top: 0;\n opacity: 0.6;\n}\ninput[type="button"].btn-disable-site:hover {\n opacity: 1;\n}\ninput[type="button"].btn-enable-site {\n /* Big button */\n width: 80%;\n height: 2em;\n max-height: 100%;\n\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n right: 0;\n margin: auto;\n}';
}), r("options", [ "require", "exports", "module", "LyricsPanel-demo", "sources/lyrics", "config", "dragndrop-nodes", "text!style/config.css" ], function(e, t) {
function r() {
var e = document.createElement("style");
e.appendChild(document.createTextNode(v)), (document.head || document.documentElement).appendChild(e);
}
function n(e, t) {
"onmouseenter" in document.documentElement ? e.addEventListener("mouseenter", t) : e.addEventListener("mouseover", function(e) {
return this === e.relatedTarget || this.contains(e.relatedTarget) ? void 0 : t.call(this, e);
});
}
function o(e) {
e.classList || (e.classList = {
add: function(t) {
-1 === (" " + e.className + " ").indexOf(t) && (e.className += " " + t);
},
remove: function(t) {
t = (" " + e.className + " ").replace(" " + t + " ", " ").trim(), e.className !== t && (e.className = t);
}
});
}
function i() {
function e(e, t) {
var r = document.getElementsByClassName(t)[0];
if (r) {
if (r === e) return;
r.classList.remove(t);
}
e.classList.add(t);
}
function t() {
p || (p = document.createElement("li"), p.className = "pref-item", p.innerHTML = '<span class="anchor">::</span><label><input type="checkbox"><span></span></label><span class="description"></span>');
var e = p.cloneNode(!0);
return o(e), e.querySelector('input[type="checkbox"]').onchange = function() {
e.classList[this.checked ? "remove" : "add"]("source-disabled"), c();
}, e;
}
function r(t) {
d || (d = document.createElement("li"), d.className = "source-item-description",
d.innerHTML = '<h2 class="sd-source-header"><a class="sd-source-link" target="_blank" rel="noreferrer"></a></h2><div><p class="sd-description"></p>View statistics on <a class="sd-alexa-link" target="_blank" rel="noreferrer" title="Alexa provides public demographics about websites, such as the visitor\'s country. You can use this tool to find out if this source suits your needs.">Alexa</a>.</div>');
var r = d.cloneNode(!0);
return o(r), n(r, function() {
e(t, "sd-highlight");
}), n(t, function() {
e(r, "sd-visible"), e(t, "sd-highlight");
}), r;
}
function i() {
var e = document.createElement("input");
return e.type = "button", e.id = "save", e.value = "Save", e.disabled = !0, e.onclick = s,
e;
}
function c() {
document.getElementById("save").disabled = !1;
}
function l() {
var e = document.createElement("input");
return e.type = "button", e.id = "restore-defaults", e.value = "Restore defaults",
e.onclick = function() {
confirm("Do you want to remove your current Lyrics Source preferences, and restore the defaults?\nWarning: This step cannot be undone!") && a();
}, e;
}
var u = document.getElementById("config-source");
u.textContent = "Loading...";
var p, d, f = document.createDocumentFragment();
m.getAllLyricsSources(function(e) {
var n = document.createElement("ol");
n.className = "pref-sources", e.forEach(function(e) {
var o = t();
e.disabled && o.classList.add("source-disabled");
var i = e.identifier, s = o.querySelector('input[type="checkbox"]');
s.checked = !e.disabled, s.setAttribute("data-source-id", i), o.querySelector(".description").textContent = i,
y(o.querySelector(".anchor"), o, c), n.appendChild(o), o = r(o);
var a = o.querySelector(".sd-source-link");
a.textContent = i, a.href = e.homepage, a = o.querySelector(".sd-alexa-link"), a.href = "http://www.alexa.com/siteinfo/" + e.homepage;
var l = o.querySelector(".sd-description");
l.textContent = e.description || "(no description)", l.appendChild(document.createElement("br")),
f.appendChild(o);
}), u.textContent = "You can disable a source, or change the priority order. Sources on top are used first.",
n.insertBefore(f, n.firstChild);
var s = document.createElement("li");
o(s), s.className = "source-item-description sd-visible", s.innerHTML = '<h2 class="sd-source-header">Description</h2>Hover over an item at the left side for brief descriptions.<br><br>Found a source which is not listed here? Send a mail to <a href="mailto:gwnRob@gmail.com">gwnRob@gmail.com</a>!',
n.appendChild(s), u.appendChild(n), u.appendChild(i()), u.appendChild(l());
});
}
function s() {
for (var e = document.querySelectorAll('ol.pref-sources > li.pref-item input[type="checkbox"]'), t = [], r = [], n = [], o = 0; e.length > o; o++) {
var i = e[o], s = i.getAttribute("data-source-id"), a = i.checked;
t.push(s), (a ? n : r).push(s);
}
var c = {
order: t,
blacklist: r,
whitelist: n
};
g.setItem("lyricsSourcePreferences", c, function(e) {
e ? b("Successfully saved preferences.") : b("Failed to save all preferences.");
}), document.getElementById("save").disabled = !0;
}
function a() {
g.removeItem("lyricsSourcePreferences", function(e) {
b(e ? "Successfully removed prefs." : "Failed to remove all prefs."), i();
});
}
function c(e) {
function t() {
g.getItem("setwmode", function(e) {
e = e !== !1, n.checked = e;
});
}
if (!(0 > Object.prototype.toString.call(window.HTMLElement).indexOf("Constructor") || /mac/i.test(navigator.platform))) {
var r = document.createElement("div");
r.id = "config-wmode", r.innerHTML = '<label title="Set wmode=opaque. \nRequired if you want to drag the panel over the video. \nSearch suggestions will also start to work properly! \nEnabling this option might affect performance."><input type="checkbox"> Set wmode parameter</label>',
e.appendChild(r);
var n = r.querySelector("input[type=checkbox]");
n.checked = !0, n.onchange = function() {
g.setItem("setwmode", n.checked, function(e) {
b(e ? "Successfully saved wmode pref." : "Failed to save wmode pref."), t();
});
}, t();
}
}
function l() {
var e = document.getElementById("launch-demo"), t = e.getAttribute("data-x");
t = (t || "_") + "_", e.setAttribute("data-x", t), e.style.display = "block";
var r = function() {
t == e.getAttribute("data-x") ? h.init() : e.removeEventListener("click", r, !1);
};
e.addEventListener("click", r, !1);
}
function u(e, t) {
function r() {
g.getItem(s, function(e) {
e = e !== !1, n.classList[e ? "remove" : "add"]("site-disabled");
});
}
var n = e.parentNode;
o(n);
var i = n.querySelector("h2").textContent, s = "enabled." + t, a = function(e) {
n.classList[e ? "remove" : "add"]("site-disabled"), g.setItem(s, e, function(e) {
b((e ? "Successfully saved " : "Failed to save ") + s + " pref.");
});
}, c = document.createElement("input");
c.type = "button", c.value = "Enable", c.className = "btn-enable-site", c.title = "Active Lyrics for " + i,
o(c), c.onclick = function() {
a(!0);
};
var l = document.createElement("input");
o(l), l.type = "button", l.value = "Disable", l.className = "btn-disable-site",
l.title = "Completely disable Lyrics for " + i, l.onclick = function() {
a(!1);
}, e.appendChild(c), e.appendChild(l), r();
}
function p(e, t) {
function r() {
g.getItem(n, function(e) {
s.checked = e !== !1;
});
}
var n = t + "-autolaunch", o = "The lyrics can be shown by clicking on the 'YouTube Lyrics' icon " + ("youtube" == t ? "after the video's title." : "grooveshark" == t ? "at the left side of the player controls." : "spotify" == t ? "at the upper-right corner of the player." : "at the upper-right corner of the video page."), i = document.createElement("div");
i.id = "config-" + t + "-autolaunch", i.innerHTML = '<label title="If unchecked, lyrics will not be displayed. \n' + o + '"><input type="checkbox"> Automatically show Lyrics.</label>',
e.appendChild(i);
var s = i.querySelector('input[type="checkbox"]');
s.checked = !0, s.onchange = function() {
g.setItem(n, s.checked, function(e) {
b((e ? "Successfully saved " : "Failed to save ") + n + " pref."), r();
});
}, r();
}
function d(e, t) {
function r() {
g.getItem(n, function(e) {
i.value = e, -1 == i.selectedIndex && (i.value = "auto");
});
}
var n = "theme." + t, o = document.createElement("div");
o.id = "config-" + t + "-theme", o.innerHTML = '<label>Theme: <select class="pref-select-theme"></select></label>',
e.appendChild(o);
var i = o.querySelector("select");
i.add(new Option("Auto-detect", "auto", !0)), i.add(new Option("Default", "default")),
i.add(new Option("Dark", "dark")), i.onchange = function() {
g.setItem(n, this.value, function(e) {
b((e ? "Successfully saved " : "Failed to save ") + n + " pref.");
});
}, r();
}
function f() {
if (!document.getElementById("get-extension")) return b("Not an options page!"),
void 0;
if (!document.documentElement.hasAttribute("YTLActivated")) {
if (document.documentElement.hasAttribute("YTLDemoActivated")) {
for (var e = document.querySelectorAll("#just-a-demo-overlay,.L759-container,.L759-overlay,.YouTubeLyricsByRobWPageActionIcon"), t = 0; e.length > t; ++t) e[t].parentNode.removeChild(e[t]);
e = null;
}
document.documentElement.setAttribute("YTLActivated", ""), b("Options page detected by YouTube Lyrics."),
r(), i(), l(), [ "youtube", "grooveshark", "spotify" ].forEach(function(e) {
var t = document.querySelector("#config-" + e + " .config-site-items");
t.textContent = "", "youtube" == e && c(t, e), u(t, e), p(t, e), d(t, e);
});
}
}
var h = e("LyricsPanel-demo"), m = e("sources/lyrics"), g = e("config"), y = e("dragndrop-nodes").bindDnD, v = e("text!style/config.css"), b = function(e) {
console && console.log("Options: " + e);
};
t.init = f;
}), t([ "config", "setwmode", "domready", "YouTubeLyrics", "GroovesharkLyrics", "SpotifyLyrics", "options" ], function(e, t, r, n, o, i, s) {
var a = /^https?:\/\/www\.youtube\.com\/(?![ve]\/)(?!embed\/)(?!dev(\/|$))/.test(location.href) ? "youtube" : /^(|(retro|html5)\.)grooveshark\.com$/.test(location.hostname) ? "grooveshark" : "play.spotify.com" === location.hostname ? "spotify" : /^https?:\/\/rob\.lekensteyn\.nl\/youtubelyrics/.test(location.href) ? "options" : "";
if (a) {
var c = function() {
if (0 === --u && l) switch (a) {
case "youtube":
document.title && n.init();
break;
case "grooveshark":
document.querySelector("#now-playing-metadata,#playerDetails_nowPlaying,#little-queue") && o.init();
break;
case "spotify":
window.top == window && i.init();
break;
case "options":
s.init();
}
}, l = "options" === a, u = 1;
l || (++u, e.getItem("enabled." + a, function(e) {
l = e !== !1, c();
})), r(c), "youtube" === a && 0 > Object.prototype.toString.call(window.HTMLElement).indexOf("Constructor") && !/mac/i.test(navigator.platform) && e.getItem("setwmode", function(e) {
e !== !1 && t();
});
}
});
})();