Skip to content

Instantly share code, notes, and snippets.

@alejandrorangel
Created February 6, 2016 00:05
Show Gist options
  • Save alejandrorangel/c66f337e3ec85ce79b87 to your computer and use it in GitHub Desktop.
Save alejandrorangel/c66f337e3ec85ce79b87 to your computer and use it in GitHub Desktop.
/*
Copyright Spotify AB 2012-2014. All rights reserved.
History.getInternetExplorerMajorVersion()
Get's the major version of Internet Explorer
@return {integer}
@license Public Domain
@author Benjamin Arthur Lupton <contact@balupton.com>
@author James Padolsey <https://gist.github.com/527683>
History.isInternetExplorer()
Are we using Internet Explorer?
@return {boolean}
@license Public Domain
@author Benjamin Arthur Lupton <contact@balupton.com>
History.js Core
@author Benjamin Arthur Lupton <contact@balupton.com>
@copyright 2010-2011 Benjamin Arthur Lupton <contact@balupton.com>
@license New BSD License <http://creativecommons.org/licenses/BSD/>
History.js HTML4 Support
Depends on the HTML5 Support
@author Benjamin Arthur Lupton <contact@balupton.com>
@copyright 2010-2011 Benjamin Arthur Lupton <contact@balupton.com>
@license New BSD License <http://creativecommons.org/licenses/BSD/>
CryptoJS v3.1.2
code.google.com/p/crypto-js
(c) 2009-2013 by Jeff Mott. All rights reserved.
code.google.com/p/crypto-js/wiki/License
History.js Native Adapter
@author Benjamin Arthur Lupton <contact@balupton.com>
@copyright 2010-2011 Benjamin Arthur Lupton <contact@balupton.com>
@license New BSD License <http://creativecommons.org/licenses/BSD/>
*/
Spotify.Web.ABTester = Spotify.Web.ABTester || {};
(function(c) {
function a(a) {
var b = 0,
c = e[a];
if (c) return c;
b = 0;
c = Array(1E4);
for (i = 0; i < c.length; i++) c[i] = i;
var h = f(d(j(a))),
b = parseInt(h.substring(0, 8), 16);
(function(a) {
for (var c = a.length - 1; c >= 1; c--) {
b = 16807 * b % 2147483647;
var v = b % (c + 1),
e = a[c];
a[c] = a[v];
a[v] = e
}
})(c);
return e[a] = c
}
function b(b, c) {
if (c && c.substring(0, 4) == "NTX_") {
var v = a(c),
e = parseInt(f(d(j("spotify:test:" + b))).substring(0, 8), 16),
e = Math.floor(1E4 * e * Math.pow(2, -32));
return Math.floor(v[e] / 10)
} else return v = "spotify:test:", c && (v += c + ":"), v +=
b, v = parseInt(f(d(j(v))).substring(0, 8), 16), Math.floor(1E3 * v * Math.pow(2, -32))
}
function d(a) {
for (var b = Array(a.length >> 2), c = 0; c < b.length; c++) b[c] = 0;
for (c = 0; c < a.length * 8; c += 8) b[c >> 5] |= (a.charCodeAt(c / 8) & 255) << c % 32;
a = a.length * 8;
b[a >> 5] |= 128 << a % 32;
b[(a + 64 >>> 9 << 4) + 14] = a;
for (var a = 1732584193, c = -271733879, e = -1732584194, d = 271733878, f = 0; f < b.length; f += 16) var j = a,
o = c,
n = e,
B = d,
a = g(a, c, e, d, b[f + 0], 7, -680876936),
d = g(d, a, c, e, b[f + 1], 12, -389564586),
e = g(e, d, a, c, b[f + 2], 17, 606105819),
c = g(c, e, d, a, b[f + 3], 22, -1044525330),
a = g(a, c, e, d, b[f + 4], 7, -176418897),
d = g(d, a, c, e, b[f + 5], 12, 1200080426),
e = g(e, d, a, c, b[f + 6], 17, -1473231341),
c = g(c, e, d, a, b[f + 7], 22, -45705983),
a = g(a, c, e, d, b[f + 8], 7, 1770035416),
d = g(d, a, c, e, b[f + 9], 12, -1958414417),
e = g(e, d, a, c, b[f + 10], 17, -42063),
c = g(c, e, d, a, b[f + 11], 22, -1990404162),
a = g(a, c, e, d, b[f + 12], 7, 1804603682),
d = g(d, a, c, e, b[f + 13], 12, -40341101),
e = g(e, d, a, c, b[f + 14], 17, -1502002290),
c = g(c, e, d, a, b[f + 15], 22, 1236535329),
a = k(a, c, e, d, b[f + 1], 5, -165796510),
d = k(d, a, c, e, b[f + 6], 9, -1069501632),
e = k(e, d, a, c, b[f + 11], 14, 643717713),
c = k(c, e, d, a, b[f + 0], 20, -373897302),
a = k(a, c, e, d, b[f + 5], 5, -701558691),
d = k(d, a, c, e, b[f + 10], 9, 38016083),
e = k(e, d, a, c, b[f + 15], 14, -660478335),
c = k(c, e, d, a, b[f + 4], 20, -405537848),
a = k(a, c, e, d, b[f + 9], 5, 568446438),
d = k(d, a, c, e, b[f + 14], 9, -1019803690),
e = k(e, d, a, c, b[f + 3], 14, -187363961),
c = k(c, e, d, a, b[f + 8], 20, 1163531501),
a = k(a, c, e, d, b[f + 13], 5, -1444681467),
d = k(d, a, c, e, b[f + 2], 9, -51403784),
e = k(e, d, a, c, b[f + 7], 14, 1735328473),
c = k(c, e, d, a, b[f + 12], 20, -1926607734),
a = l(a, c, e, d, b[f + 5], 4, -378558),
d = l(d, a, c, e, b[f + 8], 11, -2022574463),
e = l(e, d, a, c, b[f + 11], 16, 1839030562),
c = l(c, e, d, a, b[f + 14], 23, -35309556),
a = l(a, c, e, d, b[f + 1], 4, -1530992060),
d = l(d, a, c, e, b[f + 4], 11, 1272893353),
e = l(e, d, a, c, b[f + 7], 16, -155497632),
c = l(c, e, d, a, b[f + 10], 23, -1094730640),
a = l(a, c, e, d, b[f + 13], 4, 681279174),
d = l(d, a, c, e, b[f + 0], 11, -358537222),
e = l(e, d, a, c, b[f + 3], 16, -722521979),
c = l(c, e, d, a, b[f + 6], 23, 76029189),
a = l(a, c, e, d, b[f + 9], 4, -640364487),
d = l(d, a, c, e, b[f + 12], 11, -421815835),
e = l(e, d, a, c, b[f + 15], 16, 530742520),
c = l(c, e, d, a, b[f + 2], 23, -995338651),
a = h(a, c, e, d, b[f + 0], 6, -198630844),
d = h(d, a, c, e, b[f + 7], 10, 1126891415),
e = h(e, d, a, c, b[f + 14], 15, -1416354905),
c = h(c, e, d, a, b[f + 5], 21, -57434055),
a = h(a, c, e, d, b[f + 12], 6, 1700485571),
d = h(d, a, c, e, b[f + 3], 10, -1894986606),
e = h(e, d, a, c, b[f + 10], 15, -1051523),
c = h(c, e, d, a, b[f + 1], 21, -2054922799),
a = h(a, c, e, d, b[f + 8], 6, 1873313359),
d = h(d, a, c, e, b[f + 15], 10, -30611744),
e = h(e, d, a, c, b[f + 6], 15, -1560198380),
c = h(c, e, d, a, b[f + 13], 21, 1309151649),
a = h(a, c, e, d, b[f + 4], 6, -145523070),
d = h(d, a, c, e, b[f + 11], 10, -1120210379),
e = h(e, d, a, c, b[f + 2], 15, 718787259),
c = h(c, e, d, a, b[f + 9], 21, -343485551),
a = m(a, j),
c = m(c, o),
e = m(e, n),
d = m(d, B);
b = [a, c, e, d];
a = "";
for (c = 0; c < b.length * 32; c += 8) a += String.fromCharCode(b[c >> 5] >>> c % 32 & 255);
return a
}
function f(a) {
for (var b = o ? "0123456789ABCDEF" : "0123456789abcdef", c = "", e, d = 0; d < a.length; d++) e = a.charCodeAt(d), c += b.charAt(e >>> 4 & 15) + b.charAt(e & 15);
return c
}
function j(a) {
for (var b = "", c = -1, e, d; ++c < a.length;) e = a.charCodeAt(c), d = c + 1 < a.length ? a.charCodeAt(c + 1) : 0, 55296 <= e && e <= 56319 && 56320 <= d && d <= 57343 && (e = 65536 + ((e & 1023) << 10) + (d & 1023), c++), e <= 127 ? b += String.fromCharCode(e) :
e <= 2047 ? b += String.fromCharCode(192 | e >>> 6 & 31, 128 | e & 63) : e <= 65535 ? b += String.fromCharCode(224 | e >>> 12 & 15, 128 | e >>> 6 & 63, 128 | e & 63) : e <= 2097151 && (b += String.fromCharCode(240 | e >>> 18 & 7, 128 | e >>> 12 & 63, 128 | e >>> 6 & 63, 128 | e & 63));
return b
}
function g(a, b, c, e, d, h, f) {
return m(n(m(m(a, b & c | ~b & e), m(d, f)), h), b)
}
function k(a, b, c, e, d, h, f) {
return m(n(m(m(a, b & e | c & ~e), m(d, f)), h), b)
}
function l(a, b, c, e, d, h, f) {
return m(n(m(m(a, b ^ c ^ e), m(d, f)), h), b)
}
function h(a, b, c, e, d, h, f) {
return m(n(m(m(a, c ^ (b | ~e)), m(d, f)), h), b)
}
function m(a, b) {
var c =
(a & 65535) + (b & 65535);
return (a >> 16) + (b >> 16) + (c >> 16) << 16 | c & 65535
}
function n(a, b) {
return a << b | a >>> 32 - b
}
var e = {},
o = 0;
c.getGroupId = b;
c.getDefaultGroupId = function(a) {
return b(a, "")
}
})(Spotify.Web.ABTester);
(function(c, a) {
var b = c.History = c.History || {};
if (typeof b.Adapter !== "undefined") throw Error("History.js Adapter has already been loaded...");
b.Adapter = {
handlers: {},
_uid: 1,
uid: function(a) {
return a._uid || (a._uid = b.Adapter._uid++)
},
bind: function(a, c, j) {
var g = b.Adapter.uid(a);
b.Adapter.handlers[g] = b.Adapter.handlers[g] || {};
b.Adapter.handlers[g][c] = b.Adapter.handlers[g][c] || [];
b.Adapter.handlers[g][c].push(j);
a["on" + c] = function(a, c) {
return function(d) {
b.Adapter.trigger(a, c, d)
}
}(a, c)
},
trigger: function(a,
c, j) {
var j = j || {},
a = b.Adapter.uid(a),
g, k;
b.Adapter.handlers[a] = b.Adapter.handlers[a] || {};
b.Adapter.handlers[a][c] = b.Adapter.handlers[a][c] || [];
for (g = 0, k = b.Adapter.handlers[a][c].length; g < k; ++g) b.Adapter.handlers[a][c][g].apply(this, [j])
},
extractEventData: function(b, c) {
return c && c[b] || a
},
onDomLoad: function(a) {
var b = c.setTimeout(function() {
a()
}, 2E3);
c.onload = function() {
clearTimeout(b);
a()
}
}
};
typeof b.init !== "undefined" && b.init()
})(window);
(function(c, a) {
var b = c.console || a,
d = c.document,
f = c.navigator,
j = c.sessionStorage || !1,
g = c.setTimeout,
k = c.clearTimeout,
l = c.setInterval,
h = c.clearInterval,
m = c.JSON,
n = c.alert,
e = c.History = c.History || {},
o = c.history;
m.stringify = m.stringify || m.encode;
m.parse = m.parse || m.decode;
if (typeof e.init !== "undefined") throw Error("History.js Core has already been loaded...");
e.init = function() {
if (typeof e.Adapter === "undefined") return !1;
typeof e.initCore !== "undefined" && e.initCore();
typeof e.initHtml4 !== "undefined" && e.initHtml4();
return !0
};
e.initCore = function() {
if (typeof e.initCore.initialized !== "undefined") return !1;
else e.initCore.initialized = !0;
e.options = e.options || {};
e.options.hashChangeInterval = e.options.hashChangeInterval || 100;
e.options.safariPollInterval = e.options.safariPollInterval || 500;
e.options.doubleCheckInterval = e.options.doubleCheckInterval || 500;
e.options.storeInterval = e.options.storeInterval || 1E3;
e.options.busyDelay = e.options.busyDelay || 250;
e.options.debug = e.options.debug || !1;
e.options.initialTitle = e.options.initialTitle ||
d.title;
e.intervalList = [];
e.clearAllIntervals = function() {
var a, b = e.intervalList;
if (typeof b !== "undefined" && b !== null) {
for (a = 0; a < b.length; a++) h(b[a]);
e.intervalList = null
}
};
e.debug = function() {
e.options.debug && e.log.apply(e, arguments)
};
e.log = function() {
var a = !(typeof b === "undefined" || typeof b.log === "undefined" || typeof b.log.apply === "undefined"),
c = d.getElementById("log"),
e, h, f, g;
a ? (h = Array.prototype.slice.call(arguments), e = h.shift(), typeof b.debug !== "undefined" ? b.debug.apply(b, [e, h]) : b.log.apply(b, [e,
h
])) : e = "\n" + arguments[0] + "\n";
for (h = 1, f = arguments.length; h < f; ++h) {
g = arguments[h];
if (typeof g === "object" && typeof m !== "undefined") try {
g = m.stringify(g)
} catch (l) {}
e += "\n" + g + "\n"
}
c ? (c.value += e + "\n-----\n", c.scrollTop = c.scrollHeight - c.clientHeight) : a || n(e);
return !0
};
e.getInternetExplorerMajorVersion = function() {
return e.getInternetExplorerMajorVersion.cached = typeof e.getInternetExplorerMajorVersion.cached !== "undefined" ? e.getInternetExplorerMajorVersion.cached : function() {
for (var a = 3, b = d.createElement("div"),
c = b.getElementsByTagName("i");
(b.innerHTML = "<\!--[if gt IE " + ++a + "]><i></i><![endif]--\>") && c[0];);
return a > 4 ? a : !1
}()
};
e.isInternetExplorer = function() {
return e.isInternetExplorer.cached = typeof e.isInternetExplorer.cached !== "undefined" ? e.isInternetExplorer.cached : Boolean(e.getInternetExplorerMajorVersion())
};
e.emulated = {
pushState: !Boolean(c.history && c.history.pushState && c.history.replaceState && !(/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(f.userAgent) || /AppleWebKit\/5([0-2]|3[0-2])/i.test(f.userAgent))),
hashChange: Boolean(!("onhashchange" in c || "onhashchange" in d) || e.isInternetExplorer() && e.getInternetExplorerMajorVersion() < 8)
};
e.enabled = !e.emulated.pushState;
e.bugs = {
setHash: Boolean(!e.emulated.pushState && f.vendor === "Apple Computer, Inc." && /AppleWebKit\/5([0-2]|3[0-3])/.test(f.userAgent)),
safariPoll: Boolean(!e.emulated.pushState && f.vendor === "Apple Computer, Inc." && /AppleWebKit\/5([0-2]|3[0-3])/.test(f.userAgent)),
ieDoubleCheck: Boolean(e.isInternetExplorer() && e.getInternetExplorerMajorVersion() < 8),
hashEscape: Boolean(e.isInternetExplorer() && e.getInternetExplorerMajorVersion() < 7)
};
e.isEmptyObject = function(a) {
for (var b in a) return !1;
return !0
};
e.cloneObject = function(a) {
a ? (a = m.stringify(a), a = m.parse(a)) : a = {};
return a
};
e.getRootUrl = function() {
var a = d.location.protocol + "//" + (d.location.hostname || d.location.host);
d.location.port && (a += ":" + d.location.port);
a += "/";
return a
};
e.getBaseHref = function() {
var a = d.getElementsByTagName("base"),
b = null,
b = "";
a.length === 1 && (b = a[0], b = b.href.replace(/[^\/]+$/, ""));
(b = b.replace(/\/+$/, "")) && (b += "/");
return b
};
e.getBaseUrl = function() {
return e.getBaseHref() || e.getBasePageUrl() || e.getRootUrl()
};
e.getPageUrl = function() {
return ((e.getState(!1, !1) || {}).url || d.location.href).replace(/\/+$/, "").replace(/[^\/]+$/, function(a) {
return /\./.test(a) ? a : a + "/"
})
};
e.getBasePageUrl = function() {
return d.location.href.replace(/[#\?].*/, "").replace(/[^\/]+$/, function(a) {
return /[^\/]$/.test(a) ? "" : a
}).replace(/\/+$/, "") + "/"
};
e.getFullUrl = function(a, b) {
var c = a,
d = a.substring(0, 1),
b = typeof b ===
"undefined" ? !0 : b;
/[a-z]+\:\/\//.test(a) || (c = d === "/" ? e.getRootUrl() + a.replace(/^\/+/, "") : d === "#" ? e.getPageUrl().replace(/#.*/, "") + a : d === "?" ? e.getPageUrl().replace(/[\?#].*/, "") + a : b ? e.getBaseUrl() + a.replace(/^(\.\/)+/, "") : e.getBasePageUrl() + a.replace(/^(\.\/)+/, ""));
return c.replace(/\#$/, "")
};
e.getShortUrl = function(a) {
var b = e.getBaseUrl(),
c = e.getRootUrl();
e.emulated.pushState && (a = a.replace(b, ""));
a = a.replace(c, "/");
e.isTraditionalAnchor(a) && (a = "./" + a);
return a = a.replace(/^(\.\/)+/g, "./").replace(/\#$/,
"")
};
e.getLocationHref = function(a) {
a = a || d;
return a.URL === a.location.href ? a.location.href : a.location.href === decodeURIComponent(a.URL) ? a.URL : a.location.hash && decodeURIComponent(a.location.href.replace(/^[^#]+/, "")) === a.location.hash ? a.location.href : a.URL.indexOf("#") == -1 && a.location.href.indexOf("#") != -1 ? a.location.href : a.URL || a.location.href
};
e.store = {};
e.idToState = e.idToState || {};
e.stateToId = e.stateToId || {};
e.urlToId = e.urlToId || {};
e.storedStates = e.storedStates || [];
e.savedStates = e.savedStates || [];
e.normalizeStore = function() {
e.store.idToState = e.store.idToState || {};
e.store.urlToId = e.store.urlToId || {};
e.store.stateToId = e.store.stateToId || {}
};
e.getState = function(a, b) {
typeof a === "undefined" && (a = !0);
typeof b === "undefined" && (b = !0);
var c = e.getLastSavedState();
!c && b && (c = e.createStateObject());
if (a) c = e.cloneObject(c), c.url = c.cleanUrl || c.url;
return c
};
e.getIdByState = function(a) {
var b = e.extractId(a.url),
c;
if (!b)
if (c = e.getStateString(a), typeof e.stateToId[c] !== "undefined") b = e.stateToId[c];
else if (typeof e.store.stateToId[c] !==
"undefined") b = e.store.stateToId[c];
else {
for (;;)
if (b = (new Date).getTime() + String(Math.random()).replace(/\D/g, ""), typeof e.idToState[b] === "undefined" && typeof e.store.idToState[b] === "undefined") break;
e.stateToId[c] = b;
e.idToState[b] = a
}
return b
};
e.normalizeState = function(a) {
var b;
if (!a || typeof a !== "object") a = {};
if (typeof a.normalized !== "undefined") return a;
if (!a.data || typeof a.data !== "object") a.data = {};
b = {
normalized: !0
};
b.title = a.title || "";
b.url = e.getFullUrl(a.url || e.getLocationHref());
b.hash = e.getShortUrl(b.url);
b.data = e.cloneObject(a.data);
b.id = e.getIdByState(b);
b.cleanUrl = b.url.replace(/\??\&_suid.*/, "");
b.url = b.cleanUrl;
a = !e.isEmptyObject(b.data);
if (b.title || a) b.hash = e.getShortUrl(b.url).replace(/\??\&_suid.*/, ""), /\?/.test(b.hash) || (b.hash += "?"), b.hash += "&_suid=" + b.id;
b.hashedUrl = e.getFullUrl(b.hash);
if ((e.emulated.pushState || e.bugs.safariPoll) && e.hasUrlDuplicate(b)) b.url = b.hashedUrl;
return b
};
e.createStateObject = function(a, b, c) {
a = {
data: a,
title: b,
url: c
};
return a = e.normalizeState(a)
};
e.getStateById = function(b) {
b =
String(b);
return e.idToState[b] || e.store.idToState[b] || a
};
e.getStateString = function(a) {
a = {
data: e.normalizeState(a).data,
title: a.title,
url: a.url
};
return m.stringify(a)
};
e.getStateId = function(a) {
return e.normalizeState(a).id
};
e.getHashByState = function(a) {
return e.normalizeState(a).hash
};
e.extractId = function(a) {
return ((a = /(.*)\&_suid=([0-9]+)$/.exec(a)) ? String(a[2] || "") : "") || !1
};
e.isTraditionalAnchor = function(a) {
return !/[\/\?\.]/.test(a)
};
e.extractState = function(a, b) {
var c = null,
d, h, b = b || !1;
(d = e.extractId(a)) &&
(c = e.getStateById(d));
c || (h = e.getFullUrl(a), (d = e.getIdByUrl(h) || !1) && (c = e.getStateById(d)), !c && b && !e.isTraditionalAnchor(a) && (c = e.createStateObject(null, null, h)));
return c
};
e.getIdByUrl = function(b) {
return e.urlToId[b] || e.store.urlToId[b] || a
};
e.getLastSavedState = function() {
return e.savedStates[e.savedStates.length - 1] || a
};
e.getLastStoredState = function() {
return e.storedStates[e.storedStates.length - 1] || a
};
e.hasUrlDuplicate = function(a) {
var b = !1;
return b = (b = e.extractState(a.url)) && b.id !== a.id
};
e.storeState =
function(a) {
e.urlToId[a.url] = a.id;
e.storedStates.push(e.cloneObject(a));
return a
};
e.isLastSavedState = function(a) {
var b = !1;
if (e.savedStates.length) a = a.id, b = e.getLastSavedState(), b = b.id, b = a === b;
return b
};
e.saveState = function(a) {
if (e.isLastSavedState(a)) return !1;
e.savedStates.push(e.cloneObject(a));
return !0
};
e.getStateByIndex = function(a) {
var b = null;
return b = typeof a === "undefined" ? e.savedStates[e.savedStates.length - 1] : a < 0 ? e.savedStates[e.savedStates.length + a] : e.savedStates[a]
};
e.getHash = function() {
return e.unescapeHash(d.location.hash)
};
e.unescapeString = function(a) {
return a
};
e.unescapeHash = function(a) {
a = e.normalizeHash(a);
return a = decodeURI(a)
};
e.normalizeHash = function(a) {
return a.replace(/[^#]*#/, "").replace(/#.*/, "")
};
e.setHash = function(a, b) {
var c, h;
if (b !== !1 && e.busy()) return e.pushQueue({
scope: e,
callback: e.setHash,
args: arguments,
queue: b
}), !1;
c = e.escapeHash(a);
e.busy(!0);
if ((h = e.extractState(a, !0)) && !e.emulated.pushState) e.pushState(h.data, h.title, h.url, !1);
else if (d.location.hash !== c) e.bugs.setHash ? (h = e.getPageUrl(), e.pushState(null,
null, h + "#" + c, !1)) : d.location.hash = c;
return e
};
e.escapeHash = function(a) {
a = e.normalizeHash(a);
a = c.encodeURI(a);
e.bugs.hashEscape || (a = a.replace(/\%21/g, "!").replace(/\%26/g, "&").replace(/\%3D/g, "=").replace(/\%3F/g, "?"));
return a
};
e.getHashByUrl = function(a) {
a = String(a).replace(/([^#]*)#?([^#]*)#?(.*)/, "$2");
return a = e.unescapeHash(a)
};
e.setTitle = function(a) {
var b = a.title,
c;
b || (c = e.getStateByIndex(0)) && c.url === a.url && (b = c.title || e.options.initialTitle);
try {
d.getElementsByTagName("title")[0].innerHTML =
b.replace("<", "&lt;").replace(">", "&gt;").replace(" & ", " &amp; ")
} catch (h) {}
d.title = b;
return e
};
e.queues = [];
e.busy = function(a) {
if (typeof a !== "undefined") e.busy.flag = a;
else if (typeof e.busy.flag === "undefined") e.busy.flag = !1;
if (!e.busy.flag) {
k(e.busy.timeout);
var b = function() {
var a, c;
if (!e.busy.flag)
for (a = e.queues.length - 1; a >= 0; --a)
if (c = e.queues[a], c.length !== 0) c = c.shift(), e.fireQueueItem(c), e.busy.timeout = g(b, e.options.busyDelay)
};
e.busy.timeout = g(b, e.options.busyDelay)
}
return e.busy.flag
};
e.busy.flag = !1;
e.fireQueueItem = function(a) {
return a.callback.apply(a.scope || e, a.args || [])
};
e.pushQueue = function(a) {
e.queues[a.queue || 0] = e.queues[a.queue || 0] || [];
e.queues[a.queue || 0].push(a);
return e
};
e.queue = function(a, b) {
typeof a === "function" && (a = {
callback: a
});
if (typeof b !== "undefined") a.queue = b;
e.busy() ? e.pushQueue(a) : e.fireQueueItem(a);
return e
};
e.clearQueue = function() {
e.busy.flag = !1;
e.queues = [];
return e
};
e.stateChanged = !1;
e.doubleChecker = !1;
e.doubleCheckComplete = function() {
e.stateChanged = !0;
e.doubleCheckClear();
return e
};
e.doubleCheckClear = function() {
if (e.doubleChecker) k(e.doubleChecker), e.doubleChecker = !1;
return e
};
e.doubleCheck = function(a) {
e.stateChanged = !1;
e.doubleCheckClear();
if (e.bugs.ieDoubleCheck) e.doubleChecker = g(function() {
e.doubleCheckClear();
e.stateChanged || a();
return !0
}, e.options.doubleCheckInterval);
return e
};
e.safariStatePoll = function() {
var a = e.extractState(d.location.href);
if (!e.isLastSavedState(a)) return a || e.createStateObject(), e.Adapter.trigger(c, "popstate"), e
};
e.back = function(a) {
if (a !==
!1 && e.busy()) return e.pushQueue({
scope: e,
callback: e.back,
args: arguments,
queue: a
}), !1;
e.busy(!0);
e.doubleCheck(function() {
e.back(!1)
});
o.go(-1);
return !0
};
e.forward = function(a) {
if (a !== !1 && e.busy()) return e.pushQueue({
scope: e,
callback: e.forward,
args: arguments,
queue: a
}), !1;
e.busy(!0);
e.doubleCheck(function() {
e.forward(!1)
});
o.go(1);
return !0
};
e.go = function(a, b) {
var c;
if (a > 0)
for (c = 1; c <= a; ++c) e.forward(b);
else if (a < 0)
for (c = -1; c >= a; --c) e.back(b);
else throw Error("History.go: History.go requires a positive or negative integer passed.");
return e
};
if (e.emulated.pushState) {
var t = function() {};
e.pushState = e.pushState || t;
e.replaceState = e.replaceState || t
} else e.onPopState = function(a, b) {
var h = !1,
h = !1;
e.doubleCheckComplete();
if (h = e.getHash()) return (h = e.extractState(h || d.location.href, !0)) ? e.replaceState(h.data, h.title, h.url, !1) : (e.Adapter.trigger(c, "anchorchange"), e.busy(!1)), e.expectedStateId = !1;
(h = (h = e.Adapter.extractEventData("state", a, b) || !1) ? e.getStateById(h) : e.expectedStateId ? e.getStateById(e.expectedStateId) : e.extractState(d.location.href)) ||
(h = e.createStateObject(null, null, d.location.href));
e.expectedStateId = !1;
if (e.isLastSavedState(h)) return e.busy(!1), !1;
e.storeState(h);
e.saveState(h);
e.setTitle(h);
e.Adapter.trigger(c, "statechange");
e.busy(!1);
return !0
}, e.Adapter.bind(c, "popstate", e.onPopState), e.pushState = function(a, b, d, h) {
if (e.getHashByUrl(d) && e.emulated.pushState) throw Error("History.js does not support states with fragement-identifiers (hashes/anchors).");
if (h !== !1 && e.busy()) return e.pushQueue({
scope: e,
callback: e.pushState,
args: arguments,
queue: h
}), !1;
e.busy(!0);
var f = e.createStateObject(a, b, d);
e.isLastSavedState(f) ? e.busy(!1) : (e.storeState(f), e.expectedStateId = f.id, o.pushState(f.id, f.title, f.url), e.Adapter.trigger(c, "popstate"));
return !0
}, e.replaceState = function(a, b, d, h) {
if (e.getHashByUrl(d) && e.emulated.pushState) throw Error("History.js does not support states with fragement-identifiers (hashes/anchors).");
if (h !== !1 && e.busy()) return e.pushQueue({
scope: e,
callback: e.replaceState,
args: arguments,
queue: h
}), !1;
e.busy(!0);
var f = e.createStateObject(a,
b, d);
e.isLastSavedState(f) ? e.busy(!1) : (e.storeState(f), e.expectedStateId = f.id, o.replaceState(f.id, f.title, f.url), e.Adapter.trigger(c, "popstate"));
return !0
};
if (j) try {
e.store = m.parse(j.getItem("History.store")) || {}
} catch (C) {
e.store = {}
} else e.store = {};
e.normalizeStore();
e.Adapter.bind(c, "beforeunload", e.clearAllIntervals);
e.Adapter.bind(c, "unload", e.clearAllIntervals);
e.saveState(e.storeState(e.extractState(d.location.href, !0)));
if (j) e.onUnload = function() {
var a, b;
try {
a = m.parse(j.getItem("History.store")) || {}
} catch (c) {
a = {}
}
a.idToState = a.idToState || {};
a.urlToId = a.urlToId || {};
a.stateToId = a.stateToId || {};
for (b in e.idToState) e.idToState.hasOwnProperty(b) && (a.idToState[b] = e.idToState[b]);
for (b in e.urlToId) e.urlToId.hasOwnProperty(b) && (a.urlToId[b] = e.urlToId[b]);
for (b in e.stateToId) e.stateToId.hasOwnProperty(b) && (a.stateToId[b] = e.stateToId[b]);
e.store = a;
e.normalizeStore();
j.setItem("History.store", m.stringify(a))
}, e.intervalList.push(l(e.onUnload, e.options.storeInterval)), e.Adapter.bind(c, "beforeunload",
e.onUnload), e.Adapter.bind(c, "unload", e.onUnload);
if (!e.emulated.pushState && (e.bugs.safariPoll && e.intervalList.push(l(e.safariStatePoll, e.options.safariPollInterval)), f.vendor === "Apple Computer, Inc." || (f.appCodeName || "") === "Mozilla"))
if (e.Adapter.bind(c, "hashchange", function() {
e.Adapter.trigger(c, "popstate")
}), e.getHash()) e.Adapter.onDomLoad(function() {
e.Adapter.trigger(c, "hashchange")
})
};
e.init()
})(window);
(function(c) {
var a = c.document,
b = c.setInterval || b,
d = c.History = c.History || {};
if (typeof d.initHtml4 !== "undefined") throw Error("History.js HTML4 Support has already been loaded...");
d.initHtml4 = function() {
if (typeof d.initHtml4.initialized !== "undefined") return !1;
else d.initHtml4.initialized = !0;
d.enabled = !0;
d.savedHashes = [];
d.isLastHash = function(a) {
var b = d.getHashByIndex();
return a === b
};
d.saveHash = function(a) {
if (d.isLastHash(a)) return !1;
d.savedHashes.push(a);
return !0
};
d.getHashByIndex = function(a) {
var b =
null;
return b = typeof a === "undefined" ? d.savedHashes[d.savedHashes.length - 1] : a < 0 ? d.savedHashes[d.savedHashes.length + a] : d.savedHashes[a]
};
d.discardedHashes = {};
d.discardedStates = {};
d.discardState = function(a, b, c) {
var k = d.getHashByState(a);
d.discardedStates[k] = {
discardedState: a,
backState: c,
forwardState: b
};
return !0
};
d.discardHash = function(a, b, c) {
d.discardedHashes[a] = {
discardedHash: a,
backState: c,
forwardState: b
};
return !0
};
d.discardedState = function(a) {
a = d.getHashByState(a);
return d.discardedStates[a] || !1
};
d.discardedHash = function(a) {
return d.discardedHashes[a] || !1
};
d.recycleState = function(a) {
var b = d.getHashByState(a);
d.discardedState(a) && delete d.discardedStates[b];
return !0
};
if (d.emulated.hashChange) d.hashChangeInit = function() {
d.checkerFunction = null;
var f = "",
j, g, k;
d.isInternetExplorer() ? (j = a.createElement("iframe"), j.setAttribute("id", "historyjs-iframe"), j.style.display = "none", a.body.appendChild(j), j.contentWindow.document.open(), j.contentWindow.document.close(), g = "", k = !1, d.checkerFunction = function() {
if (k) return !1;
k = !0;
var a = d.getHash() || "",
b = d.unescapeHash(j.contentWindow.document.location.hash) || "";
if (a !== f) {
f = a;
if (b !== a) g = a, j.contentWindow.document.open(), j.contentWindow.document.close(), j.contentWindow.document.location.hash = d.escapeHash(a);
d.Adapter.trigger(c, "hashchange")
} else b !== g && (g = b, d.setHash(b, !1));
k = !1;
return !0
}) : d.checkerFunction = function() {
var a = d.getHash();
a !== f && (f = a, d.Adapter.trigger(c, "hashchange"));
return !0
};
d.intervalList.push(b(d.checkerFunction, d.options.hashChangeInterval));
return !0
},
d.Adapter.onDomLoad(d.hashChangeInit);
if (d.emulated.pushState) d.onHashChange = function(b) {
var j = d.getHashByUrl(b && b.newURL || a.location.href),
b = null;
if (d.isLastHash(j)) return d.busy(!1), !1;
d.doubleCheckComplete();
d.saveHash(j);
if (j && d.isTraditionalAnchor(j)) return d.Adapter.trigger(c, "anchorchange"), d.busy(!1), !1;
b = d.extractState(d.getFullUrl(j || a.location.href, !1), !0);
if (d.isLastSavedState(b)) return d.busy(!1), !1;
d.getHashByState(b);
if (j = d.discardedState(b)) return d.getHashByIndex(-2) === d.getHashByState(j.forwardState) ?
d.back(!1) : d.forward(!1), !1;
d.pushState(b.data, b.title, b.url, !1);
return !0
}, d.Adapter.bind(c, "hashchange", d.onHashChange), d.pushState = function(b, j, g, k) {
if (d.getHashByUrl(g)) throw Error("History.js does not support states with fragement-identifiers (hashes/anchors).");
if (k !== !1 && d.busy()) return d.pushQueue({
scope: d,
callback: d.pushState,
args: arguments,
queue: k
}), !1;
d.busy(!0);
var l = d.createStateObject(b, j, g),
h = d.getHashByState(l),
m = d.getState(!1),
m = d.getHashByState(m),
n = d.getHash();
d.storeState(l);
d.expectedStateId =
l.id;
d.recycleState(l);
d.setTitle(l);
if (h === m) return d.busy(!1), !1;
if (h !== n && h !== d.getShortUrl(a.location.href)) return d.setHash(h, !1), !1;
d.saveState(l);
d.Adapter.trigger(c, "statechange");
d.busy(!1);
return !0
}, d.replaceState = function(a, b, c, k) {
if (d.getHashByUrl(c)) throw Error("History.js does not support states with fragement-identifiers (hashes/anchors).");
if (k !== !1 && d.busy()) return d.pushQueue({
scope: d,
callback: d.replaceState,
args: arguments,
queue: k
}), !1;
d.busy(!0);
var l = d.createStateObject(a, b, c),
h = d.getState(!1),
m = d.getStateByIndex(-2);
d.discardState(h, l, m);
d.pushState(l.data, l.title, l.url, !1);
return !0
};
if (d.emulated.pushState && d.getHash() && !d.emulated.hashChange) d.Adapter.onDomLoad(function() {
d.Adapter.trigger(c, "hashchange")
})
};
typeof d.init !== "undefined" && d.init()
})(window);
CryptoJS = window && window.CryptoJS || function(c, a) {
var b = {},
d = b.lib = {},
f = function() {},
j = d.Base = {
extend: function(a) {
f.prototype = this;
var b = new f;
a && b.mixIn(a);
b.hasOwnProperty("init") || (b.init = function() {
b.$super.init.apply(this, arguments)
});
b.init.prototype = b;
b.$super = this;
return b
},
create: function() {
var a = this.extend();
a.init.apply(a, arguments);
return a
},
init: function() {},
mixIn: function(a) {
for (var b in a) a.hasOwnProperty(b) && (this[b] = a[b]);
a.hasOwnProperty("toString") &&
(this.toString = a.toString)
},
clone: function() {
return this.init.prototype.extend(this)
}
},
g = d.WordArray = j.extend({
init: function(b, c) {
b = this.words = b || [];
this.sigBytes = c != a ? c : 4 * b.length
},
toString: function(a) {
return (a || l).stringify(this)
},
concat: function(a) {
var b = this.words,
c = a.words,
e = this.sigBytes,
a = a.sigBytes;
this.clamp();
if (e % 4)
for (var d = 0; d < a; d++) b[e + d >>> 2] |= (c[d >>> 2] >>> 24 - 8 * (d % 4) & 255) << 24 - 8 * ((e + d) % 4);
else if (65535 < c.length)
for (d = 0; d < a; d += 4) b[e + d >>> 2] = c[d >>> 2];
else b.push.apply(b, c);
this.sigBytes +=
a;
return this
},
clamp: function() {
var a = this.words,
b = this.sigBytes;
a[b >>> 2] &= 4294967295 << 32 - 8 * (b % 4);
a.length = c.ceil(b / 4)
},
clone: function() {
var a = j.clone.call(this);
a.words = this.words.slice(0);
return a
},
random: function(a) {
for (var b = [], e = 0; e < a; e += 4) b.push(4294967296 * c.random() | 0);
return new g.init(b, a)
}
}),
k = b.enc = {},
l = k.Hex = {
stringify: function(a) {
for (var b = a.words, a = a.sigBytes, c = [], e = 0; e < a; e++) {
var d = b[e >>> 2] >>> 24 - 8 * (e % 4) & 255;
c.push((d >>> 4).toString(16));
c.push((d & 15).toString(16))
}
return c.join("")
},
parse: function(a) {
for (var b = a.length, c = [], e = 0; e < b; e += 2) c[e >>> 3] |= parseInt(a.substr(e, 2), 16) << 24 - 4 * (e % 8);
return new g.init(c, b / 2)
}
},
h = k.Latin1 = {
stringify: function(a) {
for (var b = a.words, a = a.sigBytes, c = [], e = 0; e < a; e++) c.push(String.fromCharCode(b[e >>> 2] >>> 24 - 8 * (e % 4) & 255));
return c.join("")
},
parse: function(a) {
for (var b = a.length, c = [], e = 0; e < b; e++) c[e >>> 2] |= (a.charCodeAt(e) & 255) << 24 - 8 * (e % 4);
return new g.init(c, b)
}
},
m = k.Utf8 = {
stringify: function(a) {
try {
return decodeURIComponent(escape(h.stringify(a)))
} catch (b) {
throw Error("Malformed UTF-8 data");
}
},
parse: function(a) {
return h.parse(unescape(encodeURIComponent(a)))
}
},
n = d.BufferedBlockAlgorithm = j.extend({
reset: function() {
this._data = new g.init;
this._nDataBytes = 0
},
_append: function(a) {
"string" == typeof a && (a = m.parse(a));
this._data.concat(a);
this._nDataBytes += a.sigBytes
},
_process: function(a) {
var b = this._data,
e = b.words,
d = b.sigBytes,
h = this.blockSize,
f = d / (4 * h),
f = a ? c.ceil(f) : c.max((f | 0) - this._minBufferSize, 0),
a = f * h,
d = c.min(4 * a, d);
if (a) {
for (var l = 0; l < a; l += h) this._doProcessBlock(e, l);
l = e.splice(0, a);
b.sigBytes -=
d
}
return new g.init(l, d)
},
clone: function() {
var a = j.clone.call(this);
a._data = this._data.clone();
return a
},
_minBufferSize: 0
});
d.Hasher = n.extend({
cfg: j.extend(),
init: function(a) {
this.cfg = this.cfg.extend(a);
this.reset()
},
reset: function() {
n.reset.call(this);
this._doReset()
},
update: function(a) {
this._append(a);
this._process();
return this
},
finalize: function(a) {
a && this._append(a);
return this._doFinalize()
},
blockSize: 16,
_createHelper: function(a) {
return function(b, c) {
return (new a.init(c)).finalize(b)
}
},
_createHmacHelper: function(a) {
return function(b,
c) {
return (new e.HMAC.init(a, c)).finalize(b)
}
}
});
var e = b.algo = {};
return b
}(Math);
(function(c) {
function a(a, b, c, d, h, g, f) {
a = a + (b & c | ~b & d) + h + f;
return (a << g | a >>> 32 - g) + b
}
function b(a, b, c, d, h, g, f) {
a = a + (b & d | c & ~d) + h + f;
return (a << g | a >>> 32 - g) + b
}
function d(a, b, c, d, h, g, f) {
a = a + (b ^ c ^ d) + h + f;
return (a << g | a >>> 32 - g) + b
}
function f(a, b, c, d, h, g, f) {
a = a + (c ^ (b | ~d)) + h + f;
return (a << g | a >>> 32 - g) + b
}
for (var j = CryptoJS, g = j.lib, k = g.WordArray, l = g.Hasher, g = j.algo, h = [], m = 0; 64 > m; m++) h[m] = 4294967296 * c.abs(c.sin(m + 1)) | 0;
g = g.MD5 = l.extend({
_doReset: function() {
this._hash = new k.init([1732584193, 4023233417, 2562383102, 271733878])
},
_doProcessBlock: function(c, e) {
for (var g = 0; 16 > g; g++) {
var l = e + g,
k = c[l];
c[l] = (k << 8 | k >>> 24) & 16711935 | (k << 24 | k >>> 8) & 4278255360
}
var g = this._hash.words,
l = c[e + 0],
k = c[e + 1],
j = c[e + 2],
m = c[e + 3],
w = c[e + 4],
A = c[e + 5],
x = c[e + 6],
u = c[e + 7],
y = c[e + 8],
B = c[e + 9],
D = c[e + 10],
G = c[e + 11],
E = c[e + 12],
F = c[e + 13],
I = c[e + 14],
H = c[e + 15],
p = g[0],
r = g[1],
s = g[2],
q = g[3],
p = a(p, r, s, q, l, 7, h[0]),
q = a(q, p, r, s, k, 12, h[1]),
s = a(s, q, p, r, j, 17, h[2]),
r = a(r, s, q, p, m, 22, h[3]),
p = a(p, r, s, q, w, 7, h[4]),
q = a(q, p, r, s, A, 12, h[5]),
s = a(s, q, p, r, x, 17, h[6]),
r = a(r, s, q, p, u, 22, h[7]),
p = a(p, r, s, q, y, 7, h[8]),
q = a(q, p, r, s, B, 12, h[9]),
s = a(s, q, p, r, D, 17, h[10]),
r = a(r, s, q, p, G, 22, h[11]),
p = a(p, r, s, q, E, 7, h[12]),
q = a(q, p, r, s, F, 12, h[13]),
s = a(s, q, p, r, I, 17, h[14]),
r = a(r, s, q, p, H, 22, h[15]),
p = b(p, r, s, q, k, 5, h[16]),
q = b(q, p, r, s, x, 9, h[17]),
s = b(s, q, p, r, G, 14, h[18]),
r = b(r, s, q, p, l, 20, h[19]),
p = b(p, r, s, q, A, 5, h[20]),
q = b(q, p, r, s, D, 9, h[21]),
s = b(s, q, p, r, H, 14, h[22]),
r = b(r, s, q, p, w, 20, h[23]),
p = b(p, r, s, q, B, 5, h[24]),
q = b(q, p, r, s, I, 9, h[25]),
s = b(s, q, p, r, m, 14, h[26]),
r = b(r, s, q, p, y, 20, h[27]),
p = b(p, r, s, q, F, 5, h[28]),
q = b(q, p,
r, s, j, 9, h[29]),
s = b(s, q, p, r, u, 14, h[30]),
r = b(r, s, q, p, E, 20, h[31]),
p = d(p, r, s, q, A, 4, h[32]),
q = d(q, p, r, s, y, 11, h[33]),
s = d(s, q, p, r, G, 16, h[34]),
r = d(r, s, q, p, I, 23, h[35]),
p = d(p, r, s, q, k, 4, h[36]),
q = d(q, p, r, s, w, 11, h[37]),
s = d(s, q, p, r, u, 16, h[38]),
r = d(r, s, q, p, D, 23, h[39]),
p = d(p, r, s, q, F, 4, h[40]),
q = d(q, p, r, s, l, 11, h[41]),
s = d(s, q, p, r, m, 16, h[42]),
r = d(r, s, q, p, x, 23, h[43]),
p = d(p, r, s, q, B, 4, h[44]),
q = d(q, p, r, s, E, 11, h[45]),
s = d(s, q, p, r, H, 16, h[46]),
r = d(r, s, q, p, j, 23, h[47]),
p = f(p, r, s, q, l, 6, h[48]),
q = f(q, p, r, s, u, 10, h[49]),
s = f(s, q, p, r,
I, 15, h[50]),
r = f(r, s, q, p, A, 21, h[51]),
p = f(p, r, s, q, E, 6, h[52]),
q = f(q, p, r, s, m, 10, h[53]),
s = f(s, q, p, r, D, 15, h[54]),
r = f(r, s, q, p, k, 21, h[55]),
p = f(p, r, s, q, y, 6, h[56]),
q = f(q, p, r, s, H, 10, h[57]),
s = f(s, q, p, r, x, 15, h[58]),
r = f(r, s, q, p, F, 21, h[59]),
p = f(p, r, s, q, w, 6, h[60]),
q = f(q, p, r, s, G, 10, h[61]),
s = f(s, q, p, r, j, 15, h[62]),
r = f(r, s, q, p, B, 21, h[63]);
g[0] = g[0] + p | 0;
g[1] = g[1] + r | 0;
g[2] = g[2] + s | 0;
g[3] = g[3] + q | 0
},
_doFinalize: function() {
var a = this._data,
b = a.words,
d = 8 * this._nDataBytes,
h = 8 * a.sigBytes;
b[h >>> 5] |= 128 << 24 - h % 32;
var g = c.floor(d /
4294967296);
b[(h + 64 >>> 9 << 4) + 15] = (g << 8 | g >>> 24) & 16711935 | (g << 24 | g >>> 8) & 4278255360;
b[(h + 64 >>> 9 << 4) + 14] = (d << 8 | d >>> 24) & 16711935 | (d << 24 | d >>> 8) & 4278255360;
a.sigBytes = 4 * (b.length + 1);
this._process();
a = this._hash;
b = a.words;
for (d = 0; 4 > d; d++) h = b[d], b[d] = (h << 8 | h >>> 24) & 16711935 | (h << 24 | h >>> 8) & 4278255360;
return a
},
clone: function() {
var a = l.clone.call(this);
a._hash = this._hash.clone();
return a
}
});
j.MD5 = l._createHelper(g);
j.HmacMD5 = l._createHmacHelper(g)
})(Math);
Spotify.Web.Widgets = Spotify.Web.Widgets || {};
(function(c) {
function a(a) {
this.node = null;
this.isActive = a.activated === !0;
this.options = a;
this._activeText = a.activeText || _("ON");
this._inactiveText = a.inactiveText || _("OFF");
this.document = a.document || document;
this._buildNodes();
this._setupEventHandling()
}
a.prototype._buildNodes = function() {
this.node = this.document.createElement("div");
this.node.className = "sp-toggle";
this.isActive && (this.node.className += " active");
this._activeNode = this.document.createElement("span");
this._activeNode.textContent = this._activeText;
this._activeNode.className = "active-text";
this._inactiveNode = this.document.createElement("span");
this._inactiveNode.textContent = this._inactiveText;
this._inactiveNode.className = "inactive-text";
this._handle = this.document.createElement("button");
this._handle.className = "handle";
this._handleWrapper = this.document.createElement("span");
this._handleWrapper.className = "sp-toggle-inner";
this._overlay = this.document.createElement("span");
this._overlay.className = "sp-toggle-overlay";
this._handleWrapper.appendChild(this._activeNode);
this._handleWrapper.appendChild(this._handle);
this._handleWrapper.appendChild(this._inactiveNode);
this.node.appendChild(this._handleWrapper);
this.node.appendChild(this._overlay)
};
a.prototype._setupEventHandling = function() {
var a = this,
c, f;
setTimeout(function() {
a._maxHandleTravel = a.node.offsetWidth - a._handle.offsetWidth
}, 10);
this.node.addEventListener("mouseup", function(j) {
j.preventDefault();
c = (new Date).getTime();
c - f < 250 && a.toggle()
}, !1);
this.node.addEventListener("mousedown", function(c) {
c.preventDefault();
f = (new Date).getTime();
(c.target === a._handle || c.target === a._overlay) && a._doDragHandle.call(a, c)
}, !1);
this._handle.addEventListener("keypress", function(c) {
c.preventDefault();
a.toggle()
}, !1);
this._handle.addEventListener("click", function(a) {
a.stopPropagation();
a.preventDefault()
}, !1)
};
a.prototype._doDragHandle = function(a) {
function c(a) {
a = a || window.event;
k = a.clientX - g;
h = k + l;
h <= -40 && (h = -40);
h >= 0 && (h = 0);
j._handleWrapper.style.left = h + "px"
}
function f() {
j.node.className = j.node.className.replace(" dragging",
"");
j._handleWrapper.style.left = null;
Math.abs(k) > 5 && k * m >= j._maxHandleTravel / 2 && j.toggle();
j.document.removeEventListener("mousemove", c);
j.document.removeEventListener("mouseup", f);
j.node.removeEventListener("mouseout", f)
}
var j = this,
a = a || window.event;
a.preventDefault();
var g = a.clientX,
k = 0,
l = j._handleWrapper.offsetLeft,
h = null,
m = this.isActive ? -1 : 1;
this.node.className += " dragging";
j.document.addEventListener("mousemove", c);
j.document.addEventListener("mouseup", f);
j.node.addEventListener("mouseout", f)
};
a.prototype.toggle = function() {
this.isActive ? this.deactivate() : this.activate()
};
a.prototype.activate = function(a) {
if (!this.isActive) this.isActive = !0, this.node.className += " active", !a && typeof this.options.onActivate === "function" && this.options.onActivate.apply(this), !a && typeof this.options.onChange === "function" && this.options.onChange.apply(this)
};
a.prototype.deactivate = function(a) {
if (this.isActive) this.isActive = !1, this.node.className = this.node.className.replace(" active", ""), !a && typeof this.options.onDeactivate ===
"function" && this.options.onDeactivate.apply(this), !a && typeof this.options.onChange === "function" && this.options.onChange.apply(this)
};
c.Toggle = a
})(Spotify.Web.Widgets);
Spotify.Web.Sociomantic = function(c, a) {
function b(a) {
var b = a.services;
this.track = function(a) {
if (a) {
try {
window.sociomantic.sonar.adv[o].clear()
} catch (b) {
return
}
var c = "Listen to " + a.name + " on Spotify",
e = a.uri.split(":")[2],
d = this.getCategoryId(a),
g = a.image && a.image.replace("/unbranded/", "/300/");
window.product = {
identifier: a.uri || "",
fn: "Spotify - Join Now",
brand: a.name || "",
description: c,
category: d,
price: "",
amount: "",
currency: m,
url: "http://open.spotify.com/artist/" + e,
photo: g || ""
};
window.customer = {
mhash: n,
segment: j
};
h > 0 && (window.customer.segment = h);
window.sociomantic.sonar.adv[o].track()
}
};
this.getArtistDataAndTrack = function(a) {
var c = this;
b.getArtistMetadata("spotify:artist:" + a, function(a) {
a !== !1 && c.track(a)
})
};
this.getCategoryId = function(a) {
var b = "";
if (typeof a.getRelatedArtists === "function")
for (var a = a.getRelatedArtists(), c = 0, e = Math.min(a.length, 3), d = null; c < e; c++) d = a[c], b += d.replace("spotify:artist:", "");
return b
}
}
function d(a, c) {
if (!a.bridge || !a.bridge.player || !(c instanceof b)) return null;
var e =
a.bridge.player,
d, h = !1;
this.getArtistId = function(a) {
var b = this;
e.getState(function(c, e) {
if (c !== !0) {
try {
var d = e.track.artists[0].uri.split(":")[2]
} catch (h) {
return
}
typeof a === "function" && a.call(b, d)
}
})
};
this.startTimerAndMarkAsTracked = function() {
var a = this;
clearTimeout(d);
d = setTimeout(function() {
a.getArtistId(function(a) {
c.getArtistDataAndTrack(a);
h = !0
})
}, k)
};
this.resetTimer = function() {
clearTimeout(d)
};
this.subscribe = function() {
var a = this;
e.registerForPlayerEvents(function(b, c) {
c.type === "trackLoaded" ?
h = !1 : c.type === "play" && h === !1 ? a.startTimerAndMarkAsTracked() : c.type === "pause" && a.resetTimer();
a.subscribe()
})
};
this.subscribe()
}
var f = {
free: 0,
unlimited: 1,
premium: 2
},
j = 3,
g = {
GB: {
code: "UK",
currency: "GBP"
},
IE: {
code: "IE",
currency: "EUR"
},
DE: {
code: "DE",
currency: "EUR"
}
},
k = 3E4,
l = this,
h = null,
m = null,
n = a,
e, o;
this.load = function(a) {
o = "spotify-" + a.toLowerCase();
var a = document.createElement("script"),
b = document.getElementsByTagName("script")[0];
a.type = "text/javascript";
a.async = !0;
a.src = ("https:" == document.location.protocol ?
"https://" : "http://") + "eu-sonar.sociomantic.com/js/2010-07-01/adpan/" + o;
b.parentNode.insertBefore(a, b)
};
c.services.getUserInfo(function(a) {
var k = a.catalogue,
a = g[a.country];
h = f[k] ? f[k] : 0;
if (a) m = a.currency, l.load(a.code), e = new b(c), new d(c, e)
})
};
Spotify.Web.Core = function(c, a, b, d) {
var f = this,
j = null,
g, k, l = Spotify.PlayerTypes.FLASH_RTMPS,
h = !1,
m, n = !1,
e;
this.setTracker = function(a) {
this.tracker = a
};
var o = function() {
this.getMainPlayer();
this.core.trigger("ON_TRY_TO_CONNECT");
e = setTimeout(function() {
n || c.notify(Spotify.Web.PublisherMessages.ERROR, {
type: Spotify.Web.ErrorTypes.CONNECTING
})
}, 2E3);
setTimeout(function() {
n || f.logAPConnectionFailure()
}, 1E4)
},
t = function(a) {
var b = "";
a.params && a.params.length && (b = a.params[2]);
b == "Region mismatch" && (n = !0);
c.notify(Spotify.Web.PublisherMessages.ERROR, {
type: Spotify.Web.ErrorTypes.CONNECTION_LOST,
reason: b
})
},
C = function() {
c.notify(Spotify.Web.PublisherMessages.ERROR, {
type: Spotify.Web.ErrorTypes.CONNECTION_LOST,
reason: ""
})
},
v = function() {
f.getMainPlayer().isPaused || c.notify(Spotify.Web.PublisherMessages.ERROR, {
type: Spotify.Web.ErrorTypes.TOKEN_LOST
})
},
z = function() {
f.core.migrateToIndexedDBStorage(function() {}, function() {})
},
w = function() {
c.notify(Spotify.Web.PublisherMessages.ERROR, {
type: Spotify.Web.ErrorTypes.WAIT_FOR_COMMERCIAL_TO_FINISH
})
},
A = function() {
c.notify(Spotify.Web.PublisherMessages.ERROR, {
type: Spotify.Web.ErrorTypes.CANNOT_CONNECT_TO_STREAMING_SERVER
})
},
x = function() {
c.notify(Spotify.Web.PublisherMessages.ERROR, {
type: Spotify.Web.ErrorTypes.NO_SOUND_CAPABILITIES
})
},
u = function() {
h || (c.notify(Spotify.Web.PublisherMessages.ERROR, {
type: Spotify.Web.ErrorTypes.FLASH_NOT_AVAILABLE
}), h = !0)
},
y = function() {
this.core && this.core.dispose()
},
B = function(a) {
c.notify(Spotify.Web.PublisherMessages.ERROR, {
type: Spotify.Web.ErrorTypes.TRACK_NOT_PLAYABLE_TIME_CAP,
trackUri: a.params.data
})
},
D = function() {
n = !0
},
G = function() {
m || (m = new Spotify.Web.AP.Resolver({
hostname: a.aps.resolver.hostname,
site: a.aps.resolver.site,
override: a.aps.resolver.override,
protocol: window.location.protocol.replace(":", ""),
version: a.version
}));
m.get(function(a) {
var e = Spotify.Web.Utils.getQueryStringParameter("ap");
e && (a = e);
a ? (a.match(/^(rtmp|ws)s?:\/\//) || (a = k + "://" + a), b.get(function(b) {
b === null ? (reloadWarning = !1, c.notify(Spotify.Web.PublisherMessages.ERROR, {
type: Spotify.Web.ErrorTypes.SESSION_LOST
})) : (d.log("Connecting to " +
a), f.core.connectWithToken(a, b))
}, function() {})) : d.error("Couldn't resolve any access points to connect to")
})
};
this.detachPlayer = function() {
this.getMainPlayer().load = function() {}
};
this.getMainPlayer = function() {
return this.core.audioManager.getPlayerAtIndex(0)
};
this.logAPConnectionFailure = function() {
this.tracker && this.tracker.xhrLog("UNABLE_TO_CONNECT")
};
this.initialize = function() {
g = window.location.href.indexOf("websockets") > -1 || Spotify.Web.BrowserDetect.shouldUseWebSockets ? Spotify.GatewayTypes.WEBSOCKETS :
Spotify.GatewayTypes.FLASH;
k = g == Spotify.GatewayTypes.FLASH ? "rtmps" : "wss";
if (a.aps.resolver.override && a.aps.resolver.override.match(/^(rtmp|ws)s?:\/\//)) {
var b = a.aps.resolver.override.split(/:\/\//);
j = b[0];
a.aps.resolver.override = b[1]
}
j && (k = j);
window.addEventListener("unload", y);
if (Spotify.Web.BrowserDetect.browser === "Explorer") b = Math.floor(Math.random() * 1E3), a.corejs.SWFUrl += "?rnd=" + b, a.corejs.SWFPlayerUrl += "?rnd=" + b, a.corejs.protoSchemasLocationRandomizer = "?rnd=" + b;
a.corejs.features = a.features;
Spotify.Storage.localStorage =
window.localStorage;
Spotify.Storage.indexedDB.storage = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
Spotify.Storage.indexedDB.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange;
Spotify.Storage.indexedDB.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction;
(l === Spotify.PlayerTypes.FLASH_HTTP || g === Spotify.GatewayTypes.FLASH) && window.addEvent("load", function() {
Spotify.Web.FeatureDetect.hasFlashMin() || window.setTimeout(function() {
u()
}, 1E3)
});
Spotify.Web.Debugger.init(a)
};
this.connect = function(d) {
this.core = new Spotify.Core(g, a.corejs);
this.core.onReady(o, this);
this.core.onConnect = function() {
e && clearTimeout(e);
f.core.audioManager.onReady(function() {
f.core.audioManager.bind("FAILED_CONNECTING", A, f);
f.getMainPlayer().bind("INVALID_TRACK_URI", function(a) {
a.params.domain === Spotify.Errors.Domains.TRACK_ERROR && a.params.code !== Spotify.Errors.Codes.TRACK_REQUEST_RATE_LIMITED && a.params.code !== Spotify.Errors.Codes.TIME_CAP && (a.params.code === Spotify.Errors.Codes.TRACK_CAP ? c.notify(Spotify.Web.PublisherMessages.ERROR, {
type: Spotify.Web.ErrorTypes.TRACK_NOT_PLAYABLE_TRACK_CAP,
trackUri: a.params.data
}) : c.notify(Spotify.Web.PublisherMessages.ERROR, {
type: Spotify.Web.ErrorTypes.TRACK_NOT_PLAYABLE,
trackUri: a.params.data
}))
}, f);
f.core.metadata.onReady(function() {
f.core.playlist.onReady(function() {
d()
})
})
})
};
this.core.onDisconnect = C;
this.core.onTokenLost = v;
this.core.onFailedConnecting = t.bind(this);
this.core.bind("CONNECTION_ESTABLISHED", D, this);
this.core.bind("ON_TRY_TO_CONNECT", G, this);
this.core.bind("NO_SOUND_CAPABILITIES",
x, this);
this.core.bind("STORAGE_FULL", z, this);
this.core.bind("WAIT_FOR_COMMERCIAL_TO_FINISH", w, this);
this.core.bind("FLASH_UNAVAILABLE", u, this);
this.core.bind("TIME_CAP", B, this);
this.core.bind("PASSWORD_CHANGED", function() {
b.dispose();
window.location = window.location.origin + "/logout"
})
}
};
Spotify = Spotify || {};
Spotify.Web = Spotify.Web || {};
Spotify.Web.FacebookSDK = {
_config: null,
_scope: null,
_initAlreadyCalled: !1,
_onInitializedCallbacks: [],
_isInitialized: !1,
_immediateAuthResponse: null,
_triggerOnInitialized: function() {
for (var c; c = this._onInitializedCallbacks.shift();) c()
},
_onFbAsyncInit: function() {
this._isInitialized = !0;
FB.Event.subscribe("auth.statusChange", function(c) {
this._immediateAuthResponse = c
}.bind(this));
FB.init({
version: "v2.2",
appId: this._config.appId,
status: !0,
music: !0
});
this._triggerOnInitialized()
},
init: function(c) {
if (this._initAlreadyCalled) throw Error("Facebook SDK init() already called");
else this._initAlreadyCalled = !0;
this._config = c.config;
this._scope = c.scope;
window.fbAsyncInit = this._onFbAsyncInit.bind(this);
var c = document.getElementsByTagName("script")[0],
a = document.createElement("script");
a.id = "facebook-jssdk";
a.src = "//connect.facebook.net/en_US/sdk.js";
c.parentNode.insertBefore(a, c)
},
login: function(c) {
this.onInitialized(function() {
this._immediateAuthResponse && this._immediateAuthResponse.status === "connected" ? c("already_connected", this._immediateAuthResponse.authResponse.userID,
this._immediateAuthResponse.authResponse.accessToken) : FB.login(function(a) {
a.status === "connected" ? c(a.status, a.authResponse.userID, a.authResponse.accessToken) : c(a.status, null, null)
}, {
scope: this._scope
})
}.bind(this))
},
onInitialized: function(c) {
this._isInitialized ? c() : this._onInitializedCallbacks.push(c)
}
};
Spotify.Web.Debugger = function(c) {
c._spdebugger = c._spdebugger || {};
return {
store: function(a, b, d) {
c._spdebugger[a] = c._spdebugger[a] || {};
c._spdebugger[a][b] = d
},
init: function(a) {
if (a.debugger_on && typeof DebuggerJS !== "undefined" && typeof DebuggerJS.on === "function") DebuggerJS.on(a.debugger_on)
}
}
}(window || {});
Spotify.Web.AP.Resolver = function(c) {
var a = this;
this._TTL = 6E4;
this._index = -1;
this._override = c.override ? c.override : null;
this._aps = [];
this._ajax = function(a, c, f, j) {
(new Request.CORS({
url: a,
method: c,
onSuccess: f,
onFailure: j,
onException: j
})).send()
};
this._identifier = function() {
return "24:0:0:" + c.version
};
this._getEndpointURL = function() {
var a = "?client=" + this._identifier();
return c.protocol + "://" + c.hostname + "/" + a + (c.site ? "&site=" + c.site : "")
};
this._resolve = function(a) {
this._ajax(this._getEndpointURL(), "GET",
function(c) {
var f = [];
try {
f = JSON.parse(c).ap_list || []
} catch (j) {}
a(f)
},
function() {
a([])
})
};
this._next = function() {
this._index++;
if (this._index + 1 > this._aps.length) this._index = 0;
return this._aps[this._index]
};
this.override = function(a) {
this._override = a
};
this.get = function(b) {
if (this._override) b(this._override);
else {
var c = (new Date).getTime();
typeof this._aps !== "undefined" && this._expires > c ? b(this._next()) : this._resolve(function(f) {
if (f.length > 0) a._aps = f, a._expires = c + a._TTL, a._index = -1;
b(a._next())
})
}
}
};
Spotify.Web.PostMessages.Handler = function(c, a, b, d, f, j, g) {
this.isAllowedOrigin = function(a) {
return c.allowed_origins.indexOf(a) > -1
};
this.handle = function(c) {
if (this.isAllowedOrigin(c.origin) && c.source && c.source.location) {
var f = Spotify.Web.Utils.appNameFromUrl(c.source.location.href);
if (c.data === "APP_ERROR_404") {
var h = d.getIFrameWithWindow(c.source);
h && (a.error("App not found: " + h.src), b.onReady(function() {
b.registerNotFound(f);
var c = b.getAppURL(f);
h.src !== c ? (a.info("Falling back to bundled version for app " + f),
h.src = c) : a.error("Got no other version of " + f + " to load...")
}))
} else {
var m;
try {
m = JSON.parse(c.data)
} catch (n) {
m = {}
}
m.type === "NOTIFICATION_CENTER_READY" && j && j.isVisible() ? j.getFrame().contentWindow.postMessage(JSON.stringify({
type: "WINDOW_FOCUS"
}), "*") : m.type === "USER_ACTIVE" && g.userActivityRecorded()
}
}
}
};
(function() {
var c = null;
Spotify.Web.AdAgent = function() {
if (c !== null) return c;
c = this;
var a, b, d, f = !1;
this.init = function(c, g, h) {
f || (b = c, d = g, a = h, j(), f = !0)
};
var j = function() {
d && d.registerCallback(12, function() {
b.request("ads_user_inactive", [], function() {});
b.request("ads_break_in_progress", [], function(a, b) {
g("ui_backgrounded", {
adBreakInProgress: !!b
})
})
}, function() {
b.request("ads_user_active", [], function() {});
b.request("ads_break_in_progress", [], function(a, b) {
g("ui_foregrounded", {
adBreakInProgress: !!b
})
})
})
},
g = function(b, c) {
a && a.log({
source: "spotify:main",
event: "user:hit",
event_version: b,
source_version: "",
source_vendor: "adagent",
data: c || {}
})
}
}
})();
Spotify.Web.AppLoader = function(c, a, b, d) {
var f = this,
j = new Spotify.Web.Environment(d);
this._thirdPartyApps = [];
this._apps = {};
this._notFound = [];
this._ready = !1;
this._onReadyCallbacks = [];
this._timeout = 3E3;
this.appStoreEnabled = function() {
return d.document.cookie.indexOf("appstore-enabled") >= 0 || !c.apps.bundled_only
};
this.getAppVersionsForCurrentUser = function(a, c) {
b.services.appstore.onReady(function() {
b.services.appstore.getAppVersionsForCurrentUser(f._market, f._active, f._bridgeVersion, a, c)
})
};
this.registerNotFound =
function(a) {
this._notFound.push(a);
Spotify.Web.Debugger.store("apps", "not_found", this._notFound);
this._apps[a] = c.apps.bundled[a]
};
this.getPreferredLocale = function() {
if (!c.locale || !c.locale.preferred) return "en";
var a = c.locale.preferred;
return a && a.length > 1 ? a.join(",") : a[0] || "en"
};
this.getAppLoadingQueryString = function(a) {
var b = ["id=" + a, "cb=" + (c.apps.cache_buster || ""), "locale=" + this.getPreferredLocale()];
c.locale && c.locale.rtl && b.push("rtl=1");
var d = {};
if (this._apps[a] && this._apps[a].dependencies) d =
this._apps[a].dependencies;
for (var h in d) d.hasOwnProperty(h) && b.push("spd-" + h + "=" + this.getDependencyVersion(a, h));
c.developer && b.push("spogdomain=" + c.apps.domain);
return "?" + b.join("&")
};
this.getAppDomainPrefix = function(a) {
return CryptoJS.MD5(a + this._username).toString().substring(0, 8)
};
this.getAppVersion = function(a) {
return !this._apps[a] || !this._apps[a].version ? "" : this._apps[a].version
};
this.getDependencyVersion = function(a, b) {
var c = this._apps[a] ? this._apps[a].dependencies : {};
return (!c || !c[b]) && this._apps[b] ?
this._apps[b].version : c[b]
};
this.getAppURL = function(a) {
if (!this._ready) throw 'Trying to get app URL for app "' + a + '" before AppLoader has been fully initialized';
var b = "";
if (j.isDesktop()) return "sp://" + a;
else if (this._apps[a] && this._apps[a].url) b = this._apps[a].url;
else var b = (b = this.getAppVersion(a)) ? "/" + b + "/" : "/",
d = c.apps.https ? "https" : "http",
h = this.getAppDomainPrefix(a),
b = c.developer ? "http://" + h + "-" + a + ".app.spotilocal.com:7768" + b : d + "://" + location.hostname + "/apps/" + a + b;
return b + this.getAppLoadingQueryString(a)
};
this._onReady = function() {
if (!this._ready)
for (this._ready = !0; this._onReadyCallbacks.length !== 0;) this._onReadyCallbacks.shift()()
};
this.onReady = function(a) {
this._ready && a();
Spotify.Web.Debugger.store("apps", "active", this._apps);
this._onReadyCallbacks.push(a)
};
this.init = function() {
if (!this._ready)
//TODO add Try/Catch.
if (this._apps = JSON.parse(JSON.stringify(c.apps.bundled)), this.appStoreEnabled()) {
this._active = [];
for (var d in c.apps.bundled) c.apps.bundled.hasOwnProperty(d) && this._active.push(d);
d = c.apps.bridge.split(".");
this._bridgeVersion = {
major: parseInt(d[0], 10),
minor: parseInt(d[1], 10),
patch: parseInt(d[2], 10)
};
b.services.user.onReady(function() {
b.services.user.getUserInfo(function(b) {
f._username = b.user;
f._market = b.country;
f.getAppVersionsForCurrentUser(function(a) {
if (!f._ready) {
Spotify.Web.Debugger.store("apps", "appstore_response", a);
for (var b in a) a.hasOwnProperty(b) && a[b] && !(f._apps[b] && f._apps[b].version === "develop") && (f._apps[b] = a[b]);
f._onReady()
}
}, function(b) {
b = [b.code, b.description].join(", ");
a.error("[AppLoader] Unable to get users app list: " +
b);
f._onReady()
});
setTimeout(function() {
f._ready || (a.error("[AppLoader] Timed out, using bundled apps"), f._onReady())
}, f._timeout)
}, function() {
a.error("[AppLoader] Unable to get users username");
f._onReady()
})
})
} else a.info("[AppLoader] Using only bundled apps"), f._onReady()
}
};
Spotify.Web.Config = function(c, a) {
var b = this;
this.getFeatures = function() {
return c.features
};
this.setFeature = function(a, b) {
c.features[a] = b
};
this.getFeature = function(a) {
return typeof c.features[a] !== "undefined" ? c.features[a] : null
};
this.getSettings = function() {
return c
};
this.getSetting = function(a) {
return typeof c[a] !== "undefined" ? c[a] : null
};
this.init = function() {
switch (a.getTestGroup("NTX_inline_playbutton")) {
case 0:
b.setFeature("listview-playbutton", !0);
break;
case 1:
b.setFeature("listview-playbutton-always-visible", !0)
}
}
};
Spotify.Web.ABTests = function(c) {
var a = {
example_test: [250, 500, 750],
no_stacks: [100],
NTX_inline_playbutton: [800, 900],
NTX_login_xpromo: [0, 0],
NTX_sociomantic_track: [100]
};
this.userValueForTest = function(a) {
return Spotify.Web.ABTester.getGroupId(c, a)
};
this.getTestGroup = function(b) {
if (!a[b] || !a[b].length) throw Error("test " + b + " not found");
for (var c = a[b], b = this.userValueForTest(b), f = 0; f < c.length;) {
if (b < c[f]) break;
f += 1
}
return f
};
this.isTestGroup = function(b) {
if (!a[b] || !a[b].length) return !1;
var c = a[b];
if (c.length !==
1) throw Error("use getTestGroup for multivariant tests");
return this.userValueForTest(b) < c[0]
}
};
Spotify.Web.Dotter = function(c, a, b, d) {
if (d) d = document.createElement("span"), d.style.position = "absolute", c.appendChild(d), c = d;
var f = 0,
j, g = c.innerHTML;
this.start = function() {
j || (j = setInterval(function() {
f++;
f > a && (f = 0);
for (var b = g.trim(), d = 0; d < f; d++) b += ".";
c.innerHTML = b
}, b))
};
this.stop = function() {
j && (clearInterval(j), j = null, f = 0);
c.innerHTML = g
}
};
Spotify.Web.Authenticator = function(c) {
var a = c.auth_proxy_host ? "/xhr/json/auth_proxy.php" : "/xhr/json/auth.php",
b = !1,
d = function(d, j, g) {
if (!b) {
b = !0;
var k = new XMLHttpRequest;
k.onreadystatechange = function() {
if (k.readyState === 4) {
setTimeout(function() {
b = !1
}, 1E3);
var a = {};
try {
a = JSON.parse(k.responseText)
} catch (c) {}
a.status === "OK" ? j(a.config) : g(a.error)
}
};
var l = "";
c.force_cat != -1 && (l = "&cat=" + c.force_cat);
var h = Spotify.Web.WebTracker.basic(c.tracking),
d = d == "" ? h + l : d + "&" + h + l;
k.open("POST", a, !0);
k.setRequestHeader("Content-type",
"application/x-www-form-urlencoded");
k.send(d)
}
};
this.creationFlow = "";
this.authenticateWithFacebookCredentials = function(a, b, g, k) {
a = ["type=fb", "fbuid=" + encodeURIComponent(a), "token=" + encodeURIComponent(b), "secret=" + encodeURIComponent(c.csrftoken), "trackingId=" + encodeURIComponent(c.trackingId), "referrer=" + encodeURIComponent(c.tracking.referrer), "landingURL=" + encodeURIComponent(c.tracking.landingURL), "cf=" + encodeURIComponent(this.creationFlow)].join("&");
d(a, g, k)
};
this.authenticateWithUsernameAndPassword =
function(a, b, g, k) {
a = ["type=sp", "username=" + encodeURIComponent(a), "password=" + encodeURIComponent(b), "secret=" + encodeURIComponent(c.csrftoken), "trackingId=" + encodeURIComponent(c.trackingId), "referrer=" + encodeURIComponent(c.tracking.referrer), "landingURL=" + encodeURIComponent(c.tracking.landingURL), "cf=" + encodeURIComponent(this.creationFlow)].join("&");
d(a, g, k)
};
this.authenticateWithAnonymousUser = function(a, b) {
var g = ["type=anonymous", "secret=" + encodeURIComponent(c.csrftoken), "trackingId=" + encodeURIComponent(c.trackingId),
"referrer=" + encodeURIComponent(c.tracking.referrer), "landingURL=" + encodeURIComponent(c.tracking.landingURL), "cf=" + encodeURIComponent(this.creationFlow)
].join("&");
d(g, a, b)
}
};
Spotify.Web.Overlay = function(c) {
var a = c.ownerDocument.getElementById("overlay");
this.hide = function() {
a.removeClass("visible")
};
this.setFullscreen = function() {
a.addClass("fullscreen")
};
this.show = function() {
for (; a.firstChild;) a.removeChild(a.firstChild);
a.appendChild(c);
a.addClass("visible")
}
};
Spotify.Web.PlayNow = function(c, a, b, d, f) {
var j = "playlist_create,library_subscribe,library_star,library_unstar,library_tracks_append,library_albums_append,track_star,track_unstar,client_show_share_ui".split(","),
g = ["playNow", "limitedSubscribe"],
k = null,
l = a,
h = null,
m = null,
n = [],
e = [],
o = !1,
t = null,
C = !1,
v = null,
z = [],
w = null,
A = null,
x = null,
u = null,
y = function() {
u = setTimeout(function() {
o || (h.isPlaying && (v = !0), h.pause(), k && k.log({
event: "pn_first_interaction_playback_paused"
}), t && t())
}, 9E4)
},
B = function() {
C || (C = !0, y())
},
D = function() {
return l === "anonymous"
},
G = function() {
for (var a = D() ? n : e; a.length > 0;) a.shift().call(this)
},
E = function(a) {
k && k.log({
event: "pn_limited_feature",
data: {
feature: a
}
});
z.forEach(function(b) {
b.call(this, a)
})
};
this.setAutoPlayTriggered = function(a) {
m = a
};
this.authenticateUser = function(a, b) {
c.notify(Spotify.Web.PublisherMessages.USER_CONTEXT_FREEZE, {
user: a
});
k ? k.log({
event: "pn_authenticate_user",
data: {
user: a,
anonymousUser: b
}
}, function() {
x && x()
}) : x && x()
};
this.setPlayer = function(a) {
h = a;
this.isAnonymous() &&
!(Spotify.Web.Cookie.get("sp_fi") !== void 0 || Spotify.Web.Cookie.get("sp_cc") !== void 0) && h.bind("FIRST_BYTES", B, this)
};
this.getBlocked = function() {
return j
};
this.getLimitedFeatureFlags = function() {
return g
};
this.onAnonymous = function(a) {
D() ? a() : n.push(a)
};
this.onSignedIn = function(a) {
D() ? e.push(a) : a()
};
this.onLimitedFeature = function(a) {
z.push(a)
};
this.bindBeforeReload = function(a) {
x = a
};
this.bindFirstInteractionNeeded = function(a) {
t = a
};
this.bindSignUpHandler = function(a) {
w = a
};
this.bindLoginHandler = function(a) {
A =
a
};
this.limitedFeatureCalled = function(a) {
E(a)
};
this.checkSignedIn = function(a) {
D() ? E("unknown") : a()
};
this.signUp = function(a) {
k && k.log({
event: "pn_show_signup"
});
w && w(a)
};
this.login = function(a) {
k && k.log({
event: "pn_show_login"
});
A && A(a)
};
this.isAnonymous = function() {
return D()
};
this.isYahooUser = function() {
return d === "yahoo"
};
this.change = function(a) {
l = a;
G()
};
this.setLogger = function(a) {
k = a
};
this.getLogger = function() {
return k
};
this.onNotify = function(a) {
a.messageType === Spotify.Web.PublisherMessages.USER_INTERACTION ?
m ? m = !1 : o || (k && k.log({
event: "pn_first_interaction"
}), o = !0, clearTimeout(u), Spotify.Web.Cookie.set("sp_fi", 1, {
ttl: 180,
domain: b
}), v && (k && k.log({
event: "pn_first_interaction_playback_resume"
}), h.resume())) : a.messageType === Spotify.Web.PublisherMessages.USER_INTERACTION_PAUSE_PLAYBACK && clearTimeout(u)
};
this.isFacebookFlow = function() {
return f.indexOf("utm_campaign=fb") > -1
};
this.isOpenRedirect = function() {
return this.isAnonymous() && Spotify.Web.Cookie.get("sp_og") === "d64111d9de6b4b4db229f6c6aaec0d33"
};
c.subscribe(Spotify.Web.PublisherMessages.USER_INTERACTION,
this);
c.subscribe(Spotify.Web.PublisherMessages.USER_INTERACTION_PAUSE_PLAYBACK, this);
this.isYahooUser() && (m = !0)
};
Spotify.Web.PlayNowSignUp = function(c, a, b, d) {
Spotify.Web.Overlay.call(this, a);
var f = this,
j = null,
g = function() {
d.notify(Spotify.Web.PublisherMessages.USER_INTERACTION);
f.hide()
},
k = function() {
var h = a.querySelector("#login-screen");
h && a.removeChild(h);
h = a.ownerDocument.createElement("div");
h.setAttribute("id", "login-screen");
a.appendChild(h);
Spotify.Web.WebTracker.log({
type: "INITIALIZE_LOGIN_SCREEN",
t: (new Date).getTime()
});
j = new Spotify.Web.Screens.Login(h, b, function() {}, c, g);
j.init();
c.isOpenRedirect() ||
a.querySelector("#bg-wrap").addEventListener("click", function(a) {
a.target.id === "bg-wrap" && (d.notify(Spotify.Web.PublisherMessages.USER_INTERACTION), f.hide())
})
},
l = function(a, b) {
k();
a == "login-form" ? j.showLogin() : a == "continue-listening" ? j.showContinueListening() : b && j.showRestrictedFeature(b);
c.isOpenRedirect() && f.setFullscreen(!0);
f.show()
};
this.initialize = function() {
c.bindSignUpHandler(function(a) {
l(a)
});
c.bindLoginHandler(function() {
l("login-form")
});
c.onLimitedFeature(function(a) {
l(!1, a)
});
c.bindFirstInteractionNeeded(function() {
l(!1,
"first_interaction_needed")
})
}
};
Spotify.Web.PlayNowBanner = function(c, a, b, d, f, j) {
f.subscribe(Spotify.Web.PublisherMessages.COOKIES_ACCEPTED, this);
var g, k = !1,
l = !1,
h = !d.hasAccepted(),
m = function() {
a.removeClass("hidden");
b.addClass("playnow")
},
n = function() {
b.removeClass("playnow");
a.addClass("auth");
Spotify.Web.Utils.addTransitionEndedListener(a, function() {
a.addClass("hidden")
}, 500)
},
e = function() {
k ? (a.querySelector("#playnow-cc").className = "", a.querySelector("#playnow-welcome").className = "show", k = l = !1) : l && !g && (g = setTimeout(function() {
k = !0
}, 12E4))
},
o = function() {
var b = a.ownerDocument,
e = b.createElement("div");
a.addClass("hidden");
e.className = c.isYahooUser() ? "yahoo-banner" : "";
var d, g = b.createElement("div");
g.id = "playnow-welcome";
var f = b.createElement("h1"),
k = b.createElement("p");
f.textContent = _("Keep the music going!");
g.appendChild(f);
k.textContent = _("playnow/signup_description");
g.appendChild(k);
if (h) d = b.createElement("div"), d.id = "playnow-cc", f = b.createElement("h1"), f.textContent = _("Welcome to Spotify!"), k = b.createElement("p"), k.innerHTML =
_("By interacting with this web player (e.g. by controlling music playback, searching for music, etc.) you agree to our {{TERMS_START}}Terms and Conditions{{TERMS_END}} and our {{PP_START}}Privacy Policy{{PP_END}}, and you also consent to the use of cookies as described in {{COOKIES_START}}Information About Cookies & Similar Technologies{{COOKIES_END}}.", {
TERMS_START: '<a class="cookies-noaccept" href="https://www.spotify.com/legal/end-user-agreement/" target="_blank">',
TERMS_END: "</a>",
PP_START: '<a class="cookies-noaccept" href="https://www.spotify.com/legal/privacy-policy/" target="_blank">',
PP_END: "</a>",
COOKIES_START: '<a href="http://www.spotify.com/legal/privacy-policy/#cookies" class="cookies-noaccept" target="_blank">',
COOKIES_END: "</a>"
}), d.appendChild(f), d.appendChild(k), l = !0;
e.appendChild(g);
h && e.appendChild(d);
(h ? d : g).className += "show";
d = b.createElement("button");
d.innerHTML = _("Sign Up");
g = document.createElement("span");
d.appendChild(g);
d.className = c.isFacebookFlow() ? j ? "btn btn-primary signup fb" : "button signup fb" : j ? "btn btn-primary signup" : "button signup primary";
e.appendChild(d);
d.addEventListener("click", function() {
c.signUp()
});
b = b.createElement("button");
b.textContent = _("Log In");
b.className = j ? "btn btn-default login" : "button login";
e.appendChild(b);
c.isFacebookFlow() && (b.className += " fb");
b.addEventListener("click", function() {
c.login()
});
a.appendChild(e)
};
this.enableFacepile = function() {
var b = a.ownerDocument,
c = a.querySelectorAll("div")[0];
if (a.querySelector("iframe") === null) {
var e = b.createElement("iframe");
e.setAttribute("src", "//www.facebook.com/plugins/facepile.php?href=http%3A%2F%2Ffacebook.com%2FSpotify&amp;app_id=134519659678&amp;action&amp;size=medium&amp;show_count=true&amp;colorscheme=light&amp;appId=134519659678&width=200&max_rows=1");
e.setAttribute("id", "facepile");
e.setAttribute("scrolling", "no");
e.setAttribute("frameborder", "0");
e.setAttribute("allowTransparency", "true");
c.appendChild(e);
b.querySelector("body").className += " facepile"
}
};
this.initialize = function() {
o();
c.isOpenRedirect() || (c.onAnonymous(m), c.onSignedIn(n))
};
this.onNotify = function(a) {
h && a.messageType === "COOKIES_ACCEPTED" && e()
}
};
Spotify.Web.Bridge = function(c) {
var a = this;
this.hermes = {
load_schema: function(b, c) {
a.request("hermes_load_schema_data", [b], function(a, b) {
a ? c(null) : c(b.id)
})
},
request: function(b, c, f, j, g, k, l) {
a.hermes.load_schema(k, function(h) {
for (var k = [], n = 0, e = j.length; n < e; n += 1) k.push(h + "#" + j[n]);
for (var n = [], o = 0, e = g.length; o < e; o += 1) n.push(h + "#" + g[o]);
a.request("hermes_send_request", [b, c, n, k, f], l)
})
}
};
this.player = {
getState: function(b) {
a.request("player_query", ["main"], b)
},
registerForPlayerEvents: function(b) {
a.request("player_event_wait_any", ["main"], b)
},
registerForPlayerStateChange: function(b) {
a.request("player_event_wait", ["main"], b)
},
pause: function(b) {
a.request("player_pause", ["main"], b)
},
resume: function(b) {
a.request("player_play", ["main"], b)
},
play_context: function(b, c, f, j) {
a.request("player_play_context", ["main", {
type: "list",
uri: b
}, c, f], j)
},
play_context_as_app: function(b, c, f, j, g, k) {
a.requestAsApp(b, "player_play_context", ["main", {
type: "list",
uri: c
}, f, j, -1, g], k)
},
play_track: function(b, c, f) {
a.request("player_play_track", ["main", b, c],
f)
},
play_track_as_app: function(b, c, f, j, g) {
a.requestAsApp(b, "player_play_track", ["main", c, f, -1, j], g)
}
};
this.user = {
setAttribute: function() {},
getAttribute: function() {}
};
this.logging = {
logClientEvent: function(b, c) {
a.request("application_client_event", Array.isArray(b) ? b : [b], c)
}
};
this.request = function(a, d, f) {
c.request(a, d, this, function(a) {
f(null, a)
}, function(a) {
f(!0, a)
})
};
this.requestAsApp = function(a, d, f, j) {
c.requestAsApp(a, d, f, this, function(a) {
j(null, a)
}, function(a) {
j(!0, a)
})
}
};
Spotify.Web.Confirm = function(c, a) {
var b = this,
d = function(c) {
var d = !1;
!b.hasBeenShown() && a.isPlaying && (d = _("You need to have this page open to play music, are you sure you want to leave?"), b.markAsShown());
if (d !== !1) return (c || window.event).returnValue = d
};
b.enable = function() {
window.addEventListener("beforeunload", d)
};
b.disable = function() {
window.removeEventListener("beforeunload", d)
};
b.init = function() {
b.enable();
setTimeout(b.disable, 18E5)
};
b.markAsShown = function() {
c.set("confirm_shown", !0)
};
b.hasBeenShown =
function() {
return c.get("confirm_shown") === !0
}
};
Spotify.Web.Cookie = {
get: function(c, a) {
for (var b = this.getAll(a), d = encodeURIComponent(c) + "=", f = 0; f < b.length; f++) {
var j = b[f].replace(/^\s+|\s+$/g, "");
if (j.indexOf(d) === 0) return decodeURIComponent(j.substring(d.length, j.length))
}
},
getAll: function(c) {
c = c || window.document;
return (c.cookie ? c.cookie : "").split(";")
},
set: function(c, a, b, d) {
var b = b || {},
d = d || window.document,
f = b.ttl || 0,
j = b.path || "/",
g = b.domain || "",
b = b.secure || !1,
c = encodeURIComponent(c) + "=" + encodeURIComponent(a) + ";";
f != 0 && (a = new Date, a.setDate(a.getDate() +
f), c += " expires=" + a.toUTCString() + ";");
c += " path=" + j + ";";
c += g != "" ? " domain=" + g + ";" : "";
c += b ? " secure;" : "";
d.cookie = c
},
remove: function(c, a, b, d) {
this.set(c, "", {
domain: b,
ttl: -1,
secure: d
}, a)
},
domain: function() {
return window.location.hostname ? window.location.hostname.match(/\.spotify\.(net|com)$/)[0] || ".spotify.com" : ".spotify.com"
}()
};
Spotify.Web.CookieCompliance = function(c, a) {
var b = this;
a && a.subscribe(Spotify.Web.PublisherMessages.USER_INTERACTION, this);
var d = document.getElementById("cookie-compliance"),
f = window.location.hostname.match(/\.spotify\.(net|com)$/)[0] || ".spotify.com",
j = null,
g = {
BE: "BE",
ES: "ES",
FR: "FR",
GB: "GB",
IE: "IE",
IT: "IT",
NL: "NL",
PL: "PL",
PT: "PT",
GR: "GR",
HU: "HU",
CZ: "CZ",
MT: "MT",
BG: "BG",
SK: "SK",
CY: "CY"
};
this.hasAccepted = function() {
return Spotify.Web.Cookie.get("sp_cc") !== void 0
};
this.show = function() {
if (!this.hasAccepted()) d.className =
"show"
};
this.hide = function() {
d.className = ""
};
this.mustAccept = function() {
return g[c] !== void 0 && Spotify.Web.Cookie.get("sp_cc") === void 0
};
this.setAutoPlayTriggered = function() {
j = !0
};
this.onNotify = function(a) {
a.messageType === "USER_INTERACTION" && (j ? j = !1 : b.accept())
};
this.accept = function(b) {
Spotify.Web.Cookie.set("sp_cc", 1, {
ttl: 180,
domain: f
});
a && a.notify(Spotify.Web.PublisherMessages.COOKIES_ACCEPTED, {});
typeof b === "function" && b.call()
}
};
Spotify.Web.Screens.Intermediate = function(c, a, b) {
var d = new Spotify.Web.Authenticator(a),
f = function(a) {
c.className = "hidden";
setTimeout(function() {
c.style.display = "none"
}, 1E3);
b(a)
},
j = function() {
document.getElementById("timeout").style.display = "block";
Spotify.Web.WebTracker.log({
type: "FB_CONNECTION_FAILED",
error: "account_creation_failed"
})
},
g = function() {
Spotify.Web.FacebookSDK.onInitialized(function() {
FB.getLoginStatus(function(a) {
a.status === "connected" ? d.authenticateWithFacebookCredentials(a.authResponse.userID,
a.authResponse.accessToken, f, j) : a.status === "not_authorized" ? d.authenticateWithAnonymousUser(function(a) {
a.sessionType = "anonymous";
f(a)
}, j) : (Spotify.Web.WebTracker.log({
type: "FB_CONNECTION_FAILED",
error: "not_connected"
}, !1), document.location.href = "/login/")
})
})
};
this.init = function() {
if (a.loginFlow === "spb") d.creationFlow = "spb_to_webplayer";
else if (a.loginFlow === "new_spb") d.creationFlow = "new_spb_to_webplayer";
else if (a.loginFlow === "fb") d.creationFlow = "facebook_play_to_webplayer";
c.innerHTML = ['<div id="intermediate">\n <div class="mssg">',
" <h1>" + _("Loading Spotify") + "</h1>", " <p>" + _("Lots of music coming your way. Any second now...") + "</p>", " <form></form>", ' <img src="' + a.cdn + '/images/loading_throbber.gif" alt="" id="throbber">', ' <p id="timeout">', " " + _("Seems to be taking a while. {{LINK_START}}Please click here{{LINK_END}}.", {
LINK_START: '<a href="/login/">',
LINK_END: "</a>"
}), " </p>\n </div>\n</div>"
].join("\n");
Spotify.Web.WebTracker.log({
type: "INTERMEDIATE_JS_READY"
});
g()
}
};
Spotify.Web.Forms.Builder = function(c, a) {
this._container = document.createElement("div");
this._container.className = "sign-up-form";
this._fields = c.fields;
this._form = document.createElement("form");
var b = this,
d = function(a, b) {
var c = document.createElement("p"),
e = document.createElement("label"),
d = document.createElement("input");
c.id = "wrap-" + b;
d.id = b;
d.name = b;
d.type = a.type;
e.innerHTML = a.label;
e.setAttribute("for", b);
a.maxLength && d.setAttribute("maxlength", a.maxLength);
a.placeHolder && d.setAttribute("placeholder",
a.placeHolder);
d.addEventListener("blur", function() {
m(a);
n(!0)
}, !1);
d.addEventListener("focus", function() {
t(a.node)
}, !1);
c.appendChild(e);
c.appendChild(g());
c.appendChild(d);
return a.node = c
},
f = function(a, b) {
var c = document.createElement("p"),
e = document.createElement("label");
c.id = "wrap-" + b;
e.innerHTML = a.label;
c.appendChild(e);
c.appendChild(g());
for (var d in a.choices) {
var e = a.choices[d],
h = document.createElement("label");
h.innerHTML = e.label;
h.className = "radio";
var f = document.createElement("input");
f.type = "radio";
f.name = b;
f.value = d;
if (e.selected) f.checked = !0;
h.appendChild(f);
c.appendChild(h)
}
c.addEventListener("click", function() {
t(a.node)
}, !1);
f.onchange = function() {
n(!0)
};
return a.node = c
},
j = function(a, b) {
var c = document.createElement("p"),
e = document.createElement("label"),
d = document.createElement("input"),
h = document.createElement("span");
c.id = "wrap-" + b;
d.name = b;
d.type = "checkbox";
e.className = "checkbox";
if (a.checked) d.checked = !0;
h.innerHTML = a.label;
e.appendChild(d);
e.appendChild(h);
c.appendChild(e);
c.appendChild(g());
c.addEventListener("click", function() {
t(a.node)
}, !1);
c.addEventListener("mouseup", function() {
n(!0)
}, !1);
return a.node = c
},
g = function() {
var a = document.createElement("div");
a.className = "error";
return a
},
k = function(a, b) {
var c = document.createElement("input");
c.name = b;
c.value = a.value;
c.type = "hidden";
return a.node = c
},
l = function(a, b) {
var c = document.createElement("select");
c.id = b;
for (var e = a.getOptions(), d = 0; d < e.length; d++) {
var h = document.createElement("option");
h.value = e[d][0];
h.innerHTML =
e[d][1];
c.appendChild(h)
}
c.addEventListener("focus", function() {
c.parentNode.clearErrors()
});
return a.node = c
},
h = function(a, b) {
var c = document.createElement("p"),
e = document.createElement("label");
c.id = "wrap-" + b;
e.innerHTML = a.label;
c.appendChild(e);
c.appendChild(g());
a.node = c;
c.clearErrors = function() {
t(this)
};
return c
},
m = function(a, b) {
var c = a.node.querySelector("input"),
e = !0,
d = "",
h = typeof b === "undefined" || !b,
d = _("This field is required");
if (a.required) {
if (a.type === "checkbox" && !c.checked) return h && o(a.node,
a.requiredText || d), !1;
if (a.type === "radio" && !a.node.querySelector("input:checked")) return h && o(a.node, a.requiredText || d), !1;
if (c.value.length === 0 && h) return h && o(a.node, a.requiredText || d), !1
}
for (var f in a.validate) {
var d = a.validate[f],
g;
switch (f) {
case "regEx":
e = d.rule.test(c.value);
break;
case "regExExclude":
e = !d.rule.test(c.value);
break;
case "matchField":
e = document.getElementById(d.rule);
e = c.value === e.value;
break;
case "minNum":
e = c.value >= d.rule;
break;
case "maxNum":
e = c.value <= d.rule;
break;
case "minLength":
e =
c.value.length >= d.rule;
break;
case "maxLength":
e = c.value.length <= d.rule;
break;
case "custom":
e = (g = d()) ? !1 : !0
}
if (!e) return d = g ? g : d.message, h && o(a.node, d), !1
}
return !0
},
n = function(a) {
var c = !0,
e = 0,
d = b._fields.length,
h;
for (h = 0; h < d; h++)
if (c = b._fields[h], c.node && (c.required || c.validate))(c = m(c, a)) || e++;
return e === 0
},
e = function() {
b._form.addEventListener("submit", function(c) {
c.preventDefault();
if (n() && typeof a === "function") {
for (var c = {}, e = b._fields, d = 0; d < e.length; d++) {
var h = e[d],
f = e[d].name;
switch (h.type) {
case "hidden":
c[f] =
h.node.value;
break;
case "text":
case "password":
c[f] = h.node.querySelector("input").value;
break;
case "radio":
if (h.node.querySelector("input:checked")) c[f] = h.node.querySelector("input:checked").value;
break;
case "checkbox":
h.node.querySelector("input").checked && (c[f] = "yeaaahhh");
break;
case "select":
c[f] = h.node.value
}
}
a(c)
}
}, !1)
},
o = function(a, b) {
a.querySelector(".error").textContent = b;
a.className = "has-error"
},
t = function(a) {
a.querySelector(".error").textContent = "";
a.className = ""
};
this.handleExternalErrors =
function(a) {
var c = b._fields,
e = c.length,
d, h, f;
for (f in a)
for (h = 0; h < e; h++)
if (c[h].name === f) d = c[h].node, t(d), o(d, a[f])
};
this.init = function() {
var a = document.createDocumentFragment(),
g = document.createElement("p"),
m = b._fields,
o = m.length,
n;
g.className = "submit-wrap";
b.submitButton = document.createElement("button");
b.submitButton.className = "";
b._form.method = c.method;
b._form.action = c.endPoint;
var t = document.createElement("span");
for (n = 0; n < o; n++) {
var u = m[n],
y = u.name,
B = a;
u.group && (B = a.querySelector("#wrap-" + u.group));
switch (u.type) {
case "group":
B.appendChild(h(u, y));
break;
case "text":
case "password":
B.appendChild(d(u, y));
break;
case "radio":
B.appendChild(f(u, y));
break;
case "checkbox":
B.appendChild(j(u, y));
break;
case "hidden":
B.appendChild(k(u, y));
break;
case "select":
B.appendChild(l(u, y))
}
}
b.submitButton.type = "submit";
b.submitButton.textContent = c.submitText || "Submit";
g.appendChild(b.submitButton);
b.submitButton.appendChild(t);
a.appendChild(g);
b._form.appendChild(a);
e();
this._container.appendChild(this._form);
this.node =
this._container
};
this.init()
};
Spotify.Web.Forms.Signup = function(c, a, b, d, f) {
var j = b.doubleCheckLicenseCountries,
g = function() {
var a = j.length,
c;
for (c = 0; c < a; c++)
if (j[c] === b.country) return !0;
return !1
}(),
k = new Spotify.Web.Authenticator(b),
l = 0,
h = "",
m = "",
n = b.username,
e = /^.+@.+\..+/,
o = this,
t = {
TERMS_START: '<a href="https://www.spotify.com/legal/end-user-agreement/" target="_blank">',
TERMS_END: "</a>",
PP_START: '<a href="https://www.spotify.com/legal/privacy-policy/" target="_blank">',
PP_END: "</a>"
},
C = a === !0,
v = !b.email_opt_out,
z = !v,
e = {
endPoint: "/xhr/json/signup.php",
method: "post",
submitText: _("Sign up"),
fields: [{
name: "secret",
type: "hidden",
value: b.csrftoken
}, {
name: "username",
type: "text",
label: _("Username:"),
placeHolder: _("e.g. John Doe"),
required: !0,
requiredText: _("Please enter a username"),
validate: {
regExExclude: {
rule: /[&@\/\'":`\u00b4 ]/,
message: _("Please make sure there are no invalid characters in your username")
},
minLength: {
rule: 4,
message: _("Your username should be at least 4 characters")
},
maxLength: {
rule: 100,
message: _("Your username should be at most 100 characters")
}
}
}, {
name: "email",
type: "text",
label: _("Email:"),
placeHolder: _("e.g. john@email.com"),
required: !0,
requiredText: _("Please enter an email address"),
validate: {
regEx: {
rule: e,
message: _("The email address you supplied is invalid")
}
}
}, {
name: "email-confirm",
type: "text",
label: _("Confirm email") + ":",
placeHolder: _("Confirm email"),
required: !0,
requiredText: _("Please confirm your email address here"),
validate: {
matchField: {
rule: "email",
message: _("Email confirmation doesn't match")
},
regEx: {
rule: e,
message: _("The email address you supplied is invalid")
}
}
}, {
name: "password",
type: "password",
label: _("Password:"),
placeHolder: _("Choose a password"),
required: !0,
requiredText: _("Please enter a password"),
validate: {
minLength: {
rule: 4,
message: _("Your password should be at least 4 characters")
}
}
}, {
name: "age",
type: "group",
label: _("Date of birth"),
validate: {
custom: function() {
for (var a = [document.getElementById("age-year").value, document.getElementById("age-month").value, document.getElementById("age-day").value], b = 0; b < a.length; b++)
if (a[b] === "-") return _("Please enter your date of birth");
return null
}
}
}, {
name: "age-year",
type: "select",
group: "age",
getOptions: function() {
for (var a = [
["-", _("Year")]
], b = 2013; b >= 1900; b--) a.push([b, b]);
return a
}
}, {
name: "age-month",
type: "select",
group: "age",
getOptions: function() {
for (var a = [
["-", _("Month")]
], b = 1; b <= 12; b++) a.push([b, b]);
return a
}
}, {
name: "age-day",
type: "select",
group: "age",
getOptions: function() {
for (var a = [
["-", _("Day")]
], b = 1; b <= 31; b++) a.push([b, b]);
return a
}
}, {
name: "gender",
type: "radio",
label: _("Gender:"),
required: !0,
requiredText: _("Please select your gender"),
choices: {
male: {
selected: !1,
label: _("Male")
},
female: {
selected: !1,
label: _("Female")
}
}
}, {
name: "marketing-emails",
type: "checkbox",
label: _("Please send me Spotify news by e-mail"),
checked: v
}]
},
g = g ? [{
name: "terms",
type: "checkbox",
label: _("I agree to the {{TERMS_START}}Spotify Terms and Conditions of Use{{TERMS_END}}", t),
required: !0,
requiredText: _("You must agree to our Terms and Conditions of Service to use the Spotify Service."),
checked: C
}, {
name: "terms",
type: "checkbox",
label: _("I agree to the {{PP_START}}Spotify Privacy Policy{{PP_END}}",
t),
required: !0,
requiredText: _("You must agree to our Privacy Policy to use the Spotify Service."),
checked: C
}] : [{
name: "terms",
type: "checkbox",
label: _("I agree to the {{TERMS_START}}Spotify Terms and Conditions of Use{{TERMS_END}} and {{PP_START}}Privacy Policy{{PP_END}}", t),
required: !0,
requiredText: _("You must agree to our Terms and Conditions of Service and Privacy Policy to use the Spotify Service."),
checked: C
}];
e.fields.splice.apply(e.fields, [-1, 0].concat(g));
var w = function(a) {
o._globalErrorNode.textContent =
a;
o._globalErrorNode.className = "show"
},
A = function() {
o._form.style.visibility = "visible";
o._loadingScreen.className = ""
},
x = function() {
k.authenticateWithUsernameAndPassword(h, m, function(a) {
u(a)
}, function() {
l++;
l < 5 ? setTimeout(function() {
x()
}, 2E3) : (A(), w(_("Sorry, there was a problem during the signup process - please try again")))
})
},
u = function(a) {
f === void 0 || f.isAnonymous() === !1 ? (c.className = "hidden", setTimeout(function() {
c.style.display = "none"
}, 1E3), window.dataLayer && Spotify.Web.Cookie.get("justRegistered") &&
(window.dataLayer.push({
event: "registration_flow_complete"
}), Spotify.Web.Cookie.remove("justRegistered")), d(a, window.FB || void 0)) : f.authenticateUser(a.username, n)
},
y = !1;
this.builder = new Spotify.Web.Forms.Builder(e, function(a) {
Spotify.Web.WebTracker.log({
type: "SPOTIFY_SIGNUP_CLICKED"
});
o._globalErrorNode.className = "";
o._form.style.visibility = "hidden";
o._loadingScreen.className = "show";
if (!y) {
y = !0;
var c = [],
e;
for (e in a)
if (e) {
var d = a[e];
e === "username" && (h = d = d.toLowerCase());
e === "password" && (m = d);
c.push(encodeURIComponent(e) +
"=" + encodeURIComponent(d))
}
c.push("referrer=" + encodeURIComponent(b.tracking.referrer));
c.push("landingURL=" + encodeURIComponent(b.tracking.landingURL));
var f = new XMLHttpRequest;
f.onreadystatechange = function() {
if (f.readyState === 4)
if (y = !1, f.status === 200) {
//TODO Add Try Catch
var a = JSON.parse(f.responseText);
a.success ? (x(), typeof window.dataLayer != "undefined" && (dataLayer.push({
event: "registration_success"
}), Spotify.Web.Cookie.get("justRegistered") || Spotify.Web.Cookie.set("justRegistered", 1, {
domain: Spotify.Web.Cookie.domain
}))) :
(A(), a.errors.global && w(a.errors.global), o.builder.handleExternalErrors(a.errors))
} else alert("Oups! Something went wrong. Please try again later.")
};
a = c.join("&");
f.open("POST", "/xhr/json/signup.php", !0);
f.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
f.send(a)
}
});
this.node = this.builder.node;
C && (this.node.className += " terms-imp");
z || (this.node.className += " marketing-emails-imp");
this._globalErrorNode = document.createElement("div");
this._globalErrorNode.id = "signup-global-error";
this._loadingScreen = document.createElement("div");
this._loadingScreen.id = "signup-loading";
this._loadingScreen.textContent = _("Loading Spotify") + "...";
this._form = this.node.querySelector("form");
this.node.appendChild(this._globalErrorNode);
this.node.appendChild(this._loadingScreen);
if (a) this.node.querySelector("#wrap-terms input").setAttribute("disabled", "disabled"), a = document.createElement("div"), C = this.node.querySelector(".submit-wrap"), a.className = "terms", a.innerHTML = _("By clicking on Sign up, you agree to the {{TERMS_START}}Spotify Terms and Conditions of Use{{TERMS_END}} and {{PP_START}}Privacy Policy{{PP_END}}",
t), C.insertBefore(a, C.firstChild)
};
Spotify.Web.Login = function(c, a, b, d) {
var f = a.cat_enabled;
this.init = function() {
Spotify.Web.FacebookSDK.init(a.fbjssdk);
Spotify.Web.WebTracker.setConfig(a.tracking);
if (a.locale && a.locale.current) document.getElementsByTagName("html")[0].className = "lang-" + a.locale.current;
if (a.credentials && a.credentials[0]) j(a);
else {
var b;
b = c.createElement("div");
b.id = "login-screen";
b.className = "main-login-class";
c.body.appendChild(b);
a.loginFlow === "fb" || a.loginFlow === "spb" ? (Spotify.Web.WebTracker.log({
type: "FACEBOOK_AUTO_LOGIN"
}),
b = new Spotify.Web.Screens.Intermediate(b, a, j)) : (Spotify.Web.WebTracker.log({
type: "INITIALIZE_LOGIN_SCREEN",
t: (new Date).getTime()
}), b = new Spotify.Web.Screens.Login(b, a, j));
b.init()
}
};
var j = function(a) {
a.version !== b ? c.location.reload(!0) : f !== a.cat_enabled ? c.location.reload(!0) : d(a)
}
};
Spotify.Web.Screens.Login = function(c, a, b, d, f) {
var j = this,
g = {
invalid_credentials: _("Incorrect username and password"),
invalid_country: _("Spotify is currently not available in your country"),
capped: _("You have reached your maximum number of login attempts, please try again later"),
service_unavailable: _("Service is currently unavailable. Please try again later"),
fallback: _("Authentication failed. Please try again.")
},
k = ["GB", "US", "ZZ"],
k = a.country && k.indexOf(a.country) !== -1,
l = a.sessionType === "anonymous",
h = d && d.isFacebookFlow(),
m = a.features && a.features.signup || l,
n = new Spotify.Web.Authenticator(a),
e = new Spotify.Web.Forms.Signup(c, k, a, Spotify.Web.App.initialize.bind(Spotify.Web.App), d),
o, t, C, v, z, w, A, x, u, y, B, D, G, E, F = a.sessionType,
I = a.username,
H, p, r, s, q, L, S, M, K, N, O, P, Q, T = function() {
c.className = "hidden";
document.body.classList.remove("login");
setTimeout(function() {
c.style.display = "none"
}, 1E3)
},
U = function(a) {
a.created === "created" && window.dataLayer && window.dataLayer.push({
event: "registration_flow_complete"
});
t.stop();
C.stop();
T();
F === "anonymous" && d.authenticateUser(a.username, I);
b(a, window.FB || void 0)
},
J = function(a) {
z.querySelector(".show").classList.remove("show");
a.classList.add("show");
E.style.display = "none"
},
V = function(a) {
C.stop();
t.stop();
E.innerHTML = g[a] ? g[a] : g.fallback;
E.style.display = "block";
z.classList.add("error");
setTimeout(function() {
z.classList.remove("error")
}, 500)
},
W = function(a) {
a.preventDefault();
Spotify.Web.WebTracker.log({
type: "FB_LOGIN_CLICKED"
});
H.mustAccept() && (H.hide(), H.accept());
t.start();
L.start();
Spotify.Web.FacebookSDK.login(function(a, b, c) {
Spotify.Web.WebTracker.log({
type: "INITIALIZE_GDP"
});
a === "unknown" || a === "not_authorized" ? (Spotify.Web.WebTracker.log({
type: "REJECTED_GDP"
}), t.stop(), L.stop()) : (a === "already_connected" ? Spotify.Web.WebTracker.log({
type: "ALREADY_CONNECTED_GDP"
}) : Spotify.Web.WebTracker.log({
type: "ACCEPTED_GDP"
}), n.authenticateWithFacebookCredentials(b, c, U, V))
})
},
X = function(a) {
a.preventDefault();
T();
f && f("continue")
},
aa = function() {
v.addEventListener("submit",
function(a) {
a.preventDefault();
Spotify.Web.WebTracker.log({
type: "SPOTIFY_LOGIN_CLICKED"
});
C.start();
H.mustAccept() && (H.hide(), H.accept());
var a = v.querySelector('[name="username"]').value,
b = v.querySelector('[name="password"]').value;
n.authenticateWithUsernameAndPassword(a, b, U, V)
});
z.addEventListener("dragstart", function(a) {
a.preventDefault()
});
A.addEventListener("click", function(a) {
a.preventDefault();
J(u);
D.focus()
});
G.addEventListener("click", function(a) {
a.preventDefault();
J(p)
});
y.addEventListener("click",
function(a) {
a.preventDefault();
J(B)
}, !1);
x.addEventListener("click", function(a) {
a.preventDefault();
J(p);
s.className = ""
}, !1);
N.addEventListener("click", function(a) {
a.preventDefault();
J(u)
}, !1);
O.addEventListener("click", function(a) {
a.preventDefault();
J(p)
}, !1);
Q.addEventListener("click", X, !1);
P.addEventListener("click", X, !1);
o.addEventListener("click", W, !1);
q.addEventListener("click", W, !1);
a.showLogin && j.showLogin()
},
ba = function() {
var b = "",
b = m ? ["<h1>" + _("Get the right music, right now") + "</h1>", "<h2>" +
_("Listen to millions of songs for free.") + "</h2>", "<ul>", " <li>" + _("Search & discover music you'll love") + "</li>", " <li>" + _("Create playlists of your favorite music") + "</li>", " <li>" + _("Spotify Radio - unlimited stations and skips") + "</li>", "</ul>"
].join("\n") : ["<h2>" + _("Spotify hasn\u2019t launched in your country yet") + "</h2>", "<p>" + _('Want an invite when we launch? <a href="https://www.spotify.com/int/why-not-available/">Leave your contact</a>.') + "</p>", "<p>" + _("If you have a Spotify account in another part of the world, you can log into the web player as usual.") +
"</p>"
].join("\n"),
e = _("CookieComplianceBannerText", {
LINK_START: '<a class="cookie-link" target="_blank" href="http://www.spotify.com/legal/privacy-policy/#cookies">',
LINK_END: "</a>"
});
c.innerHTML = ['<div id="cookie-compliance">', " " + e, '</div>\n<div id="bg-wrap">\n <div id="login">\n <div id="login-method">', ' <div class="step ' + (m ? "show" : "") + '" id="screen-signup-flow">', ' <div class="step-outer">\n <div class="step-inner">\n <div class="heading logo">', ' <img alt="" src="' +
a.cdn + '/images/logo.png"/>', " </div>", ' <button id="fb-signup-btn" href="#" class="button fb">' + _("Sign up with Facebook") + "</button>", ' <button id="signup-spotify" class="button hide-for-fb" data-or="' + _("or") + '">', " " + _("Sign up with your email address"), " </button>", ' <button id="continue-listening" class="button continue-listening">' + _("Continue Listening") + "</button>", ' <div class="acceptance text-small">' + _("signup/signup_acceptance", {
TERMS_START: '<a class="cookies-noaccept" href="https://www.spotify.com/legal/end-user-agreement/" target="_blank">',
TERMS_END: "</a>",
PP_START: '<a class="cookies-noaccept" href="https://www.spotify.com/legal/privacy-policy/" target="_blank">',
PP_END: "</a>"
}) + "</div>", ' <div class="has-account text-small">', ' <a id="has-account" href="#">' + _("Already have an account? Log in here.") + "</a>", " </div>\n </div>\n </div>\n </div>", ' <div class="step ' +
(m ? "" : "show") + '" id="screen-login-spotify">', ' <div class="step-outer">\n <div class="step-inner">\n <div class="heading logo">', ' <img class="logo-small" alt="" src="' + a.cdn + '/images/logo.png" />', ' <div class="error" id="error"></div>\n </div>\n <form id="sp-login-form" action="#" method="post">', ' <button type="button" id="fb-login-btn" class="button fb">' + _("Log in with Facebook") + "</button>", " <em>" +
_("or") + "</em>", " <div>", ' <label for="login-usr">' + _("Username") + "</label>", ' <input type="text" name="username" id="login-usr" placeholder="' + _("Spotify username") + '" />', ' <label for="login-pass" class="pass">' + _("Password") + "</label>", ' <input type="password" name="password" id="login-pass" class="pass" placeholder="' + _("Password") + '" />', ' <button type="submit">' + _("Login") + "</button>", ' </div>\n </form>\n <div class="footer text-small">',
' <a class="forgot" href="https://www.spotify.com/password-reset/" target="_blank">' + _("Forgotten your password?") + "</a>", " </div>", ' <div class="footer text-small ' + (m ? "" : "hide") + '">', " " + _("Don't have an account?") + ' <a id="login-cancel" href="#">' + _("Sign up here!") + "</a>", ' </div>\n </div>\n </div>\n </div>\n <div class="step" id="screen-signup-spotify">\n <div class="step-outer">\n <div class="step-inner">\n <div class="heading logo">',
' <img class="logo-small" alt="" src="' + a.cdn + '/images/logo.png" />', " <h3>" + _("Create your free Spotify account") + "</h3>", ' </div>\n <div id="signup-form"></div>\n <div class="footer text-small">', ' <a href="#" id="cancel-spotify-signup" class="go-back">&laquo; ' + _("Go back") + "</a>", ' </div>\n </div>\n </div>\n </div>\n <div class="step" id="screen-feature-restricted">\n <div class="step-outer">\n <div class="step-inner">\n <div class="heading logo">',
' <img class="logo-small" alt="" src="' + a.cdn + '/images/logo.png" />', " </div>", ' <h3 id="restricted-feature-title">' + _("Get access to all of Spotify's features!") + "</h3>", ' <div id="restricted-feature"></div>\n <div class="footer">', ' <button class="button primary hide" id="restricted-continue">' + _("Continue") + "</button>", ' <button class="button primary" id="restricted-signup">' + _("Sign up") + "</button>", ' <button class="button" id="restricted-login">' +
_("Log In") + "</button>", " </div>\n </div>\n </div>\n </div>", ' <div id="login-features"' + (!m ? ' class="no-signup"' : "") + ">", " " + b, " </div>\n </div>\n </div>\n</div>"
].join("\n")
},
Y = function() {
var a = {};
return function(b, e) {
typeof a[b] === "undefined" && (a[b] = c.querySelectorAll(b));
for (var d = a[b], h = 0, f = d.length, g = null; h < f; h++) g = d[h], e.call(this, g)
}
}(),
Z = function(a) {
Y(a, function(a) {
a.style.display = "block"
})
},
R = function(a) {
Y(a, function(a) {
a.style.display =
"none"
})
};
this.init = function() {
document.body.classList.add("login");
var b;
ba();
z = c.querySelector("#login");
w = c.querySelector("#bg-wrap");
r = c.querySelector("#login-features");
l && (z.classList.add("playNow"), w.classList.add("playNow"), r.classList.add("playNow"), b = "playnow");
d && d.isOpenRedirect() && (b = "contextual_login", w.classList.add("fullscreen"));
h && (b = "facebook_login_only", R(".hide-for-fb"));
p = c.querySelector("#screen-signup-flow");
c.querySelector("#cancel-spotify-signup");
s = c.querySelector("h1");
o = c.querySelector("#fb-login-btn");
t = new Spotify.Web.Dotter(o, 3, 500);
q = c.querySelector("#fb-signup-btn");
L = new Spotify.Web.Dotter(q, 3, 500);
v = c.querySelector("#sp-login-form");
loginWithSpotifyBtn = v.querySelector("button");
C = new Spotify.Web.Dotter(loginWithSpotifyBtn, 3, 500, !0);
x = c.querySelector("#cancel-spotify-signup");
A = c.querySelector("#has-account");
u = c.querySelector("#screen-login-spotify");
y = c.querySelector("#signup-spotify");
B = c.querySelector("#screen-signup-spotify");
c.querySelector("#signup-form").appendChild(e.node);
D = c.querySelector("#login-usr");
G = c.querySelector("#login-cancel");
E = document.querySelector("#error");
S = c.querySelector("#screen-feature-restricted");
M = c.querySelector("#restricted-feature");
K = c.querySelector("#restricted-feature-title");
N = c.querySelector("#restricted-login");
O = c.querySelector("#restricted-signup");
P = c.querySelector("#restricted-continue");
Q = c.querySelector("#continue-listening");
Q.style.display = "none";
H = new Spotify.Web.CookieCompliance(a.country);
H.mustAccept() && H.show();
aa();
l ?
w.classList.add("loaded") : (b = new Image, b.onload = function() {
w.classList.add("loaded")
}, b.src = a.cdn + "/images/login-overlay.png", b = "legacy_login");
Spotify.Web.WebTracker.log({
type: "LOGIN_SCREEN_DISPLAYED",
error: b,
t: (new Date).getTime()
})
};
this.showLogin = function() {
R(".continue-listening");
h || Z(".hide-for-fb");
J(u)
};
this.showContinueListening = function() {
R(".hide-for-fb");
Z(".continue-listening")
};
this.resetProcess = function() {
J(p)
};
this.showRestrictedFeature = function(a) {
J(S);
a === "first_interaction_needed" ?
(M.innerHTML = _("blocked/" + a, {
TERMS_START: '<a class="cookies-noaccept" href="https://www.spotify.com/legal/end-user-agreement/" target="_blank">',
TERMS_END: "</a>",
PP_START: '<a class="cookies-noaccept" href="https://www.spotify.com/legal/privacy-policy/" target="_blank">',
PP_END: "</a>",
COOKIES_START: '<a href="http://www.spotify.com/legal/privacy-policy/#cookies" class="cookies-noaccept" target="_blank">',
COOKIES_END: "</a>"
}), P.classList.remove("hide"), O.classList.add("hide"), N.classList.add("hide")) :
M.innerHTML = _("blocked/" + a);
switch (a) {
case "time_cap":
K.innerHTML = _("Want to keep listening?");
break;
case "first_interaction_needed":
K.innerHTML = _("Want to keep listening? Press continue!");
break;
default:
K.innerHTML = _("Get access to all of Spotify's features!")
}
}
};
Spotify.Web.BrowserDetect = {
init: function(c) {
this._navigator = c || window.navigator;
this.browser = this._searchString(this.dataBrowser) || "An unknown browser";
this.version = this._searchVersion(this._navigator.userAgent) || this._searchVersion(this._navigator.appVersion) || "an unknown version";
this.OS = this._searchString(this.dataOS) || "an unknown OS";
this.shouldUseWebSockets = this._useWebSockets()
},
_useWebSockets: function() {
return Spotify.Web.FeatureDetect.getFlashVersion().major >= 11 && !(this.browser === "Explorer" &&
this.version < 10 || this.browser === "Safari" && this.version < 6 || this.browser === "Firefox" && this.version < 11)
},
_searchString: function(c) {
for (var a = 0; a < c.length; a++) {
var b = c[a].field ? this._navigator[c[a].field] : null;
this.versionSearchString = c[a].versionSearch || c[a].identity;
if (!(this.versionSearchString instanceof Array)) this.versionSearchString = [this.versionSearchString];
if (b) {
if (!(c[a].subString instanceof Array)) c[a].subString = [c[a].subString];
for (var d = 0; d < c[a].subString.length; d++)
if (b.indexOf(c[a].subString[d]) !=
-1) return c[a].identity
}
}
},
_searchVersion: function(c) {
for (var a = -1, b, d = 0; d < this.versionSearchString.length && a == -1; d++) b = this.versionSearchString[d], a = c.indexOf(b);
return a == -1 ? void 0 : parseFloat(c.substring(a + b.length + 1))
},
dataBrowser: [{
field: "userAgent",
subString: "Chrome",
identity: "Chrome"
}, {
field: "userAgent",
subString: "OmniWeb",
versionSearch: "OmniWeb/",
identity: "OmniWeb"
}, {
field: "userAgent",
subString: "Apple",
identity: "Safari",
versionSearch: "Version"
}, {
field: "userAgent",
subString: ["Opera", "OPR"],
identity: "Opera",
versionSearch: ["Version", "OPR"]
}, {
field: "vendor",
subString: "iCab",
identity: "iCab"
}, {
field: "vendor",
subString: "KDE",
identity: "Konqueror"
}, {
field: "userAgent",
subString: "Firefox",
identity: "Firefox"
}, {
field: "vendor",
subString: "Camino",
identity: "Camino"
}, {
field: "userAgent",
subString: "Netscape",
identity: "Netscape"
}, {
field: "userAgent",
subString: ["MSIE", "Trident"],
identity: "Explorer",
versionSearch: ["MSIE", "rv"]
}, {
field: "userAgent",
subString: "Gecko",
identity: "Mozilla",
versionSearch: "rv"
}, {
field: "userAgent",
subString: "Mozilla",
identity: "Netscape",
versionSearch: "Mozilla"
}],
dataOS: [{
field: "platform",
subString: "Win",
identity: "Windows"
}, {
field: "platform",
subString: "Mac",
identity: "Mac"
}, {
field: "userAgent",
subString: "iPhone",
identity: "iPhone/iPod"
}, {
field: "platform",
subString: "Linux",
identity: "Linux"
}],
getVendorPrefix: function() {
if ("result" in arguments.callee) return arguments.callee.result;
var c = /^(Moz|Webkit|Khtml|O|ms|Icab)(?=[A-Z])/,
a = document.getElementsByTagName("script")[0],
b;
for (b in a.style)
if (c.test(b)) return arguments.callee.result =
b.match(c)[0];
return "WebkitOpacity" in a.style ? arguments.callee.result = "Webkit" : "KhtmlOpacity" in a.style ? arguments.callee.result = "Khtml" : arguments.callee.result = ""
}
};
Spotify.Web.ScrollBlocker = function(c, a, b) {
this.publisher = a;
this.blocker = c;
this.popupManager = b
};
Spotify.Web.ScrollBlocker.prototype.init = function() {
this.publisher.subscribe(Spotify.Web.PublisherMessages.SCROLL_BLOCK, this);
this.publisher.subscribe(Spotify.Web.PublisherMessages.SCROLL_ALLOW, this);
this.blocker.addEventListener("mouseover", function(a) {
a.stopPropagation()
}, !1);
this.blocker.addEventListener("contextmenu", function(a) {
a.preventDefault()
}, !1);
var c = this;
this.blocker.addEventListener("mousedown", function() {
c.deactivate()
}, !1)
};
Spotify.Web.ScrollBlocker.prototype.activate = function() {
this.blocker.style.display = "block"
};
Spotify.Web.ScrollBlocker.prototype.deactivate = function() {
if (this.popupManager.closeAll()) this.blocker.style.display = "none"
};
Spotify.Web.ScrollBlocker.prototype.onNotify = function(c) {
switch (c.messageType) {
case Spotify.Web.PublisherMessages.SCROLL_BLOCK:
this.activate();
break;
case Spotify.Web.PublisherMessages.SCROLL_ALLOW:
this.deactivate()
}
};
Spotify.Web.Messaging = function(c, a) {
Spotify.Web.EventTarget.call(this);
var b = this;
this.notifications = {};
this.init = function() {
a.onMessagingUnreadCountChange(function(a) {
c.notify(Spotify.Web.PublisherMessages.UNREAD_COUNT_CHANGE, {
count: a
})
});
window.Notification && a.subscribeMessagingEvents(function(a, c) {
var j = c[0];
switch (j.type) {
case "NEW_MESSAGE":
b.onNewMessage(j);
break;
case "READ_CONVERSATION":
b.onReadConversation(j)
}
})
};
this.onNewMessage = function(d) {
var f = d.newMessage.conversation,
j = f.preview,
g = "spotify:app:messages:thread:" +
encodeURIComponent(f.id);
a.getUsername(function(d) {
"spotify:user:" + d !== j.sender && a.getSocialDataForUser(j.sender, function(a) {
if (a) {
var d = _("NewMessageWebNotificationTitle", {
USER_NAME: a.name
}),
a = new Notification(d, {
tag: g,
body: j.text,
icon: a.image
});
a.show && a.show();
b.notifications[f.id] = a;
a.addEventListener("click", function() {
var a = Spotify.Web.PublisherMessages.APPLICATION_OPEN_URI,
b = Spotify.Link.fromString(g);
c.notify(a, {
link: b
});
window.focus()
})
}
})
})
};
this.onReadConversation = function(a) {
var a = a.readConversation.conversationId,
c = b.notifications[a];
c && c.close && (c.close(), delete b.notifications[a])
}
};
Spotify.Web.Notifications = function(c, a) {
Spotify.Web.EventTarget.call(this);
this.init = function() {
a.onNotificationsUnreadCountChange(function(a) {
c.notify(Spotify.Web.PublisherMessages.UNREAD_NOTIFICATIONS_COUNT_CHANGE, {
count: a
})
})
}
};
Spotify.Web.SocialData = function(c, a, b) {
Spotify.Web.EventTarget.call(this);
var d = this;
this._userSurname = this._userFirstName = this._userImage = "";
this._fbComplete = this._apComplete = !1;
var f = function() {
c.notify(Spotify.Web.PublisherMessages.SOCIAL_DATA_SUCCESS, {
name: d._userFirstName,
surname: d._userSurname,
image: d._userImage
})
},
j = function() {
b.getUserImage(function(a) {
b.getUsersName(function(b) {
var c = a.message[0];
if (d._userImage === "" && c && c.url !== "") d._userImage = c.url;
if (d._userFirstName === "" && b.message.first_name &&
b.message.first_name !== "") d._userFirstName = b.message.first_name;
if (d._userSurname === "" && b.message.last_name && b.message.last_name !== "") d._userSurname = b.message.last_name;
d._fbComplete = !0;
f()
})
})
},
g = function() {
a.getSocialDataForCurrentUser(function(a) {
d._apComplete = !0;
if (a) {
if (a.image && a.image !== "") d._userImage = a.image;
if (a.name && a.name !== "") {
var a = a.name,
b = a.split(" ");
d._userFirstName = b[0];
d._userSurname = b.length > 1 ? a.substring(a.indexOf(" ") + 1) : ""
}
f()
}
})
};
this.init = function() {
g();
c.subscribe(Spotify.Web.PublisherMessages.FB_APP_CONNECTED,
d)
};
this.onNotify = function(a) {
a.messageType === Spotify.Web.PublisherMessages.FB_APP_CONNECTED && (this._userFirstName === "" || this._userImage === "") && j()
}
};
Spotify.Web.Static = function() {
this.preloadImage = function(c, a) {
var b = new Image;
b.src = c;
if (typeof a !== "undefined") b.onload = a
};
this.loadScript = function(c) {
var a = document.createElement("script");
a.type = "text/javascript";
a.async = !0;
a.src = c;
c = document.getElementsByTagName("script")[0];
c.parentNode.insertBefore(a, c)
}
};
Spotify.Web.EventTarget = function() {
var c = {};
this.bind = function(a, b, d) {
var f = {
callback: b,
context: d
},
j = !1,
g;
c[a] === void 0 && (c[a] = []);
g = c[a];
for (var k = 0; k < g.length; k++)
if (g[k].callback === b && g[k].context === d) {
j = !0;
break
}
j === !1 && c[a].push(f)
};
this.trigger = function(a, b) {
var d = c[a],
f;
if (typeof d !== "undefined")
for (f = 0; f < d.length; f++) {
var j = d[f];
j.callback.call(j.context, {
type: a,
sender: this,
params: b
})
}
};
this.unbind = function(a, b, d) {
var f, j = c[a];
if (typeof j !== "undefined") {
for (var g = 0; g < j.length; g++)
if (j[g].callback ===
b && j[g].context === d) {
f = g;
break
}
f !== -1 && c[a].splice(f, 1)
}
}
};
Spotify.Web.Publisher = function() {
var c = {},
a = function(a) {
c[a] === void 0 && (c[a] = []);
return c[a]
};
this.subscribe = function(b, c) {
if (!b) throw Error("Spotify.Web.Publisher message type must be set");
if (!c) throw Error("Spotify.Web.Publisher listener object must be set");
var f = a(b);
f.indexOf(c) === -1 && f.push(c)
};
this.unsubscribe = function(b, c) {
var f = a(b),
j = f.indexOf(c);
j > -1 && f.splice(j, 1)
};
this.notify = function(b, c, f) {
for (var j = a(b), g = 0; g < j.length; g++) j[g].onNotify({
messageType: b,
message: c,
origin: f
})
}
};
Spotify.Web.PublisherMessages = {
ERROR: "ERROR",
APPLICATION_STATE_CHANGED: "APPLICATION_STATE_CHANGED",
APPLICATION_STATE_PUSH: "APPLICATION_STATE_PUSH",
APPLICATION_STATE_REPLACE: "APPLICATION_STATE_REPLACE",
APPLICATION_OPEN_URI: "APPLICATION_OPEN_URI",
APPLICATION_POST_MESSAGE: "APPLICATION_POST_MESSAGE",
APPLICATION_ENABLED: "APPLICATION_ENABLED",
APPLICATION_VERSION_CHANGED: "APPLICATION_VERSION_CHANGED",
APPLICATION_CLOSED: "APPLICATION_CLOSED",
APPLICATION_DISPOSED: "APPLICATION_DISPOSED",
APPLICATION_ACTIVATED: "APPLICATION_ACTIVATED",
APPLICATION_DEACTIVATED: "APPLICATION_DEACTIVATED",
APPLICATION_SET_PREFERRED_SIZE: "APPLICATION_SET_PREFERRED_SIZE",
LIMITED_FEATURE_CALL: "LIMITED_FEATURE_CALL",
CLIENT_SHOW_SHARE_UI: "CLIENT_SHOW_SHARE_UI",
CLIENT_SHOW_CONTEXT_UI: "CLIENT_SHOW_CONTEXT_UI",
CLIENT_SHOW_COLLECTION_UNION_REMOVE_UI: "CLIENT_SHOW_COLLECTION_UNION_REMOVE_UI",
CHROME_READY: "CHROME_READY",
FB_APP_CONNECTED: "FB_APP_CONNECTED",
FB_APP_NOT_AUTHENTICATED: "FB_APP_NOT_AUTHENTICATED",
FB_APP_UNKNOWN: "FB_APP_UNKNOWN",
FB_CONNECTION_FAILURE: "FB_CONNECTION_FAILURE",
FB_MESSAGE: "FB_MESSAGE",
FB_POST: "FB_POST",
FB_SESSION_QUERY: "FB_SESSION_QUERY",
FB_SESSION_USER_METADATA: "FB_SESSION_USER_METADATA",
USER_AUTHENTICATED: "USER_AUTHENTICATED",
USER_AUTHENTICATION_FAILURE: "USER_AUTHENTICATION_FAILURE",
USER_CONTEXT_FREEZE: "USER_CONTEXT_FREEZE",
WINDOW_FOCUS: "WINDOW_FOCUS",
SCROLL_ALLOW: "SCROLL_ALLOW",
SCROLL_BLOCK: "SCROLL_BLOCK",
SUGGEST_SHOW: "SUGGEST_SHOW",
SUGGEST_HIDE: "SUGGEST_HIDE",
SUGGEST_SHOWN: "SUGGEST_SHOWN",
SUGGEST_HIDDEN: "SUGGEST_HIDDEN",
NOTIFICATIONS_SHOW: "NOTIFICATIONS_SHOW",
NOTIFICATIONS_HIDE: "NOTIFICATIONS_HIDE",
NOTIFICATIONS_SHOWN: "NOTIFICATIONS_SHOWN",
NOTIFICATIONS_HIDDEN: "NOTIFICATIONS_HIDDEN",
SOCIAL_DATA_SUCCESS: "SOCIAL_DATA_SUCCESS",
UNREAD_COUNT_CHANGE: "UNREAD_COUNT_CHANGE",
UNREAD_NOTIFICATIONS_COUNT_CHANGE: "UNREAD_NOTIFICATIONS_COUNT_CHANGE",
MODEL_UPDATED: "MODEL_UPDATED",
USER_INTERACTION: "USER_INTERACTION",
USER_INTERACTION_PAUSE_PLAYBACK: "USER_INTERACTION_PAUSE_PLAYBACK",
COOKIES_ACCEPTED: "COOKIES_ACCEPTED",
LASTFM_CONNECT: "LASTFM_CONNECT",
APPLICATION_LOAD_TIME: "APPLICATION_LOAD_TIME",
APPLICATION_LOAD_STARTED: "APPLICATION_LOAD_STARTED"
};
Spotify.Web.BaseModalWindow = function(c, a) {
Spotify.Web.EventTarget.call(this);
var b = this,
d = !1,
f = !1,
c = c || {},
j = !1,
g = Spotify.Web.BrowserDetect.browser === "Explorer" && Spotify.Web.BrowserDetect.version < 10,
k = c.url,
l = c.id || null,
h = c.wrapper,
m = c.iframe,
n = function(a) {
//TODO add Try Catch. I think that assing a variable value inside of switch stament it's really good idea
if (a.source == m.contentWindow) switch (a = JSON.parse(a.data), a.type) {
case "POPUP_WINDOW_POSITION":
delete a.type;
b.position(a);
break;
case "POPUP_WINDOW_SHOW":
b.show();
break;
case "POPUP_WINDOW_CLOSE":
b.hide();
break;
case "POPUP_WINDOW_RESIZE":
b.resize(a.height,
a.width)
}
},
e = function(a) {
m.contentWindow.postMessage(JSON.stringify({
type: a
}), "*")
};
this.getFrame = function() {
return m || null
};
this.getElement = function() {
return h
};
this.getUrl = function() {
return k
};
this.isVisible = function() {
return j
};
this.initialize = function() {
this._initializeWindow()
};
this.show = function() {
this._showWindow()
};
this.hide = function() {
this._hideWindow()
};
this._initializeWindow = function() {
this.trigger("ON_BEFORE_INITIALIZE");
if (!k) throw Error("Application URL not specified.");
h || (h = document.createElement("div"));
if (!m) {
var e = document.createElement("iframe");
e.setAttribute("id", "app-" + k);
e.setAttribute("frameBorder", "no");
e.style.width = "100%";
e.style.height = "100%";
m = e;
h.appendChild(m)
}
c.loadAfter !== "ON_DEMAND" && setTimeout(function() {
b.load()
}, c.loadAfter);
a.subscribe(Spotify.Web.PublisherMessages.APPLICATION_LOAD_TIME, this);
a.subscribe(Spotify.Web.PublisherMessages.APPLICATION_STATE_CHANGED, this)
};
this.load = function() {
if (!d) a.notify(Spotify.Web.PublisherMessages.APPLICATION_LOAD_STARTED, {
uri: "spotify:app:" +
l,
start: (new Date).getTime()
}), m.src = k, window.addEventListener("message", n, !1), a.notify(Spotify.Web.PublisherMessages.APPLICATION_STATE_CHANGED, {
link: Spotify.Link.applicationLink(l),
iframe: m
}), d = !0, this.trigger("ON_AFTER_INITIALIZE")
};
this.onNotify = function(a) {
switch (a.messageType) {
case Spotify.Web.PublisherMessages.APPLICATION_STATE_CHANGED:
a.message.link.id != l && e(a.message.link.id);
break;
case Spotify.Web.PublisherMessages.APPLICATION_LOAD_TIME:
!f && a.message.uri === "spotify:app:" + l && (f = !0)
}
};
this._showWindow =
function(a) {
d || this.load();
if (f) {
if (!j) {
try {
j = !0;
this.trigger("ON_BEFORE_SHOW");
if (g) h.style.opacity = 1;
h.addClass("show");
h.addClass("scale-start");
setTimeout(function() {
h.addClass("scale-end")
}, 100);
Spotify.Web.Utils.addTransitionEndedListener(h, function() {
h.removeClass("scale-start").removeClass("scale-end")
}, 2E3);
Browser.firefox && this.getElement().id === c.id + "-area" && document.activeElement.blur();
e("WINDOW_FOCUS");
this.trigger("ON_SHOW")
} catch (l) {}
this.trigger("ON_AFTER_SHOW")
}
a && a()
} else setTimeout(function() {
b._showWindow(a)
},
200)
};
this._hideWindow = function() {
if (j) {
j = !1;
this.trigger("ON_BEFORE_HIDE");
h.removeClass("show");
if (g) h.style.opacity = 0;
this.trigger("ON_HIDE")
}
window.focus();
e("WINDOW_CLOSED");
this.trigger("ON_AFTER_HIDE")
}
};
Spotify.Web.LightboxWindow = function(c, a) {
Spotify.Web.BaseModalWindow.call(this, c, a);
var b = this;
this.initialize = function() {
this._initializeWindow();
this.getFrame();
var a = this.getElement(),
b = a.className.split(" ");
b.push("lightbox");
a.className = b.join(" ")
};
this.show = function(c) {
this._showWindow(function() {
a.notify(Spotify.Web.PublisherMessages.APPLICATION_STATE_CHANGED, {
link: c,
iframe: b.getFrame()
})
})
}
};
Spotify.Web.PopupWindow = function(c, a, b) {
Spotify.Web.BaseModalWindow.call(this, c, a);
var c = c || {},
d = null,
f = c.width || 220,
j = null,
g = {
url: c.url,
id: c.id || null,
wrapper: c.wrapper,
iframe: c.iframe,
preventScrolling: c.preventScrolling || !1,
hideOnWindowResize: c.hideOnWindowResize || !1,
postShowCallback: c.postShowCallback,
postHideCallback: c.postHideCallback,
persistent: c.persistent || !1,
loadAfter: c.loadAfter
};
this.initialize = function() {
this._initializeWindow();
if (g.hideOnWindowResize) this.onWindowResize = this.onWindowResize.bind(this),
window.addEventListener("resize", this.onWindowResize, !1);
this.bind("ON_BEFORE_SHOW", this._onBeforeShow, this)
};
this.onWindowResize = function() {
this.hide()
};
this.getWidth = function() {
return f
};
this.getHeight = function() {
return d
};
this.updateSize = function() {
if (this.isVisible()) g.wrapper.style.width = f + "px", g.wrapper.style.height = d + "px"
};
this.resize = function(a, b) {
d = a;
if (b && (f = b, j)) g.wrapper.style.left = j - b / 2 + "px";
this.updateSize()
};
this.position = function(a) {
if (!a.top && !a.bottom || !a.left && !a.right || a.top &&
a.bottom || a.left && a.right) throw Error("Must specify position with either top/bottom and either left/right");
var b, c, d, f, e = "top",
j = "left";
a.top ? b = a.top : (e = "bottom", c = a.bottom);
a.left ? d = a.left : (j = "right", f = a.right);
e == "top" ? (g.wrapper.style.bottom = "auto", g.wrapper.style.top = b + "px") : (g.wrapper.style.top = "auto", g.wrapper.style.bottom = c + "px");
j == "left" ? (g.wrapper.style.right = "auto", g.wrapper.style.left = d + "px") : (g.wrapper.style.left = "auto", g.wrapper.style.right = f + "px")
};
this._onBeforeShow = function() {
this.updateSize()
};
this.show = function(b, d) {
if (!this.isVisible()) {
this.trigger("onBeforeShow");
if (b) g.wrapper.style.left = b.left + "px", b.direction == b.popupBelow ? (g.wrapper.style.bottom = "auto", g.wrapper.style.top = b.top + "px") : (g.wrapper.style.top = "auto", g.wrapper.style.bottom = b.bottom + "px"), g.wrapper.className = "popup-area popover", g.wrapper.addClass(b.direction), b.arrow && g.wrapper.addClass(b.arrow), j = b.arrowLeft, b.arrow || g.wrapper.addClass("no-arrow");
this._showWindow(d);
c.showMessage && a.notify(c.showMessage);
g.preventScrolling &&
a.notify(Spotify.Web.PublisherMessages.SCROLL_BLOCK);
g.postShowCallback && g.postShowCallback();
this.trigger("onAfterShow")
}
};
this.hide = function() {
this.isVisible() && (this._hideWindow(), c.hideMessage && a.notify(c.hideMessage), g.postHideCallback && g.postHideCallback());
setTimeout(function() {
g.preventScrolling && !b.anyPopupVisible() && a.notify(Spotify.Web.PublisherMessages.SCROLL_ALLOW)
}, 250)
};
this.isPersistent = function() {
return g.persistent
}
};
Spotify.Web.PopupManager = function(c, a, b, d) {
var f = this,
j = {},
g = {},
k = !1,
l = d ? "arrow-top" : "top",
h = d ? "arrow-bottom" : "bottom",
m = function() {
k = !0
},
n = function() {
setTimeout(function() {
k = !1
}, 250)
};
this.createAndRegisterPopup = function(e, d) {
var h;
if (d.wrapper) h = d.wrapper;
else {
h = b.ownerDocument.createElement("div");
h.className = "popup-area";
h.setAttribute("id", e + "-area");
var l = b.ownerDocument.createElement("iframe");
l.setAttribute("id", e);
l.setAttribute("tabindex", "-1");
l.setAttribute("frameborder", "0");
l.setAttribute("scrolling",
"no");
l.setAttribute("allowTransparency", "true");
h.appendChild(l);
b.appendChild(h)
}
h = new Spotify.Web.PopupWindow({
url: c.getAppUrl("/" + e + "/"),
id: e,
wrapper: h,
iframe: d.iframe || h.querySelectorAll("iframe")[0],
hideMessage: d.hideMessage,
showMessage: d.showMessage,
preventScrolling: d.preventScrolling,
hideOnWindowResize: d.hideOnWindowResize,
width: d.width,
postHideCallback: d.postHideCallback,
loadAfter: d.loadAfter || 0
}, a, f);
h.resize(d.height || 200);
j[e] = h;
g[h.getFrame().id] = h;
h.bind("onBeforeShow", m);
h.bind("onAfterShow",
n);
return h
};
this.registerPopup = function(a, b) {
j[a] = b
};
this.anyPopupVisible = function() {
for (var a in j)
if (j[a].isVisible()) return !0;
return !1
};
this.initializePopups = function() {
for (var a in j) j[a].initialize()
};
this.popup = function(c, f, g) {
var k = j[c.id];
if (!k) throw Error("cannot find popup with id", c.id);
var m = k.getWidth(),
n, w, A, x = l,
u;
if (g) n = window.innerWidth / 2 - m / 2, w = 160;
else {
u = parseInt(c.args[0], 10);
var g = parseInt(c.args[1], 10),
y = parseInt(c.args[2], 10),
B = parseInt(c.args[3], 10);
if (!u || !g) throw Error("popup can only be triggered for popup URIs");
if (!f) throw Error("unknown origin");
f = Spotify.Web.Utils.getWindowPosition(f);
n = u + f.left;
w = g + f.top;
A = 0;
u = "middle";
var D = b.ownerDocument.body.offsetWidth;
n -= m / 2 - y / 2;
w += B + (d ? 0 : 10);
if (w + 300 > window.innerHeight) x = document.body, A = document.documentElement, A = Math.max(x.scrollHeight, x.offsetHeight, A.clientHeight, A.scrollHeight, A.offsetHeight) - (g + f.top) + 10, x = h;
n + m > D && (n = n - m / 2 + 15, u = "arrow-position-right")
}
c.args.splice(0, 4);
k.show({
left: n,
top: w,
bottom: A,
arrowLeft: n + m / 2,
direction: x,
arrow: u,
popupBelow: l
}, function() {
a.notify(Spotify.Web.PublisherMessages.APPLICATION_STATE_CHANGED, {
link: c,
iframe: k.getFrame()
})
})
};
this.closeAll = function() {
if (k) return !1;
for (var a in j) j[a].isVisible() && !j[a].isPersistent() && j[a].hide();
return !0
};
this.closeById = function(a) {
if (k) return !1;
j[a].isVisible() && j[a].hide();
return !0
};
this.onNotify = function(a) {
var b = a.message;
switch (a.messageType) {
case Spotify.Web.PublisherMessages.APPLICATION_SET_PREFERRED_SIZE:
if (a = g[b.origin.id]) a.resize(b.height, b.width), b.callback(b.width, b.height)
}
};
a.subscribe(Spotify.Web.PublisherMessages.APPLICATION_SET_PREFERRED_SIZE,
f)
};
Spotify.Web.Window = function(c) {
Spotify.Web.EventTarget.call(this);
var a = this,
c = c || {},
b = c.url,
d = c.iframe,
f = function(c) {
b.indexOf(c.origin) === 0 && c.origin !== "" && a.trigger("onMessage", c.data)
};
this.initialize = function() {
if (!b) throw Error("Application URL not specified.");
if (!d) {
var a = document.createElement("iframe");
a.setAttribute("frameBorder", "no");
a.style.width = "100%";
a.style.height = "100%";
d = a
}
window.addEventListener("message", f);
a = "app-" + Spotify.Web.Utils.appNameFromUrl(b);
d.setAttribute("id", a);
d.src = b
};
this.getElement = function() {
return d
};
this.getUrl = function() {
return b
};
this.show = function() {
d.style.display = "block"
};
this.hide = function() {
d.style.display = "none"
}
};
Spotify.Web.URLParser = function() {
var c = {},
a = /^(?:(\w+):)?(?:\/\/(?:(?:([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#]*)(?::(\d*))?)?(\.\.?$|(?:[^?#\/]*\/)*)([^?#]*)(?:\?([^#]*))?(?:#(.*))?/;
c.parseURL = function(b, c) {
var b = c ? b.match(a) : decodeURI(b).match(a),
f = {
protocol: b[1] || null,
user: b[2] || null,
domain: b[4] || null,
query: b[8] || null,
port: b[5] || null,
hash: b[9] || null,
path: ((b[6] || "") + (b[7] || "")).replace(/^\/|\/$/g, "") || null,
url: b[0]
};
if (f.path) f.pathSegments = f.path.replace(/^\/|\/$/g, "").split("/");
if (f.hash) f.hashSegments =
f.hash.replace(/^\/|\/$/g, "").split("/");
if (f.query) {
f.params = {};
for (var j = /([^=&]+)\=([^=&]+)/g, g = j.exec(f.query); g;) f.params[g[1]] = g[2], g = j.exec(f.query)
}
return f
};
c.isRoot = function(a) {
return (a = c.parseURL(a)) && a.path === null
};
return c
}();
Spotify.Web.Notification = function(c) {
Spotify.Web.EventTarget.call(this);
var c = c || {},
a = c.message || "",
b = c.id || null,
d = c.timeout,
f = this,
j = null;
this.initialize = function() {
j = document.createElement("div");
var b = document.createElement("p");
b.innerHTML = a;
var c = document.createElement("div");
c.onclick = function() {
f.trigger("onclose", {})
};
j.appendChild(b);
j.appendChild(c)
};
this.getElement = function() {
return j
};
this.getId = function() {
return b
};
this.getTimeout = function() {
return d
};
this.setWidth = function(a) {
j.style.width =
"" + a + "px";
j.style.position = "relative";
j.style.left = [300 - a, "px"].join("")
}
};
Spotify.Web.NotificationArea = function(c) {
var c = c || {},
a = c.element || {},
b = null,
d = [],
f = {},
j = function(a) {
if (a) return f[a]
},
g = function(a) {
var c = d.indexOf(a);
c > -1 && (d.splice(c, 1), b.removeChild(a.getElement()), a.getId() && delete f[a.getId()])
},
k = function(a) {
d.push(a);
b.appendChild(a.getElement());
a.getId() && (f[a.getId()] = a);
a.getTimeout() && setTimeout(function() {
g(a)
}, a.getTimeout())
};
this.initialize = function() {
b = a;
if (b === null) throw Error("Spotify.Web.NotificationArea element not found");
};
this.show = function(a) {
var b;
b = j(a.id);
if (!b) return b = new Spotify.Web.Notification(a), b.initialize(), a.width && b.setWidth(a.width), b.bind("onclose", function(a) {
g(a.sender)
}), k(b), b
};
this.hide = function(a) {
(a = j(a)) && g(a)
}
};
Spotify.Web.Dialog = function(c) {
var c = c || {},
a = c.element,
b = !1,
d = function() {
f()
},
f;
this.initialize = function() {
if (!a) throw Error("Spotify.Web.Dialog element not specified");
a.querySelector("button").onclick = d
};
this.show = function(c) {
var d = a.querySelector("p");
d.innerHTML = c.message;
d.className = c.className;
var d = a.querySelector("button"),
k = a.querySelector(".buttonContainer");
c.button ? (d.innerHTML = c.button, f = c.action, k.style.display = "block") : k.style.display = "none";
a.style.display = "block";
b = !0
};
this.hide =
function() {
a.style.display = "none";
b = !1
};
this.isVisible = function() {
return b
}
};
Spotify.Web.ErrorTypes = {
SESSION_LOST: "SESSION_LOST",
TOKEN_LOST: "TOKEN_LOST",
NO_SOUND_CAPABILITIES: "NO_SOUND_CAPABILITIES",
AD_BLOCK_DETECTED: "AD_BLOCK_DETECTED",
CONNECTION_RESTORED: "CONNECTION_RESTORED",
HEARTBEAT: "HEARTBEAT",
CONNECTION_LOST: "CONNECTION_LOST",
CONNECTING: "CONNECTING",
TRACK_NOT_PLAYABLE: "TRACK_NOT_PLAYABLE",
TRACK_NOT_PLAYABLE_TRACK_CAP: "TRACK_NOT_PLAYABLE_TRACK_CAP",
TRACK_NOT_PLAYABLE_TIME_CAP: "TRACK_NOT_PLAYABLE_TIME_CAP",
WAIT_FOR_COMMERCIAL_TO_FINISH: "WAIT_FOR_COMMERCIAL_TO_FINISH",
FLASH_NOT_AVAILABLE: "FLASH_NOT_AVAILABLE",
FB_CONNECTING_TO: "FB_CONNECTING_TO",
FB_CONNECTION_FAILED: "FB_CONNECTION_FAILED",
APPLICATION_RELOAD_NEEDED: "APPLICATION_RELOAD_NEEDED",
UNCAUGHT_EXCEPTION: "UNCAUGHT_EXCEPTION",
CANNOT_CONNECT_TO_STREAMING_SERVER: "CANNOT_CONNECT_TO_STREAMING_SERVER",
BOOKMARK: "BOOKMARK"
};
Spotify.Web.ErrorMessages = {
FLASH_NOT_AVAILABLE: {
message: _("To enjoy Spotify, please install Adobe Flash. It's free."),
className: "normal",
button: _("Get Flash"),
action: function() {
window.open("http://get.adobe.com/flashplayer/")
}
},
SESSION_LOST: {
message: _("Session lost. Please login again."),
className: "normal",
button: _("Login"),
action: function() {
location.href = "/login/"
}
},
NO_SOUND_CAPABILITIES: {
message: _("Your computer doesn't support audio."),
className: "normal",
button: _("Exit"),
action: function() {
window.open("/login/")
}
},
APPLICATION_RELOAD_NEEDED: {
message: _("There's a new version of Spotify available. Please reload the page."),
className: "normal",
button: _("Reload"),
action: function() {
window.location.reload()
}
},
CONNECTING: {
message: _("Connecting to Spotify{{LOADER}}", {
LOADER: '...<br /><span class="indicator"></span>'
}),
className: "indicator"
},
FB_CONNECTING_TO: {
message: _("Connecting to Facebook{{LOADER}}", {
LOADER: '...<br /><span class="indicator"></span>'
}),
className: "indicator"
},
FB_CONNECTION_FAILED: {
message: _("We're sorry but connection to Facebook is not working. Please, try to {{LINK_START}}login using the main page{{LINK_END}}.", {
LINK_START: '<a href="/">',
LINK_END: "</a>"
}),
className: "indicator"
}
};
Spotify.Web.Error = function(c, a) {
var c = c || {},
b = c.publisher,
d = c.element,
f = c.dialog,
j = c.timeout,
g = null,
k = null;
this.initialize = function() {
if (!b) throw Error("Spotify.Web.Error - Publisher instance is missing");
if (!d) throw Error("Spotify.Web.Error container not specified");
if (!f) throw Error("Spotify.Web.Error dialog element not specified");
g = new Spotify.Web.NotificationArea({
element: d
});
g.initialize();
k = new Spotify.Web.Dialog({
element: f
});
k.initialize();
b.subscribe(Spotify.Web.PublisherMessages.ERROR, this)
};
this.onNotify = function(b) {
var b = b.message,
c = Spotify.Web.ErrorTypes,
d = Spotify.Web.ErrorMessages;
switch (b.type) {
case c.TRACK_NOT_PLAYABLE:
switch (b.response) {
case "Rate limit reached":
c = _("Sorry, but you've reached your track limit.");
break;
case "Song only on storage":
c = _("Sorry, but this track is not yet available.");
break;
case "Track restricted":
c = _("Sorry, but this track is not yet available in your country.");
break;
default:
c = _("Track is currently not available")
}
g.show({
message: c,
id: b.type + "_" + b.trackUri,
timeout: j
});
break;
case c.TRACK_NOT_PLAYABLE_TRACK_CAP:
g.show({
message: _("You've reached the limit of how many times you can listen to this track. This means you won't be able to play this track from our catalogue unless you {{LINK_START}}upgrade{{LINK_END}} your Spotify account.", {
LINK_START: '<a href="/redirect/www/account-page/" target="_blank">',
LINK_END: "</a>"
}),
id: b.type,
timeout: j + 2E4
});
break;
case c.TRACK_NOT_PLAYABLE_TIME_CAP:
c = "You've used all your free hours for this week. This means you won't be able to play music from our catalogue until next week unless you {{LINK_START}}upgrade{{LINK_END}} your Spotify account.";
a.isAnonymous() ? a.limitedFeatureCalled("time_cap") : g.show({
message: _(c, {
LINK_START: '<a href="/redirect/www/account-page/" target="_blank">',
LINK_END: "</a>"
}),
id: b.type,
timeout: j + 2E4
});
break;
case c.WAIT_FOR_COMMERCIAL_TO_FINISH:
c = _("This song will be played after this commercial");
g.show({
message: c,
id: b.type,
timeout: j
});
break;
case c.SESSION_LOST:
k.show(d.SESSION_LOST);
break;
case c.TOKEN_LOST:
c = _("Spotify has been paused because your account is in use somewhere else.");
g.show({
message: c,
id: "token_lost",
timeout: j
});
break;
case c.AD_BLOCK_DETECTED:
c = _("For the best Spotify experience, please disable adblock.");
g.show({
message: c,
id: "adblocker_detected",
timeout: j + 1E4
});
break;
case c.BOOKMARK:
c = _("<strong>Drag this button to your Bookmarks Bar</strong> for an easy way to get back to the Spotify Web Player:");
c += '<a id="bookmark-btn" href="https://play.spotify.com/?utm_source=web-player&utm_campaign=bookmark" onclick="return false;">' + _("Spotify Web Player") + "</a>";
g.show({
message: c,
id: "bookmark_notification",
timeout: j + 2E4,
width: 370
});
break;
case c.CANNOT_CONNECT_TO_STREAMING_SERVER:
c = _("Sorry, but it seems that we cannot stream music to you at this time. This is probably because of restrictions placed on your network, but we are working on ways to get around this");
g.show({
message: c,
id: "cannot_connect_to_streaming_service",
timeout: j + 2E4
});
break;
case c.NO_SOUND_CAPABILITIES:
k.show(d.NO_SOUND_CAPABILITIES);
break;
case c.FLASH_NOT_AVAILABLE:
k.show(d.FLASH_NOT_AVAILABLE);
break;
case c.APPLICATION_RELOAD_NEEDED:
k.show(d.APPLICATION_RELOAD_NEEDED);
break;
case c.CONNECTION_LOST:
b = b.reason;
switch (b) {
case "Invalid user":
b = _("ap/error/invalid_user") + "<br/><br/>";
break;
case "Region mismatch":
b = _("ap/error/region_mismatch", {
ACCOUNT_URL: "/redirect/www/account-page/",
UPGRADE_URL: "/redirect/www/upgrade-product/"
}) + "<br/><br/>"
}
b = {
message: _("Can't connect to Spotify. {{REASON}}Trying again now{{LOADER}}", {
LOADER: '...<br /><span class="indicator"></span>',
REASON: b
}),
className: "indicator"
};
k.show(b);
break;
case c.CONNECTING:
k.show(d.CONNECTING);
break;
case c.FB_CONNECTING_TO:
k.show(d.FB_CONNECTING_TO);
break;
case c.FB_CONNECTION_FAILED:
k.hide();
k.show(d.FB_CONNECTION_FAILED);
break;
case c.CONNECTION_RESTORED:
k.hide();
break;
default:
g.hide(b.type)
}
}
};
Spotify.Web.FeatureDetect = new function() {
return {
testWebSockets: function() {
return window.WebSocket
},
testHTML5Audio: function() {
var c = document.createElement("audio");
return !(!c.canPlayType || !c.canPlayType("audio/mpeg;").replace(/no/, ""))
},
getFlashVersion: function() {
return swfobject.getFlashPlayerVersion()
},
hasFlashMin: function() {
return swfobject.hasFlashPlayerVersion("9")
},
adBlockCheck: function() {
var c = document.getElementById("ads");
if (c) {
if (c.offsetHeight === 0) return !0
} else return !0;
document.body.removeChild(c);
return !1
}
}
};
Spotify.Web.Menu = function(c, a, b) {
Spotify.Web.EventTarget.call(this);
var d = this,
c = c || {},
f = c.publisher,
j = c.container,
g = c.features || {},
k = [],
l = !1,
h = null,
m = null,
n = null,
e = null,
o = c.container.querySelector("#nav-items"),
t = j.ownerDocument,
C = c.cat ? "active" : "current",
v = function(a) {
a || (a = "");
for (var c = 0; c < k.length; c++) b(k[c]).toggleClass(C, k[c].getAttribute("id") == "nav-" + a)
},
z = function(a) {
a.onmousedown = function() {
if (l) {
var b = a.getAttribute("data-href");
d.trigger("onAppOpen", {
id: b
})
}
}
},
w = function() {
l = !0;
for (var a =
0; a < k.length; a++) b(k[a]).removeClass("disabled")
},
A = function(a) {
if (!m) return !1;
if (!e && a.image !== "") {
var d = new Image;
d.onload = function() {
c.cat || m.appendChild(this);
setTimeout(function() {
c.cat ? b(m).getElement(".media-image-internal").style.backgroundImage = "url(" + d.src + ")" : d.className = "show"
}, 10)
};
e = a.image;
if (typeof e === "string") e = e.replace("http://profile.ak.fbcdn.net", "https://fbcdn-profile-a.akamaihd.net"), d.src = e
}
if (!n && a.name !== "") c.cat ? b(m).getElement(".name").innerHTML = a.name : m.textContent = a.name,
n = a.name;
n && e && (m.parentNode.className += " show")
},
x = function(a, b, c, e, d) {
var h = t.createElement("a"),
f = t.createElement("span");
f.className = "nav-text";
h.setAttribute("data-href", b);
h.id = "nav-" + a;
b = d ? "" : " spoticon-" + a + "-32";
a === "settings" && (b = " spoticon-" + a + "-16");
a === "messages" && (b = " spoticon-inbox-32");
h.className = "disabled" + b + (e ? "" : " standard-menu-item");
f.innerHTML = c || "";
h.appendChild(f);
k.push(h);
a = t.createElement("li");
if (typeof e !== "undefined") a.className = e;
a.appendChild(h);
o.appendChild(a);
return a
},
u = function() {
x("search", "suggest", _("Search"));
g.browse && x("browse", "browse", _("Browse"));
x("radio", "radio", _("Radio"));
g.collection ? x("collection", "collection", _("Your Music")) : x("playlist", "playlist", _("Playlists"));
a.onSignedIn(function() {
g.follow && x("follow", "follow", _("Follow"));
var a;
a = !c.cat ? _("Me") : '<div class="media simple user"> <div class="media-image"> <div class="media-placeholder"> <span class="icon"></span> </div> <div class="media-image-internal"></div> </div></div><div class="name">' +
_("Me") + "</div>";
a = g.profile ? x("profile", "user", a, "item-profile etched-top", !0) : x("profile", "playlist", a, "item-profile etched-top", !0);
(g.messaging || g.notifications) && a.addClass("has-extra-bottom-row");
g.messaging && (a = x("messages", "messages", null, "messages-link"), g.notifications || a.addClass("alone-item"));
g.notifications && (a = x("notifications", "notification-center", null, "item-notifications"), g.messaging || a.addClass("alone-item"))
});
x("settings", "settings", null, "settings-link clearfix")
},
y = function(a,
b) {
var e = o.querySelector(a);
if (e)
if (c.cat) e.textContent = b;
else {
var d = e.querySelector(".badge");
if (!d) d = document.createElement("span"), d.className = "badge", e.appendChild(d);
b ? (d.textContent = b, d.addClass("badge-lit")) : d.removeClass("badge-lit")
}
};
this.initialize = function() {
if (!f) throw Error("Publisher instance not specified.");
u();
f.subscribe(Spotify.Web.PublisherMessages.APPLICATION_STATE_CHANGED, this);
f.subscribe(Spotify.Web.PublisherMessages.APPLICATION_ENABLED, this);
f.subscribe(Spotify.Web.PublisherMessages.SUGGEST_SHOWN,
this);
f.subscribe(Spotify.Web.PublisherMessages.SUGGEST_HIDDEN, this);
f.subscribe(Spotify.Web.PublisherMessages.NOTIFICATIONS_SHOWN, this);
f.subscribe(Spotify.Web.PublisherMessages.NOTIFICATIONS_HIDDEN, this);
f.subscribe(Spotify.Web.PublisherMessages.SOCIAL_DATA_SUCCESS, this);
f.subscribe(Spotify.Web.PublisherMessages.UNREAD_COUNT_CHANGE, this);
f.subscribe(Spotify.Web.PublisherMessages.UNREAD_NOTIFICATIONS_COUNT_CHANGE, this);
f.subscribe(Spotify.Web.PublisherMessages.APPLICATION_POST_MESSAGE, this);
for (var b =
0; b < k.length; b++) k[b].id === "nav-profile" && (m = k[b]), z(k[b]);
c.container.querySelector("#logo").addEventListener("click", function(a) {
a.preventDefault();
d.trigger("onAppOpen", {
id: g.browse ? "browse" : "home"
})
});
this.bind("onAppOpen", function(b) {
b = b.params.id;
b === "settings" && a.isAnonymous() ? c.settingsView.toggleOpenClose() : c.router.openUri(Spotify.Link.fromString("spotify:app:" + b).toAppLink())
})
};
this.highlightMenu = function(a) {
h = a;
v(a)
};
this.onNotify = function(a) {
switch (a.messageType) {
case Spotify.Web.PublisherMessages.SUGGEST_SHOWN:
v("search");
break;
case Spotify.Web.PublisherMessages.SUGGEST_HIDDEN:
v(h);
break;
case Spotify.Web.PublisherMessages.NOTIFICATIONS_SHOWN:
v("notifications");
break;
case Spotify.Web.PublisherMessages.NOTIFICATIONS_HIDDEN:
v(h);
break;
case Spotify.Web.PublisherMessages.APPLICATION_ENABLED:
w();
break;
case Spotify.Web.PublisherMessages.SOCIAL_DATA_SUCCESS:
A(a.message);
break;
case Spotify.Web.PublisherMessages.UNREAD_COUNT_CHANGE:
y("#nav-messages", a.message.count);
break;
case Spotify.Web.PublisherMessages.UNREAD_NOTIFICATIONS_COUNT_CHANGE:
y("#nav-notifications",
a.message.count)
}
};
this.setUpgradeButton = function(a) {
if (typeof this._upgradeButton === "undefined") this._upgradeButton = document.createElement("a"), this._upgradeButton.className = "upgrade", c.container.querySelector(".item-profile").appendChild(this._upgradeButton);
this._upgradeButton.textContent = a;
this._upgradeButton.setAttribute("data-href", "purchase");
this._upgradeButton.setAttribute("id", "nav-purchase");
z(this._upgradeButton)
};
this.disable = function() {
l = !1;
for (var a = 0; a < k.length; a++) b(k[a]).addClass("disabled")
};
this.enable = function() {
w()
};
this.getNavItemElements = function() {
return k
}
};
Spotify.Web.Credentials = function(c, a) {
var b = this,
d = null,
f = 0;
this.cache = function(a, b) {
f = (new Date).getTime() + b * 1E3;
d = a
};
this.get = function(j, g) {
var k = (new Date).getTime();
d && f > k ? j(d) : (new Request({
url: c,
method: "post",
onSuccess: function(a) {
var c = {};
try {
c = JSON.parse(a)
} catch (d) {}!c.config || !c.config.credentials ? g() : (b.cache(c.config.credentials[0], c.config.credentials[1]), j(c.config.credentials[0]))
},
onFailure: g,
onException: g
})).send("secret=" + a)
};
this.dispose = function() {
f = 0;
d = null
}
};
Spotify.Web.WebTracker = {
_config: {},
setConfig: function(c) {
this._config = c
},
log: function(c, a) {
if (typeof c == "object") {
postData = [];
for (var b in c) c.hasOwnProperty(b) && postData.push(encodeURIComponent(b) + "=" + encodeURIComponent(c[b]));
c = postData.join("&")
}
b = this.basic(this._config);
c = !c ? b : c + "&" + b;
b = new XMLHttpRequest;
b.open("POST", "/xhr/json/log.php", a || !0);
b.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
b.send(c)
},
basic: function(c) {
var a = [];
c.flow && a.push("f=" + c.flow);
c.source && a.push("s=" +
c.source);
c.landingURL && a.push("landingURL=" + c.landingURL);
c.referrer && a.push("referrer=" + c.referrer);
return a.join("&")
}
};
Spotify.Web.Tracking = function(c, a, b, d) {
this.LIMIT_PER_TYPE = 5;
var f = {},
j = !0;
window._gaq = window._gaq || [];
var g = this;
this.initialize = function(d) {
if (b.gaId) {
_gaq.push(["_setAccount", b.gaId]);
typeof d == "string" && _gaq.push(["_trackPageview", d]);
a.loadScript("//stats.g.doubleclick.net/dc.js");
var d = c.subscribe,
f = Spotify.Web.PublisherMessages;
d(f.APPLICATION_STATE_PUSH, this);
d(f.ERROR, this);
d(f.CHROME_READY, this);
d(f.WINDOW_FOCUS, this)
}
};
this.onNotify = function(a) {
var b = a.message,
c = Spotify.Web.PublisherMessages;
switch (a.messageType) {
case c.APPLICATION_STATE_PUSH:
this.pageView(b.url);
break;
case c.WINDOW_FOCUS:
this.event("Window", a.messageType, b.type, 0, !0);
break;
case c.CHROME_READY:
this.xhrLog(a.messageType);
break;
case c.ERROR:
this.errors(b)
}
};
this.pageView = function(a) {
_gaq.push(["_trackPageview", a]);
!j && window.dataLayer && window.dataLayer.push({
event: "page_view"
});
j = !1
};
this.event = function(a, b, c, d, f) {
_gaq.push(["_trackEvent", a, b, c, d, f])
};
this.handleException = function(a, b, c, f, j) {
b = escape(b) + "/" + escape(f) + "/" +
j + "/" + d.getAddressBarUrl();
g.event("exception", a, b, void 0, !0)
};
this.xhrLog = function(a) {
if (typeof f[a] === "undefined") f[a] = 1;
else {
if (f[a] >= g.LIMIT_PER_TYPE) return;
f[a]++
}
a = {
type: a,
t: (new Date).getTime()
};
Spotify.Web.WebTracker.log(a)
};
this.errors = function(a) {
var b = "",
c = "",
b = Spotify.Web.ErrorTypes,
d = a.type;
switch (d) {
case b.CONNECTING:
case b.CONNECTION_LOST:
case b.CONNECTION_RESTORED:
b = "ap";
break;
case b.FLASH_NOT_AVAILABLE:
b = "browser";
break;
case b.APPLICATION_RELOAD_NEEDED:
b = "server";
break;
case b.TRACK_NOT_PLAYABLE:
case b.CANNOT_CONNECT_TO_STREAMING_SERVER:
b =
"playback";
c = a.trackUri || "";
break;
case b.FB_CONNECTING_TO:
case b.FB_CONNECTION_FAILED:
b = "fb";
break;
default:
b = "general"
}
if (b === "ap") return !1;
c !== "" && (d += "/" + c);
this.event("error", b, d, void 0, !0)
}
};
Spotify.Web.ConsoleLogger = function() {
this.enabled = !0;
this.fallbackToAlert = !1;
this.consoleUnavailable = typeof console === "undefined" || typeof console.log === "undefined"
};
Spotify.Web.ConsoleLogger.prototype.log = function(c) {
this._writeOut("log", c)
};
Spotify.Web.ConsoleLogger.prototype.dir = function(c) {
this._writeOut("dir", c)
};
Spotify.Web.ConsoleLogger.prototype.warn = function(c) {
this._writeOut("warn", c)
};
Spotify.Web.ConsoleLogger.prototype.error = function(c) {
this._writeOut("error", c)
};
Spotify.Web.ConsoleLogger.prototype.info = function(c) {
this._writeOut("info", c)
};
Spotify.Web.ConsoleLogger.prototype._writeOut = function(c, a) {
if (this.enabled)
if (!this.consoleUnavailable && console[c]) console[c](a);
else this.fallbackToAlert && alert(a)
};
Spotify.Web.ClientEventLogger = function(c) {
this.log = function(a, b) {
b || (b = function() {});
c.logging.logClientEvent({
source: a.source,
appVersion: a.source_version,
appVendor: a.source_vendor,
args: ["", a.event, a.event_version || null, a.test_version || null, a.data]
}, b)
}
};
Spotify.Web.AppLogger = function(c, a, b) {
this._apps = {};
this._maxApps = 15;
this._sessionID = a;
this._router = b;
this._applicationReadyLogged = !1;
this._logToAp = function(a, b) {
var j = Array.prototype.slice.call(arguments);
typeof a === "undefined" || typeof b === "undefined" || c.log.apply(c, j)
};
this._logElapsedTime = function(a, b) {
this._logToAp(244, 1, this._sessionID, a, b)
}
};
Spotify.Web.AppLogger.prototype.loadingStart = function(c) {
var a = 0,
b = !1,
d;
for (d in this._apps)
if (this._apps.hasOwnProperty(d)) {
if (!b || this._apps[d].msStart < this._apps[b].msStart) b = d;
a++
}
b && a > this._maxApps && delete this._apps[b];
this._apps[c.uri] = {
msStart: c.start,
intent: 0
}
};
Spotify.Web.AppLogger.prototype.loadingTime = function(c) {
var a;
if (c.complete) this.completeLogging(c);
else {
a = this._apps[c.uri];
if (!a || !a.msStart) return !1;
a.containerInit = c.start - a.msStart;
a.containerReady = c.end - a.msStart
}
};
Spotify.Web.AppLogger.prototype.completeLogging = function(c) {
var a;
a = this._apps[c.uri];
if (!a || !a.msStart) return delete this._apps[c.uri], !1;
a.appReady = c.complete - a.msStart;
this._logElapsedTime("stitch-startup/intent/" + c.uri, 0);
a.containerInit && this._logElapsedTime("stitch-startup/container-initialized/" + c.uri, a.containerInit);
a.containerReady && this._logElapsedTime("stitch-startup/container-ready/" + c.uri, a.containerReady);
if (a.appReady) {
var b = this._router.getInitialUrl();
if (!this._applicationReadyLogged &&
b && window.spperformance && c.uri === b.toURI()) this._applicationReadyLogged = !0, window.spperformance.authenticated && (b = (new Date).getTime() - window.spperformance.page_received, this._logElapsedTime("web-player/application-ready/" + c.uri, b));
this._logElapsedTime("stitch-startup/app-ready/" + c.uri, a.appReady)
}
delete this._apps[c.uri]
};
Spotify.Web.Services = function(c, a) {
var b, d, f, j = [],
g = [],
k = !1,
l = !1,
h = function(a) {
j ? (j.push(a), k || (k = !0, o())) : a(d)
},
m = function(a) {
g ? (g.push(a), l || (l = !0, t())) : a(f)
},
n = function(a) {
d = a;
for (var b = 0, c = j.length; b < c; b++) j[b](a);
j = null
},
e = function(a) {
f = a;
for (var b = 0, c = g.length; b < c; b++) g[b](a);
g = null
},
o = function() {
c.hermes.load_schema("message ListRequest {\n optional int32 limit = 1;\n optional string lastId = 2; \n optional int64 lastTimestamp = 3;}\nmessage DirectMessage {\n optional string id = 1;\n optional int64 timestamp = 2;\n optional string text = 3;\n optional string attachment = 4;\n optional string sender = 5;\n}\nmessage Conversation {\n optional string id = 1;\n optional bool read = 2;\n repeated string users = 3;\n optional DirectMessage preview = 4;\n optional string readUntil = 5;\n}\nmessage ConversationList {\n optional int32 unread = 1;\n optional int32 total = 2;\n repeated Conversation threads = 3;\n}\nenum EventType {\n UNKNOWN = 0;\n NEW_MESSAGE = 1;\n READ_CONVERSATION = 2;\n UNREAD_COUNT_CHANGE = 3;\n}\nmessage MessagingEvent {\n optional EventType type = 1;\n optional NewMessageEvent newMessage = 2;\n optional ReadConversationEvent readConversation = 3;\n optional UnreadCountChangeEvent unreadCountChange = 4;\n}\nmessage NewMessageEvent {\n optional Conversation conversation = 1;\n optional bool wasRead = 2;\n}\nmessage ReadConversationEvent {\n optional string user = 1;\n optional string conversationId = 2;\n optional string messageId = 3;\n}\nmessage UnreadCountChangeEvent {\n optional int32 delta = 1;\n optional int32 total = 2;\n}",
n)
},
t = function() {
c.hermes.load_schema("enum SocialReactionType {\n UNKNOWN_SOCIAL_REACTION = 0;\n LIKED_SOCIAL_REACTION = 1;\n STREAMED_SOCIAL_REACTION = 2;\n RESHARED_SOCIAL_REACTION = 3;\n}\nenum BouncerStoryType {\n FOLLOWED_PROFILE_BOUNCER_STORY = 0;\n PUBLISHED_PLAYLIST_BOUNCER_STORY = 1;\n FOLLOWED_PLAYLIST_BOUNCER_STORY = 2;\n SHARED_URI_BOUNCER_STORY = 3;\n}\nmessage SocialReactionObject {\n optional SocialReactionType reaction = 1;\n optional string story_creator = 2;\n optional string story_id = 3;\n optional BouncerStoryType story_type = 4;\n optional string item_uri = 5;\n optional int64 reaction_time_ms = 6;\n}\nenum AppType {\n TYPE_UNKNOWN_APP = 0;\n TYPE_IOS_APP = 1;\n TYPE_ANDROID_APP = 2;\n TYPE_LINK_APP = 3;\n TYPE_MFT_LAUNCH = 4;\n TYPE_MFT_REMINDER = 5;\n TYPE_MFT_SEASON = 6;\n}\nmessage User {\n optional string canonical_username = 1;\n optional string real_name = 2;\n}\nmessage PlaylistSubObject {\n optional string uri = 1;\n optional User owner = 2;\n optional User profile_user = 4;\n}\nmessage TrackAddObject {\n optional int32 track_count = 1;\n optional string uri = 2;\n repeated string track_uri = 3;\n}\nmessage AlbumReleaseObject {\n optional string album_gid = 1;\n optional string artist_gid = 2;\n optional string album_name = 3;\n optional string artist_name = 4;\n optional string track_gid = 5;\n optional string track_name = 6;\n optional bool exclusive = 7;\n}\nmessage ApplicationReleaseObject {\n optional AppType app = 1;\n optional string uri = 2;\n optional string image_url = 3;\n optional bool new_app = 4;\n}\nmessage MessagePlayedObject {\n optional string thread_id = 1;\n optional string message_id = 2;\n optional string attachment_uri = 3;\n optional User user = 4;\n}\nmessage InClientNotificationData {\n optional int32 version = 1;\n optional NotificationState state = 2;\n repeated User subject = 4;\n optional int32 subject_total = 5;\n optional string notification_verb = 6;\n repeated PlaylistSubObject playlist_sub_object = 8;\n repeated TrackAddObject track_add_object = 10;\n repeated AlbumReleaseObject album_release_object = 11;\n repeated ApplicationReleaseObject application_release_object=12;\n repeated SocialReactionObject social_reaction_object = 13;\n repeated MessagePlayedObject message_played_object = 14;\n}\nenum NotificationType {\n TYPE_UNKNOWN_NOTIFICATION = 0;\n TYPE_RESET_NOTIFICATION = 1;\n TYPE_IN_CLIENT_NOTIFICATION = 5;\n}\nmessage Notification {\n optional int32 version = 1;\n optional NotificationType type = 2;\n optional InClientNotificationData in_client_data = 5;\n optional bool dry = 7;\n}\nmessage NotificationState {\n optional bool seen = 2;\n optional bool dismissed = 3;\n optional bool followed_through = 4;\n optional string notification_id_hex = 5;\n optional string state_id_hex = 6;\n optional int64 notification_id_ms = 10;\n optional int64 state_id_ms = 11;\n}\nmessage NotificationList {\n repeated Notification notification = 1;\n}\nmessage NotificationStateList {\n repeated NotificationState state = 1;\n}\nmessage NotificationCounts {\n optional int32 version = 1;\n optional int32 active = 2;\n}\n",
e)
};
this.getAlbumForTrack = function(a, b) {
c.request("track_metadata", [a], function(a, c) {
a ? b(null) : b(c.album.uri)
})
};
this.getTrackIndexInAlbum = function(a, b, e) {
var d = "spotify:track:" + b;
c.request("album_tracks_snapshot", [{
type: "list",
uri: a
}, 0, -1], function(a, b) {
a ? e(-1) : e(b.array.indexOf(d))
})
};
this.getTrackIndexInPlaylist = function(a, b, e) {
var d = [],
h, f = 0,
g = function(a, j, k) {
c.request("playlist_tracks_snapshot", [{
type: "list",
uri: a
}, j, k], function(c, j) {
c ? e(-1) : (d = d.concat(j.array), h = d.indexOf("spotify:track:" +
b), h !== -1 ? (e(h), d = null) : (f += j.array.length, f >= j.length ? e(0) : g(a, f, -1)))
})
};
g(a, 0, -1)
};
o();
t();
this.getUnreadThreadsCount = function(a) {
c.hermes.request("hm://messaging/threads", "GET", [{
limit: 0
}], ["ListRequest"], ["ConversationList"], "message ListRequest {\n optional int32 limit = 1;\n optional string lastId = 2; \n optional int64 lastTimestamp = 3;}\nmessage DirectMessage {\n optional string id = 1;\n optional int64 timestamp = 2;\n optional string text = 3;\n optional string attachment = 4;\n optional string sender = 5;\n}\nmessage Conversation {\n optional string id = 1;\n optional bool read = 2;\n repeated string users = 3;\n optional DirectMessage preview = 4;\n optional string readUntil = 5;\n}\nmessage ConversationList {\n optional int32 unread = 1;\n optional int32 total = 2;\n repeated Conversation threads = 3;\n}\nenum EventType {\n UNKNOWN = 0;\n NEW_MESSAGE = 1;\n READ_CONVERSATION = 2;\n UNREAD_COUNT_CHANGE = 3;\n}\nmessage MessagingEvent {\n optional EventType type = 1;\n optional NewMessageEvent newMessage = 2;\n optional ReadConversationEvent readConversation = 3;\n optional UnreadCountChangeEvent unreadCountChange = 4;\n}\nmessage NewMessageEvent {\n optional Conversation conversation = 1;\n optional bool wasRead = 2;\n}\nmessage ReadConversationEvent {\n optional string user = 1;\n optional string conversationId = 2;\n optional string messageId = 3;\n}\nmessage UnreadCountChangeEvent {\n optional int32 delta = 1;\n optional int32 total = 2;\n}",
function(b, c) {
b ? a(null) : c.result ? a(c.result[0].unread) : a(null)
})
};
this.onMessagingUnreadCountChange = function(a) {
var b = this,
c = 0;
this.getUnreadThreadsCount(function(e) {
c = e;
a(c);
b.subscribeMessagingEvents(function(b, e) {
var d = e[0];
if (d.type == "UNREAD_COUNT_CHANGE") {
d = d.unreadCountChange;
if ("total" in d) c = d.total;
"delta" in d && (c += d.delta);
a(c)
}
})
})
};
this.subscribeMessagingEvents = function(b) {
this.getUsername(function(c) {
var d = encodeURIComponent(c);
h(function(c) {
a.subscribe("hm://messaging/user/" + d, [], [], [c + "#MessagingEvent"], function() {}, function() {}, b, null)
})
})
};
this.getUnreadNotificationsCount = function(a) {
this.getUsername(function(b) {
b = "hm://inclient-notifications/feed/" + encodeURIComponent(b + ":inclient") + "/counts";
c.hermes.request(b, "GET", [], [], ["NotificationCounts"], "enum SocialReactionType {\n UNKNOWN_SOCIAL_REACTION = 0;\n LIKED_SOCIAL_REACTION = 1;\n STREAMED_SOCIAL_REACTION = 2;\n RESHARED_SOCIAL_REACTION = 3;\n}\nenum BouncerStoryType {\n FOLLOWED_PROFILE_BOUNCER_STORY = 0;\n PUBLISHED_PLAYLIST_BOUNCER_STORY = 1;\n FOLLOWED_PLAYLIST_BOUNCER_STORY = 2;\n SHARED_URI_BOUNCER_STORY = 3;\n}\nmessage SocialReactionObject {\n optional SocialReactionType reaction = 1;\n optional string story_creator = 2;\n optional string story_id = 3;\n optional BouncerStoryType story_type = 4;\n optional string item_uri = 5;\n optional int64 reaction_time_ms = 6;\n}\nenum AppType {\n TYPE_UNKNOWN_APP = 0;\n TYPE_IOS_APP = 1;\n TYPE_ANDROID_APP = 2;\n TYPE_LINK_APP = 3;\n TYPE_MFT_LAUNCH = 4;\n TYPE_MFT_REMINDER = 5;\n TYPE_MFT_SEASON = 6;\n}\nmessage User {\n optional string canonical_username = 1;\n optional string real_name = 2;\n}\nmessage PlaylistSubObject {\n optional string uri = 1;\n optional User owner = 2;\n optional User profile_user = 4;\n}\nmessage TrackAddObject {\n optional int32 track_count = 1;\n optional string uri = 2;\n repeated string track_uri = 3;\n}\nmessage AlbumReleaseObject {\n optional string album_gid = 1;\n optional string artist_gid = 2;\n optional string album_name = 3;\n optional string artist_name = 4;\n optional string track_gid = 5;\n optional string track_name = 6;\n optional bool exclusive = 7;\n}\nmessage ApplicationReleaseObject {\n optional AppType app = 1;\n optional string uri = 2;\n optional string image_url = 3;\n optional bool new_app = 4;\n}\nmessage MessagePlayedObject {\n optional string thread_id = 1;\n optional string message_id = 2;\n optional string attachment_uri = 3;\n optional User user = 4;\n}\nmessage InClientNotificationData {\n optional int32 version = 1;\n optional NotificationState state = 2;\n repeated User subject = 4;\n optional int32 subject_total = 5;\n optional string notification_verb = 6;\n repeated PlaylistSubObject playlist_sub_object = 8;\n repeated TrackAddObject track_add_object = 10;\n repeated AlbumReleaseObject album_release_object = 11;\n repeated ApplicationReleaseObject application_release_object=12;\n repeated SocialReactionObject social_reaction_object = 13;\n repeated MessagePlayedObject message_played_object = 14;\n}\nenum NotificationType {\n TYPE_UNKNOWN_NOTIFICATION = 0;\n TYPE_RESET_NOTIFICATION = 1;\n TYPE_IN_CLIENT_NOTIFICATION = 5;\n}\nmessage Notification {\n optional int32 version = 1;\n optional NotificationType type = 2;\n optional InClientNotificationData in_client_data = 5;\n optional bool dry = 7;\n}\nmessage NotificationState {\n optional bool seen = 2;\n optional bool dismissed = 3;\n optional bool followed_through = 4;\n optional string notification_id_hex = 5;\n optional string state_id_hex = 6;\n optional int64 notification_id_ms = 10;\n optional int64 state_id_ms = 11;\n}\nmessage NotificationList {\n repeated Notification notification = 1;\n}\nmessage NotificationStateList {\n repeated NotificationState state = 1;\n}\nmessage NotificationCounts {\n optional int32 version = 1;\n optional int32 active = 2;\n}\n",
function(b, c) {
b || !c.result ? a(null) : a(c.result[0].active)
})
})
};
this.onNotificationsUnreadCountChange = function(a) {
var b = 0;
this.getUnreadNotificationsCount(function(c) {
b = c;
a(b);
this.subscribeNotificationEvents(function(c, d) {
var e = d[0];
e.type == "TYPE_IN_CLIENT_NOTIFICATION" ? (b++, a(b)) : e.type === "TYPE_RESET_NOTIFICATION" && (b = 0, a(b))
})
}.bind(this))
};
this.subscribeNotificationEvents = function(b) {
this.getUsername(function(c) {
var d = "hm://inclient-notifications/feed/" + encodeURIComponent(c + ":inclient") + "/";
m(function(c) {
a.subscribe(d, [], [], [c + "#Notification"], function() {}, function() {}, b, null)
})
})
};
this.getUsername = function(a) {
b ? a(b) : this.getUserInfo(function(c) {
if (c) b = c._username, a(b)
})
};
this.getUserInfo = function(a) {
c.request("session_query", [], function(b, c) {
b ? a(null) : a(c)
})
};
this.getSocialDataForCurrentUser = function(a) {
var b = this;
this.getUsername(function(c) {
c ? b.getSocialDataForUser("spotify:user:" + c, a) : a(null)
})
};
this.getSocialDataForUser = function(a, b) {
c.request("user_metadata", [a], function(a, c) {
b(a || c)
})
};
this.isOwnPlaylist =
function(a, b) {
var d = this,
e = a.toURI().replace("app:", "");
c.request("playlist_metadata", [e], function(a, c) {
a ? b(!1) : c.subscribed ? b(!0) : d.getUsername(function(a) {
b(c.owner.uri === "spotify:user:" + a)
})
})
};
this.canPublishPlaylist = function(a, b) {
var d = a.toURI().replace("app:", "");
c.request("playlist_metadata", [d], function(a, c) {
a ? b(a) : b(null, !(c.collaborative || c.ownedByCurrentUser && !c.published))
})
};
this.isSubscribedPlaylist = function(a, b) {
var d = a.toURI().replace("app:", "");
c.request("playlist_metadata", [d], function(a,
c) {
a ? b(!1) : b(c.subscribed)
})
};
this.getFacebookUserId = function(a) {
this.getUsername(function(b) {
b ? c.hermes.request("hm://username/splookup", "GET", [{
usernames: [b]
}], ["UserRequest"], ["UserIdentifier"], "message UserRequest {\n repeated string usernames = 1;\n}\nmessage UserIdentifier {\n optional string username = 1;\n optional string facebook_uid = 2;\n optional bool deleted = 3 [default = false];\n}", function(b, c) {
b ? a(null) : c.result ? c.result[0] && a(c.result[0].facebook_uid || null) : a(null)
}) : a(null)
})
};
this.getArtistMetadata = function(a, b) {
c.request("artist_metadata", [a], function(a, c) {
a ? b(!1) : b(c)
})
}
};
Spotify.Web.AutoPlay = function(c, a, b, d) {
var f = [new Spotify.Web.FacebookURLSchema, new Spotify.Web.OpenURLSchema],
j = function(a, b, d, f, g, e) {
f = typeof f !== "function" ? function() {} : f;
g = typeof g !== "function" ? function() {} : g;
d === void 0 && (d = -1);
a ? c.player.play_context_as_app(a, b, d, 0, e, function(a, b) {
a ? g(b) : f(b)
}) : c.player.play_context(b, d, 0, function(a, b) {
a ? g(b) : f(b)
})
},
g = function(a, b, d, f) {
d = typeof d !== "function" ? function() {} : d;
f = typeof f !== "function" ? function() {} : f;
a ? c.player.play_track_as_app(a, b, 0, function(a,
b) {
a ? f(b) : d(b)
}) : c.player.play_track(b, 0, function(a, b) {
a ? f(b) : d(b)
})
};
this.shouldPlay = function(a) {
for (var b = !1, c = 0; c < f.length; c++)
if (f[c].shouldPlay(a)) {
b = !0;
break
}
return b
};
this.play = function(a, b, c, d, f) {
return this.playAsApp(null, a, b, c, d, f)
}.bind(this);
this.playAsApp = function(a, f, h, m, n, e) {
var o, t;
try {
o = b.fromString(f), t = o.toURI()
} catch (C) {
return null
}
switch (o.type) {
case "track":
d.getAlbumForTrack(t, function(b) {
var c = t.split(":")[2];
d.getTrackIndexInAlbum(b, c, function(c) {
j(a, b, c, m, n, e)
}, n)
}, n);
break;
case "playlist":
h ? d.getTrackIndexInPlaylist(t, h, function(b) {
j(a, t, b, m, n, e)
}) : j(a, t, void 0, m, n, e);
break;
case "album":
h ? d.getTrackIndexInAlbum(t, h, function(b) {
j(a, t, b, m, n, e)
}) : j(a, t, void 0, m, n, e);
break;
case "artist":
j(a, t + ":top:tracks", void 0, m, n, e);
break;
case "artist-toplist":
j(a, t, void 0, m, n, e);
break;
case "ad":
g(a, t, m, n);
break;
case "trackset":
if (h)
for (var h = Spotify.Utils.Base62.toHex(h, 32), f = 0, v = o.tracks.length; f < v; f++)
if (h == o.tracks[f].id) {
o.index = f;
break
}
a ? c.player.play_context_as_app(a, t, o.index,
0, e,
function(a, b) {
a ? n(b) : m(b)
}) : c.player.play_context(t, o.index, 0, function(a, b) {
a ? n(b) : m(b)
})
}
};
this.pause = function() {
c.request("player_pause", ["main"], function() {})
};
this.resume = function() {
c.request("player_play", ["main"], function() {})
};
this.playUrl = function(a, b, c) {
for (var d = 0; d < f.length; d++)
if (f[d].playUrl(a, this.play, b, c)) break
};
this.enableRepeatMode = function() {
c.request("player_set_repeat", ["main", !0], function() {})
};
this.getUrl = function(a, b) {
for (var c, g = 0; g < f.length; g++)
if (c = f[g].getUrl(a), f[g].shouldPlay(a)) break;
(g = Spotify.Web.Utils.decodeOpenGraphUrl(c)) && g.context === "track" ? d.getAlbumForTrack("spotify:track:" + g.contextId, function(a) {
var a = a.replace("spotify:album:", ""),
d = Spotify.Web.URLParser.parseURL(c);
b(d.protocol + "://" + d.domain + "/album/" + a)
}) : b(c)
}
};
Spotify.Web.Exceptions = function() {
Spotify.Web.EventTarget.call(this);
var c = this,
a = function(a, d, f, j, g) {
c.trigger(Spotify.Web.ErrorTypes.UNCAUGHT_EXCEPTION, {
module: a,
message: d + (f ? " " + f : ""),
url: j,
lineNumber: g
})
};
this.bindWindow = function(b, d) {
var f;
typeof b.onerror === "function" && c.bind("INTERNAL_ONERROR", c._wrapOnErrorCallback(b.onerror));
f = b.onerror = function(a, b, d) {
c.trigger("INTERNAL_ONERROR", arguments)
};
try {
Object.defineProperty(b, "onerror", {
get: function() {
return f
},
set: function(a) {
c.bind("INTERNAL_ONERROR",
c._wrapOnErrorCallback(a))
}
})
} catch (j) {}
b.onerror = function(b, c, f) {
c = c || History.getPageUrl();
c = Spotify.Web.URLParser.parseURL(c).path;
a(d, b, "", c, f)
}
};
this.restoreOnErrorHandlers = function(a) {
try {
Object.defineProperty(a, "onerror", {
value: null
})
} catch (c) {}
};
this.logError = function(b, c, f) {
a(b, c, f, "", "")
};
this._wrapOnErrorCallback = function(a) {
return function(c) {
try {
a.apply(window, c.params)
} catch (f) {}
}
}
};
Spotify.Web.Router = function(c, a, b, d) {
Spotify.Web.EventTarget.call(this);
var f = this,
j = !0,
g, k, l = "browse,collection,discover,follow,messages,playlists,profile,radio,settings,social-feed,home".split(",");
this.EVENT_TRACK_URI_ROUTED = "TRACK_URI_ROUTED";
this.setServices = function(a) {
g = a
};
this.getInitialUrl = function() {
return k
};
this._isBrandedProfileArgumentBlacklisted = function(b) {
return a.apps.blacklisted_branded_profile_args.indexOf(b) != -1
};
this._mapBrandedProfileAppLinkToUserLink = function(b) {
var c = a.apps.user_to_app;
if (c !== void 0 && b.type == "application") {
var d = {},
e;
for (e in c) c.hasOwnProperty(e) && typeof d[c[e]] === "undefined" && (d[c[e]] = e);
c = d[b.id];
if (typeof c !== "undefined" && !this._isBrandedProfileArgumentBlacklisted(b.args[0])) return d = Spotify.Link.fromString(b.toURI()), d.id = "user", d.args = b.args && b.args.length > 0 ? [c].concat(b.args) : [c], d
}
};
this._mapBrandedProfileUsernameToAppName = function(b) {
var c = a.apps.user_to_app;
if (c !== void 0) return b = c[b], b === void 0 ? void 0 : b
};
this._isBrandProfilesDeeplink = function(a) {
var b = !1;
a && a.type == Spotify.Link.Type.APPLICATION && a.id == "user" && (a.args.length == 1 ? b = !0 : a.args.length > 1 && (b = !this._isBrandedProfileArgumentBlacklisted(a.args[1])));
return b
};
this.openUri = function(d, l, k) {
j || b.notify(Spotify.Web.PublisherMessages.USER_INTERACTION);
var e = d.toURI(),
o = this._mapBrandedProfileAppLinkToUserLink(d);
o ? d = o : d.type == Spotify.Link.Type.APPLICATION && d.id == "user" && this._mapBrandedProfileUsernameToAppName(d.args[0]) && (this._isBrandedProfileArgumentBlacklisted(d.args[1]) || (k = !1));
if (e.indexOf("%40") !==
-1 && e.indexOf("spotify:app:search") !== 0) g.getUsername(function(a) {
if ("username" in d) d.username = a;
else if (d.type === Spotify.Link.Type.APPLICATION)
for (var b = 0; b < d.args.length; b++) d.args[b] = d.args[b].replace("@", a);
f.openUri(d, l, k)
});
else if (d.type !== "application" && (d = d.toAppLink()), d.id === "user" && d.args[0] === "tunigo" && (d.args[0] = "spotify"), d.id === "home" && (d = Spotify.Link.fromString("spotify:app:browse").toAppLink(), k = !0), a.features && a.features.collection && d.id === "playlist" ? d = Spotify.Link.fromString("spotify:app:collection:playlists").toAppLink() :
(!a.features || !a.features.collection) && d.id === "collection" && d.args[0] === "playlists" && (d = Spotify.Link.fromString("spotify:app:playlist").toAppLink()), k = k || !1, l = l || "", d.type === "application" && d.id === "track") e = Spotify.Link.fromString("spotify:track:" + d.args[0]), this.trigger(this.EVENT_TRACK_URI_ROUTED, {
link: e
}), g.getAlbumForTrack(e.toURI(), function(a) {
a = Spotify.Link.fromString(a).toAppLink();
c.openUri(a, l, k)
}, function() {});
else {
var e = {},
o = this._isBrandProfilesDeeplink(c.getCurrentLink()) ? 1 : 0,
t = this._isBrandProfilesDeeplink(d) ?
1 : 0;
if ((o ^ t) == 1) e.forceOpen = !0;
c.openUri(d, l, k, e)
}
};
this.getAppUrl = function(a) {
a.charAt(0) === "/" && (a = a.substr(1, a.length - 1));
var a = a.split("/"),
b = a[0];
if (b == "user" && a.length > 1) {
var c = f._mapBrandedProfileUsernameToAppName(a[1]);
c && !f._isBrandedProfileArgumentBlacklisted(a[2]) && (b = c, a.splice(0, 3))
}
b === "user" && (b = "profile");
if (b === "profile" && (a[2] === "playlist" || a[2] === "starred" || a[2] === "toplist")) b = "playlist";
if (b === "collection" && a[1] === "album" && a[2] || a[0] === "user" && a[2] === "collection" && a[3] === "album" &&
a[4]) b = "collection-album";
if (b === "collection" && a[1] === "artist" && a[2] || a[0] === "user" && a[2] === "collection" && a[3] === "artist" && a[4]) b = "collection-artist";
return d.getAppURL(b)
};
this.openInitialUrl = function(b) {
b = Spotify.Web.Utils.openGraphUrlToSpotifyUri(b);
b === "" && (b = a.features && a.features.browseAsStartPage ? "spotify:app:browse" : "spotify:app:browse");
b = Spotify.Link.fromString(b).toAppLink();
if (a.developer || l.indexOf(b.id) === -1 && !(a.features && a.features.collection && b.id === "playlist")) a.features && a.features.browseAsStartPage ?
this.openUri(Spotify.Link.fromString("spotify:app:browse").toAppLink(), "", !1) : this.openUri(Spotify.Link.fromString("spotify:app:browse").toAppLink(), "", !1);
f.openUri(b, "", !1);
j = !1;
k = b
}
};
Spotify.Web.Router.History = function(c, a) {
Spotify.Web.EventTarget.call(this);
var b = ["play", "ap", "websockets"],
d = this,
f = this,
j = 0,
g = 0,
k = function() {
var b = a.getState();
d.trigger("pageChange", {
url: b.url
});
if (g > 0) g -= 1;
else {
var h = b.data.index,
b = 0,
k = "undo";
h > j ? (b = h - j, k = "redo") : h < j && (b = -(j - h));
j = h;
for (h = 0; h < Math.abs(b); h += 1) k === "undo" ? (c.undo(), f && f.event("ux", "history_back")) : (c.redo(), f && f.event("ux", "history_forward"))
}
};
this.setTracking = function(a) {
f = a
};
this.getAddressBarUrl = function() {
var c = a.getPageUrl(),
d = c.indexOf("?"),
f = d > -1,
g = !1,
e;
for (e in b)
if (c.indexOf("?" + b[e] + "=") > -1) {
g = !0;
break
}
f && !g && (c = c.substr(0, d));
return c
};
this.push = function(b) {
var c = "/" + b.toURLPath();
j += 1;
g += 1;
a.pushState({
index: j,
link: b
}, document.title, c)
};
this.replace = function(b) {
url = "/" + b.toURLPath();
a.replaceState({
index: j,
link: b
}, document.title, url)
};
(function() {
a.Adapter.bind(window, "statechange", k, this)
})()
};
Spotify.Web.StateHistory = {};
Spotify.Web.StateHistory.Commands = {};
Spotify.Web.StateHistory.CommandTypes = {
EMPTY: "EMPTY",
SHOW_SECTION: "SHOW_SECTION",
UPDATE_APP_ARGUMENTS: "UPDATE_APP_ARGUMENTS",
PUSH: "PUSH",
POP: "POP",
MOVE_VIEWPORT: "MOVE_VIEWPORT",
COMPOSED_COMMAND: "COMPOSED_COMMAND",
UPDATE_VIEWPORT_BEGIN: "UPDATE_VIEWPORT_BEGIN",
UPDATE_VIEWPORT_END: "UPDATE_VIEWPORT_END",
BROWSER_HISTORY_PUSH_URL: "BROWSER_HISTORY_PUSH_URL"
};
Spotify.Web.StateHistory.Manager = function(c, a, b) {
Spotify.Web.EventTarget.call(this);
if (typeof c === "undefined") throw Error("No arguments were supplied while initializing the State History Manager class.");
this.activeSection = null;
var d = this,
f = {},
j = a,
g = new Spotify.Web.StateHistory.Stack,
k = new Spotify.Web.StateHistory.Stack,
l = function(a) {
this.activeSection = f[a.params.id]
},
h = function(a, b) {
a.execute(function(a) {
b && a.type === Spotify.Web.StateHistory.CommandTypes.BROWSER_HISTORY_PUSH_URL && d.trigger("onBrowserHistoryPush", {
link: a.link
});
d.trigger("doCommand", {
command: a
})
})
},
m = function(a) {
var a = new Spotify.Web.StateHistory.App(d.activeSection.id, d.activeSection.viewport.endsAt, a),
b = [];
b.push(new Spotify.Web.StateHistory.Commands.PushApp(d.activeSection, a));
b.push(new Spotify.Web.StateHistory.Commands.MoveViewport(d.activeSection, 1));
b.push(new Spotify.Web.StateHistory.Commands.BrowserHistoryPushUrl(a.link));
a = new Spotify.Web.StateHistory.Commands.ComposedCommand(b);
d.run(a)
},
n = function(a, b, c, e) {
if (!c) c = d.activeSection;
e || (e = c.getTopApp());
var f = [];
f.push(new Spotify.Web.StateHistory.Commands.UpdateAppLink(c, e, a));
b || f.push(new Spotify.Web.StateHistory.Commands.BrowserHistoryPushUrl(a));
a = new Spotify.Web.StateHistory.Commands.ComposedCommand(f);
d.run(a, b)
},
e = function(a) {
var b = ["playlist", "starred", "toplist"];
return a.id === "playlist" || a.id === "user" && b.indexOf(a.args[1]) > -1
},
o = function(a) {
var b = ["overview", "playlists", "songs", "albums", "artists"];
return a.id === "user" && a.args && a.args[1] === "collection" && (a.args.length ===
2 || b.indexOf(a.args[2]) !== -1 && a.args.length === 3)
},
t = function() {
var a = d.activeSection;
a.persistent && a.viewport.endsAt === 0 && d.trigger("onBrowserHistoryReplace", {
link: a.apps[0].link
})
};
this.initialize = function() {
if (typeof c.sections === "undefined") throw Error("No sections were supplied.");
for (var a = 0, b = c.sections.length, d = c.sections; a < b; a += 1) {
var e = d[a].link;
f[e.id] = new Spotify.Web.StateHistory.Section(e, d[a].type, d[a].persistent);
f[e.id].bind("onActive", l, this)
}
};
this.getCurrentLink = function() {
return this.activeSection &&
this.activeSection.getTopApp() ? this.activeSection.getTopApp().link : null
};
this.run = function(a, b) {
b || (k.push(a), g.clear());
h(a, !b)
};
this.undo = function() {
var a = k.pop().invert();
h(a);
g.push(a);
t();
return a
};
this.redo = function() {
var a = g.pop().invert();
h(a);
k.push(a);
t();
return a
};
this.openUri = function(a, g, h, k) {
var l = (k || {}).forceOpen || !1;
if (typeof a === "undefined") throw Error("openUri needs a Spotify.Link as an argument");
if ((k = this.getCurrentLink()) && a.toURI() === k.toURI()) this.trigger("onCurrentLink", {
link: a
});
else {
this.trigger("beforeOpenUri", {
link: a
});
var t = a.id,
k = !1,
u;
for (u in f)
if (u === t && (k = !0, f[u].type === "popup")) {
this.trigger("onPopup", {
link: a,
origin: g
});
return
}
if (k && (!a.args || a.args.length === 0)) c.useClassicMode ? this.goToRoot(f[t]) : this.activeSection !== f[t] ? this.showSection(f[t], h) : this.activeSection.viewport.endsAt !== 0 && this.goToRoot();
else if (h) {
var g = b.features.collection ? "collection" : "playlist",
y = e(a) ? g : a.id;
y === this.activeSection.getTopApp().id ? (this.trigger("onBrowserHistoryReplace", {
link: a
}), n(a, !0)) : (y === "radio" || y === g) && n(a, !0, f[y], f[y].apps[0])
} else if (e(a)) y = b.features.collection ? "collection" : "playlist", (this.activeSection.id === "playlist" || this.activeSection.id === "collection") && this.activeSection.apps.length === 1 ? n(a, h) : j.isOwnPlaylist(a, function(b) {
b ? d.goToRoot(f[y], a) : m(a, h)
});
else if (o(a)) m(a, h);
else if (a.id === "user" && a.args[1] === "collection" && a.args[2] === "album" && a.args[3]) m(a, h);
else if (a.id === "user" && a.args[1] === "collection" && a.args[2] === "artist" && a.args[3]) m(a, h);
else if (k)
if (a.id === "user" && a.args[0]) {
var B = a.args[0];
j.getUsername(function(b) {
if (b === B) d.goToRoot(f[t], a);
else {
var c = d.activeSection.getTopApp(),
b = !e(c.link) && c.link.id === "user",
c = a.args[0] === c.link.args[0];
b && c && !l ? n(a, h) : m(a, h)
}
})
} else a.args && a.args.length > 0 && this.goToRoot(f[t], a);
else m(a, h)
}
};
this.goToRoot = function(a, b) {
var c = [],
d = this.activeSection;
a && this.activeSection !== a && (c.push(new Spotify.Web.StateHistory.Commands.ShowSection(this.activeSection, a)), d = a);
c.push(new Spotify.Web.StateHistory.Commands.UpdateViewportBegin(d));
for (var e = d.viewport.endsAt + 1; --e;) {
var f = d.apps[e];
c.push(new Spotify.Web.StateHistory.Commands.MoveViewport(d, -1));
c.push(new Spotify.Web.StateHistory.Commands.PopApp(d, f))
}
c.push(new Spotify.Web.StateHistory.Commands.UpdateViewportEnd(d));
b ? (c.push(new Spotify.Web.StateHistory.Commands.UpdateAppLink(d, d.apps[0], b)), d = b) : d = a ? d.getTopApp().link : d.apps[0].link;
c.push(new Spotify.Web.StateHistory.Commands.BrowserHistoryPushUrl(d));
this.run(new Spotify.Web.StateHistory.Commands.ComposedCommand(c))
};
this.showSection = function(a) {
var b = [];
b.push(new Spotify.Web.StateHistory.Commands.ShowSection(this.activeSection, a));
b.push(new Spotify.Web.StateHistory.Commands.BrowserHistoryPushUrl(a.getTopApp().link));
this.run(new Spotify.Web.StateHistory.Commands.ComposedCommand(b))
};
this.moveViewport = function(a) {
if (a !== -1) throw Error("not supported");
this.trigger("beforeOpenUri", {});
var b = this.activeSection.apps.length - 1 + a;
b < 0 || this.run(new Spotify.Web.StateHistory.Commands.ComposedCommand([new Spotify.Web.StateHistory.Commands.MoveViewport(this.activeSection,
a), new Spotify.Web.StateHistory.Commands.PopApp(this.activeSection, this.activeSection.getTopApp()), new Spotify.Web.StateHistory.Commands.BrowserHistoryPushUrl(this.activeSection.apps[b].link)]))
};
this.getSection = function(a) {
return typeof f[a] !== "undefined" ? f[a] : null
};
this.isRootActive = function() {
return this.activeSection.viewport.endsAt === 0
};
this.getSections = function() {
return f
};
this.getUndoStack = function() {
return k
};
this.getRedoStack = function() {
return g
};
this.setServices = function(a) {
j = a
}
};
Spotify.Web.StateHistory.Stack = function() {
var c = [];
this.isEmpty = function() {
return c.length === 0
};
this.clear = function() {
c = []
};
this.getLength = function() {
return c.length
};
this.getItemAtIndex = function(a) {
return typeof c[a] !== "undefined" ? c[a] : null
};
this.push = function(a) {
c.push(a)
};
this.pop = function() {
return c.pop()
}
};
Spotify.Web.StateHistory.Section = function(c, a, b) {
Spotify.Web.EventTarget.call(this);
if (typeof c === "undefined") throw Error("The link argument is required!");
this.id = c.id;
this.type = a;
this.persistent = b || !1;
this.apps = [new Spotify.Web.StateHistory.App(this.id, 0, c)];
this.viewport = new Spotify.Web.StateHistory.Viewport;
this.clear = function() {
this.apps = this.apps.slice(0, 1)
};
this.setActive = function() {
this.trigger("onActive", {
id: this.id
})
};
this.getTopApp = function() {
return this.apps[this.apps.length - 1]
}
};
Spotify.Web.StateHistory.App = function(c, a, b) {
if (typeof b === "undefined") throw Error("Argument missing: link");
var d = c + "-app-" + b.toAppURI() + "-" + a + "-" + Date.now();
this.link = b;
this.id = b.id;
this.uri = b.toAppURI();
this.args = b.args || [];
this.updateLink = function(a) {
this.link = a;
this.id = a.id;
this.uri = a.toAppURI();
this.args = a.args || []
};
this.getUniqueId = function() {
return d
}
};
Spotify.Web.StateHistory.Viewport = function() {
this.length = 2;
this.endsAt = 0
};
Spotify.Web.StateHistory.Commands.PushApp = function(c, a) {
this.section = c;
this.app = a;
this.type = Spotify.Web.StateHistory.CommandTypes.PUSH;
this.execute = function(b) {
c.apps.push(a);
b(this)
};
this.invert = function() {
return new Spotify.Web.StateHistory.Commands.PopApp(c, a)
}
};
Spotify.Web.StateHistory.Commands.PopApp = function(c, a) {
this.section = c;
this.app = a;
this.type = Spotify.Web.StateHistory.CommandTypes.POP;
this.execute = function(a) {
c.apps.pop();
a(this)
};
this.invert = function() {
return new Spotify.Web.StateHistory.Commands.PushApp(c, a)
}
};
Spotify.Web.StateHistory.Commands.MoveViewport = function(c, a) {
this.section = c;
this.type = Spotify.Web.StateHistory.CommandTypes.MOVE_VIEWPORT;
this.execute = function(b) {
c.viewport.endsAt += a;
b(this)
};
this.getOffset = function() {
return a
};
this.invert = function() {
return new Spotify.Web.StateHistory.Commands.MoveViewport(c, -1 * a)
}
};
Spotify.Web.StateHistory.Commands.ShowSection = function(c, a) {
this.section = a;
this.app = a.apps[0];
this.type = Spotify.Web.StateHistory.CommandTypes.SHOW_SECTION;
this.execute = function(a) {
this.app = this.section.apps[0];
this.section.setActive(!0);
a(this)
};
this.invert = function() {
return new Spotify.Web.StateHistory.Commands.ShowSection(this.section, c)
}
};
Spotify.Web.StateHistory.Commands.UpdateAppLink = function(c, a, b) {
var d = a.link;
this.section = c;
this.type = Spotify.Web.StateHistory.CommandTypes.UPDATE_APP_ARGUMENTS;
this.execute = function(c) {
a.updateLink(b);
c(this)
};
this.invert = function() {
return this.section.persistent ? new Spotify.Web.StateHistory.Commands.Empty : new Spotify.Web.StateHistory.Commands.UpdateAppLink(c, a, d)
}
};
Spotify.Web.StateHistory.Commands.Empty = function() {
this.type = Spotify.Web.StateHistory.CommandTypes.EMPTY;
this.execute = function(c) {
c(this)
};
this.invert = function() {
return new Spotify.Web.StateHistory.Commands.Empty
}
};
Spotify.Web.StateHistory.Commands.UpdateViewportBegin = function(c) {
this.section = c;
this.execute = function(a) {
a(this)
};
this.type = Spotify.Web.StateHistory.CommandTypes.UPDATE_VIEWPORT_BEGIN;
this.invert = function() {
return new Spotify.Web.StateHistory.Commands.UpdateViewportEnd(c)
}
};
Spotify.Web.StateHistory.Commands.UpdateViewportEnd = function(c) {
this.section = c;
this.type = Spotify.Web.StateHistory.CommandTypes.UPDATE_VIEWPORT_END;
this.execute = function(a) {
a(this)
};
this.invert = function() {
return new Spotify.Web.StateHistory.Commands.UpdateViewportBegin(c)
}
};
Spotify.Web.StateHistory.Commands.BrowserHistoryPushUrl = function(c) {
this.type = Spotify.Web.StateHistory.CommandTypes.BROWSER_HISTORY_PUSH_URL;
this.link = c;
this.execute = function(a) {
a(this)
};
this.invert = function() {
return this
}
};
Spotify.Web.StateHistory.Commands.ComposedCommand = function(c) {
if (!c.length || !(c.length > 0)) throw Error("The ComposedCommand argument must be an array");
this.type = Spotify.Web.StateHistory.CommandTypes.COMPOSED_COMMAND;
this.execute = function(a) {
for (var b = 0; b < c.length; b++) c[b].execute(a)
};
this.invert = function() {
for (var a = [], b = c.length - 1; b >= 0; b--) a.push(c[b].invert());
return new Spotify.Web.StateHistory.Commands.ComposedCommand(a)
};
this.getCommands = function() {
return c
};
this.getCommandAtIndex = function(a) {
a =
c[a];
return typeof a !== "undefined" ? a : null
}
};
Spotify.Web.AppManager = function(c, a, b) {
Spotify.Web.EventTarget.call(this);
var d = {},
f = {},
j = [],
g = this,
k = [];
c.bind("doCommand", function(a) {
a = a.params.command;
if (a.type === Spotify.Web.StateHistory.CommandTypes.UPDATE_APP_ARGUMENTS) {
var b = a.section.apps[a.section.viewport.endsAt],
f = c.getSection(a.section.id).apps[a.section.viewport.endsAt].getUniqueId();
g.trigger("onFrameUpdated", {
app: b,
node: d[a.section.id][f]
})
}
});
this.getActiveFrame = function() {
var a = c.activeSection,
b = a.id,
a = c.getSection(b).apps[a.viewport.endsAt].getUniqueId();
return d[b][a]
};
this.registerDiv = function(a, b) {
f[a] = b
};
this.get = function(g, h) {
var m = c.getSection(g).apps[h],
n = m.getUniqueId(),
e = d[g] || (d[g] = {}),
o = e[n];
if (o) return o;
if (f[m.id]) return m = f[m.id].getElement(), e[n] = m;
var t = a(m.link.toURLPath()),
o = j.length ? j.shift() : b.createElement("iframe");
o.id = n;
o.src = t;
e[n] = o;
n = k[m.id] ? !0 : !1;
k[m.id] = 1;
this.trigger("onFrameCreated", {
app: m,
node: o,
cached: n
});
return o
};
this.dispose = function(a, b) {
if (b !== 0) {
var f = c.getSection(a).apps[b],
g = f.getUniqueId(),
e = d[a],
k = e[g];
this.trigger("onFrameDisposed", {
app: f,
node: k
});
delete e[g];
j.push(k)
}
return this
};
this.registerAppWindow = function(a, b) {
this.trigger("onFrameCreated", {
app: {
link: b
},
node: a
})
};
this.getIFrameWithWindow = function(a) {
for (var b in d)
for (var c in d[b]) {
var f = d[b][c];
if (f.contentWindow === a) return f
}
return null
}
};
Spotify.Web.Queue = function() {
var c = null;
this.execute = function(a) {
c && c.forceFinish();
c = a;
c.execute()
};
this.forceFinish = function() {
c && c.forceFinish()
}
};
Spotify.Web.Queue.TransitionStep = function(c, a) {
var b = !1,
d = null,
f = function() {
try {
c()
} finally {
b = !0
}
};
this.execute = function() {
a ? d = setTimeout(f, a) : f()
};
this.forceFinish = function() {
b || (clearTimeout(d), f())
};
this.delay = a
};
Spotify.Web.Queue.Transition = function(c) {
this.execute = function() {
for (var a = 0; a < c.length; a++) c[a].execute()
};
this.forceFinish = function() {
for (var a = 0; a < c.length; a++) c[a].forceFinish()
}
};
Spotify.Web.View = function(c, a, b, d, f) {
Spotify.Web.EventTarget.call(this);
var j = this,
g = {},
k, l = null,
h = function(e) {
var h = c.getSections()[e],
h = new Spotify.Web.View.Section(h, a, b.ownerDocument, f);
g[e] = h;
b.appendChild(h.getWrapper());
d ? h.getWrapper().addClass("classic") : h.getWrapper().addClass("stacked");
h.bind("onMoveViewportLeft", function() {
c.moveViewport(-1);
l && l.event("ux", "stacks_overlay_clicked")
}, j);
h.bind("onFrontPaneUpdate", function(a) {
this.trigger("onFrontPaneUpdate", a.params)
}, j)
},
m = function(a) {
a =
a.params.command;
switch (a.type) {
case Spotify.Web.StateHistory.CommandTypes.SHOW_SECTION:
a = g[a.section.id];
if (!a) throw Error("incorrect section id");
k !== a && (k && (k.hide(), f.notify(Spotify.Web.PublisherMessages.APPLICATION_DEACTIVATED, {
node: k.getFrontPane().iFrame
})), a.show(), k = a, f.notify(Spotify.Web.PublisherMessages.APPLICATION_ACTIVATED, {
node: a.getFrontPane().iFrame
}));
break;
case Spotify.Web.StateHistory.CommandTypes.MOVE_VIEWPORT:
var b = a.getOffset();
g[a.section.id].moveViewport(b);
break;
case Spotify.Web.StateHistory.CommandTypes.UPDATE_VIEWPORT_BEGIN:
k.updateViewportBegin();
break;
case Spotify.Web.StateHistory.CommandTypes.UPDATE_VIEWPORT_END:
k.updateViewportEnd()
}
},
n = function() {
k && k.forceQueue()
};
this.setTracking = function(a) {
l = a
};
(function() {
var a = c.getSections(),
b;
for (b in a) a.hasOwnProperty(b) && h(a[b].id);
c.bind("doCommand", m, j);
c.bind("beforeOpenUri", n, j)
})()
};
Spotify.Web.View.Section = function(c, a, b, d) {
Spotify.Web.EventTarget.call(this);
var f = this,
j, g = Array(3),
k = new Spotify.Web.Queue,
l = !1,
h = null,
m = function() {
var a = g[g.length - 1].iFrame;
f.trigger("onFrontPaneUpdate", {
node: a
});
h && d.notify(Spotify.Web.PublisherMessages.APPLICATION_DEACTIVATED, {
node: h
});
d.notify(Spotify.Web.PublisherMessages.APPLICATION_ACTIVATED, {
node: a
});
h = a
},
n = function(a) {
a.isRoot() ? a.wrapper.className = "limbo" : (a.updatePaneStyle("fadeOut"), setTimeout(function() {
j.removeChild(a.wrapper)
},
500))
},
e = function(a, b, c, d) {
a = new Spotify.Web.Queue.Transition([new Spotify.Web.Queue.TransitionStep(a), new Spotify.Web.Queue.TransitionStep(b, 5), new Spotify.Web.Queue.TransitionStep(c, d ? d : 25)]);
k.execute(a)
},
o = function(d) {
var e = d === 0,
g = new Spotify.Web.View.Pane(e),
d = a.get(c.id, d);
g.updateIFrame(d);
if (!e || !j.querySelectorAll(".limbo")[0]) {
if (g.wrapper = b.createElement("div"), g.wrapper.appendChild(g.iFrame), g.wrapper.addEventListener("click", function() {
f.trigger("onMoveViewportLeft", {})
}), e = b.createElement("div"),
e.className = "overlay", g.wrapper.appendChild(e), g.iFrame.tagName.toLowerCase() === "iframe") {
var h = b.createElement("div");
h.className = "loading-indicator";
g.wrapper.appendChild(h);
var k = !1;
setTimeout(function() {
if (!k) h.style.display = "block"
}, 500);
var l = function() {
k = !0;
h.style.display = "none";
g.iFrame.removeEventListener("load", l, !1)
};
g.iFrame.addEventListener("load", l, !1)
}
} else g.wrapper = j.querySelectorAll(".limbo")[0];
return g
},
t = function() {
for (var a = 0, b = g.length - 1; b >= 0; b--) g[b] && a++;
return a
},
C = function() {
var b,
d, f;
t();
e(function() {
b = g[0];
for (var a = 0; a < g.length - 1; a++) g[a] = g[a + 1], g[a] && (g[a].isRoot() && g[a].updatePaneStyle("root", "covered"), a === g.length - 2 && !g[a].isRoot() && (f = g[a], f.updatePaneStyle("back")));
g[g.length - 1] = o(c.viewport.endsAt);
d = g[2];
d.updatePaneStyle("front", "fadeIn");
j.appendChild(d.wrapper)
}, function() {}, function() {
f && f.updatePaneStyle("back");
b && (n(b), a.dispose(c.id, c.viewport.endsAt - c.viewport.length - 1));
m()
})
};
this.getWrapper = function() {
if (!j) {
var a = b.createElement("div");
a.setAttribute("id",
"section-" + c.id);
a.className = "hidden";
j = a
}
return j
};
this.show = function() {
if (!g[2]) {
g[2] = o(0);
var a = g[2];
a.updatePaneStyle();
j.appendChild(a.wrapper)
}
j.addClass("active");
j.removeClass("hidden")
};
this.forceQueue = function() {
k.forceFinish()
};
this.hide = function() {
j.addClass("hidden");
j.removeClass("active")
};
this.getFrontPane = function() {
return g[2]
};
this.moveViewport = function(b) {
if (!l)
if (b === 1) C();
else if (b === -1) {
for (var b = g[2], d = t(), e = g.length - 1; e > 0; e--) {
g[e] = g[e - 1];
if (g[e] && g[e].isRoot())
if (d > 1) g[e].updatePaneStyle("root",
"covered");
else {
g[e].updatePaneStyle();
break
} else g[e] && e === g.length - 1 ? g[e].updatePaneStyle("front") : g[e] && g[e].updatePaneStyle("back");
g[e - 1] = null
}
n(b);
b = g[2];
b.updatePaneStyle("front");
b = c.viewport.endsAt - c.viewport.length;
b >= 0 && (g[0] = o(b), b > 0 && j.insertBefore(g[0].wrapper, j.childNodes[1]));
a.dispose(c.id, c.viewport.endsAt + 1);
m()
} else throw Error("not implemented");
};
this.updateViewportBegin = function() {
l = !0;
for (var b = 0; b < g.length; b++) g[b] && (n(g[b]), a.dispose(c.id, c.viewport.endsAt - g.length + 1 + b),
g[b] = null)
};
this.updateViewportEnd = function() {
l = !1;
for (var a = -1, b = c.viewport.endsAt - 2; b <= c.viewport.endsAt; b++)
if (a += 1, !(b < 0)) {
var d = o(b);
g[a] = d;
d.isRoot() && d.updatePaneStyle();
d.wrapper.parentElement !== j && j.appendChild(d.wrapper)
}
}
};
Spotify.Web.View.Pane = function(c) {
this.wrapper = this.iFrame = null;
this.updateIFrame = function(a) {
this.iFrame = a
};
this.updatePaneStyle = function(a, b) {
var d = this;
if (b) this.wrapper.className = b;
c === !0 ? this.wrapper.className = "root" + (b ? " " + b : "") : typeof a !== "undefined" && setTimeout(function() {
d.wrapper.className = a
}, 25)
};
this.isRoot = function() {
return c
}
};
Spotify.Web.NowPlaying = function() {
var c = document.getElementById("now-playing-widgets");
this._displayRecomendations = function(a) {
a = new Spotify.Web.Window({
url: a.getAppUrl("/now-playing-recs/")
});
a.initialize();
a = a.getElement();
a.tabIndex = -1;
c.appendChild(a);
return a
};
this._displayAndRegisterRecommendations = function(a, b, c) {
a = this._displayRecomendations(b);
b = Spotify.Link.fromString("spotify:app:now-playing-recs").toAppLink();
c.registerAppWindow(a, b)
};
this._displayUpsell = function(a, b, d, f) {
a = new Spotify.Web.Upsell({
useCat: d,
useMft: f
}, a, b);
c.appendChild(a.getElement());
return a
};
this.displayWidget = function(a) {
a.core.core.user.getUserInfo(function(b) {
var c = this,
f = b.catalogue === "free",
j = a.config.getFeature("nowPlayingRecs"),
g = a.config.getFeature("underPlayerUpsell"),
k = function() {
c._displayUpsell(a.core.core.user, a.tracking, a.config.getSetting("cat_enabled"), f).init()
},
l = function() {
c._displayAndRegisterRecommendations(a.config, a.router, a.appManager)
},
h = function(a, b) {
//TODO add Try/Catch
a || JSON.parse(b.result[0]) ? k() : j && l()
};
f ? g ? (b = "hm://xpromo/user/" +
encodeURIComponent(b.user) + "/platform/webplayer/promote/desktop", a.bridge.request("hermes_send_request", [b, "GET", [],
[],
[]
], h)) : j && l() : j ? l() : g && k()
}.bind(this))
}
};
Spotify.Web.FocusTracker = function(c) {
var a = this,
b = [],
d = (new Date).getTime(),
f = 0,
j = 0,
g = !0,
k = function() {
d = (new Date).getTime();
f = 0;
g = !0;
l()
},
l = function() {
for (var a, d = 0; d < b.length; d++) {
a = b[d];
if (g && a.fired) {
a.onActive.call();
a.fired = !1;
f = 0;
c.clearTimeout(a.timeout);
a.timeout = h(a.timeMS);
break
}
if (!g && !a.fired && f >= a.timeMS) {
a.onInactive.call();
a.fired = !0;
break
}
}
},
h = function() {
c.setInterval(function() {
a.onBackgroundActivity()
}, 1E3)
};
this.registerCallback = function(a, c, d) {
b.push({
timeMS: a * 1E3,
onInactive: c,
onActive: d,
fired: !1
})
};
this.onBackgroundActivity = function() {
j++;
j === 10 && (j = 0, f = (new Date).getTime() - d, g = !1, l())
};
this.userActivityRecorded = function() {
k()
};
this.init = function() {
c.addEventListener("mousemove", Spotify.Web.Utils.debounce(function() {
k()
}, 1E3));
h()
}
};
window._debug = !1;
Spotify = Spotify || {};
Spotify.Web = Spotify.Web || {};
window.addEventListener("mousewheel", function() {}, !1);
Spotify.Web.App = function() {
var c = this,
a, b = {},
d, f, j, g, k, l, h, m, n, e, o, t, C, v, z = [],
w, A, x, u, y, B = function() {
G();
a.popupManager.createAndRegisterPopup("context-actions", {
preventScrolling: !0,
hideOnWindowResize: !0,
loadAfter: 2E3
});
a.config.getFeature("share") && a.popupManager.createAndRegisterPopup("share", {
preventScrolling: !0,
hideOnWindowResize: !0,
loadAfter: "ON_DEMAND"
});
a.config.getFeature("collection") === 2 && a.popupManager.createAndRegisterPopup("col-union-rem-dialog", {
preventScrolling: !0,
hideOnWindowResize: !0,
width: 400,
loadAfter: "ON_DEMAND"
});
u = new Spotify.Web.LightboxWindow({
url: a.router.getAppUrl("/revgen-modal/"),
id: "revgen-modal",
wrapper: document.getElementById("modal-ad-area"),
iframe: document.getElementById("ad-modal"),
loadAfter: "ON_DEMAND"
}, a.publisher, a.popupManager);
u.initialize();
x.displayWidget(a);
g = a.popupManager.createAndRegisterPopup("suggest", {
preventScrolling: !0,
wrapper: document.getElementById("suggest-area"),
iframe: document.getElementById("suggest"),
hideMessage: Spotify.Web.PublisherMessages.SUGGEST_HIDDEN,
showMessage: Spotify.Web.PublisherMessages.SUGGEST_SHOWN,
postHideCallback: function() {
Spotify.Web.BrowserDetect.browser === "Firefox" && document.activeElement.blur();
a.appManager.getActiveFrame().focus()
},
loadAfter: 2E3
});
if (a.config.getFeature("notifications")) {
var b = a.config.getSetting("cat_enabled") ? [280, 240] : [314, 280];
k = a.popupManager.createAndRegisterPopup("notification-center", {
width: b[0],
height: b[1],
preventScrolling: !0,
wrapper: document.getElementById("notifications-area"),
iframe: document.getElementById("notifications"),
hideMessage: Spotify.Web.PublisherMessages.NOTIFICATIONS_HIDDEN,
showMessage: Spotify.Web.PublisherMessages.NOTIFICATIONS_SHOWN,
postHideCallback: function() {
Spotify.Web.BrowserDetect.browser === "Firefox" && document.activeElement.blur();
a.appManager.getActiveFrame().focus()
},
loadAfter: "ON_DEMAND"
})
}
a.popupManager.initializePopups();
Spotify.Web.GA.trackEvent("landing", "render", "web-player-load-finished")
},
D = function() {
var b = a.history.getAddressBarUrl(),
d = !0;
a.publisher.notify(Spotify.Web.PublisherMessages.APPLICATION_ENABLED, {});
o = new Spotify.Web.AutoPlay(a.bridge, Spotify.Bridge, Spotify.Link, a.services, a.router.getAppUrl);
if (o.shouldPlay(b) || Spotify.Web.SpbMusicBridge.isReferrerFromSPB(a.config.getSetting("playLandingURL"))) d = !1;
Spotify.Shuttle.init(a.core.core, {
publisher: a.publisher,
getAppUrl: a.router.getAppUrl,
shouldGetSavedState: d,
blackList: a.playNow.isAnonymous() ? a.playNow.getBlocked() : {}
});
Spotify.Shuttle.onReady(function(a, b) {
b.contextPlayer.once("trackLoaded", function() {
Spotify.Web.GA.trackEvent("landing", "render",
"web-player-playing")
})
});
clientEventLogger = new Spotify.Web.ClientEventLogger(a.bridge);
a.playNow.setLogger(clientEventLogger);
a.playNow.isOpenRedirect() && a.core.detachPlayer();
if (o.shouldPlay(b) && !a.playNow.isOpenRedirect()) {
a.playNow.setAutoPlayTriggered(!0);
A.setAutoPlayTriggered(!0);
var e = function() {
a.appLoader.onReady(function() {
o.getUrl(b, function(b) {
a.router.openInitialUrl(b)
});
B();
j.showPlayer()
})
},
f = function() {
w.unbind("FIRST_BYTES", g, c);
w.unbind("CANNOT_PLAY_TRACK", k, c);
w.unbind("PLAYBACK_FAILED",
k, c);
w.unbind("INVALID_TRACK_URI", k, c)
},
g = function() {
clearTimeout(h);
f();
e()
},
h, k = function() {
clearTimeout(h);
f();
e()
};
w.bind("FIRST_BYTES", g, c);
w.bind("CANNOT_PLAY_TRACK", k, c);
w.bind("PLAYBACK_FAILED", k, c);
w.bind("INVALID_TRACK_URI", k, c);
h = setTimeout(function() {
k()
}, 5E3);
o.playUrl(b, function() {
setTimeout(o.enableRepeatMode, 5E3);
F()
}, function(a) {
k(a);
F(a)
})
} else a.appLoader.onReady(function() {
a.router.openInitialUrl(b);
B();
F()
});
d = new Spotify.Web.Storage.Cookie("settingsShort", a.services, Spotify.Utils.Base64, {
expires: 0
}, document);
d.init(function() {});
var l = new Spotify.Web.Storage.Cookie("settings", a.services, Spotify.Utils.Base64, {
expires: 366
}, document);
l.init(function() {});
a.services.getUserInfo(function(b) {
b = b.product;
b === "unlimited" || b === "premium" || a.playNow.isAnonymous() || m.setUpgradeButton(_("Upgrade"))
});
I();
n = new Spotify.Web.Settings.Model(a.core.core, a.bridge, d, l, a.fbBridge, a.playNow);
n.init();
n.setServices(a.services);
m.setModel(n);
a.appManager.registerAppWindow(document.getElementById("app-player"),
Spotify.Link.fromString("spotify:app:player").toAppLink());
(new Spotify.Web.AppNotifications(a.bridge, n, a.config.getSettings())).init();
C = new Spotify.Web.LastFm(a.bridge, a.core.core, n, a.config.getSetting("lastfm"));
C.init();
(new Spotify.Web.AdAgent).init(a.bridge, y, clientEventLogger)
},
G = function() {
var b = document.getElementById("app-player");
j = new Spotify.Web.Player(a.bridge, a.core.core, {
url: a.router.getAppUrl("/player/"),
iframe: b,
publisher: a.publisher
});
j.initialize()
},
E = function() {
p();
if (!e) {
w = a.core.getMainPlayer();
a.playNow.setPlayer(w);
if (window.localStorage && window.localStorage.playNow_isPlaying === "true") {
window.localStorage.playNow_isPlaying = "false";
var b = function() {
var c = a.core.core.contextPlayer;
c && c.resume();
w.unbind("LOAD", b)
};
w.bind("LOAD", b, c)
}
e = !0;
D()
}
a.publisher.notify(Spotify.Web.PublisherMessages.ERROR, {
type: Spotify.Web.ErrorTypes.CONNECTION_RESTORED
});
document.getElementById("main").style["background-image"] = "none"
},
F = function(b) {
Spotify.Web.SpbMusicBridge.initMusicBridge(a.stateHistory, a.bridge,
a.publisher, a.config.getSettings(), a.consoleLogger, o, b)
},
I = function() {
a.fbBridge.connect(a.config.getSettings().fbjssdk.config, function() {
t = new Spotify.Web.OpenGraph(a.fbBridge, a.bridge, v, n, a.services);
t.start();
d.enableFacepile()
}, function(b) {
a.consoleLogger.warn("[FB] error", b);
window.setTimeout(I, 3E5);
b === "not_authorized" && d.enableFacepile()
})
},
H = function(a) {
z.push(a.params);
p()
},
p = function() {
try {
for (var b = 0, c = z.length; b < c; b += 1) a.core.core.logging.logger.logJSExceptions(z[b].module, z[b].message,
z[b].url + ":" + a.history.getAddressBarUrl(), z[b].lineNumber);
z = []
} catch (d) {}
};
b.developerMode = !1;
b.initialize = function(c) {
Spotify.Web.GA.trackEvent("landing", "render", "web-player-load-initiated");
Spotify.Web.BrowserDetect.init();
var e = window.location.href;
if (!c) throw Error("Server-side settings not provided");
var j = Spotify.Web.URLParser.parseURL(e),
n = Spotify.Web.Utils.filterQSParams(["utm_source", "utm_medium", "utm_term", "utm_content", "utm_campaign"], e);
if (c.force_zow == 1 || c.features.zow) e = "", n ? (e = "?" +
n, c.http_flag && (e += "&http=1")) : c.http_flag && (e = "?http=1"), window.location = "/" + (j && j.path ? j.path : "") + e;
else if (c.needsToAcceptEULA && c.needsToAcceptEULA === !0) window.location = "/legal/?fwdurl=" + encodeURIComponent(!j || !j.path ? "/" : "/" + j.path + (j.query ? "?" + j.query : "")) + (n ? "&" + n : "");
else {
v = new Spotify.Web.Exceptions(window);
v.bind(Spotify.Web.ErrorTypes.UNCAUGHT_EXCEPTION, H, this);
v.bindWindow(window, "global");
a = new Spotify.Web.Setup(c, e);
a.init(E);
A = new Spotify.Web.CookieCompliance(a.config.getSetting("country"),
a.publisher);
d = new Spotify.Web.PlayNowBanner(a.playNow, document.getElementById("playnow"), document.getElementById("main"), A, a.publisher, a.config.getSetting("cat_enabled"));
d.initialize();
if (a.playNow.isAnonymous()) {
j = a.playNow.getLimitedFeatureFlags();
for (n = 0; n < j.length; n++) c.features[j[n]] = !0
}
if (!c) throw Error("Server-side settings not provided");
b.developerMode = a.config.getSetting("developer") || !1;
a.config.getFeature("collection") && (Spotify.Web.Utils.enableAppInUrl("collection"), Spotify.Web.Utils.enableAppInUrl("collection-album"),
Spotify.Web.Utils.enableAppInUrl("collection-artist"));
a.config.getFeature("social-feed") && Spotify.Web.Utils.enableAppInUrl("social-feed");
a.publisher.subscribe(Spotify.Web.PublisherMessages.APPLICATION_STATE_PUSH, this);
a.publisher.subscribe(Spotify.Web.PublisherMessages.APPLICATION_OPEN_URI, this);
a.publisher.subscribe(Spotify.Web.PublisherMessages.APPLICATION_CLOSED, this);
a.publisher.subscribe(Spotify.Web.PublisherMessages.CLIENT_SHOW_SHARE_UI, this);
a.publisher.subscribe(Spotify.Web.PublisherMessages.CLIENT_SHOW_CONTEXT_UI,
this);
a.publisher.subscribe(Spotify.Web.PublisherMessages.CLIENT_SHOW_COLLECTION_UNION_REMOVE_UI, this);
a.publisher.subscribe(Spotify.Web.PublisherMessages.FB_APP_UNKNOWN, this);
a.publisher.subscribe(Spotify.Web.PublisherMessages.FB_APP_CONNECTED, this);
a.publisher.subscribe(Spotify.Web.PublisherMessages.FB_APP_NOT_AUTHENTICATED, this);
a.publisher.subscribe(Spotify.Web.PublisherMessages.FB_CONNECTION_FAILURE, this);
a.publisher.subscribe(Spotify.Web.PublisherMessages.FB_MESSAGE, this);
a.publisher.subscribe(Spotify.Web.PublisherMessages.FB_POST,
this);
a.publisher.subscribe(Spotify.Web.PublisherMessages.FB_SESSION_QUERY, this);
a.publisher.subscribe(Spotify.Web.PublisherMessages.FB_SESSION_USER_METADATA, this);
a.publisher.subscribe(Spotify.Web.PublisherMessages.USER_AUTHENTICATION_FAILURE, this);
a.publisher.subscribe(Spotify.Web.PublisherMessages.APPLICATION_VERSION_CHANGED, this);
a.publisher.subscribe(Spotify.Web.PublisherMessages.APPLICATION_POST_MESSAGE, this);
a.publisher.subscribe(Spotify.Web.PublisherMessages.LIMITED_FEATURE_CALL, this);
a.publisher.subscribe(Spotify.Web.PublisherMessages.SUGGEST_SHOW,
this);
a.publisher.subscribe(Spotify.Web.PublisherMessages.SUGGEST_HIDE, this);
a.publisher.subscribe(Spotify.Web.PublisherMessages.APPLICATION_LOAD_TIME, this);
a.publisher.subscribe(Spotify.Web.PublisherMessages.APPLICATION_LOAD_STARTED, this);
a.publisher.subscribe(Spotify.Web.PublisherMessages.NOTIFICATIONS_SHOW, this);
a.publisher.subscribe(Spotify.Web.PublisherMessages.NOTIFICATIONS_HIDE, this);
window.addEventListener("message", function(b) {
var c = Spotify.Web.Utils.appNameFromUrl(b.origin);
a.publisher.notify(Spotify.Web.PublisherMessages.APPLICATION_POST_MESSAGE, {
url: c,
name: c,
data: b.data,
evt: b
})
}, !1);
b.abTests = a.abTests;
x = new Spotify.Web.NowPlaying;
a.router.bind(a.router.EVENT_TRACK_URI_ROUTED, function(b) {
if (!a.playNow.isOpenRedirect()) {
var c = b.params.link;
o.play(c.toURI(), c.id, function() {
a.consoleLogger.log("Autoplaying track", c)
}, function() {
a.consoleLogger.warn("Unable to auto play track")
})
}
});
document.getElementById("main-nav").addEventListener("click", function(b) {
b.target.id === "main-nav" && !a.stateHistory.isRootActive() && (a.stateHistory.moveViewport(-1),
a.tracking.event("ux", "stacks_overlay_clicked"))
});
a.stateHistory.bind("doCommand", function(a) {
a = a.params.command;
a.type === Spotify.Web.StateHistory.CommandTypes.SHOW_SECTION && f.highlightMenu(a.section.id)
});
a.stateHistory.bind("onPopup", function(b) {
var c = b.params.link.id,
d = b.params.origin;
c === "suggest" ? g.isVisible() ? a.publisher.notify(Spotify.Web.PublisherMessages.SUGGEST_HIDE) : a.publisher.notify(Spotify.Web.PublisherMessages.SUGGEST_SHOW) : c === "notification-center" ? k.isVisible() ? a.publisher.notify(Spotify.Web.PublisherMessages.NOTIFICATIONS_HIDE) :
a.publisher.notify(Spotify.Web.PublisherMessages.NOTIFICATIONS_SHOW) : c === "context-actions" || c === "share" ? a.popupManager.popup(b.params.link, d) : c === "revgen-modal" && (a.popupManager.closeAll(), u.show(b.params.link, d))
});
a.stateHistory.bind("onCurrentLink", function() {
g.isVisible() && a.publisher.notify(Spotify.Web.PublisherMessages.SUGGEST_HIDE);
k.isVisible() && a.publisher.notify(Spotify.Web.PublisherMessages.NOTIFICATIONS_HIDE)
});
a.history.bind("pageChange", function(b) {
a.tracking.pageView("/" + Spotify.Web.URLParser.parseURL(b.params.url).path);
a.popupManager.closeAll()
});
a.stateHistory.bind("onBrowserHistoryPush", function(b) {
a.history.push(b.params.link)
});
a.stateHistory.bind("onBrowserHistoryReplace", function(b) {
a.history.replace(b.params.link)
});
h = new Spotify.Web.Error({
publisher: a.publisher,
element: document.getElementById("notification-area"),
dialog: document.getElementById("modal-notification-area"),
timeout: 4E3
}, a.playNow);
h.initialize();
a.playNow.isAnonymous() ? m = new Spotify.Web.Settings.Anonymous({
wrapper: document.getElementById("settings"),
scrollBlocker: a.scrollBlocker,
publisher: a.publisher
}, c) : (j = new Spotify.Web.SettingsApp(a.config.getSetting("cat_enabled")), a.appManager.registerDiv("settings", j), m = new Spotify.Web.Settings.View({
wrapper: j.getElement(),
scrollBlocker: a.scrollBlocker,
publisher: a.publisher
}, c));
m.init();
m.bind(Spotify.Web.PublisherMessages.APPLICATION_OPEN_URI, function(b) {
a.router.openUri(b.params.link)
});
f = new Spotify.Web.Menu({
publisher: a.publisher,
container: document.getElementById("main-nav"),
features: a.config.getFeatures(),
settingsView: m,
router: a.router,
cat: a.config.getSetting("cat_enabled")
}, a.playNow, $);
f.initialize();
v.bind(Spotify.Web.ErrorTypes.UNCAUGHT_EXCEPTION, function(b) {
b = b.params;
a.tracking.handleException(b.module, b.message, "", b.url, b.lineNumber)
});
Spotify.Web.FeatureDetect.adBlockCheck() && a.publisher.notify(Spotify.Web.PublisherMessages.ERROR, {
type: Spotify.Web.ErrorTypes.AD_BLOCK_DETECTED
});
y = new Spotify.Web.FocusTracker(window);
y.init();
l = new Spotify.Web.PostMessages.Handler({
allowed_origins: [window.location.protocol +
"//" + window.location.hostname
]
}, a.consoleLogger, a.appLoader, a.appManager, a.popupManager, k, y);
a.publisher.notify(Spotify.Web.PublisherMessages.CHROME_READY);
setTimeout(function() {
(new Spotify.Web.CookieCleaner(Spotify.Web.Cookie)).clean()
}, 2E3)
}
};
b.onNotify = function(b) {
var c = b.message,
d = Spotify.Web.PublisherMessages;
switch (b.messageType) {
case d.APPLICATION_POST_MESSAGE:
l.handle(c.evt);
break;
case d.APPLICATION_OPEN_URI:
f.enable();
a.router.openUri(c.link, c.origin, c.replace);
break;
case d.APPLICATION_VERSION_CHANGED:
a.publisher.notify(d.ERROR, {
type: Spotify.Web.ErrorTypes.APPLICATION_RELOAD_NEEDED
});
break;
case d.LIMITED_FEATURE_CALL:
a.playNow.limitedFeatureCalled(c.feature);
break;
case d.CLIENT_SHOW_SHARE_UI:
b = "spotify:share:" + c.left + ":" + (c.top + 10) + ":0:0:" + encodeURIComponent(c.uri);
b = Spotify.Link.fromString(b);
d = a.appManager.getIFrameWithWindow(c.origin);
a.popupManager.popup(b, d, !0);
c.callback(!0);
break;
case d.CLIENT_SHOW_CONTEXT_UI:
b = "spotify:app:context-actions:" + c.left + ":" + c.top + ":0:0:";
b += encodeURIComponent(c.items[0]);
b += ":" + (c.itemContext ?
encodeURIComponent(c.itemContext) : "");
b += ":" + (typeof c.itemIndex !== "undefined" ? c.itemIndex : "");
b = Spotify.Link.fromString(b);
d = a.appManager.getIFrameWithWindow(c.origin);
a.popupManager.popup(b, c.origin);
break;
case d.CLIENT_SHOW_COLLECTION_UNION_REMOVE_UI:
b = Spotify.Link.applicationLink("col-union-rem-dialog", [0, 0, 0, 0].concat(c.uri.split(":").slice(1)));
d = a.appManager.getIFrameWithWindow(c.origin);
a.popupManager.popup(b, d, !0);
c.callback(!0);
break;
case d.SUGGEST_SHOW:
g.show();
break;
case d.SUGGEST_HIDE:
g.hide();
break;
case d.NOTIFICATIONS_SHOW:
k.show();
break;
case d.NOTIFICATIONS_HIDE:
k.hide();
break;
case d.APPLICATION_LOAD_STARTED:
a.appLogger.loadingStart(c);
break;
case d.APPLICATION_LOAD_TIME:
a.appLogger.loadingTime(c);
break;
case d.APPLICATION_CLOSED:
b = w.trackUri;
b.indexOf("spotify:ad:") > -1 && a.core.core.adChooser.recordAdEvent(b, "attempt");
break;
case d.FB_MESSAGE:
a.fbBridge.sendMessage(c.uids, c.url, c.message, function(a) {
c.callback(a)
});
break;
case d.FB_POST:
a.fbBridge.postToWall(c.url, c.message, function(a) {
c.callback(a)
});
break;
case d.FB_SESSION_QUERY:
a.fbBridge.getFacebookSession(function(a) {
c.callback(a)
});
break;
case d.FB_SESSION_USER_METADATA:
a.fbBridge.getUsersName(function(a) {
c.callback(a)
})
}
};
return b
}();
Spotify.Web.GA = Spotify.Web.GA || {};
Spotify.Web.GA.RETRY_MS = 50;
Spotify.Web.GA.trackEvent = function(c, a, b, d) {
var f = setInterval(function() {
window.ga && (ga("send", "event", c, a, b, d), clearInterval(f))
}, Spotify.Web.GA.RETRY_MS)
};
Spotify.Web.GDP = function(c) {
function a(a) {
if (a.status === "connected") {
var c = a.authResponse.userID,
a = a.authResponse.accessToken;
d.notify(Spotify.Web.PublisherMessages.FB_APP_CONNECTED, {
userID: c,
accessToken: a
});
b.hide();
(new Request({
url: "/xhr/json/gdp/create.php",
method: "get",
data: {
fbuid: c,
access_token: a
},
onSuccess: k
})).send()
}
}
var b = this,
d = c.publisher,
f = c.fbBridge,
j, g = new Spotify.Web.GDP.View({
player: c.core.player
});
this.initialize = function() {
j = f.getAPI();
d.subscribe(Spotify.Web.PublisherMessages.FB_APP_CONNECTED,
b);
d.subscribe(Spotify.Web.PublisherMessages.FB_APP_NOT_AUTHENTICATED, b);
j.Event.subscribe("auth.statusChange", a)
};
this.createDialog = function() {
g.initialize(null, b.show)
};
this.show = function() {
g.show()
};
this.hide = function() {
g.hide()
};
this.error = function() {
g.render(g.templates.ERROR)
};
this.deny = function() {
g.render(g.templates.CANCEL)
};
this.authenticate = function() {
f.getLoginStatus()
};
this.onNotify = function(a) {
var c = Spotify.Web.PublisherMessages;
switch (a.messageType) {
case c.APPLICATION_ENABLED:
setupTrack();
break;
case c.FB_APP_NOT_AUTHENTICATED:
d.unsubscribe(Spotify.Web.PublisherMessages.FB_APP_CONNECTED, b);
break;
case c.FB_APP_CONNECTED:
window.location.href = "/login/?forward=" + encodeURIComponent("/welcome/")
}
};
var k = function(a) {
//TODO add Try/Catch
a = JSON.parse(a);
a.status === "success" ? d.notify(Spotify.Web.PublisherMessages.USER_AUTHENTICATED) : d.notify(Spotify.Web.PublisherMessages.USER_AUTHENTICATION_FAILURE, a)
}
};
Spotify.Web.GDP = Spotify.Web.GDP || {};
Spotify.Web.GDP.View = function() {
function c(a, b) {
var c = f[a];
c ? (d.node.innerHTML = c, typeof b === "function" && b.call(this, c)) : (new Request({
url: a,
method: "get",
onSuccess: function(c) {
f[a] = c;
d.node.innerHTML = c;
typeof b === "function" && b.call(this, c)
}
})).send()
}
function a() {
document.getElementById("retry-button").addEventListener("click", function() {
d.render(d.templates.MAIN)
})
}
function b() {
var a = document.createElement("div");
a.id = "gdp-container";
a.classList.add("modal-notification");
document.body.appendChild(a);
return a
}
var d = this,
f = {};
this.player = this.node = null;
this.templates = {
MAIN: "/static/templates/gdp-main.html",
ERROR: "/static/templates/gdp-error.html",
CANCEL: "/static/templates/gdp-cancel.html"
};
this.initialize = function(a, c) {
d.node = d.node || b();
this.render(this.templates.MAIN, function() {
typeof c === "function" && c.call(this)
})
};
this.render = function(b, d) {
var f;
switch (b) {
case this.templates.ERROR:
f = a;
break;
case this.templates.CANCEL:
f = a;
break;
default:
f = d
}
c(b, f)
};
this.show = function() {
d.node.style.display = "block"
};
this.hide = function() {
d.node.style.display = "none"
}
};
Spotify.Web.Utils = function() {
function c() {
d = RegExp("^https?://[^/]+/(?:user/([^/]*)/)?(" + b.join("|") + ")/?(.*)?/?(.*)?/?")
}
var a = {},
b = "hub,home,browse,article,genre,collection-album,discover,starred,welcome,radio,trackset,labs,track,artist,album,messages,playlist,purchase,search,settings,debug,user,test-runner,pitchfork,promo-mft,songkick,follow(?!ers|ing),cosmosecho,cosmos-artist,brand-header,queue,social-chart,charts,chart".split(","),
d, f = /^https?:\/\/.*\/(?:user\/([^/]*)\/)?([a-z]{1}[a-z0-9-]+)\/?(.*)?\/?(.*)?\/?/;
c();
a.enableAppInUrl = function(a) {
b.indexOf(a) !== 0 && (b.push(a), c())
};
a.disableAppInUrl = function(a) {
a = b.indexOf(a);
a !== 0 && (b.splice(a, 1), c())
};
a.spotifyUriToOrigin = function(a) {
var a = a.split(":"),
b = a[1],
c = a[2];
b === "user" && a[3] === "playlist" ? (b = "playlist", c += ":" + a[4]) : b === "user" && a[3] === "collection" && (b = "collection-album", c += ":" + a[5]);
return "spotify:app:" + b + ":" + c
};
a.spotifyUriToOpenUrl = function(a, b) {
if (a) {
for (var c = a.split(":"), d = b || "http://open.spotify.com", f = 1; f < c.length; f++) {
if (c[f] === "top") break;
d +=
"/" + c[f]
}
return d
} else return ""
};
a.decodeOpenGraphUrl = function(a) {
a = a.replace("#_=_", "");
if (a = a.match(typeof Spotify.Web.App !== "undefined" && Spotify.Web.App.developerMode ? f : d)) {
var b = a[3] || null;
b !== null && (b = b.replace(/\?.*/g, ""), b = b.replace(/\//g, ":"), b = b[b.length - 1] === ":" ? b.slice(0, -1) : b);
return {
user: a[1] || null,
context: a[2] || null,
contextId: b
}
} else return null
};
a.openGraphUrlToSpotifyUri = function(b) {
if (!b) return null;
var c = a.decodeOpenGraphUrl(b);
if (!c) return "";
c.user ? b = c.contextId ? "spotify:user:" +
c.user + ":" + c.context + ":" + c.contextId : "spotify:user:" + c.user + ":" + c.context : c.contextId ? c.context === "search" ? (b = b.replace("#_=_", "").replace(/\/$/, "").split("/"), b.splice(0, 3), b.unshift("https://play.spotify.com/app"), b = b.join("/"), b = Spotify.Link.fromString(b).toURI()) : b = c.context === "collection" ? !c.contextId || ["overview", "playlists", "songs", "albums", "artists"].indexOf(c.contextId) !== -1 ? "spotify:app:collection" + (c.contextId ? ":" + c.contextId : "") : "spotify:user:@:" + c.context + ":" + c.contextId : "spotify:" + c.context +
":" + c.contextId : b = "spotify:app:" + c.context;
return b
};
a.addTransitionEndedListener = function(a, b, c) {
var d = !1,
f = function(a) {
d = !0;
b(a);
m()
},
m = function() {
a.removeEventListener("webkitTransitionEnd", f, !1);
a.removeEventListener("transitionend", f, !1);
a.removeEventListener("msTransitionEnd", f, !1);
a.removeEventListener("oTransitionEnd", f, !1)
};
a.addEventListener("webkitTransitionEnd", f, !1);
a.addEventListener("transitionend", f, !1);
a.addEventListener("msTransitionEnd", f, !1);
a.addEventListener("oTransitionEnd",
f, !1);
setTimeout(function() {
d || m()
}, c || 2E3)
};
a.getWindowPosition = function(a) {
var b = 0,
c = 0;
do b += a.offsetLeft, c += a.offsetTop; while (a = a.offsetParent);
return {
left: b,
top: c
}
};
a.appNameFromUrl = function(a) {
var b = null;
b = a.indexOf("/apps/") >= 0 ? a.split("/apps/")[1].split("/")[0] : (a = a.match(/^https?:\/\/[A-Za-z0-9]{8,40}-([A-Za-z0-9_-]+).*/)) ? a[1] : null;
return b
};
a.getQueryStringParameter = function(a) {
if (!window) return null;
for (var b = window.location.search.substr(1).split("&"), c = {}, d = 0; d < b.length; d++)
if (b[d].indexOf("=") >
-1) {
var f = b[d].split("=");
c[f[0]] = f[1]
}
return c[a] ? c[a] : null
};
a.stripQSParams = function(a, b) {
var c = b.split("?");
if (c.length < 2 || c[1].length == 0) return b;
for (var d = c[1].split("&"), f = [], m = 0; m < d.length; m++) {
var n = d[m].split("=");
a.indexOf(n[0]) == -1 && f.push(d[m])
}
return c[0] + (f.length > 0 ? "?" + f.join("&") : "")
};
a.filterQSParams = function(a, b) {
var c = b.split("?");
if (c.length < 2 || c[1].length == 0) return "";
for (var c = c[1].split("&"), d = [], f = 0; f < c.length; f++) {
var m = c[f].split("=");
a.indexOf(m[0]) != -1 && d.push(c[f])
}
return d.join("&")
};
a.debounce = function(a, b) {
var c = null;
return function() {
var d = this,
f = arguments;
window.clearTimeout(c);
c = window.setTimeout(function() {
a.apply(d, f)
}, b)
}
};
return a
}();
Spotify.Web.Fb = function(c, a, b) {
var d = this,
f = window.FB || null,
j = Spotify.Web.PublisherMessages;
this.getFacebookSession = function(a) {
b.getFacebookUserId(function(b) {
a({
facebookUser: b
})
})
};
var g = function(a, b) {
d.getFacebookSession(function(c) {
if (!c || !c.facebookUser) b("not_authorized");
else {
var d = f.getUserID();
c.facebookUser === d ? a() : b("not_authorized")
}
})
},
k = function(a, b) {
f.getLoginStatus(function(d) {
switch (d.status) {
case "connected":
g(function() {
c.notify(j.FB_APP_CONNECTED);
a()
}, b);
break;
case "not_authorized":
b("not_authorized");
break;
default:
b("not_logged_in")
}
}, !0)
},
l = function(a) {
var b = {
status: "failure",
message: ""
};
typeof a.error_msg != "undefined" ? b.message = a.error_msg : (b.status = "success", b.message = a);
return b
};
this.connect = function(a, b, c) {
if (!a || typeof a.appId !== "string") throw Error("AppId required");
Spotify.Web.FacebookSDK.onInitialized(function() {
f = window.FB;
k(b, c)
})
};
this.getApi = function() {
if (f) return f;
else throw Error("FB API not initialized");
};
this.requestExtentedPermissions = function(a) {
Spotify.Web.FacebookSDK.onInitialized(function() {
f.login(function(b) {
b.authResponse ?
d.checkPublishActionsPermissions(a) : a(Error("User not logged in"))
}, {
scope: "publish_actions"
})
})
};
this.checkPublishActionsPermissions = function(a) {
Spotify.Web.FacebookSDK.onInitialized(function() {
k(function() {
f.api("/me/permissions", function(b) {
if (b.error) a(b.error);
else {
for (var b = b.data, c = 0, d = b.length; c < d; c++) {
var f = b[c];
if (f.permission == "publish_actions" && f.status == "granted") {
a(null, !0);
return
}
}
a(null, !1)
}
})
}, function(b) {
a(b)
})
})
};
this.getDevices = function(a) {
this.getApi().api("/me?fields=devices",
function(b) {
if (typeof a === "function") {
var c = [];
if (typeof b.devices !== "undefined" && b.devices.length > 0)
for (var b = b.devices, d = b.length, f = 0; f < d; f++) typeof b[f].hardware !== "undefined" ? c.push(b[f].hardware.toLowerCase()) : typeof b[f].os !== "undefined" && c.push(b[f].os.toLowerCase());
a.call(this, c)
}
})
};
this.getFriendsUsingApp = function(a) {
this.getApi().api({
method: "fql.query",
query: "SELECT uid, name FROM user WHERE is_app_user = 1 AND uid IN (SELECT uid2 FROM friend WHERE uid1 = me())"
}, function(b) {
b = l(b);
typeof a ===
"function" && a.call(this, b)
})
};
this.getFriendsNotUsingApp = function(a) {
this.getApi().api({
method: "fql.query",
query: "SELECT uid, name FROM user WHERE is_app_user = 0 AND uid IN (SELECT uid2 FROM friend WHERE uid1 = me())"
}, function(b) {
b = l(b);
typeof a === "function" && a.call(this, b)
})
};
this.getUserImage = function(a) {
this.getApi().api({
method: "fql.query",
query: "select id, width, height, url, is_silhouette, real_width, real_height from profile_pic where id=me()"
}, function(b) {
b = l(b);
typeof a === "function" && a.call(this,
b)
})
};
this.getUsersName = function(a) {
this.getApi().api("/me?fields=name,last_name,first_name", function(b) {
b = l(b);
typeof a === "function" && a.call(this, b)
})
};
this.postToWall = function(a, b, c) {
this.getApi().api("/feed", "post", {
link: a,
message: b
}, c)
};
this.sendMessage = function(a, b, c, e) {
var f = d.getApi(),
a = {
to: "[" + a.join(",") + "]",
message: c
};
if (b) a.link = b;
f.api("/threads", "post", a, e)
};
this.connectUser = function(a, b) {
this.getApi().getLoginStatus(function(f) {
f.status === "connected" ? (a(f.authResponse.userID, f.authResponse.accessToken),
c.notify(j.FB_APP_CONNECTED)) : d.getApi().login(function(d) {
d.authResponse ? (a(d.authResponse.userID, d.authResponse.accessToken), c.notify(j.FB_APP_CONNECTED)) : b(d)
}, {
scope: "publish_actions"
})
})
}
};
Spotify.Web.Context = function(c) {
this._parseRadioUri = function(a) {
return "spotify:radio:" + a.split(":")[3].replace(/%3A/g, ":").replace("spotify:", "")
};
this.getState = function(a) {
c.player.getState(a)
};
this.getFacebookContextType = function(a) {
var b = this;
this.getState(function(c, f) {
var j = f.context;
if (!j || !j.uri) a(null);
else {
var g = j.uri.split(":"),
k = null;
switch (g[1]) {
case "user":
k = "playlist";
break;
case "album":
k = "album";
break;
case "artist":
k = "musician";
break;
case "temp-playlist":
if (g[2] === "radio") k = "radio_station",
j.uri = b._parseRadioUri(j.uri), j.stationUri = j.uri.replace("spotify:radio:", "spotify:")
}
a(k, f)
}
})
}
};
Spotify.Web.FacebookURLSchema = function() {
var c = function(a) {
var b = {};
if (a.song) b.trackUrl = decodeURIComponent(a.song);
if (a.musician) b.contextUrl = decodeURIComponent(a.musician);
else if (a.album) b.contextUrl = decodeURIComponent(a.album);
else if (a.playlist) b.contextUrl = decodeURIComponent(a.playlist);
return b
};
this.shouldPlay = function(a) {
a = Spotify.Web.URLParser.parseURL(a).params;
return !(!a || !a.song && !a.musician && !a.album && !a.playlist)
};
this.getUrl = function(a) {
var b = Spotify.Web.URLParser.parseURL(a, !0);
if (!b.path) b.path =
"";
if (this.shouldPlay(a)) {
a = Spotify.Web.URLParser.parseURL(a).params;
a = c(a);
if (!a.contextUrl && a.trackUrl) a.contextUrl = a.trackUrl, a.trackUrl = void 0;
if (a.contextUrl) a = Spotify.Web.Utils.decodeOpenGraphUrl(a.contextUrl), b.path = "", a.user && (b.path += "user/" + a.user + "/"), b.path += a.context + "/" + a.contextId
}
return b.protocol + "://" + b.domain + "/" + b.path
};
this.playUrl = function(a, b, d, f) {
if (this.shouldPlay(a)) {
a = Spotify.Web.URLParser.parseURL(a).params;
a = c(a);
if (!a.contextUrl && a.trackUrl) a.contextUrl = a.trackUrl, a.trackUrl =
void 0;
if (a.contextUrl) {
var j = Spotify.Web.Utils.openGraphUrlToSpotifyUri(a.contextUrl),
g;
if (a.trackUrl) g = Spotify.Web.Utils.decodeOpenGraphUrl(a.trackUrl).contextId;
Spotify.Web.Utils.decodeOpenGraphUrl(a.contextUrl).context === "artist" && g && (j = Spotify.Web.Utils.openGraphUrlToSpotifyUri(a.trackUrl), g = void 0);
b(j, g, d, f);
return !0
}
} else return !1
}
};
Spotify.Web.OpenURLSchema = function() {
var c = RegExp("/(?:user/([\\w|\\-|\\.]*))?/?(ad|playlist|album|artist|track|radio/genre|radio/album|radio/artist|radio/track|radio)/(\\w{0,32})(?:.*?play=)?(true|\\w{0,32})?"),
a = RegExp("(trackset)/((?:[A-Za-z0-9]|%[0-9a-fA-F]{2}){0,32})?/?([\\w,%]+)/?(%23/(\\d{0,2})|\\?play=(true|\\w{0,32}))?/?"),
b = function(b) {
var f;
if (f = b.match(c)) return {
user: f[1] || null,
context: f[2] || null,
contextId: f[3] || null,
play: f[4] || null
};
else if (f = b.match(a)) {
var j = f[3].split(/%2C|,/g),
b =
j.join(","),
g = f[1] + ":" + f[2],
k = f[5] || 0;
f = j.indexOf(f[6]);
f >= 0 && (k = f);
return {
user: null,
context: g,
contextId: b + ":%23:" + k,
play: "true"
}
} else return null
};
this.shouldPlay = function(a) {
a = b(a);
return !(!a || !a.context || !(a.context === "track" || a.context === "ad" || a.play))
};
this.getUrl = function(a) {
a = Spotify.Web.URLParser.parseURL(a, !0);
if (!a.path) a.path = "";
return a.protocol + "://" + a.domain + "/" + a.path
};
this.playUrl = function(a, c, j, g) {
if (this.shouldPlay(a)) {
var a = b(a),
k = "spotify:";
a.user && (k += "user:" + a.user + ":");
k += a.context +
":" + a.contextId;
var l;
if (a.play !== "true") l = a.play;
a.context === "artist" && l && (k = "spotify:track:" + l, l = void 0);
c(k, l, j, g);
return !0
} else return !1
}
};
Spotify.Web.OpenGraph = function(c, a, b, d, f) {
var j = new Spotify.Web.Context(a),
g = c.getApi().getAccessToken();
new Spotify.Events;
var k, l = function(a, c, d) {
a = "https://graph.facebook.com/me/music.listens?song=" + a;
c && (a += "&" + c + "=" + d);
a += "&access_token=" + g;
(new Request.CORS({
url: a,
data: null,
method: "post",
onSuccess: function(a) {
//TODO add Try/Catch
JSON.parse(a)
},
onFailure: function(a) {
b.logError("web.fb.opengraph.js", a.statusText, a.responseText)
}
})).send()
},
h = function(a, b, c) {
k && clearTimeout(k);
k = setTimeout(function() {
l(a, b, c);
clearTimeout(k)
},
15E3)
},
m = function() {
a.player.registerForPlayerEvents(function(a, b) {
if (!a) switch (b.type) {
case "play":
e(b);
break;
case "pause":
k && clearTimeout(k);
break;
case "stop":
k && clearTimeout(k)
}
m()
})
},
n = function(a) {
d.getPrivateSession() || d.getPostToOpenGraph(function(b) {
b && a()
})
},
e = function() {
j.getFacebookContextType(function(a, b) {
if (a) {
var c = b.context.uri,
d = b.track.uri,
e = Spotify.Web.Utils.spotifyUriToOpenUrl(d),
g = Spotify.Web.Utils.spotifyUriToOpenUrl(c);
d.indexOf(":ad:") > -1 || n(function() {
if (a === "playlist" || a ===
"radio_station") {
var d;
d = a === "playlist" ? Spotify.Link.fromString(c) : Spotify.Link.fromString(b.context.stationUri);
f.canPublishPlaylist(d, function(b, c) {
c ? h(e, a, g) : h(e, null, null)
})
} else h(e, a, g)
})
}
})
};
this.start = function() {
m()
}
};
Spotify.Web.AppNotifications = function(c, a, b) {
new Spotify.Events;
var d = null,
f = null,
j = null,
g = b.cdn + "/images/48.png",
k = function(a, b) {
f && f.cancel();
f = webkitNotifications.createNotification(g, a, b);
f.show();
setTimeout(function() {
f.cancel()
}, 3500)
},
l = function(b, f) {
var e = f.data.track.uri;
h();
if (typeof chrome !== "undefined" && chrome.app.isInstalled && a.getAppNotifications() && e && !(e.indexOf(":ad:") !== -1 || f.data.playing === !1)) clearTimeout(d), d = setTimeout(function() {
c.request("track_metadata", [e], function(a, b) {
if (b.uri !==
j) {
for (var c = "", d = 0; d < b.artists.length; d++) c += b.artists[d].name, d !== b.artists.length - 1 && (c += ", ");
j = b.uri;
k(b.name, c)
}
})
}, 1E3)
},
h = function() {
c.request("player_event_wait", ["main"], l)
};
this.init = function() {
h()
}
};
Spotify.Web.Player = function(c, a, b) {
var d = this,
f, j = b.iframe,
g = b.url,
k = b.publisher,
l = !1;
new Spotify.Events;
var h = !1,
m = a.audioManager.getPlayerAtIndex(0),
n = function(a, b) {
if (h !== b.data.playing) h = b.data.playing, h === !0 ? k.notify(Spotify.Web.PublisherMessages.USER_INTERACTION) : k.notify(Spotify.Web.PublisherMessages.USER_INTERACTION_PAUSE_PLAYBACK);
c.player.registerForPlayerStateChange(n);
!l && b.data.track && b.data.track.uri && (l = !0, d.showPlayer())
};
this.showPlayer = function() {
document.body.addClass("started");
j.tabIndex = "0"
};
this.initialize = function() {
f = new Spotify.Web.Window({
url: g,
iframe: j
});
f.initialize();
c.player.registerForPlayerStateChange(n);
f.bind("onMessage", function(b) {
b.params && b.params.indexOf && b.params.indexOf("ad_clicked") !== -1 && c.player.getState(function(b, c) {
if (c.track && c.track.advertisement) a.adChooser.recordAdEvent("spotify:ad:" + m.ad.file_id, "click"), m.ad.clicked = !0
})
})
}
};
Spotify.Web.Ads = {};
Spotify.Web.Ads.PixelTracker = function(c) {
this.bridge = c
};
Spotify.Web.Ads.PixelTracker.prototype._registerForPlayerEvents = function() {
this.bridge.player.registerForPlayerEvents(this._onPlayerEvent.bind(this))
};
Spotify.Web.Ads.PixelTracker.prototype._onPlayerEvent = function(c, a) {
if (!c && a.type === "play") this.onTrackAboutToBePlayed();
this._registerForPlayerEvents()
};
Spotify.Web.Ads.PixelTracker.prototype.init = function() {
img = document.createElement("img");
img.id = "tpx";
document.getElementById("main-nav").appendChild(img);
this._registerForPlayerEvents()
};
Spotify.Web.Ads.PixelTracker.prototype.onTrackAboutToBePlayed = function() {
this.bridge.player.getState(function(c, a) {
var b = a.track;
if (b && b.advertisement && typeof b.popularity === "string" && b.popularity.match(/^https/)) {
var d = b.popularity.replace(/\[timestamp\]/i, Date.now());
setTimeout(function() {
img.src = d
}, 10)
}
})
};
Spotify.Web.Upsell = function(c, a, b) {
var d, f, j, g, k, l, h;
function m() {
var a = document.createElement("div"),
b = a.cloneNode();
b.id = d;
var c = a.cloneNode();
c.className = "content";
var e = document.createElement("h3");
e.className = "title";
e.innerHTML = _("Enjoy");
a = a.cloneNode();
a.className = "subtitle";
a.innerHTML = _("The full Spotify Experience");
var g = document.createElement("button");
g.id = f;
g.type = "button";
g.tabIndex = -1;
g.className = j ? "btn btn-default" : "button";
g.innerHTML = _("Get Started");
var h = document.createElement("A");
h.href = "https://itunes.apple.com/us/app/spotify/id324684580";
h.className = "app-store-links iphone";
h.target = "_blank";
var k = document.createElement("A");
k.href = "https://play.google.com/store/apps/details?id=com.spotify.music";
k.className = "app-store-links android";
k.target = "_blank";
var l = document.createElement("A");
l.href = "http://windowsphone.com/s?appId=10f2995d-1f82-4203-b7fa-46ddbd07a6e6";
l.className = "app-store-links wp";
l.target = "_blank";
c.appendChild(e);
c.appendChild(a);
c.appendChild(g);
c.appendChild(h);
c.appendChild(k);
c.appendChild(l);
b.appendChild(c);
return b
}
var n = this,
c = c || {};
g = c.onBeforeTimeout || 500;
k = c.loggingEnabled || !0;
l = c.controlGroup || 0;
j = c.useCat || !1;
h = c.useMft || !1;
var e = null,
o = !1,
t = _("An unexpected error occurred when sending the SMS"),
C = _("The phone number is invalid");
this.simulation = !1;
f = "download-spotify";
d = "desktop";
var v = m(),
z = null,
w = null,
A = null;
this.init = function() {
var a = this.getDisplayMode();
a && this.applyDisplayMode(a)
};
this.getElement = function() {
v || (v = m());
return v
};
var c = function(a) {
window.location =
a.downloadLink
},
x = function() {
var a = z.querySelector('input[name="phone_number"]'),
b = z.querySelector('button[class="button"]'),
c = z.querySelector(".error");
/^\d{7,}$/.test(a.value.replace(/[\s()+\-\.]|ext/gi, "")) ? (a.setAttribute("disabled", "disabled"), b.setAttribute("disabled", "disabled"), c.innerHTML = "", (new Request({
url: "/xhr/json/sms/send_sms.php",
method: "get",
data: {
phone_number: a.value
},
onSuccess: function(d) {
try {
d = JSON.parse(d)
} catch (e) {
d = {}
}
if (typeof d.status !== "undefined" && d.status) z.querySelector(".phone-input").style.display =
"none", $(z.querySelector(".success-feedback")).addClass("show"), I("send_sms");
else {
var f = t;
if (typeof d.message !== "undefined") f = d.message;
c.innerHTML = f;
a.removeAttribute("disabled");
b.removeAttribute("disabled")
}
},
onError: function() {
c.innerHTML = t;
a.removeAttribute("disabled");
b.removeAttribute("disabled")
}
})).send()) : c.innerHTML = C
},
u = {
mft: {
id: d,
label: "mft",
text: _("MftLaunchTitle"),
subText: "",
mainClass: "mft",
options: {
actions: {
".app-store-links": function(a) {
a.stop();
var a = a.target,
b = a.className.replace("app-store-links ",
"");
I("mft_click", b);
window.open(a.href)
}
}
}
},
android: {
id: "send-sms-android",
label: "android",
text: _("Get Spotify"),
subText: _("on your Android"),
buttonText: _("Get Started"),
mainClass: "android",
options: {
actions: {
".button": x
}
}
},
iphone: {
id: "send-sms-iphone",
label: "iphone",
text: _("Get Spotify"),
subText: _("on your iPhone"),
buttonText: _("Get Started"),
mainClass: "iphone",
options: {
actions: {
".button": x
}
}
},
windows: {
id: "download-dialog-windows",
label: "windows",
text: _("Install Spotify on Windows"),
subText: _("For the full Spotify experience"),
buttonText: _("Install Spotify"),
downloadLink: "http://download.spotify.com/Spotify%20Installer.exe",
mainClass: "desktop-background",
options: {},
onBefore: c
},
mac: {
id: "download-dialog-mac",
label: "mac",
text: _("Install Spotify on Your Mac"),
subText: _("For the full Spotify experience"),
buttonText: _("Install Spotify"),
downloadLink: "http://download.spotify.com/SpotifyInstaller.zip",
mainClass: "desktop-background",
options: {},
onBefore: c
}
};
this.getDisplayMode = function(a) {
var b;
if (h) b = u.mft;
else {
b = null;
var c = Spotify.Web.BrowserDetect.OS.toLowerCase();
typeof u[c] !== "undefined" && (b = u[c])
}
if (typeof a === "function") a(b);
else return b
};
this.isEnabled = function() {
return e == null || e >= l || this.simulation
};
this.applyDisplayMode = function(b) {
if (a !== null) a.onReady(function() {
a.getUserInfo(function(a) {
a && (e = parseInt(a.ab_test_group, 10));
n.setDisplayMode(b)
})
}, this)
};
this.showPopup = function(a) {
if (!o) A = document.getElementById(f), z = document.getElementById(a.id), z.style.display = "block", w = z.querySelector(".dialog"), E(w, A), w.className += " show", o = !0, window.addEventListener("resize",
y, !1), window.addEventListener("keydown", B), z.addEventListener("click", F)
};
this.hidePopup = function() {
if (o) {
var a = z.querySelector(".dialog");
$(a).removeClass("show");
z.style.display = "none";
o = !1;
window.removeEventListener && (window.removeEventListener("resize", y), window.removeEventListener("keydown", B), z.removeEventListener("click", F))
}
};
this.setDisplayMode = function(a) {
if (a && this.isEnabled()) {
v.querySelector(".title").innerHTML = a.text;
v.querySelector(".subtitle").innerHTML = a.subText;
v.querySelector("button").innerHTML =
a.buttonText;
if (typeof a.mainClass !== "undefined") {
var b = v.querySelector(".content");
b.className = "content";
$(b).addClass("upsell-background");
$(b).addClass(a.mainClass)
}
D(a);
G(a);
v.querySelector(".content").addClass("show");
I("show_version", a.label)
}
};
this.simulate = function(a) {
if (typeof u[a] !== "undefined") this.simulation = !0, this.setDisplayMode(u[a])
};
var y = function() {
E(w, A)
},
B = function(a) {
a.keyCode == 27 && n.hidePopup()
},
D = function(a) {
v.querySelector("#" + f).onclick = function() {
typeof a.onBefore !== "undefined" ?
(n.showPopup(a), window.setTimeout(function() {
a.onBefore(a)
}, g)) : n.showPopup(a);
I("click_version")
}
},
G = function(a) {
if (typeof a.options.actions !== "undefined")
for (action in a.options.actions) a.options.actions.hasOwnProperty(action) && $$("#" + a.id).getElements(action).each(function(b) {
b.addEvent("click", function(b) {
a.options.actions[action](b)
})
})
},
E = function(a, b) {
var c = $(b).getSize().y / 2,
d = $(b).getPosition(),
c = {
x: d.x - (a.getSize().x + 15),
y: d.y - a.getSize().y * 0.7 + c
};
$(a).position(c)
},
F = function(a) {
o && (!a.target ||
!$(a.target).getParents().contains(z)) && n.hidePopup()
},
I = function(a, c) {
k && b && b.event("upsell", a, c || "", 1)
}
};
Spotify.Web.Storage.Cookie = function(c, a, b, d, f) {
var d = d || {},
j = d.expires === 0 ? d.expires : d.expires || 360,
g = d.path || "/",
k, l;
this._read = function(a) {
this._getCookieName(function(c) {
if (c = Spotify.Web.Cookie.get(c, f)) try {
l = JSON.parse(b.decode(c.replace(/\_/g, "=")))
} catch (d) {
l = {}
} else l = {};
typeof a !== "undefined" && a(l)
})
};
this._write = function(a) {
this._getCookieName(function(c) {
var d = h(b.encode(l ? JSON.stringify(l) : ""));
Spotify.Web.Cookie.set(c, d, {
ttl: j,
path: g,
secure: window.location && window.location.protocol ===
"https:"
}, f);
typeof a !== "undefined" && a()
})
};
var h = function(a) {
return a.replace(/\=/g, "_")
};
this._getCookieName = function(b) {
typeof k !== "undefined" && b(k);
a.getUsername(function(a) {
k = "spp_" + CryptoJS.MD5(c + a).toString().substring(0, 8);
b(k)
}, function() {})
};
this.init = function(a) {
var b = this;
typeof l !== "undefined" ? a() : this._read(function() {
b._migrate(a)
})
};
this._migrate = function(a) {
if (typeof l !== "undefined")
for (var c in l)
if (l.hasOwnProperty(c)) {
a();
return
}
var d = this;
this._getOldCookieName(function(c) {
var g =
Spotify.Web.Cookie.get(c, f),
h;
if (g) try {
h = JSON.parse(b.decode(g.replace(/\_/g, "=")))
} catch (j) {}
typeof h !== "undefined" && (l = h, d._write(), Spotify.Web.Cookie.remove(c));
a()
}, function() {
a()
})
};
this._getOldCookieName = function(d) {
a.getUsername(function(a) {
d(h(b.encode(c + a)))
}, function() {
d(void 0)
})
};
this.get = function(a) {
if (typeof l === "undefined") throw Error("Cookie " + c + " is not ready to be used yet!");
return l[a]
};
this.set = function(a, b) {
l || (l = {});
l[a] = b;
this._write()
};
this.remove = function(a) {
return typeof l[a] !==
"undefined" ? (delete l[a], this._write(), !0) : !1
};
this.destroy = function() {
l = {};
this._write()
}
};
Spotify.Web.Bookmark = function(c, a) {
this.STORAGE_KEY = "bookmark_seen";
this.TIME_UNTIL_SHOWN = 1E4;
var b = this;
this.init = function() {
this.hasBeenShown() || typeof chrome !== "undefined" && chrome.app.isInstalled || setTimeout(function() {
b.show();
b.markAsShown()
}, this.TIME_UNTIL_SHOWN)
};
this.show = function() {
c.notify(Spotify.Web.PublisherMessages.ERROR, {
type: Spotify.Web.ErrorTypes.BOOKMARK
})
};
this.markAsShown = function() {
a.set(this.STORAGE_KEY, !0)
};
this.hasBeenShown = function() {
return a.get(this.STORAGE_KEY)
}
};
Spotify.Web.Settings.Model = function(c, a, b, d, f, j, g) {
Spotify.Web.EventTarget.call(this);
var k = this,
g = g || Spotify.Web.Cookie,
l, h, m, n, e, o, t, C, v = !1,
z = "",
w, A, x, u, y = window.navigator.userAgent.indexOf("MSIE 9") !== -1;
this._callbacks = [];
this._ready = !1;
this.init = function() {
function c(a, f) {
if (!a) l = f.product, u = f.publicToplist, A = f.publishActivity, x = f.publishPlaylists, m = f.postOpenGraph === "1", t = (C = f.developer) && d.get("dm") === "1", y || d.get("lastfm"), h = b.get("ps") === "1", n = g.get("is_spotified") === "yes", e = d.get("appnotifs") ===
"1", o = g.get("locale", null), h && (x = A = !1), k._onReady()
}
d.init(function() {
a.request("session_query", [], c)
})
};
this._onReady = function() {
this._ready = !0;
for (var a = 0; a < this._callbacks.length; a++) this._callbacks[a]();
this._callbacks = []
};
this.setServices = function(a) {
w = a
};
this.onReady = function(a) {
this._ready ? a() : this._callbacks.push(a)
};
this.getLastFmUser = function() {
return z
};
this.setLastFmUser = function(a) {
z = a;
d.set("lastfm-user", a);
this.onUpdated()
};
this.getProduct = function() {
return j.isAnonymous() ? "anonymous" :
l
};
this.getPrivateSession = function() {
return h
};
this.getPublishToFacebookState = function(a) {
w.getFacebookUserId(function(b) {
!b || b === "None" ? a(null, {
is_connected: !1
}) : f.checkPublishActionsPermissions(function(b, c) {
b ? b === "not_logged_in" ? a(null, {
is_connected: !0,
is_logged_in: !1
}) : a(b) : a(null, {
is_connected: !0,
is_logged_in: !0,
publish_allowed: c
})
})
})
};
this.setPrivateSession = function(a, c, d, e) {
h = a;
c && b.set("ps", h ? "1" : "0");
if (!e && (h ? (b.set("soc_pa", this.getPublishActivity() ? "1" : "0"), b.set("soc_pp", this.getPublishPlaylist() ?
"1" : "0"), b.set("soc_og", m ? "1" : "0"), this.setPublishActivity(!1, !1, !1), this.setPublishPlaylist(!1, !1, !1), this.setPostToOpenGraph(!1, !1, !1)) : (this.setPublishActivity(b.get("soc_pa") === "1", !1, !1), this.setPublishPlaylist(b.get("soc_pp") === "1", !1, !1), this.setPostToOpenGraph(b.get("soc_og") === "1", !1, !1)), d)) this.onUpdated()
};
this.getOpenUrlsDesktops = function() {
return n || !1
};
this.setOpenUrlsDesktops = function(a) {
(n = a) ? g.set("is_spotified", "yes", {
domain: g.domain,
ttl: 1337
}): g.remove("is_spotified", null, g.domain)
};
this.getAppNotifications = function() {
return e
};
this.setAppNotifications = function(a) {
e = a;
d.set("appnotifs", e ? "1" : "0")
};
this.getLastFmConnected = function() {
return v
};
this.setLastFmConnected = function(a) {
v = a;
d.set("lastfm-connected", v ? "1" : "0");
this.onUpdated()
};
this.lastFmDisconnect = function() {
var a = this;
c.user.setUserAttribute("lastfm_session", "", function() {
a.setLastFmConnected(!1);
a.setLastFmUser("")
}, function() {})
};
this.lastFmConnect = function(a, b) {
var d = this;
c.user.setUserAttribute("lastfm_session",
b + "|" + a,
function() {
d.setLastFmConnected(!0);
d.setLastFmUser(a)
},
function() {})
};
this.getLastFmScrobble = function() {
return this.getLastFmConnected() && !h
};
this.connectToLastFm = function() {
this.trigger(Spotify.Web.PublisherMessages.LASTFM_CONNECT)
};
this.connectToFacebook = function(a, b) {
f.connectUser(function(d, e) {
c.facebook.enable(e, a, b)
}, b)
};
this.getPublishActivity = function() {
return A
};
this.setPublishActivity = function(a, b, c) {
A = a;
if (b) this._setUserAttribute("publish_activity", A ? "1" : "0", c);
else if (c) k.onUpdated()
};
this.getPublishPlaylist = function() {
return x
};
this.setPublishPlaylist = function(a, b, c) {
x = a;
if (b) this._setUserAttribute("publish_playlist", x ? "1" : "0", c);
else if (c) k.onUpdated()
};
this.getPostToOpenGraph = function(a) {
this.getPublishToFacebookState(function(b, c) {
b || !c.is_connected || !c.publish_allowed ? a(!1) : a(m)
})
};
this.setPostToOpenGraph = function(a, b, c) {
var d = function(a) {
m = a;
if (b) k._setUserAttribute("post_open_graph", a ? "1" : "0", c);
else if (c) k.onUpdated()
};
a ? this.getPublishToFacebookState(function(a, b) {
!a &&
b.is_connected && b.publish_allowed ? d(!0) : f.requestExtentedPermissions(function(a, b) {
if (a || !b) {
if (c) k.onUpdated()
} else d(!0)
})
}) : d(!1)
};
this.getPublicTopTracks = function() {
return u & 4 ? !0 : !1
};
this.setPublicTopTracks = function(a, b, c) {
u = a ? u |= 4 : u &= -5;
if (b) this._setUserAttribute("public_toplist", u.toString(), c);
else if (c) k.onUpdated()
};
this.getPublicTopArtists = function() {
return u & 1 ? !0 : !1
};
this.setPublicTopArtists = function(a, b, c) {
u = a ? u |= 1 : u &= -2;
if (b) this._setUserAttribute("public_toplist", u.toString(), c);
else if (c) k.onUpdated()
};
this.setLocale = function(a, b) {
o = a;
Spotify.Web.Cookie.set("locale", a, {
ttl: 1460
});
this._setUserAttribute("preferred_locale", o ? o : "", !1);
if (b) this.onUpdated()
};
this._setUserAttribute = function(b, c, d) {
a.request("user_set_attribute", [b, c], function() {
if (d) k.onUpdated()
})
};
this.getLocale = function() {
return o || "en"
};
this.setDeveloperMode = function(a) {
t = a;
d.set("dm", t ? "1" : "0")
};
this.getDeveloperMode = function() {
return t || !1
};
this.isDeveloperModeAllowed = function() {
return C || !1
};
this.triggerSignUp = function() {
j.signUp(function() {})
};
this.triggerLogin = function() {
j.login(function() {})
};
this.onUpdated = function() {
this.trigger(Spotify.Web.PublisherMessages.MODEL_UPDATED)
}
};
Spotify.Web.Settings.View = function(c, a) {
Spotify.Web.EventTarget.call(this);
var b = this;
this._scrollBlocker = c.scrollBlocker;
this._wrapper = c.wrapper;
this._isOpen = !1;
var d = window.navigator.userAgent.indexOf("MSIE 9") !== -1,
f = c.publisher,
j = function(a) {
a.preventDefault();
b._model.triggerSignUp()
},
g = function(a) {
a.preventDefault();
b.trigger(Spotify.Web.PublisherMessages.APPLICATION_OPEN_URI, {
link: Spotify.Link.fromString("spotify:app:purchase")
})
};
this.init = function() {
b._eUserBasedSettings = b._wrapper.querySelector(".user-settings");
d && (b._eUserBasedSettings.className += " ie9");
var a = b._wrapper.querySelector("#about-link");
a && a.addEventListener("click", function(a) {
a.preventDefault();
b.trigger(Spotify.Web.PublisherMessages.APPLICATION_OPEN_URI, {
link: Spotify.Link.fromString("spotify:app:" + this.getAttribute("data-href"))
});
b._wrapper.blur()
}, !1);
(a = b._wrapper.querySelector("#spotify-jazz-panel a")) && a.addEventListener("click", function(a) {
a.preventDefault();
b.trigger(Spotify.Web.PublisherMessages.APPLICATION_OPEN_URI, {
link: Spotify.Link.fromString("spotify:app:labs")
});
b._wrapper.blur()
}, !1);
f.subscribe(Spotify.Web.PublisherMessages.SOCIAL_DATA_SUCCESS, this);
f.subscribe(Spotify.Web.PublisherMessages.USER_INTERACTION, this)
};
this.onNotify = function(a) {
switch (a.messageType) {
case Spotify.Web.PublisherMessages.SOCIAL_DATA_SUCCESS:
b.addUserInfo(a.message)
}
};
this.setServices = function() {};
this.setModel = function(a) {
this.hideLoadingIndicator();
this.createUserBasedDOM();
this.addUserBasedEventListeners();
this._model = a;
this._model.onReady(function() {
b._model.setLocale(b._currentLocale, !1);
b._model.bind(Spotify.Web.PublisherMessages.MODEL_UPDATED, b.onModelUpdated);
b.onModelUpdated()
})
};
this.hideLoadingIndicator = function() {
b._wrapper.querySelector(".initial").style.display = "none"
};
this.createUserBasedDOM = function() {
var c = "",
c = a.cat_enabled ? ['<div class="account" id="account-info">\n <div id="account-info-pic" class="media simple user">\n <div class="media-image placeholder-visible">\n <a class="media-placeholder">\n <svg viewBox="0 0 10 10" preserveAspectRatio="xMidYMid meet">\n <text class="user-placeholder" x="5" y="9.8">&#xf15d;</text>\n </svg>\n </a>\n <div class="media-image-internal">\n <span class="verified-badge">\n <span class="spoticon-check-16"></span>\n </span>\n </div>\n </div>\n </div>\n <div class="clearfix"></div>\n <div id="user-name" class="hdr-l text-center"></div>\n <div class="account text-center text-secondary">',
" " + _("Account") + " :", ' <span id="account-type"></span>\n </div>\n <div class="account-links text-center">', ' <a target="_blank" class="btn btn-info" href="/redirect/www/account-page/">' + _("View Account") + "</a>", ' <a id="btn-upgrade" target="_blank" href="/redirect/www/upgrade-product/" class="btn btn-primary">' + _("Upgrade") + "</a>", ' </div>\n</div>\n<div class="section hidden">', ' <div class="description lang-select">' + _("Choose language") + "</div>", ' <div class="action" id="lang-select"></div>\n <div id="lang-changed">\n <span></span>\n <a class="reload" href="/"></a>\n </div>\n</div>\n<div class="section privatesession">',
' <div class="description">' + _("Private Session"), ' <div id="private-session-indicator" class="description-subtitle">', " " + _("Private session lasts until you log out."), ' </div>\n </div>\n <div class="action" id="private-session"></div>\n</div>'
].join("\n") : ['<div class="section account" id="account-info">\n <div class="description">\n <div class="wrapper" id="user-info">\n <div id="user-name"></div>\n <div class="account">', " " + _("Account") + " :", ' <span id="account-type"></span>\n </div>\n </div>\n </div>\n <div class="action account-links">',
' <a target="_blank" class="button" href="/redirect/www/account-page/">' + _("View Account") + "</a>", ' <a id="btn-upgrade" target="_blank" href="/redirect/www/upgrade-product/" class="button primary">' + _("Upgrade") + "</a>", ' </div>\n</div>\n<div class="section hidden">', ' <div class="description lang-select">' + _("Choose language") + "</div>", ' <div class="action" id="lang-select"></div>\n <div id="lang-changed">\n <span></span>\n <a class="reload" href="/"></a>\n </div>\n</div>\n<div class="section privatesession">',
' <div class="description">' + _("Private Session") + "</div>", ' <div class="action" id="private-session"></div>\n <div id="private-session-indicator"><span></span>', " <p><strong>" + _("Private Session") + "</strong>", " <span>" + _("Private session lasts until you log out.") + "</span></p>", " </div>\n</div>"
].join("\n");
b._eUserBasedSettings.innerHTML = [c, '<div class="section hidden fbconnect" id="fbconnect">', ' <div class="description">' + _("Connect my account to Facebook") + "</div>", ' <div class="action" id="connect-to-fb"></div>',
' <a id="fbconnect-btn" href="#" class="button btn btn-info pull-right">' + _("Connect") + "</a>", ' <div class="spinner" class="hidden" id="fbconnect-spinner"><img src="' + a.cdn + '/images/loading_throbber.gif" alt=""></div>', '</div>\n<div class="section hidden fb" id="og-share">', ' <div class="description">' + _("Share activity on Facebook") + "</div>", ' <div class="action" id="post-to-open-graph"></div>\n <div class="privatemode"></div>\n</div>\n<div class="section">', ' <div class="description">' + _("Share my activity and what I listen to with my followers on Spotify") +
"</div>", ' <div class="action" id="publish-activity"></div>\n <div class="privatemode"></div>\n</div>\n<div class="section">', ' <div class="description">' + _("Automatically make new playlists public") + "</div>", ' <div class="action" id="publish-playlist"></div>\n</div>\n<div class="section">', ' <div class="description">' + _("Show the Top Artists I've been listening to") + "</div>", ' <div class="action" id="public-top-artists"></div>\n</div>\n<div class="section">', ' <div class="description">' + _("Play open.spotify.com URLs in desktop app") +
"</div>", ' <div class="action" id="open-urls-desktop"></div>\n</div>\n<div class="section hidden notif">', ' <div class="description">' + _("Show app notifications") + "</div>", ' <div class="action" id="app-notifications"></div>\n</div>\n<div class="section hidden devmode">', ' <div class="description">' + _("Enable developer mode") + "</div>", ' <div class="action" id="developer-mode"></div>', ' <div id="developer-mode-changed"><span>' + _("Your changes will be applied when you reload the page."), ' </span><a class="button primary" href="/">' +
_("Reload now") + "</a>", ' </div>\n</div>\n<div class="section lastfm">', ' <div class="description">' + _("Scrobble to Last.fm") + "</div>", ' <div class="action" id="lastfm-scrobble"></div>', ' <a id="lastfm-connect" href="#" class="button btn btn-info pull-right">' + _("Connect") + "</a>", ' <div id="lastfm-connected"></div>\n <div class="privatemode"></div>\n</div>'
].join("\n");
this._eAccountInfoWrap = b._eUserBasedSettings.querySelector("#account-info");
this._eUserInfo = b._eUserBasedSettings.querySelector("#user-info");
this._eUserName = b._eUserBasedSettings.querySelector("#user-name");
this._eLangSelectWrap = b._eUserBasedSettings.querySelector("#lang-select");
this._eLangSelector = b._eUserBasedSettings.ownerDocument.createElement("select");
this._eLangChangedNotifier = b._eUserBasedSettings.querySelector("#lang-changed");
this._eProduct = b._eUserBasedSettings.querySelector("#account-type");
this._ePrivateSessionWrapper = b._eUserBasedSettings.querySelector("#private-session");
this._ePrivateSessionIndicator = b._eUserBasedSettings.querySelector("#private-session-indicator");
this._ePostToOpenGraphWrapper = b._eUserBasedSettings.querySelector("#post-to-open-graph");
this._ePublishActivityWrapper = b._eUserBasedSettings.querySelector("#publish-activity");
this._ePublishPlaylistWrapper = b._eUserBasedSettings.querySelector("#publish-playlist");
this._ePublicTopArtistsWrapper = b._eUserBasedSettings.querySelector("#public-top-artists");
this._eOpenUrlsDesktopsWrapper = b._eUserBasedSettings.querySelector("#open-urls-desktop");
this._eAppNotificationsWrapper = b._eUserBasedSettings.querySelector("#app-notifications");
this._eMediaImage = b._eUserBasedSettings.querySelector(".media-image");
this._eMediaImageInternal = b._eUserBasedSettings.querySelector(".media-image-internal");
this._eDeveloperModeWrapper = b._eUserBasedSettings.querySelector("#developer-mode");
this._eDeveloperModeChangedNotifier = b._eUserBasedSettings.querySelector("#developer-mode-changed");
this._eFbConnectWrapper = b._eUserBasedSettings.querySelector("#fbconnect");
this._eFbConnectBtn = b._eUserBasedSettings.querySelector("#fbconnect-btn");
this._eFbConnectSpinner =
b._eUserBasedSettings.querySelector("#fbconnect-spinner");
this._eFbOptionsWrapper = b._eUserBasedSettings.querySelector("#og-share");
this._eLastFmWrapper = b._eUserBasedSettings.querySelector("#lastfm-scrobble");
this._eLastFmConnect = b._eUserBasedSettings.querySelector("#lastfm-connect");
this._eLastFmConnected = b._eUserBasedSettings.querySelector("#lastfm-connected");
this._eUpgradeBtn = b._eUserBasedSettings.querySelector("#btn-upgrade");
b._eUpgradeBtn.style.display = "none";
this._eLogoutBtn = b._wrapper.querySelector(".logout");
this._ePrivateModeDisablers = b._wrapper.querySelectorAll(".privatemode");
this._spotifyJazzPanel = b._wrapper.querySelectorAll("#spotify-jazz-panel")[0];
this._ePrivateSession = new Spotify.Web.Widgets.Toggle({
onChange: function() {
b._model.setPrivateSession(this.isActive, !0, !0)
},
activated: !1,
document: b._eUserBasedSettings.ownerDocument
});
this._ePrivateSessionWrapper.appendChild(this._ePrivateSession.node);
this._ePostToOpenGraph = new Spotify.Web.Widgets.Toggle({
onChange: function() {
b._model.setPostToOpenGraph(this.isActive, !0, !0)
},
activated: !1,
document: b._eUserBasedSettings.ownerDocument
});
this._ePostToOpenGraphWrapper.appendChild(this._ePostToOpenGraph.node);
this._ePublishActivity = new Spotify.Web.Widgets.Toggle({
onChange: function() {
b._model.setPublishActivity(this.isActive, !0, !0)
},
activated: !1,
document: b._eUserBasedSettings.ownerDocument
});
this._ePublishActivityWrapper.appendChild(this._ePublishActivity.node);
this._ePublishPlaylist = new Spotify.Web.Widgets.Toggle({
onChange: function() {
b._model.setPublishPlaylist(this.isActive, !0, !0)
},
activated: !1,
document: b._eUserBasedSettings.ownerDocument
});
this._ePublishPlaylistWrapper.appendChild(this._ePublishPlaylist.node);
this._ePublicTopArtists = new Spotify.Web.Widgets.Toggle({
onChange: function() {
b._model.setPublicTopArtists(this.isActive, !0, !0)
},
activated: !1,
document: b._eUserBasedSettings.ownerDocument
});
this._ePublicTopArtistsWrapper.appendChild(this._ePublicTopArtists.node);
this._eOpenUrlsDesktops = new Spotify.Web.Widgets.Toggle({
onChange: function() {
b._model.setOpenUrlsDesktops(this.isActive)
},
activated: !1,
document: b._eUserBasedSettings.ownerDocument
});
this._eOpenUrlsDesktopsWrapper.appendChild(this._eOpenUrlsDesktops.node);
this._eAppNotifications = new Spotify.Web.Widgets.Toggle({
onChange: function() {
b._model.setAppNotifications(this.isActive)
},
activated: !1,
document: b._eUserBasedSettings.ownerDocument
});
this._eAppNotificationsWrapper.appendChild(this._eAppNotifications.node);
this._eDeveloperMode = new Spotify.Web.Widgets.Toggle({
onChange: function() {
b._model.setDeveloperMode(this.isActive);
b.onDeveloperModeChange()
},
activated: !1,
document: b._eUserBasedSettings.ownerDocument
});
this._eDeveloperModeWrapper.appendChild(this._eDeveloperMode.node);
this._eLastFmConnect.addEventListener("click", function(a) {
a.preventDefault();
b._model.connectToLastFm()
}, !1);
var d = function(a) {
a.className.indexOf("hidden") == -1 && (a.className += " hidden")
},
f = function(a) {
a.className = a.className.replace("hidden", "")
};
this.userHasFacebook = function() {
b._eFbOptionsWrapper.className = "section";
d(b._eFbConnectWrapper)
};
this.userDoesNotHaveFacebook =
function() {
f(b._eFbConnectWrapper);
d(b._eFbOptionsWrapper)
};
this.manageFacebookOptions = function() {
b._model.getPublishToFacebookState(function(a, c) {
d(b._eFbConnectSpinner);
f(b._eFbConnectBtn);
a || !c.is_connected ? b.userDoesNotHaveFacebook() : b.userHasFacebook()
})
};
b._eFbConnectBtn.addEventListener("click", function(a) {
a.preventDefault();
d(b._eFbConnectBtn);
f(b._eFbConnectSpinner);
b._model.connectToFacebook(b.manageFacebookOptions, function() {
f(b._eFbConnectBtn);
d(b._eFbConnectSpinner)
})
}, !1);
if (typeof chrome !==
"undefined" && chrome.app.isInstalled) b._eUserBasedSettings.querySelector(".notif").className = "section";
if (a.locale.available.length > 1) b._eLangSelectWrap.parentNode.className = "section";
b._currentLocale = a.locale.current;
for (var c = b._eUserBasedSettings.ownerDocument.createDocumentFragment(), g = 0; g < a.locale.available.length; g++) {
var e = a.locale.available[g],
j = b._eUserBasedSettings.ownerDocument.createElement("option");
j.textContent = _("lang/" + e);
j.value = e;
e === a.locale.current && j.setAttribute("selected", "selected");
c.appendChild(j)
}
b._eLangSelector.appendChild(c);
b._eLangSelectWrap.appendChild(b._eLangSelector);
b._eLangSelector.addEventListener("change", function() {
var a = this.options[this.selectedIndex].value;
a !== b._model.getLocale() && b._model.setLocale(a, !0)
})
};
this.addUserInfo = function(c) {
if (c.image !== "") {
if (a.cat_enabled) this._eMediaImageInternal.style.backgroundImage = "url(" + c.image + ")", this._eMediaImage.removeClass("placeholder-visible");
else {
var d = new Image;
d.onload = function() {
b._eUserInfo.addClass("user-info-added");
b._eAccountInfoWrap.addClass("user-info-added");
b._eUserInfo.appendChild(this);
setTimeout(function() {
d.className = "show"
}, 10)
};
d.src = c.image
}
profileImage = c.image
}
if (c.name !== "") b._eUserName.textContent = c.name + " " + c.surname
};
this.addUserBasedEventListeners = function() {
this._eLogoutBtn.addEventListener("click", k, !1)
};
this.getVerboseProductName = function(a) {
if (a === "anonymous") return _("Not signed in");
else if (a === "free" || a === "open") return _("Free");
else if (a === "basic-desktop") return _("Unlimited");
else if (a ===
"premium") return _("Premium");
return _("Unknown")
};
this.onDeveloperModeChange = function() {
this._eDeveloperModeChangedNotifier.className = "show"
};
this.onLocaleChange = function() {
var c = new XMLHttpRequest;
c.onreadystatechange = function() {
if (c.readyState === 4 && c.status === 200) {
//TODO add Try/Catch. What would happen if you can't parse c.responseText?
var a = JSON.parse(c.responseText),
d = "Your language choice will be applied when you reload the page.";
a[d] && (d = a[d]);
var e = "Reload now";
a[e] && (e = a[e]);
b._eLangChangedNotifier.querySelector("span").innerHTML = d;
b._eLangChangedNotifier.querySelector("a").innerHTML =
e;
b._eLangChangedNotifier.className = "show"
}
};
var d = "/xhr/json/translations.php?locale=" + b._model.getLocale() + "&cb=" + a.version;
c.open("GET", d, !0);
c.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
c.send()
};
this.onPrivateSessionOn = function() {
this._ePrivateSession.activate(!0);
this._ePrivateSessionIndicator.addClass("show");
for (var a = 0; a < this._ePrivateModeDisablers.length; a++) this._ePrivateModeDisablers[a].addClass("show")
};
this.onPrivateSessionOff = function() {
this._ePrivateSession.deactivate(!0);
this._ePrivateSessionIndicator.removeClass("show");
for (var a = 0; a < this._ePrivateModeDisablers.length; a++) this._ePrivateModeDisablers[a].removeClass("show")
};
this.getContent = function() {
return this._wrapper
};
this.onModelUpdated = function() {
b.manageFacebookOptions();
var c = b._model.getProduct();
if (c === "free" || c === "open") b._eLogoutBtn.style.display = "inline-block";
if (c === "anonymous") b._eLogoutBtn.style.display = "none";
if (c === "premium") b._eProduct.className = "premium";
b._eProduct.innerHTML = b.getVerboseProductName(c);
b._upgradeBtnUrl && b._upgradeBtnText ? (b._eUpgradeBtn.textContent = b._upgradeBtnText, b._eUpgradeBtn.style.display = "inline-block", b._eUpgradeBtn.addEventListener("click", g)) : c === "anonymous" ? (b._eUpgradeBtn.style.display = "inline-block", b._eUpgradeBtn.textContent = _("Sign Up"), b._eUpgradeBtn.addEventListener("click", j), b._eUpgradeBtn.removeEventListener("click", g)) : (b._eUpgradeBtn.removeEventListener("click", j), b._eUpgradeBtn.addEventListener("click", g));
b._model.getPrivateSession() ? b.onPrivateSessionOn() :
b.onPrivateSessionOff();
b._model.getPostToOpenGraph(function(a) {
a ? b._ePostToOpenGraph.activate(!0) : b._ePostToOpenGraph.deactivate(!0)
});
b._model.getPublishActivity() ? b._ePublishActivity.activate(!0) : b._ePublishActivity.deactivate(!0);
b._model.getPublishPlaylist() ? b._ePublishPlaylist.activate(!0) : b._ePublishPlaylist.deactivate(!0);
b._model.getPublicTopArtists() ? b._ePublicTopArtists.activate(!0) : b._ePublicTopArtists.deactivate(!0);
b._model.getOpenUrlsDesktops() ? b._eOpenUrlsDesktops.activate() : b._eOpenUrlsDesktops.deactivate();
b._model.getAppNotifications() ? b._eAppNotifications.activate() : b._eAppNotifications.deactivate();
c = b._model.getLocale();
b._model.getDeveloperMode() ? b._eDeveloperMode.activate(!0) : b._eDeveloperMode.deactivate(!0);
if (b._model.isDeveloperModeAllowed()) {
var d = b._eUserBasedSettings.querySelector(".devmode");
if (d) d.className = "section"
}
if (b._currentLocale && c !== b._currentLocale) b._currentLocale = c, b.onLocaleChange();
b._model.getLastFmConnected() ? (b._eLastFmConnect.style.display = "none", b._eLastFmConnected.style.display =
"block", b._eLastFmConnected.innerHTML = ": " + _("Connected as <strong>{{USERNAME}}</strong>. <a target='_blank' href='{{DISCONNECT_URL}}'>(Disconnect)</a>", {
USERNAME: b._model.getLastFmUser() || "",
DISCONNECT_URL: "http://www.last.fm/settings/applications"
}), b._eLastFmConnected.querySelector("a").addEventListener("click", function() {
b._model.lastFmDisconnect()
}, !1)) : (b._eLastFmConnect.style.display = "block", b._eLastFmConnected.style.display = "none");
b._spotifyJazzPanel.style.display = a.features.labs ? "block" :
"none"
};
this.setUpgradeButton = function(a, b) {
this._upgradeBtnUrl = b ? b : "/redirect/www/upgrade-product/";
this._upgradeBtnText = a;
this._eUpgradeBtn.style.display = "inline"
};
var k = function() {
b._model.setPrivateSession(!1, !0, !1, !0)
}
};
Spotify.Web.SettingsApp = function(c) {
var a = document.createElement("div");
a.id = "settings-pane";
a.className = "col-sm-12 col-md-10 col-lg-8 col-md-offset-1 col-lg-offset-2";
_("Need more help? {{LINK_START}}Read the guide{{LINK_END}}", {
LINK_START: '<a target="_blank" href="http://www.spotify.com/help/guides/account/">',
LINK_END: "</a>"
});
_("Your Spotify Download should start within seconds. If it doesn't, {{LINK_START}}restart the download{{LINK_END}}", {
LINK_START: '<a href="http://download.spotify.com/Spotify%20Installer.exe">',
LINK_END: "</a>"
});
_("Your Spotify Download should start within seconds. If it doesn't, {{LINK_START}}restart the download{{LINK_END}}", {
LINK_START: '<a href="http://download.spotify.com/SpotifyInstaller.zip">',
LINK_END: "</a>"
});
a.innerHTML = c ? ['<div class="main">\n <div class="initial section">\n <div class="description">', " " + _("Loading") + "...", ' </div>\n </div>\n <div class="user-settings"><\!-- User based settings will be added here --\></div>\n <div id="spotify-jazz-panel" style="display: none">',
" " + _("SettingsJazzIntroLine"), ' <a href="#">' + _("SettingsJazzLink") + "</a>", ' </div>\n <div class="logout-area text-center">', ' <a id="logout-settings" href="/logout" class="logout btn btn-info">' + _("Log Out") + "</a>", ' </div>\n <div class="text-center text-secondary">', ' <a href="/about" data-href="about" id="about-link">' + _("About") + "</a> &nbsp;|&nbsp;", ' <a href="https://www.spotify.com/legal/end-user-agreement/?utm_source=web-player" target="_blank" id="legal-link">' + _("Legal") +
"</a> &nbsp;|&nbsp;", ' <a href="/redirect/www/help/" target="_blank" id="help-link">' + _("Help") + "</a>", " </div>\n</div>"
].join("\n") : ['<div class="main">', " <h2>" + _("Settings") + "</h2>", ' <a id="logout-settings" href="/logout" class="logout button">' + _("Log Out") + "</a>", ' <div class="initial section">\n <div class="description">', " " + _("Loading") + "...", ' </div>\n </div>\n <div class="user-settings"><\!-- User based settings will be added here --\></div>\n <div id="spotify-jazz-panel" style="display: none">',
" " + _("SettingsJazzIntroLine"), ' <a href="#">' + _("SettingsJazzLink") + "</a>", ' </div>\n <div class="bottom">\n <div class="description">', ' <a href="/about" data-href="about" id="about-link">' + _("About") + "</a> &nbsp;|&nbsp;", ' <a href="https://www.spotify.com/legal/end-user-agreement/?utm_source=web-player" target="_blank" id="legal-link">' + _("Legal") + "</a> &nbsp;|&nbsp;", ' <a href="/redirect/www/help/" target="_blank" id="help-link">' + _("Help") + "</a>", " </div>\n </div>\n</div>"
].join("\n");
this.getElement = function() {
return a
};
this.destroyElement = function() {}
};
Spotify.Web.Settings.Anonymous = function(c, a) {
Spotify.Web.EventTarget.call(this);
var b = this;
this._scrollBlocker = c.scrollBlocker;
this._wrapper = c.wrapper;
this._isOpen = !1;
var d = c.publisher;
this.init = function() {
b._eUserBasedSettings = b._wrapper.querySelector(".user-settings");
var a = b._wrapper.querySelector("#about-link");
a && a.addEventListener("click", function(a) {
a.preventDefault();
b.trigger(Spotify.Web.PublisherMessages.APPLICATION_OPEN_URI, {
link: Spotify.Link.fromString("spotify:app:" + this.getAttribute("data-href"))
});
b._wrapper.blur()
}, !1);
d.subscribe(Spotify.Web.PublisherMessages.USER_INTERACTION, this)
};
this.onNotify = function(a) {
switch (a.messageType) {
case Spotify.Web.PublisherMessages.USER_INTERACTION:
b.close()
}
};
this.setServices = function() {};
this.setModel = function(a) {
this.hideLoadingIndicator();
this.createUserBasedDOM();
this._model = a;
this._model.bind(Spotify.Web.PublisherMessages.MODEL_UPDATED, this.onModelUpdated);
this.onModelUpdated()
};
this.hideLoadingIndicator = function() {
b._wrapper.querySelector(".initial").style.display =
"none"
};
this.createUserBasedDOM = function() {
b._eUserBasedSettings.innerHTML = ['<div class="section account anon">\n <div class="description">\n </div>\n <div class="action">', ' <a id="btn-login" href="#" class="button">' + _("Log In") + "</a>&nbsp;", ' <a id="btn-signup" href="#" class="button primary">' + _("Sign Up") + "</a>", ' </div>\n</div>\n<div class="section hidden">', ' <div class="description">' + _("Choose language") + ": </div>", ' <div class="action anon" id="lang-select"></div>\n <div id="lang-changed">\n <span></span>\n <a class="reload" href="/"></a>\n </div>\n</div>'].join("\n");
this._eLangSelectWrap = b._eUserBasedSettings.querySelector("#lang-select");
this._eLangSelector = b._eUserBasedSettings.ownerDocument.createElement("select");
this._eLangChangedNotifier = b._eUserBasedSettings.querySelector("#lang-changed");
this._eSignupButton = b._eUserBasedSettings.querySelector("#btn-signup");
this._eLoginButton = b._eUserBasedSettings.querySelector("#btn-login");
if (a.locale.available.length > 1) b._eLangSelectWrap.parentNode.className = "section";
b._currentLocale = a.locale.current;
for (var c = b._eUserBasedSettings.ownerDocument.createDocumentFragment(),
d = 0; d < a.locale.available.length; d++) {
var f = a.locale.available[d],
h = b._eUserBasedSettings.ownerDocument.createElement("option");
h.textContent = _("lang/" + f);
h.value = f;
f === a.locale.current && h.setAttribute("selected", "selected");
c.appendChild(h)
}
b._eLangSelector.appendChild(c);
b._eLangSelectWrap.appendChild(b._eLangSelector);
b._eLangSelector.addEventListener("change", function() {
var a = this.options[this.selectedIndex].value;
a !== b._model.getLocale() && b._model.setLocale(a, !0)
});
b._eSignupButton.addEventListener("click",
function(a) {
a.preventDefault();
b._model.triggerSignUp()
}, !1);
b._eLoginButton.addEventListener("click", function(a) {
a.preventDefault();
b._model.triggerLogin()
}, !1)
};
this.onLocaleChange = function() {
var c = new XMLHttpRequest;
c.onreadystatechange = function() {
if (c.readyState === 4 && c.status === 200) {
//TODO add Try/Catch. What would happen if you can't c.responseText
var a = JSON.parse(c.responseText),
d = "Your language choice will be applied when you reload the page.";
a[d] && (d = a[d]);
var f = "Reload now";
a[f] && (f = a[f]);
b._eLangChangedNotifier.querySelector("span").innerHTML = d;
b._eLangChangedNotifier.querySelector("a").innerHTML =
f;
b._eLangChangedNotifier.className = "show"
}
};
var d = "/xhr/json/translations.php?locale=" + b._model.getLocale() + "&cb=" + a.version;
c.open("GET", d, !0);
c.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
c.send()
};
this.onModelUpdated = function() {
b._model.getProduct();
var a = b._model.getLocale();
if (b._currentLocale) document.getElementsByTagName("html")[0].className = "lang-" + b._currentLocale;
if (b._currentLocale && a !== b._currentLocale) b._currentLocale = a, b.onLocaleChange()
};
this.open = function() {
if (!b._isOpen) b._wrapper.addClass("show"),
b._isOpen = !0, b._wrapper.focus(), b._wrapper.addClass("scale-start"), setTimeout(function() {
b._wrapper.addClass("scale-end")
}, 150), Spotify.Web.Utils.addTransitionEndedListener(b._wrapper, function() {
b._wrapper.removeClass("scale-start").removeClass("scale-end")
}, 2E3), b._scrollBlocker.activate(), window.addEventListener("keydown", j, !1), setTimeout(function() {
document.addEventListener("click", f, !1)
}, 500)
};
this.close = function() {
if (b._isOpen) b._scrollBlocker.deactivate(), b._wrapper.removeClass("show"), b._isOpen = !1, window.removeEventListener("keydown", j, !1), document.removeEventListener("click", f, !1)
};
var f = function(a) {
for (var c = !1, d = a.target; d.parentNode;)
if (d = d.parentNode, d.id === b._wrapper.id) {
c = !0;
a.target.tagName.toLowerCase() === "a" && setTimeout(function() {
b.close()
}, 300);
break
}
c || b.close()
},
j = function(a) {
a.keyCode === 27 && b.close()
};
this.toggleOpenClose = function() {
b._isOpen ? b.close() : b.open()
}
};
Spotify.Web.SpbMusicBridge = function(c, a, b, d, f, j, g) {
function k(a, b) {
F.hasOwnProperty(a) && (typeof E[a] == "undefined" && (E[a] = []), E[a].push(b))
}
function l(a, b, c) {
for (var c = c || u, b = b instanceof Array ? b : [b], d, e = 0, f = E[a].length; e < f; e++) d = E[a][e], d.apply(c, b)
}
function h(a, b) {
D.contentWindow.postMessage(JSON.stringify({
key: a,
data: b || {}
}), B)
}
function m(a) {
h("spb-error", a)
}
function n(a) {
z(function(b, c) {
if (c.track) {
var d = c.track.uri || "",
e = {
playing: a || c.playing,
playing_position: typeof c.position !== "object" ? c.position : 0,
track: d,
isAd: c.track.advertisement,
time: Date.now()
};
l("STATUS", e, d)
}
})
}
function e(a) {
if (typeof y.indexOf === "undefined") y.indexOf = function(a) {
for (var b = 0, c = this.length; b < c; b++)
if (this[b] == a) return b;
return -1
};
return y.indexOf(a) < 0 ? !1 : !0
}
function o() {
G || (G = !0, window.setTimeout(function() {
G = !1
}, 1E3))
}
function t(a) {
if (!G) {
o();
var b = a.track,
d = a.reason || null;
if (b && b.test(/^spotify:\w+(:.+)+$/) !== !1) {
var e = b.split(":"),
g = e[1] == "trackset" ? null : e[2],
h = a.context;
z(function(a, e) {
var j = e.track ? e.track.uri :
null,
k;
I[j] && (k = I[j]);
(b === j || b === k) && !e.playing ? f.resume() : setTimeout(function() {
c.openUri(Spotify.Link.fromString(h).toAppLink(), "", !1);
f.play(h, g, function() {
z(function(a, c) {
b !== c.track.uri && (I[c.track.uri] = b)
})
}, function(a) {
if (b && typeof a.uri === "undefined") a.uri = b;
l("ERROR", a);
n()
}, d)
}, 5)
})
}
}
}
function C() {
G || (o(), f.pause())
}
function v() {
z(function(a, b) {
n(b.playing)
})
}
function z(b) {
a.player.getState(b)
}
function w() {
a.player.registerForPlayerEvents(function(a, b) {
if (!a) switch (b.type) {
case "play":
n(!0);
break;
case "pause":
n(!1);
break;
case "stop":
n(!1);
break;
case "positionChanged":
A(b)
}
w()
})
}
function A() {
z(function(a, b) {
b.playing && n(b.playing)
})
}
function x(a) {
//TODO add Try/Catch. What would happen if you can't parse a.data?
if (e(a.origin)) switch (a = typeof a.data == "object" ? a.data : JSON.parse(a.data), a.key) {
case "connection-request":
l(F.CONNECT, a.data);
break;
case "spb-connected":
H = !0;
E = {
ERROR: [m],
STATUS: [p]
};
k(F.PLAY, t);
k(F.PAUSE, C);
k(F.CONNECT, v);
w();
b.subscribe(Spotify.Web.PublisherMessages.APPLICATION_CLOSED, u);
typeof g !== "undefined" ? l("ERROR", g) : l(F.CONNECT, a.data);
break;
case "status-message":
a.data.play === !0 ? l(F.PLAY, a.data) : l(F.PAUSE, a.data)
}
}
var u = this,
y = d || [],
B, D, G = !1,
E, F = {
PLAY: "PLAY",
PAUSE: "PAUSE",
STATUS: "STATUS",
CONNECT: "CONNECT"
},
I = {},
H = !1,
p = function() {
var a, b, c = 0;
return function(d) {
b = d;
c++;
a && clearTimeout(a);
a = setTimeout(function() {
a = null;
c = 0;
h("spb-event", b)
}, 10)
}
}();
return {
loadIframe: function(a) {
B = a;
a = document.createElement("iframe");
a.src = B;
document.body.appendChild(a);
D = a;
window.attachEvent && !window.addEventListener ? window.attachEvent("onmessage",
x) : window.addEventListener("message", x)
},
removeIframe: function() {
D && D.parentNode && D.parentNode.removeChild(D);
window.detachEvent && !window.removeEventListener ? window.detachEvent("onmessage", x) : window.removeEventListener("message", x)
},
isLoaded: function() {
return H
}
}
};
Spotify.Web.SpbMusicBridge._musicBridge = null;
Spotify.Web.SpbMusicBridge.initMusicBridge = function(c, a, b, d, f, j, g) {
if (Spotify.Web.SpbMusicBridge._musicBridge === null && d.music_bridge.enable === !0) {
var k = d.music_bridge,
l = k && k.retries || 1,
h = 0,
m = (k.timeout || 1) * 1E3,
n = null,
e = function(a, b) {
!a || !b || isNaN(b) ? f.warn("[SPB iframe could not load]") : (Spotify.Web.SpbMusicBridge._musicBridge.loadIframe(a), n = setTimeout(o, b))
},
o = function() {
clearTimeout(n);
Spotify.Web.SpbMusicBridge._musicBridge.isLoaded() || (Spotify.Web.SpbMusicBridge._musicBridge.removeIframe(), ++h <
l ? e(k.url, m) : f.warn("[SPB iframe could not load]"))
};
Spotify.Web.SpbMusicBridge._musicBridge = new Spotify.Web.SpbMusicBridge(c, a, b, k.allowed_sites, j, new Spotify.Events, g);
e(k.url, m)
}
};
Spotify.Web.SpbMusicBridge.isReferrerFromSPB = function(c) {
return /utm_source=(embed\.spotify|\w+\.yahoo)\.com/.test(c)
};
Spotify.Web.LastFm = function(c, a, b, d) {
Spotify.Web.EventTarget.call(this);
var f = this,
j = {};
new Spotify.Events;
var g, k, l = null,
h = null,
m = function(a) {
if (a.playing && a.__uid != h) {
var b = a.track;
if (b && !b.advertisement && (h = a.__uid, !(b.duration < 3E4))) {
var c = b.artists[0] || {},
a = Math.min(Math.floor(b.duration / 2) - a.position, 24E4);
clearTimeout(l);
l = setTimeout(function() {
k.scrobble(b.name, c.name || "", b.albumName || "", b.duration || 0)
}, a)
}
}
};
this.onModelUpdated = function() {
!b.getLastFmScrobble() || !k || k.getSession()
};
this.authenticateWithApi =
function() {
g.authenticate()
};
this.onSessionLost = function() {
k.setSession("");
b.lastFmDisconnect()
};
this.onScrobbleFailed = function() {};
var n = function(a, c) {
e();
j = c.data;
b.getLastFmScrobble() && c.type === "change" && m(j)
},
e = function() {
c.request("player_event_wait", ["main"], n)
};
this.init = function() {
if (d.enabled) a.user.onReady(function() {
a.user.getUserInfo(function(a) {
a = a || {};
g = new Spotify.Web.LastFmApi(d.key);
g.bind("SESSION_LOST", f.onSessionLost);
g.bind("SCROBBLE_FAILED", f.onScrobbleFailed);
k = new Spotify.Web.LastFmScrobbler(g,
a.user);
b.bind(Spotify.Web.PublisherMessages.MODEL_UPDATED, f.onModelUpdated);
b.bind(Spotify.Web.PublisherMessages.LASTFM_CONNECT, f.authenticateWithApi);
e();
d.token ? g.getSession(d.token, function(a) {
var c = a.split("|");
b.lastFmConnect(c[1], c[0]);
k.setSession(a)
}) : a && a.lastfm_session && (k.setSession(a.lastfm_session), b.setLastFmConnected(!0), b.setLastFmUser(a.lastfm_session.split("|")[1]))
}, function() {})
})
}
};
Spotify.Web.LastFmApi = function(c) {
Spotify.Web.EventTarget.call(this);
var a = this,
b = location.protocol + "//ws.audioscrobbler.com/2.0/";
this.call = function(a, b, c, d) {
var l = new Request({
url: b !== "GET" ? a : a += "&format=json",
method: b,
onSuccess: function(a) {
//TODO Add Try/Catch. I guess that d is a callback, What would happen if you can't parse a? and if this value is pass to d function?
d(JSON.parse(a))
},
onFailure: function(a) {
Spotify.Web.WebTracker.log({
type: "LASTFM_API_CALL_FAILED",
error: JSON.stringify({
request: l,
data: a
})
})
}
});
b === "POST" && (c += "&format=json");
l.setHeader("Content-type", "application/x-www-form-urlencoded");
l.send(c)
};
this.authenticate =
function() {
var a = encodeURIComponent("http://" + window.location.host + "/settings?lastfm=1");
window.location = "http://www.last.fm/api/auth/?api_key=" + c + "&cb=" + a
};
this.sign = function(a, b) {
var c = new XMLHttpRequest;
c.onreadystatechange = function() {
if (c.readyState === 4)
if (c.status !== 200 || c.responseText === "error") Spotify.Web.WebTracker.log({
type: "LASTFM_UNABLE_TO_SIGN_SCROBBLE_REQUEST",
error: JSON.stringify(a)
});
else {
//TODO add Try/Catch. What would happen if you can't parse c.responseText?, I guess that b is a callback function
var d = JSON.parse(c.responseText);
b(d.signature)
}
};
c.open("POST", "/xhr/json/lastfm/sign.php", !0);
c.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
c.send("data=" + a)
};
this.getSession = function(f, j) {
var g = d({
method: "auth.getSession",
api_key: c,
token: f
}),
k = b + "?" + g.query;
a.sign(g.string, function(b) {
k += "&api_sig=" + b;
a.call(k, "GET", null, function(a) {
a.session && a.session.key && j(a.session.key + "|" + a.session.name || "")
}, function(a) {
Spotify.Web.WebTracker.log({
type: "LASTFM_UNABLE_TO_COMMUNICATE_WITH_LASTFM",
error: JSON.stringify({
endpoint: k,
response: a
})
})
})
})
};
this.scrobble = function(f, j) {
var g = {
method: "track.scrobble",
api_key: c,
sk: j,
track: encodeURIComponent(f.track),
artist: encodeURIComponent(f.artist),
album: encodeURIComponent(f.album),
timestamp: f.timestamp
};
if (f.duration) g.duration = Math.round(f.duration / 1E3);
var k = d(g);
a.sign(k.string, function(c) {
for (var d in g)
if (d.indexOf("track") === 0 || d.indexOf("artist") === 0) encodeURIComponent(g[d] = g[d]);
a.call(b, "POST", k.query + "&api_sig=" + c, function(b) {
if (b.error) switch (Spotify.Web.WebTracker.log({
type: "LASTFM_UNABLE_TO_SCROBBLE",
error: JSON.stringify(b.error)
}),
b.error) {
case 9:
a.trigger("SESSION_LOST");
break;
default:
a.trigger("SCROBBLE_FAILED")
}
})
})
};
var d = function(a) {
var b = [],
c = "",
d = "",
l;
for (l in a) a.hasOwnProperty(l) && b.push(l);
b.sort();
for (l = 0; l < b.length; l++) c += b[l] + a[b[l]], d += b[l] + "=" + a[b[l]], l < b.length - 1 && (d += "&");
return {
string: c,
query: d
}
}
};
Spotify.Web.LastFmScrobbler = function(c) {
var a;
this.scrobble = function(b, d, f, j) {
a && a !== "" && (b = {
track: b,
artist: d,
album: f,
timestamp: Math.floor((new Date).getTime() / 1E3),
duration: j
}, c.scrobble(b, a))
};
this.getSession = function() {
return a || ""
};
this.setSession = function(b) {
a = b.split("|")[0]
}
};
Spotify.Web.Setup = function(c, a) {
var b = this,
d = CryptoJS.MD5((c.username || "") + (new Date).getTime()).toString().substring(0, 16);
this.publisher = new Spotify.Web.Publisher;
this._preloadAssets = function() {
for (var a = [c.cdn + "/images/loading_throbber.gif", c.cdn + "/images/logo.png"], b = 0; b < a.length; b++) this.assets.preloadImage(a[b])
};
this._onCoreConnected = function() {
this.appLoader.init();
this.bridge = new Spotify.Web.Bridge(SpotifyApi.api);
this.services = new Spotify.Web.Services(this.bridge, this.core.core.pubsub, this.tracking);
this.router.setServices(this.services);
this.stateHistory.setServices(this.services);
(new Spotify.Web.Ads.PixelTracker(this.bridge)).init();
this.appLogger = new Spotify.Web.AppLogger(this.core.core.logging.logger, d, this.router);
this.fbBridge = new Spotify.Web.Fb(this.publisher, this.assets, this.services);
(new Spotify.Web.SocialData(this.publisher, this.services, this.fbBridge)).init();
this.config.getFeature("messaging") && (new Spotify.Web.Messaging(this.publisher, this.services)).init();
this.config.getFeature("notifications") &&
(new Spotify.Web.Notifications(this.publisher, this.services)).init();
if (this.abTests.getTestGroup("NTX_sociomantic_track")) this.sociomantic = new Spotify.Web.Sociomantic(this, c.mhash)
};
this.init = function() {
try {
//TODO what is this line for?
JSON.parse = JSON.parse && function() {
var a = JSON.parse;
return function(b) {
try {
return a.apply(JSON, arguments)
} catch (c) {
throw new SyntaxError(c.message + ", context: " + b);
}
}
}()
} catch (d) {}
this.assets = new Spotify.Web.Static;
this.consoleLogger = new Spotify.Web.ConsoleLogger;
this.abTests = new Spotify.Web.ABTests(c.username);
this.config = new Spotify.Web.Config(c, this.abTests);
this.config.init();
this.stateHistory = new Spotify.Web.StateHistory.Manager({
sections: [{
link: Spotify.Link.applicationLink("home"),
type: "section"
}, {
link: Spotify.Link.applicationLink("browse"),
type: "section"
}, {
link: Spotify.Link.applicationLink("collection"),
type: "section"
}, {
link: Spotify.Link.applicationLink("labs"),
type: "section"
}, {
link: Spotify.Link.applicationLink("discover"),
type: "section"
}, {
link: Spotify.Link.applicationLink("radio"),
type: "section",
persistent: !0
}, {
link: Spotify.Link.applicationLink("playlist"),
type: "section"
}, {
link: Spotify.Link.applicationLink("purchase"),
type: "section"
}, {
link: Spotify.Link.applicationLink("follow"),
type: "section"
}, {
link: Spotify.Link.applicationLink("messages"),
type: "section"
}, {
link: Spotify.Link.applicationLink("social-feed"),
type: "section"
}, {
link: Spotify.Link.applicationLink("welcome"),
type: "section"
}, {
link: Spotify.Link.applicationLink("user"),
type: "section"
}, {
link: Spotify.Link.applicationLink("settings"),
type: "section",
persistent: !0
}, {
link: Spotify.Link.applicationLink("brand-header"),
type: "section"
}, {
link: Spotify.Link.applicationLink("suggest"),
type: "popup"
}, {
link: Spotify.Link.applicationLink("notification-center"),
type: "popup"
}, {
link: Spotify.Link.applicationLink("context-actions"),
type: "popup"
}, {
link: Spotify.Link.applicationLink("about"),
type: "section"
}, {
link: Spotify.Link.applicationLink("revgen-modal"),
type: "popup"
}, {
link: Spotify.Link.applicationLink("share"),
type: "popup"
}, {
link: Spotify.Link.applicationLink("queue"),
type: "section"
}, {
link: Spotify.Link.applicationLink("charts"),
type: "section"
}],
useClassicMode: !1
}, null, {
features: c.features
});
this.stateHistory.initialize();
this.history = new Spotify.Web.Router.History(this.stateHistory, History);
this.tracking = new Spotify.Web.Tracking(this.publisher, this.assets, c.tracking, this.history);
this.core.setTracker(this.tracking);
this.tracking.initialize(a);
this.history.setTracking(this.tracking);
this.playNow = new Spotify.Web.PlayNow(this.publisher, c.sessionType, Spotify.Web.Cookie.domain,
c.spb_referrer, a);
this._preloadAssets();
this.appLoader = new Spotify.Web.AppLoader(c, this.consoleLogger, this.core.core, window);
this.router = new Spotify.Web.Router(this.stateHistory, c, this.publisher, this.appLoader);
this.appManager = new Spotify.Web.AppManager(this.stateHistory, this.router.getAppUrl, document);
this.appManager.bind("onFrameCreated", function(a) {
var c = a.params.app,
d = a.params.node,
a = a.params.cached;
b.publisher.notify(Spotify.Web.PublisherMessages.APPLICATION_LOAD_STARTED, {
uri: c.link.toURI(),
start: (new Date).getTime()
});
b.publisher.notify(Spotify.Web.PublisherMessages.APPLICATION_STATE_CHANGED, {
link: c.link,
iframe: d,
cached: a
})
});
this.appManager.bind("onFrameUpdated", function(a) {
b.publisher.notify(Spotify.Web.PublisherMessages.APPLICATION_STATE_CHANGED, {
link: a.params.app.link,
iframe: a.params.node
})
});
this.appManager.bind("onFrameDisposed", function(a) {
b.publisher.notify(Spotify.Web.PublisherMessages.APPLICATION_DISPOSED, {
link: a.params.app.link,
iframe: a.params.node
})
});
var f = new Spotify.Web.View(this.stateHistory,
this.appManager, document.getElementById("main"), !1, this.publisher);
f.bind("onFrontPaneUpdate", function(a) {
a.params.node.focus()
});
f.setTracking(this.tracking);
this.popupManager = new Spotify.Web.PopupManager(this.router, this.publisher, document.getElementById("wrapper"), this.config.getSetting("cat_enabled"));
this.scrollBlocker = new Spotify.Web.ScrollBlocker(document.getElementById("sb"), this.publisher, this.popupManager);
this.scrollBlocker.init()
};
var f = new Spotify.Web.Environment(window);
if (f.isWeb()) f =
Spotify.Web.Setup.WebSetup;
else if (f.isDesktop()) f = Spotify.Web.Setup.DesktopSetup;
else throw Error("Invalid environment");
f.prototype = this;
return new f(c, a)
};
Spotify.Web.Setup.WebSetup = function(c, a) {
var b = this,
d = !1,
f, j = function(a) {
return function() {
d || (d = !1, b._onCoreConnected());
a()
}
};
this._onCoreConnected = function() {
Spotify.Web.Setup.WebSetup.prototype._onCoreConnected.call(this);
f = new Spotify.Web.Storage.Cookie("common", this.services, Spotify.Utils.Base64, {}, document);
f.init(function() {
b.playNow.onSignedIn(function() {
(new Spotify.Web.Bookmark(b.publisher, f)).init()
})
})
};
this.init = function(d) {
var f = new Spotify.Web.Credentials("/xhr/json/auth.php", c.csrftoken);
c.credentials && f.cache(c.credentials[0], c.credentials[1]);
this.core = new Spotify.Web.Core(this.publisher, c, f, new Spotify.Web.ConsoleLogger);
this.core.initialize();
this.core.connect(j(d));
Spotify.Web.Setup.WebSetup.prototype.init.call(this);
this.playNow.bindBeforeReload(function() {
if (window.localStorage) {
var c = b.core.core.contextPlayer;
window.localStorage.playNow_isPlaying = c && c.getState().playing ? "true" : "false"
}
b.playNow.isOpenRedirect() ? window.location.replace(Spotify.Web.Utils.stripQSParams("s,f,utm_medium,utm_campaign,utm_source,cp,cr".split(","),
a)) : window.location.reload()
});
(new Spotify.Web.PlayNowSignUp(this.playNow, document.getElementById("playNowSignUp"), c, this.publisher)).initialize();
this.playNow.isOpenRedirect() && this.playNow.signUp()
}
};
Spotify.Web.Environment = function(c) {
var a = c.location.protocol === "sp:" ? "desktop" : "web";
this.isWeb = function() {
return a === "web"
};
this.isDesktop = function() {
return a === "desktop"
}
};
Spotify.Web.CookieCleaner = function(c) {
this.MAX_COOKIE_NAME_LENGTH = 50;
this.clean = function() {
this.removeHugeAnonymousSettingsCookies()
};
this.removeHugeAnonymousSettingsCookies = function() {
for (var a = c.getAll(), b = 0; b < a.length; b++) {
var d = a[b].split("=");
(d = d[0] ? d[0].trim() : "") && d.length > this.MAX_COOKIE_NAME_LENGTH && c.remove(d, window.document, null, window.location.protocol === "https:")
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment