/* * Purl (A JavaScript URL parser) v2.3.1 * Developed and maintanined by Mark Perkins, mark@allmarkedup.com * Source repository: https://github.com/allmarkedup/jQuery-URL-Parser * Licensed under an MIT-style license. See https://github.com/allmarkedup/jQuery-URL-Parser/blob/master/LICENSE for details. */ ;(function(factory) { if (typeof define === 'function' && define.amd) { define(factory); } else { window.purl = factory(); } })(function() { var tag2attr = { a : 'href', img : 'src', form : 'action', base : 'href', script : 'src', iframe : 'src', link : 'href', embed : 'src', object : 'data' }, key = ['source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'fragment'], // keys available to query aliases = { 'anchor' : 'fragment' }, // aliases for backwards compatability parser = { strict : /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, //less intuitive, more accurate to the specs loose : /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ // more intuitive, fails on relative paths and deviates from specs }, isint = /^[0-9]+$/; function parseUri( url, strictMode ) { var str = decodeURI( url ), res = parser[ strictMode || false ? 'strict' : 'loose' ].exec( str ), uri = { attr : {}, param : {}, seg : {} }, i = 14; while ( i-- ) { uri.attr[ key[i] ] = res[i] || ''; } // build query and fragment parameters uri.param['query'] = parseString(uri.attr['query']); uri.param['fragment'] = parseString(uri.attr['fragment']); // split path and fragement into segments uri.seg['path'] = uri.attr.path.replace(/^\/+|\/+$/g,'').split('/'); uri.seg['fragment'] = uri.attr.fragment.replace(/^\/+|\/+$/g,'').split('/'); // compile a 'base' domain attribute uri.attr['base'] = uri.attr.host ? (uri.attr.protocol ? uri.attr.protocol+'://'+uri.attr.host : uri.attr.host) + (uri.attr.port ? ':'+uri.attr.port : '') : ''; return uri; } function getAttrName( elm ) { var tn = elm.tagName; if ( typeof tn !== 'undefined' ) return tag2attr[tn.toLowerCase()]; return tn; } function promote(parent, key) { if (parent[key].length === 0) return parent[key] = {}; var t = {}; for (var i in parent[key]) t[i] = parent[key][i]; parent[key] = t; return t; } function parse(parts, parent, key, val) { var part = parts.shift(); if (!part) { if (isArray(parent[key])) { parent[key].push(val); } else if ('object' == typeof parent[key]) { parent[key] = val; } else if ('undefined' == typeof parent[key]) { parent[key] = val; } else { parent[key] = [parent[key], val]; } } else { var obj = parent[key] = parent[key] || []; if (']' == part) { if (isArray(obj)) { if ('' !== val) obj.push(val); } else if ('object' == typeof obj) { obj[keys(obj).length] = val; } else { obj = parent[key] = [parent[key], val]; } } else if (~part.indexOf(']')) { part = part.substr(0, part.length - 1); if (!isint.test(part) && isArray(obj)) obj = promote(parent, key); parse(parts, obj, part, val); // key } else { if (!isint.test(part) && isArray(obj)) obj = promote(parent, key); parse(parts, obj, part, val); } } } function merge(parent, key, val) { if (~key.indexOf(']')) { var parts = key.split('['); parse(parts, parent, 'base', val); } else { if (!isint.test(key) && isArray(parent.base)) { var t = {}; for (var k in parent.base) t[k] = parent.base[k]; parent.base = t; } if (key !== '') { set(parent.base, key, val); } } return parent; } function parseString(str) { return reduce(String(str).split(/&|;/), function(ret, pair) { try { pair = decodeURIComponent(pair.replace(/\+/g, ' ')); } catch(e) { // ignore } var eql = pair.indexOf('='), brace = lastBraceInKey(pair), key = pair.substr(0, brace || eql), val = pair.substr(brace || eql, pair.length); val = val.substr(val.indexOf('=') + 1, val.length); if (key === '') { key = pair; val = ''; } return merge(ret, key, val); }, { base: {} }).base; } function set(obj, key, val) { var v = obj[key]; if (typeof v === 'undefined') { obj[key] = val; } else if (isArray(v)) { v.push(val); } else { obj[key] = [v, val]; } } function lastBraceInKey(str) { var len = str.length, brace, c; for (var i = 0; i < len; ++i) { c = str[i]; if (']' == c) brace = false; if ('[' == c) brace = true; if ('=' == c && !brace) return i; } } function reduce(obj, accumulator){ var i = 0, l = obj.length >> 0, curr = arguments[2]; while (i < l) { if (i in obj) curr = accumulator.call(undefined, curr, obj[i], i, obj); ++i; } return curr; } function isArray(vArg) { return Object.prototype.toString.call(vArg) === "[object Array]"; } function keys(obj) { var key_array = []; for ( var prop in obj ) { if ( obj.hasOwnProperty(prop) ) key_array.push(prop); } return key_array; } function purl( url, strictMode ) { if ( arguments.length === 1 && url === true ) { strictMode = true; url = undefined; } strictMode = strictMode || false; url = url || window.location.toString(); return { data : parseUri(url, strictMode), // get various attributes from the URI attr : function( attr ) { attr = aliases[attr] || attr; return typeof attr !== 'undefined' ? this.data.attr[attr] : this.data.attr; }, // return query string parameters param : function( param ) { return typeof param !== 'undefined' ? this.data.param.query[param] : this.data.param.query; }, // return fragment parameters fparam : function( param ) { return typeof param !== 'undefined' ? this.data.param.fragment[param] : this.data.param.fragment; }, // return path segments segment : function( seg ) { if ( typeof seg === 'undefined' ) { return this.data.seg.path; } else { seg = seg < 0 ? this.data.seg.path.length + seg : seg - 1; // negative segments count from the end return this.data.seg.path[seg]; } }, // return fragment segments fsegment : function( seg ) { if ( typeof seg === 'undefined' ) { return this.data.seg.fragment; } else { seg = seg < 0 ? this.data.seg.fragment.length + seg : seg - 1; // negative segments count from the end return this.data.seg.fragment[seg]; } } }; } purl.jQuery = function($){ if ($ != null) { $.fn.url = function( strictMode ) { var url = ''; if ( this.length ) { url = $(this).attr( getAttrName(this[0]) ) || ''; } return purl( url, strictMode ); }; $.url = purl; } }; purl.jQuery(window.jQuery); return purl; }); ; /* SWFObject v2.2 is released under the MIT License */ var swfobject = function () { var UNDEF = "undefined", OBJECT = "object", SHOCKWAVE_FLASH = "Shockwave Flash", SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash", FLASH_MIME_TYPE = "application/x-shockwave-flash", EXPRESS_INSTALL_ID = "SWFObjectExprInst", ON_READY_STATE_CHANGE = "onreadystatechange", win = window, doc = document, nav = navigator, plugin = false, domLoadFnArr = [], regObjArr = [], objIdArr = [], listenersArr = [], storedFbContent, storedFbContentId, storedCallbackFn, storedCallbackObj, isDomLoaded = false, isExpressInstallActive = false, dynamicStylesheet, dynamicStylesheetMedia, autoHideShow = true, encodeURIEnabled = false, /* Centralized function for browser feature detection - User agent string detection is only used when no good alternative is possible - Is executed directly for optimal performance */ ua = function () { var w3cdom = typeof doc.getElementById !== UNDEF && typeof doc.getElementsByTagName !== UNDEF && typeof doc.createElement !== UNDEF, u = nav.userAgent.toLowerCase(), p = nav.platform.toLowerCase(), windows = p ? /win/.test(p) : /win/.test(u), mac = p ? /mac/.test(p) : /mac/.test(u), webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false, // returns either the webkit version or false if not webkit ie = nav.appName === "Microsoft Internet Explorer", playerVersion = [0, 0, 0], d = null; if (typeof nav.plugins !== UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] === OBJECT) { d = nav.plugins[SHOCKWAVE_FLASH].description; // nav.mimeTypes["application/x-shockwave-flash"].enabledPlugin indicates whether plug-ins are enabled or disabled in Safari 3+ if (d && (typeof nav.mimeTypes !== UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) { plugin = true; ie = false; // cascaded feature detection for Internet Explorer d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1"); playerVersion[0] = toInt(d.replace(/^(.*)\..*$/, "$1")); playerVersion[1] = toInt(d.replace(/^.*\.(.*)\s.*$/, "$1")); playerVersion[2] = /[a-zA-Z]/.test(d) ? toInt(d.replace(/^.*[a-zA-Z]+(.*)$/, "$1")) : 0; } } else if (typeof win.ActiveXObject !== UNDEF) { try { var a = new ActiveXObject(SHOCKWAVE_FLASH_AX); if (a) { // a will return null when ActiveX is disabled d = a.GetVariable("$version"); if (d) { ie = true; // cascaded feature detection for Internet Explorer d = d.split(" ")[1].split(","); playerVersion = [toInt(d[0]), toInt(d[1]), toInt(d[2])]; } } } catch (e) {} } return {w3: w3cdom, pv: playerVersion, wk: webkit, ie: ie, win: windows, mac: mac}; }(), /* Cross-browser onDomLoad - Will fire an event as soon as the DOM of a web page is loaded - Internet Explorer workaround based on Diego Perini's solution: http://javascript.nwbox.com/IEContentLoaded/ - Regular onload serves as fallback */ onDomLoad = function () { if (!ua.w3) { return; } if ((typeof doc.readyState !== UNDEF && (doc.readyState === "complete" || doc.readyState === "interactive")) || (typeof doc.readyState === UNDEF && (doc.getElementsByTagName("body")[0] || doc.body))) { // function is fired after onload, e.g. when script is inserted dynamically callDomLoadFunctions(); } if (!isDomLoaded) { if (typeof doc.addEventListener !== UNDEF) { doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, false); } if (ua.ie) { doc.attachEvent(ON_READY_STATE_CHANGE, function detach() { if (doc.readyState === "complete") { doc.detachEvent(ON_READY_STATE_CHANGE, detach); callDomLoadFunctions(); } }); if (win == top) { // if not inside an iframe (function checkDomLoadedIE() { if (isDomLoaded) { return; } try { doc.documentElement.doScroll("left"); } catch (e) { setTimeout(checkDomLoadedIE, 0); return; } callDomLoadFunctions(); }()); } } if (ua.wk) { (function checkDomLoadedWK() { if (isDomLoaded) { return; } if (!/loaded|complete/.test(doc.readyState)) { setTimeout(checkDomLoadedWK, 0); return; } callDomLoadFunctions(); }()); } } }(); function callDomLoadFunctions() { if (isDomLoaded || !document.getElementsByTagName("body")[0]) { return; } try { // test if we can really add/remove elements to/from the DOM; we don't want to fire it too early var t, span = createElement("span"); span.style.display = "none"; //hide the span in case someone has styled spans via CSS t = doc.getElementsByTagName("body")[0].appendChild(span); t.parentNode.removeChild(t); t = null; //clear the variables span = null; } catch (e) { return; } isDomLoaded = true; var dl = domLoadFnArr.length; for (var i = 0; i < dl; i++) { domLoadFnArr[i](); } } function addDomLoadEvent(fn) { if (isDomLoaded) { fn(); } else { domLoadFnArr[domLoadFnArr.length] = fn; // Array.push() is only available in IE5.5+ } } /* Cross-browser onload - Based on James Edwards' solution: http://brothercake.com/site/resources/scripts/onload/ - Will fire an event as soon as a web page including all of its assets are loaded */ function addLoadEvent(fn) { if (typeof win.addEventListener !== UNDEF) { win.addEventListener("load", fn, false); } else if (typeof doc.addEventListener !== UNDEF) { doc.addEventListener("load", fn, false); } else if (typeof win.attachEvent !== UNDEF) { addListener(win, "onload", fn); } else if (typeof win.onload === "function") { var fnOld = win.onload; win.onload = function () { fnOld(); fn(); }; } else { win.onload = fn; } } /* Detect the Flash Player version for non-Internet Explorer browsers - Detecting the plug-in version via the object element is more precise than using the plugins collection item's description: a. Both release and build numbers can be detected b. Avoid wrong descriptions by corrupt installers provided by Adobe c. Avoid wrong descriptions by multiple Flash Player entries in the plugin Array, caused by incorrect browser imports - Disadvantage of this method is that it depends on the availability of the DOM, while the plugins collection is immediately available */ function testPlayerVersion() { var b = doc.getElementsByTagName("body")[0]; var o = createElement(OBJECT); o.setAttribute("style", "visibility: hidden;"); o.setAttribute("type", FLASH_MIME_TYPE); var t = b.appendChild(o); if (t) { var counter = 0; (function checkGetVariable() { if (typeof t.GetVariable !== UNDEF) { try { var d = t.GetVariable("$version"); if (d) { d = d.split(" ")[1].split(","); ua.pv = [toInt(d[0]), toInt(d[1]), toInt(d[2])]; } } catch (e) { //t.GetVariable("$version") is known to fail in Flash Player 8 on Firefox //If this error is encountered, assume FP8 or lower. Time to upgrade. ua.pv = [8, 0, 0]; } } else if (counter < 10) { counter++; setTimeout(checkGetVariable, 10); return; } b.removeChild(o); t = null; matchVersions(); }()); } else { matchVersions(); } } /* Perform Flash Player and SWF version matching; static publishing only */ function matchVersions() { var rl = regObjArr.length; if (rl > 0) { for (var i = 0; i < rl; i++) { // for each registered object element var id = regObjArr[i].id; var cb = regObjArr[i].callbackFn; var cbObj = {success: false, id: id}; if (ua.pv[0] > 0) { var obj = getElementById(id); if (obj) { if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) { // Flash Player version >= published SWF version: Houston, we have a match! setVisibility(id, true); if (cb) { cbObj.success = true; cbObj.ref = getObjectById(id); cbObj.id = id; cb(cbObj); } } else if (regObjArr[i].expressInstall && canExpressInstall()) { // show the Adobe Express Install dialog if set by the web page author and if supported var att = {}; att.data = regObjArr[i].expressInstall; att.width = obj.getAttribute("width") || "0"; att.height = obj.getAttribute("height") || "0"; if (obj.getAttribute("class")) { att.styleclass = obj.getAttribute("class"); } if (obj.getAttribute("align")) { att.align = obj.getAttribute("align"); } // parse HTML object param element's name-value pairs var par = {}; var p = obj.getElementsByTagName("param"); var pl = p.length; for (var j = 0; j < pl; j++) { if (p[j].getAttribute("name").toLowerCase() !== "movie") { par[p[j].getAttribute("name")] = p[j].getAttribute("value"); } } showExpressInstall(att, par, id, cb); } else { // Flash Player and SWF version mismatch or an older Webkit engine that ignores the HTML object element's nested param elements: display fallback content instead of SWF displayFbContent(obj); if (cb) { cb(cbObj); } } } } else { // if no Flash Player is installed or the fp version cannot be detected we let the HTML object element do its job (either show a SWF or fallback content) setVisibility(id, true); if (cb) { var o = getObjectById(id); // test whether there is an HTML object element or not if (o && typeof o.SetVariable !== UNDEF) { cbObj.success = true; cbObj.ref = o; cbObj.id = o.id; } cb(cbObj); } } } } } /* Main function - Will preferably execute onDomLoad, otherwise onload (as a fallback) */ domLoadFnArr[0] = function () { if (plugin) { testPlayerVersion(); } else { matchVersions(); } }; function getObjectById(objectIdStr) { var r = null, o = getElementById(objectIdStr); if (o && o.nodeName.toUpperCase() === "OBJECT") { //If targeted object is valid Flash file if (typeof o.SetVariable !== UNDEF) { r = o; } else { //If SetVariable is not working on targeted object but a nested object is //available, assume classic nested object markup. Return nested object. //If SetVariable is not working on targeted object and there is no nested object, //return the original object anyway. This is probably new simplified markup. r = o.getElementsByTagName(OBJECT)[0] || o; } } return r; } /* Requirements for Adobe Express Install - only one instance can be active at a time - fp 6.0.65 or higher - Win/Mac OS only - no Webkit engines older than version 312 */ function canExpressInstall() { return !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312); } /* Show the Adobe Express Install dialog - Reference: http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=6a253b75 */ function showExpressInstall(att, par, replaceElemIdStr, callbackFn) { var obj = getElementById(replaceElemIdStr); //Ensure that replaceElemIdStr is really a string and not an element replaceElemIdStr = getId(replaceElemIdStr); isExpressInstallActive = true; storedCallbackFn = callbackFn || null; storedCallbackObj = {success: false, id: replaceElemIdStr}; if (obj) { if (obj.nodeName.toUpperCase() === "OBJECT") { // static publishing storedFbContent = abstractFbContent(obj); storedFbContentId = null; } else { // dynamic publishing storedFbContent = obj; storedFbContentId = replaceElemIdStr; } att.id = EXPRESS_INSTALL_ID; if (typeof att.width === UNDEF || (!/%$/.test(att.width) && toInt(att.width) < 310)) { att.width = "310"; } if (typeof att.height === UNDEF || (!/%$/.test(att.height) && toInt(att.height) < 137)) { att.height = "137"; } var pt = ua.ie ? "ActiveX" : "PlugIn", fv = "MMredirectURL=" + encodeURIComponent(win.location.toString().replace(/&/g, "%26")) + "&MMplayerType=" + pt + "&MMdoctitle=" + encodeURIComponent(doc.title.slice(0, 47) + " - Flash Player Installation"); if (typeof par.flashvars !== UNDEF) { par.flashvars += "&" + fv; } else { par.flashvars = fv; } // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it, // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work if (ua.ie && obj.readyState != 4) { var newObj = createElement("div"); replaceElemIdStr += "SWFObjectNew"; newObj.setAttribute("id", replaceElemIdStr); obj.parentNode.insertBefore(newObj, obj); // insert placeholder div that will be replaced by the object element that loads expressinstall.swf obj.style.display = "none"; removeSWF(obj); //removeSWF accepts elements now } createSWF(att, par, replaceElemIdStr); } } /* Functions to abstract and display fallback content */ function displayFbContent(obj) { if (ua.ie && obj.readyState != 4) { // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it, // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work obj.style.display = "none"; var el = createElement("div"); obj.parentNode.insertBefore(el, obj); // insert placeholder div that will be replaced by the fallback content el.parentNode.replaceChild(abstractFbContent(obj), el); removeSWF(obj); //removeSWF accepts elements now } else { obj.parentNode.replaceChild(abstractFbContent(obj), obj); } } function abstractFbContent(obj) { var ac = createElement("div"); if (ua.win && ua.ie) { ac.innerHTML = obj.innerHTML; } else { var nestedObj = obj.getElementsByTagName(OBJECT)[0]; if (nestedObj) { var c = nestedObj.childNodes; if (c) { var cl = c.length; for (var i = 0; i < cl; i++) { if (!(c[i].nodeType == 1 && c[i].nodeName === "PARAM") && !(c[i].nodeType == 8)) { ac.appendChild(c[i].cloneNode(true)); } } } } } return ac; } function createIeObject(url, paramStr) { var div = createElement("div"); div.innerHTML = "" + paramStr + ""; return div.firstChild; } /* Cross-browser dynamic SWF creation */ function createSWF(attObj, parObj, id) { var r, el = getElementById(id); id = getId(id); // ensure id is truly an ID and not an element if (ua.wk && ua.wk < 312) { return r; } if (el) { var o = (ua.ie) ? createElement("div") : createElement(OBJECT), attr, attrLower, param; if (typeof attObj.id === UNDEF) { // if no 'id' is defined for the object element, it will inherit the 'id' from the fallback content attObj.id = id; } //Add params for (param in parObj) { //filter out prototype additions from other potential libraries and IE specific param element if (parObj.hasOwnProperty(param) && param.toLowerCase() !== "movie") { createObjParam(o, param, parObj[param]); } } //Create IE object, complete with param nodes if (ua.ie) { o = createIeObject(attObj.data, o.innerHTML); } //Add attributes to object for (attr in attObj) { if (attObj.hasOwnProperty(attr)) { // filter out prototype additions from other potential libraries attrLower = attr.toLowerCase(); // 'class' is an ECMA4 reserved keyword if (attrLower === "styleclass") { o.setAttribute("class", attObj[attr]); } else if (attrLower !== "classid" && attrLower !== "data") { o.setAttribute(attr, attObj[attr]); } } } if (ua.ie) { objIdArr[objIdArr.length] = attObj.id; // stored to fix object 'leaks' on unload (dynamic publishing only) } else { o.setAttribute("type", FLASH_MIME_TYPE); o.setAttribute("data", attObj.data); } el.parentNode.replaceChild(o, el); r = o; } return r; } function createObjParam(el, pName, pValue) { var p = createElement("param"); p.setAttribute("name", pName); p.setAttribute("value", pValue); el.appendChild(p); } /* Cross-browser SWF removal - Especially needed to safely and completely remove a SWF in Internet Explorer */ function removeSWF(id) { var obj = getElementById(id); if (obj && obj.nodeName.toUpperCase() === "OBJECT") { if (ua.ie) { obj.style.display = "none"; (function removeSWFInIE() { if (obj.readyState == 4) { //This step prevents memory leaks in Internet Explorer for (var i in obj) { if (typeof obj[i] === "function") { obj[i] = null; } } obj.parentNode.removeChild(obj); } else { setTimeout(removeSWFInIE, 10); } }()); } else { obj.parentNode.removeChild(obj); } } } function isElement(id) { return (id && id.nodeType && id.nodeType === 1); } function getId(thing) { return (isElement(thing)) ? thing.id : thing; } /* Functions to optimize JavaScript compression */ function getElementById(id) { //Allow users to pass an element OR an element's ID if (isElement(id)) { return id; } var el = null; try { el = doc.getElementById(id); } catch (e) {} return el; } function createElement(el) { return doc.createElement(el); } //To aid compression; replaces 14 instances of pareseInt with radix function toInt(str) { return parseInt(str, 10); } /* Updated attachEvent function for Internet Explorer - Stores attachEvent information in an Array, so on unload the detachEvent functions can be called to avoid memory leaks */ function addListener(target, eventType, fn) { target.attachEvent(eventType, fn); listenersArr[listenersArr.length] = [target, eventType, fn]; } /* Flash Player and SWF content version matching */ function hasPlayerVersion(rv) { rv += ""; //Coerce number to string, if needed. var pv = ua.pv, v = rv.split("."); v[0] = toInt(v[0]); v[1] = toInt(v[1]) || 0; // supports short notation, e.g. "9" instead of "9.0.0" v[2] = toInt(v[2]) || 0; return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false; } /* Cross-browser dynamic CSS creation - Based on Bobby van der Sluis' solution: http://www.bobbyvandersluis.com/articles/dynamicCSS.php */ function createCSS(sel, decl, media, newStyle) { var h = doc.getElementsByTagName("head")[0]; if (!h) { return; } // to also support badly authored HTML pages that lack a head element var m = (typeof media === "string") ? media : "screen"; if (newStyle) { dynamicStylesheet = null; dynamicStylesheetMedia = null; } if (!dynamicStylesheet || dynamicStylesheetMedia != m) { // create dynamic stylesheet + get a global reference to it var s = createElement("style"); s.setAttribute("type", "text/css"); s.setAttribute("media", m); dynamicStylesheet = h.appendChild(s); if (ua.ie && typeof doc.styleSheets !== UNDEF && doc.styleSheets.length > 0) { dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1]; } dynamicStylesheetMedia = m; } // add style rule if (dynamicStylesheet) { if (typeof dynamicStylesheet.addRule !== UNDEF) { dynamicStylesheet.addRule(sel, decl); } else if (typeof doc.createTextNode !== UNDEF) { dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}")); } } } function setVisibility(id, isVisible) { if (!autoHideShow) { return; } var v = isVisible ? "visible" : "hidden", el = getElementById(id); if (isDomLoaded && el) { el.style.visibility = v; } else if (typeof id === "string") { createCSS("#" + id, "visibility:" + v); } } /* Filter to avoid XSS attacks */ function urlEncodeIfNecessary(s) { var regex = /[\\\"<>\.;]/; var hasBadChars = regex.exec(s) !== null; return hasBadChars && typeof encodeURIComponent !== UNDEF ? encodeURIComponent(s) : s; } /* Release memory to avoid memory leaks caused by closures, fix hanging audio/video threads and force open sockets/NetConnections to disconnect (Internet Explorer only) */ var cleanup = function () { if (ua.ie) { window.attachEvent("onunload", function () { // remove listeners to avoid memory leaks var ll = listenersArr.length; for (var i = 0; i < ll; i++) { listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]); } // cleanup dynamically embedded objects to fix audio/video threads and force open sockets and NetConnections to disconnect var il = objIdArr.length; for (var j = 0; j < il; j++) { removeSWF(objIdArr[j]); } // cleanup library's main closures to avoid memory leaks for (var k in ua) { ua[k] = null; } ua = null; for (var l in swfobject) { swfobject[l] = null; } swfobject = null; }); } }(); return { /* Public API - Reference: http://code.google.com/p/swfobject/wiki/documentation */ registerObject: function (objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) { if (ua.w3 && objectIdStr && swfVersionStr) { var regObj = {}; regObj.id = objectIdStr; regObj.swfVersion = swfVersionStr; regObj.expressInstall = xiSwfUrlStr; regObj.callbackFn = callbackFn; regObjArr[regObjArr.length] = regObj; setVisibility(objectIdStr, false); } else if (callbackFn) { callbackFn({success: false, id: objectIdStr}); } }, getObjectById: function (objectIdStr) { if (ua.w3) { return getObjectById(objectIdStr); } }, embedSWF: function (swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) { var id = getId(replaceElemIdStr), callbackObj = {success: false, id: id}; if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) { setVisibility(id, false); addDomLoadEvent(function () { widthStr += ""; // auto-convert to string heightStr += ""; var att = {}; if (attObj && typeof attObj === OBJECT) { for (var i in attObj) { // copy object to avoid the use of references, because web authors often reuse attObj for multiple SWFs att[i] = attObj[i]; } } att.data = swfUrlStr; att.width = widthStr; att.height = heightStr; var par = {}; if (parObj && typeof parObj === OBJECT) { for (var j in parObj) { // copy object to avoid the use of references, because web authors often reuse parObj for multiple SWFs par[j] = parObj[j]; } } if (flashvarsObj && typeof flashvarsObj === OBJECT) { for (var k in flashvarsObj) { // copy object to avoid the use of references, because web authors often reuse flashvarsObj for multiple SWFs if (flashvarsObj.hasOwnProperty(k)) { var key = (encodeURIEnabled) ? encodeURIComponent(k) : k, value = (encodeURIEnabled) ? encodeURIComponent(flashvarsObj[k]) : flashvarsObj[k]; if (typeof par.flashvars !== UNDEF) { par.flashvars += "&" + key + "=" + value; } else { par.flashvars = key + "=" + value; } } } } if (true) { // create SWF var obj = createSWF(att, par, replaceElemIdStr); if (att.id == id) { setVisibility(id, true); } callbackObj.success = true; callbackObj.ref = obj; callbackObj.id = obj.id; } else if (xiSwfUrlStr && canExpressInstall()) { // show Adobe Express Install att.data = xiSwfUrlStr; showExpressInstall(att, par, replaceElemIdStr, callbackFn); return; } else { // show fallback content setVisibility(id, true); } if (callbackFn) { callbackFn(callbackObj); } }); } else if (callbackFn) { callbackFn(callbackObj); } }, switchOffAutoHideShow: function () { autoHideShow = false; }, enableUriEncoding: function (bool) { encodeURIEnabled = (typeof bool === UNDEF) ? true : bool; }, ua: ua, getFlashPlayerVersion: function () { return {major: ua.pv[0], minor: ua.pv[1], release: ua.pv[2]}; }, hasFlashPlayerVersion: hasPlayerVersion, createSWF: function (attObj, parObj, replaceElemIdStr) { if (ua.w3) { return createSWF(attObj, parObj, replaceElemIdStr); } else { return undefined; } }, showExpressInstall: function (att, par, replaceElemIdStr, callbackFn) { if (ua.w3 && canExpressInstall()) { showExpressInstall(att, par, replaceElemIdStr, callbackFn); } }, removeSWF: function (objElemIdStr) { if (ua.w3) { removeSWF(objElemIdStr); } }, createCSS: function (selStr, declStr, mediaStr, newStyleBoolean) { if (ua.w3) { createCSS(selStr, declStr, mediaStr, newStyleBoolean); } }, addDomLoadEvent: addDomLoadEvent, addLoadEvent: addLoadEvent, getQueryParamValue: function (param) { var q = doc.location.search || doc.location.hash; if (q) { if (/\?/.test(q)) { q = q.split("?")[1]; } // strip question mark if (!param) { return urlEncodeIfNecessary(q); } var pairs = q.split("&"); for (var i = 0; i < pairs.length; i++) { if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) { return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1))); } } } return ""; }, // For internal usage only expressInstallCallback: function () { if (isExpressInstallActive) { var obj = getElementById(EXPRESS_INSTALL_ID); if (obj && storedFbContent) { obj.parentNode.replaceChild(storedFbContent, obj); if (storedFbContentId) { setVisibility(storedFbContentId, true); if (ua.ie) { storedFbContent.style.display = "block"; } } if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); } } isExpressInstallActive = false; } }, version: "2.3" }; }(); if(typeof CP === 'undefined') { CP = {}; } if(!CP.utils) { CP.utils = {}; } CP.utils.Modal = function(options) { // options that can overwritten this.options = { overlayOpacity: 0.8, overlayClickClose: true, showClose: true, contentCloseDelegate: null, centerOnResize: true, transitionDuration: 250, onOpenComplete: function(){}, onCloseComplete: function(){}, onOpenStart: function(){}, onCloseStart: function(){} }; jQuery.extend(true, this.options, options); // states this.isOpen = false; this.isLoading = false; //Due to conflicts with Panels only run this on the homepage at this time. -- Added to backlog for permanent fix. if (location.pathname.match(/(\/|\/fr|\/es|\/de|\/pt)(\/index.php)?/)) { this.inject(); this.attach(); } }; CP.utils.Modal.prototype.inject = function(){ //create and embed required elements this.overlay = jQuery('').appendTo('body'); this.loading = jQuery('').appendTo('body'); this.modal = jQuery('').appendTo('body'); // optional - close button if(this.options.showClose){ this.closeButton = jQuery('close').appendTo(this.modal); } this.modalContent = jQuery('').appendTo(this.modal); // set overlay opacity to value in options this.overlay.css('opacity', this.options.overlayOpacity); this.body = jQuery('body'); }; CP.utils.Modal.prototype.attach = function(){ var self = this; // overlay and loading resize handler jQuery(window).resize(function(){ self.positionOverlay(); self.centerElement(self.loading); }); // optional - content triggered close event if(this.options.contentCloseDelegate != null){ this.modalContent.delegate(this.options.contentCloseDelegate, 'click', function(e){ e.preventDefault(); self.close(); }); } // optional - hide on overlay click this.overlay.click(function(e){ e.stopPropagation(); if(self.options.overlayClickClose){ self.close(); } }); // optional - close button if(this.options.showClose){ // hide on close button click this.closeButton.click(function(e){ e.preventDefault(); self.close(); }); } // optional - window resize handler if(this.options.centerOnResize){ jQuery(window).resize(function(){ self.centerElement(self.modal); }); } }; CP.utils.Modal.prototype.centerElement = function(element){ // usefull dimensions var elementWidth = element.width(); var elementHeight = element.height(); var windowWidth = jQuery(window).width(); var windowHeight = jQuery(window).height(); var scrollTop = jQuery(window).scrollTop(); // calculate center var left = (windowWidth / 2) - (elementWidth / 2); var top = scrollTop + ((windowHeight / 2) - (elementHeight / 2)); // bounding if(top < 0 ) top = 0; if(left < 0) left = 0; // set position element.css({ top: top, left: left }); } CP.utils.Modal.prototype.positionOverlay = function(){ // ie6 alternate overlay size other browsers use css if(jQuery.browser.msie && jQuery.browser.version === '6.0'){ this.overlay.css('height', jQuery(document).height()); } }; CP.utils.Modal.prototype.positionModal = function(){ this.centerElement(this.modal); }; CP.utils.Modal.prototype.showLoading = function(){ if(this.isOpen){ // already open just show loading indicator this.modal.fadeOut(this.options.transitionDuration); this.loading.fadeIn(this.options.transitionDuration); }else{ // not open yet this.overlay.fadeIn(this.options.transitionDuration); this.positionOverlay(); this.loading.fadeIn(this.options.transitionDuration); this.centerElement(this.loading); } this.isLoading = true; }; CP.utils.Modal.prototype.open = function(modalContent, openCallback, closeCallback){ var self = this; if(!this.isOpen){ if(this.isLoading){ // modal is already in loading state just open content this.loading.hide(); this.modalContent.append(modalContent); this.modal.fadeIn(this.options.transitionDuration, function() { // callbacks self.options.onOpenComplete(); if(closeCallback) self.activeCloseCallback = closeCallback; }); this.options.onOpenStart(); if(openCallback) openCallback(); this.centerElement(this.modal); // update state this.isOpen = true; this.isLoading = false; if (self.closeButton) { self.closeButton.show(); } this.body.addClass('modal-active'); } else{ // fresh modal nothing is open yet this.overlay.fadeIn(self.options.transitionDuration, function(){ self.modalContent.append(modalContent); self.modal.fadeIn(self.options.transitionDuration, function() { // callbacks self.options.onOpenComplete(); if(closeCallback) self.activeCloseCallback = closeCallback; }); self.options.onOpenStart(); if (self.closeButton) { self.closeButton.show(); } if(openCallback) openCallback(); self.centerElement(self.modal); // update state self.isOpen = true; self.isLoading = false; self.body.addClass('modal-active'); }); this.positionOverlay(); } }else{ // window already open just refresh content this.modal.css({visibility: 'hidden'}); ////to support interapp linking, instead of //this.modal.hide(); this.modalContent.empty(); this.modalContent.append(modalContent); this.options.onOpenStart(); this.modal.css({visibility: 'visible'}); //to support interapp linking, instead of //this.modal.show(); this.centerElement(this.modal); // update state this.isOpen = true; this.isLoading = false; this.body.addClass('modal-active'); // callbacks this.options.onOpenComplete(); if(openCallback) openCallback(); if(closeCallback) this.activeCloseCallback = closeCallback; } }; CP.utils.Modal.prototype.close = function(callback){ if(this.isOpen){ var self = this; //If you are in IE, find all embedded objects and replace them with divs. fadeout doesn't play too nice them if(jQuery.browser.msie) { var embeddedObjects = self.modalContent.find('object'); //Pro, Swfobject 2.x only uses object element! embeddedObjects.each(function(index, embObj) { embeddedObjects.replaceWith('
'); }); } // callback this.options.onCloseStart(); // hide everything this.modal.fadeOut(this.options.transitionDuration, function(){ self.modalContent.empty(); self.loading.hide(); self.overlay.hide(); if (self.closeButton) { self.closeButton.hide(); } // update state self.isLoading = false; self.isOpen = false; // remove class to body to signify closed modal self.body.removeClass('modal-active'); // callbacks self.options.onCloseComplete(); if(callback) callback(); if(self.activeCloseCallback) { self.activeCloseCallback(); self.activeCloseCallback = null; } }); } }; /** * Common Mobile Interstitial * @see cp_sitewide_settings.module "cp_sitewide_settings_init()" */ (function($) { Drupal.behaviors.cp_mobile_interstitial = { attach: function (context,settings) { var add_mobile_popup = false; var mobile_slug = ''; // Watching Play buttons for iOS devices if( (navigator.userAgent.match(/iP(hone|od|ad)/i)) ) { add_mobile_popup = true; mobile_slug = 'ios'; } // Watching Play buttons for Android devices else if( (navigator.userAgent.match(/android/i)) ) { add_mobile_popup = true; mobile_slug = 'android'; } // Inject mobile interstitial details if ( add_mobile_popup ) { var popup = settings.cp_mobile_interstitial; $('a.play-now, a.play-now-v2, a.cp-mobile-pop') .addClass('agegated-link') .attr('href', popup[ mobile_slug ].action_link ) .attr('data-interstitial_ok', popup[ mobile_slug ].buttons.action ) .attr('data-interstitial_cancel', popup[ mobile_slug ].buttons.cancel ) .attr('data-interstitial_text', popup[ mobile_slug ].content ) .attr('data-interstitial_title', popup[ mobile_slug ].title ) .attr('data-interstitial_class', popup[ mobile_slug ].class ) } } }; })(jQuery); ; /** * Sets a cookie in the user's browser * * @param name of the cookie * @param value of the cookie * @param expiry_days from now, null for a session cookie */ function setCookie(name, value, expiry_days) { // checking domains var domain_name = 'clubpenguin.com'; var hostname = window.location.hostname; if (hostname.search(/cp.local/) > -1) { domain_name = hostname; } expiry_str = ''; path_str = '; path=/'; domain_str = '; domain='+domain_name; if(expiry_days) { var d = new Date(); d.setDate(d.getDate() + expiry_days); expiry_str = ';expires=' + d.toGMTString(); } document.cookie = name + '=' + escape(value) + expiry_str + path_str + domain_str; } /** * Gets the value of the cookie from the user's browser * * @param name of the cookie * @return value of the cookie, null if the cookie isn't found */ function getCookie(name) { var s = document.cookie.indexOf(name + "="); if(s == -1) { return null; } s += name.length + 1; var e = document.cookie.indexOf(";", s); if(e == -1) { e = document.cookie.length; } return unescape(document.cookie.substring(s, e)); } /* The following checks for and records if a visitor is new or is a return visitor -- for A/B testing T&T */ if (!getCookie ('cpvisitor')) { setCookie('cpvisitorsession', 'true', ''); setCookie ('cpvisitor', 'new', 2400); } else { if (!getCookie ('cpvisitorsession')) { if ((getCookie ('cpvisitor')) == 'new') { setCookie ('cpvisitor', 'new', -1); setCookie ('cpvisitor', 'return', 2400); } } } /* The following checks for and records the OAST source code present in a URL clicked on from a creative asset on an external site */ var qsParm = new Array(); function qs() { var query = window.location.search.substring(1); var parms = query.split('&'); for (var i=0; i 0) { var key = parms[i].substring(0,pos); var val = parms[i].substring(pos+1); qsParm[key] = val; } } } qsParm['oast'] = null; qs(); if (qsParm['oast'] != null) { if (getCookie ('oast')) { setCookie ('oast', '', -1); setCookie ('oast', qsParm['oast'], 2400); } else { setCookie ('oast', qsParm['oast'], 2400); } } // -- BrowserID (cpBROWSERID) browserid = getCookie('cpBROWSERID'); if (browserid == '-1' || browserid == "null" || browserid == null) { //Generate a GUID browserid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8); return v.toString(16); }); try { setCookie('cpBROWSERID', browserid, 365); } catch (e){} } if(typeof jsAPI === 'undefined') { jsAPI = {}; } jsAPI.showHTMLElements = function() { $('#membershipOptionsPrimary, #membershipOptions_real, #membershipOptions_other, #membershipOptionsSecondary, #membershipOptions_ca').css({"visibility":"visible"}); } jsAPI.mboxBackground = function() { try{ $('#content').css({ 'background' : '#417DC5' }); var IE7 = ($.browser.msie && parseInt($.browser.version) == 7); if (IE7){ if ($('#membershipOptionsPrimary').length > 0){ $('#membershipOptionsPrimary').css({ 'background' : 'url(/images/pricing_bg_ca_ie7.png) 0 0 no-repeat', 'height':'135px', 'margin': '8px 0 0 -14px' }); } } else{ if ($('#membershipOptionsPrimary').length > 0){ $('#membershipOptionsPrimary').css({ 'background' : 'url(/images/pricing_bg_ca_b.png) 0 0 no-repeat', 'height':'135px', 'margin': '8px 0 0 -14px' }); } } if ($('#membershipOptions_other').length > 0){ $('#membershipOptions_other').css({ 'background' : 'url(/images/pricing_bg_ca_b.png) 0 0 no-repeat' }); } if ($('#membershipOptions_ca').length > 0){ $('#membershipOptions_ca').css({ 'background' : 'url(/images/pricing_bg_ca_a.png) 0 0 no-repeat', 'height':'154px', 'margin-left': '-15px' }); } if ($('#membershipOptions_real').length > 0){ $('#membershipOptions_real').css({ 'background' : 'url(/images/pricing_bg_ca_b.png) 0 0 no-repeat', 'height':'135px', 'margin-left': '-15px' }); } if ($('#content .padd').length > 2) { //euro style template with no padding $('#membershipOptions_other').css({ 'height':'135px', 'margin': '8px 0 20px 15px' }); } else { //ar style template with padding already in place if (!$($('#membershipOptions_other').parent()).hasClass('padd')){ $('#membershipOptions_other').css({ 'height':'135px', 'margin': '8px 0 20px 15px' }); } else { $('#membershipOptions_other').css({ 'height':'135px', 'margin': '8px 0 20px -15px' }); } } if ($('#content .padd').length > 1) { $($('#content .padd')[0]).css({ 'background' : '#fefde1', 'border-bottom' : '3px solid #013A69' }); var lastPad = $($('#content .padd')[($('#content .padd').length-1)]); if (lastPad.find('object').length == 0) { //last pad container doesn't contains flash lastPad.css({ 'background' : '#fff', 'border-top' : '3px solid #013A69', 'margin-top' : '25px' }); } else { //last pad container contains both flash and purchase image if (lastPad.find('#membershipOptionsSecondary').length > 0) { $('#membershipOptionsSecondary').wrap('
'); $('#content .padd').css({ 'padding-bottom':0 }); } } } }catch(e){} } ; String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ""); }; if (typeof CP === 'undefined') { CP = {}; } CP.runningVars = { layoutDirty: true, isTouchDevice: false, cleanWidth: 0, firstLoad: true, langDir: "" }; (function($) { CP.agegate = function(isGated, cutoffYear, langDir) { CP.runningVars.cutoffYear = cutoffYear; CP.runningVars.isGated = isGated; CP.runningVars.langDir = langDir; $.extend(true, this.options, {}); this.load(); }; CP.agegate.prototype.initListeners = function() { var self = this; var htmltext = ""; var hideContinue = false; $('#agegate label').live("click", function() { if (!$(this).hasClass('option')) { $(this).hide(); } }); $("#agegate input").live("focus", function() { //Hide label if (!$("label[for='" + $(this).attr('id') + "']").hasClass('option')) { $("label[for='" + $(this).attr('id') + "']").hide(); } }); $("#agegate input").live("blur", function() { var value = $(this).val(); if (value == "") { $("label[for='" + $(this).attr('id') + "']").css('display', 'inline-block'); } $("#tip-box").html(''); $("#tip-box").hide(); }); //agegate -- Gated Link Pressed $('.agegated-link').live('mousedown', function() { CP.runningVars.clickedLink = this; CP.runningVars.pendingUrl = $(this).attr("href"); CP.runningVars.interstitialText = $(this).attr("rel"); CP.runningVars.interstitialData = $(this).data(); if (typeof CP.runningVars.interstitialText == 'undefined') { CP.runningVars.interstitialText = false; } CP.runningVars.visitorAge = getCookie('cpvisitor-yob') || null; if (!(CP.runningVars.isGated || self.isLinkGated(CP.runningVars.pendingUrl)) || (CP.runningVars.visitorAge != null && parseInt(CP.runningVars.visitorAge) <= CP.runningVars.cutoffYear)) { //show interstitial self.showAgegate(function() { $('#modal-window #modal-close').hide(); $('#agegate .question').hide(); $('#agegate .sorry').hide(); if (CP.runningVars.interstitialData) { if (CP.runningVars.interstitialData.interstitial_title) { $('#agegate h3.interstitial').html(CP.runningVars.interstitialData.interstitial_title); } if (CP.runningVars.interstitialData.interstitial_text) { $('#agegate #interstitial').html(CP.runningVars.interstitialData.interstitial_text); } if (CP.runningVars.interstitialData.interstitial_cancel) { $('#agegate #cancel').html(CP.runningVars.interstitialData.interstitial_cancel); } if (CP.runningVars.interstitialData.interstitial_ok) { if (CP.runningVars.interstitialData.interstitial_ok == 'hide') { hideContinue = true; } else { $('#agegate #continue').html(CP.runningVars.interstitialData.interstitial_ok); } } if (CP.runningVars.interstitialData.interstitial_class) { $('#agegate').addClass(CP.runningVars.interstitialData.interstitial_class); } } else if (CP.runningVars.interstitialText) { htmltext = CP.runningVars.interstitialText.split("|"); if (htmltext.length >= 2) { $('#agegate h3.interstitial').html(htmltext[0]); $('#agegate #interstitial').html(htmltext[1]); //custom text for cancel button if (htmltext.length >= 3) { $('#agegate #cancel').html(htmltext[2]); } //custom text for ok button if (htmltext.length >= 4) { if (htmltext[3] == 'hide') { hideContinue = true; } else { $('#agegate #continue').html(htmltext[3]); } } //add class to the agegate wrapper if (htmltext.length >= 5) { $('#agegate').addClass(htmltext[4]); } } } try { var clickedLinkUrl = CP.runningVars.clickedLink.href.split('/'); if (clickedLinkUrl.length > 2) { clickedLinkUrl = clickedLinkUrl[0] + '/' + clickedLinkUrl[1] + '/' + clickedLinkUrl[2]; } else { clickedLinkUrl = clickedLinkUrl[0]; } } catch (e) { clickedLinkUrl = "" }; var newText = $('#interstitial').text().replace('%1', clickedLinkUrl); $('#interstitial').text(newText); $('#agegate .interstitial').show(); $('#agegate #cancel').show(); if (hideContinue) { $('#agegate #continue').hide(); } else { $('#agegate #continue').show(); } $('#agegate #submit').hide(); }); return false; } else { //show age gate question self.showAgegate(function() { $('#modal-window #modal-close').hide(); $('#agegate .question').show(); $('#agegate .sorry').hide(); $('#agegate .interstitial').hide(); $('#agegate #cancel').hide(); $('#agegate #continue').hide(); $('#agegate #submit').show(); }); return false; } }).live('click', function() { return false }); // Age gate -- submit date $('#agegate #submit').live('click', function() { var month = $('#agegate #edit-month').val(); var day = $('#agegate #edit-day').val(); var year = $('#agegate #edit-year').val(); if (month.length == 0 || month <= 0 || month > 31 //for ease of implementing MM/DD/YYYY and DD/MM/YYYY we just reverse the labels. || day.length == 0 || day <= 0 || day > 31 //for ease of implementing MM/DD/YYYY and DD/MM/YYYY we just reverse the labels. || year.length == 0 || year <= 1900 || year >= 2100) { $('#agegate h3').css({ 'color': '#f00' }); } else { $('#agegate h3').css({ 'color': '#fff' }); //write cookie setCookie('cpvisitor-yob', year, null); if (parseInt(year) < parseInt(CP.runningVars.cutoffYear)) { $('#agegate .question').fadeOut(200, function() { if (CP.runningVars.interstitialText) { htmltext = CP.runningVars.interstitialText.split("|"); if (htmltext.length >= 2) { $('#agegate h3.interstitial').html(htmltext[0]); $('#agegate #interstitial').html(htmltext[1]); } //custom text for cancel button if (htmltext.length >= 3) { $('#agegate #cancel').html(htmltext[2]); } //custom text for ok button if (htmltext.length >= 4) { $('#agegate #continue').html(htmltext[3]); } //add class to the agegate wrapper if (htmltext.length >= 5) { $('#agegate').addClass(htmltext[4]); } } try { var clickedLinkUrl = CP.runningVars.clickedLink.href.split('/'); if (clickedLinkUrl.length > 2) { clickedLinkUrl = clickedLinkUrl[0] + '/' + clickedLinkUrl[1] + '/' + clickedLinkUrl[2]; } else { clickedLinkUrl = clickedLinkUrl[0]; } } catch (e) { clickedLinkUrl = "" }; var newText = $('#interstitial').text().replace('%1', clickedLinkUrl); $('#interstitial').text(newText); $('#agegate .interstitial').fadeIn(200); $('#agegate #submit').hide(); $('#agegate #cancel').show(); $('#agegate #continue').show(); }); } else { $('#agegate .question').fadeOut(200, function() { $('#agegate .sorry').fadeIn(200); $('#agegate #submit').hide(); $('#agegate #cancel').show(); }); } } }); // Age gate -- insterstitial answers $('#agegate #continue').live('click', function() { CP.runningVars.modal.close(); window.location.href = CP.runningVars.pendingUrl; }); $('#agegate #cancel').live('click', function() { CP.runningVars.modal.close(); }); }; CP.agegate.prototype.initLinks = function(selector) { selector = selector || 'a'; //determine external links $(selector).each(function(i, link) { var isExternal = (link.href.indexOf('clubpenguin.com') < 0 && link.href.indexOf('cpassets-a') < 0 && link.href.indexOf('cpsslassets-a') < 0 && link.href.indexOf('clubpenguin.de') < 0 && link.href.indexOf('clubpenguinimg') < 0 && link.href.indexOf('clubpenguin-island') < 0 && link.href.indexOf('clubpenguinisland') < 0 && link.href.indexOf('disneycareers.com') < 0 && link.href.indexOf('disneytermsofuse.com') < 0 && link.href.indexOf('disneyprivacycenter.com') < 0 && link.href.indexOf('clubpenguinoffer.com') < 0 && link.href.indexOf('clubpenguintv.com') < 0 && link.href.indexOf('getclubpenguin.com') < 0 && link.href.indexOf('tryclubpenguin.com') < 0 && link.href.indexOf('www.disneylatino.bumeran.com.ar') < 0 && link.href.indexOf('disney.com') < 0 && link.href.indexOf('localhost') < 0 && link.href.indexOf('cp.local') < 0 && link.href.indexOf('javascript:') < 0 && link.href.indexOf('#nogo') < 0 && link.href.indexOf('mailto:') < 0 && !$(link).hasClass("ui-selectmenu") && link.href.length > 0 && link.href.indexOf('204.') < 0); if (isExternal) { if (link.href.indexOf("?nochrome=1") < 0) { $(link).addClass('agegated-link'); $(link).attr('target', '_blank'); } } }); }; //Is this link age gated for all users (not just specific regions) //ie twitter. CP.agegate.prototype.isLinkGated = function(href) { var isGated = (href.indexOf('twitter.com') >= 0) return isGated; }; CP.agegate.prototype.initModal = function() { $("#modal-overlay").remove(); $("#modal-loading").remove(); $("#modal-window").remove(); CP.runningVars.modal = new CP.utils.Modal({ showClose: false, contentCloseDelegate: '.modal-close', onOpenComplete: function() {}, onCloseComplete: function() {}, onCloseStart: function() {}, onOpenStart: function() {} }); }; CP.agegate.prototype.showAgegate = function(openCallback, closeCallback) { var host = window.location.host; // if (host.indexOf("play") > -1) { // host = host.replace("play","www"); // } var url = window.location.protocol + "//" + host + CP.runningVars.langDir + "/geoip/agegate-overlay"; // Allow Cross Domain $.ajaxPrefilter( function(options, originalOptions, jqXHR) { options.crossDomain = { crossDomain: true }; options.xhrFields = { withCredentials: true }; }); // Get Agegate Overlay $.ajax({ type: "GET", url: url, success: function(overlay) { //open modal if (!closeCallback) closeCallback = null; if (!openCallback) openCallback = null; CP.runningVars.modal.open(overlay, openCallback, closeCallback); } }); }; CP.agegate.prototype.load = function() { var self = this; CP.runningVars.visitorAge = getCookie('cpvisitor-yob') || null; this.initLinks(); this.initListeners(); this.initModal(); if (window.PIE) { $('.base a.button, .menu li a').each(function() { PIE.detach(this); PIE.attach(this); }); } try { imgSizer.collate(); } catch (e) {} CP.runningVars.firstLoad = false; }; })(window.jQuery); /* ExternalInterface Functions called from CP or MP client -----------------------------------------------------------------*/ /** * @function {public} launchMPGame * Begins trying to load MP through the snowball theme. The call to this * function originates from the CP client. * * @param {String} gameDetails Some game details from the CPClient for MP */ function launchMPGame(gameDetails) { //throw { name: 'FatalError', message: 'Something went badly wrong' }; if (window.snowball) { window.snowball.loadMP(gameDetails); } } /** * @function {public} returnToClubPenguin * Begins trying to return to club penguin using the snowball theme. The call * to this function originates from the MP client. * * @param {String} commandString Some details that will be sent back to CP Client from MP */ function returnToClubPenguin(commandString) { if (window.snowball) { window.snowball.returnToClient(commandString); } } /** * @function {public} nameResubmission * This function is called from the CP Client when the user logging in had his/her * penguin name reject. * * @param {Number} player_id The player id * @param {String} token The players auth token? * @param {Object} data Some data that was passed in from the client, no idea. */ function nameResubmission(player_id, token, data) { var newHostname = location.hostname.replace("play", "secured"); var newProtocol = ((newHostname.indexOf("sandbox") >= 0) ? "http" : "https"); var langPath = window.snowball ? window.snowball.getLangPath() : '/'; var href = newProtocol + "://" + newHostname + langPath + "penguin/update-username/" + player_id + "/" + token + "/" + data; Disney.Play.showModal(href); } /* BANNERS -----------------------------------------------------------------*/ /** * @function {public} showActivationBanner * Checks to see if the activation banner should be displayed. * Display the banner accordingly. * * @param {Number} hoursRemaining The number of hours remaining in the penguins activation */ function showActivationBanner(hoursRemaining) { if (window.snowball) { window.snowball.handleDisplayBanner('activation', {'hoursRemaining': hoursRemaining}); } jQuery("#pre-activated-banner-btn").click(function(e) { e.preventDefault(); if (window.snowball) { window.snowball.handleShowActivation(); } }); } /** * @function {public} showMembershipBanner * Checks to see if the membership banner should be displayed. * Display the banner accordingly. * * @param {String} swid The Penguins StarWave id */ function showMembershipBanner(swid) { var request = jQuery.ajax({ url: "http://" + location.hostname + "/web-service/membership", type: "POST", data: {'swid':swid}, success: function(result) { if (result.membershipExpiring) { if (result.showBanner) { if (window.snowball) { window.snowball.handleDisplayBanner('membership', {'daysRemaining': result.daysRemaining}); } } } } }); } /** * @function {public} showRules * Display Club Penguin rules. Triggered from client. * * @param {String} lang A two character language code like 'en' or 'de' */ function showRules(lang) { // Calls into the Disney.CP pre-port functionality. var newBaseUrl = location.hostname; var href = "http://" + newBaseUrl; href = lang != 'en' ? href + '/' + lang : href; window.cp.showRules(href); } /** * @function {public} goBack * Tells the browser to go back one step in the browsers history. */ function goBack() { window.history.back(); }; if (typeof CP === 'undefined') { CP = {}; } /** * @class Error */ /** * @constructor Error * @param {object} details The error object from PHP */ CP.Error = function(details) { this.code = details.code; this.header = details.header; this.headerTag = details.headerTag; this.message = details.message; this.messageTag = details.messageTag; this.links = details.links; this.errorTextClass = "errorText"; } /** * @function {public} render * Render the header, message, and links and return the result. * * @return {object} The jQuery object with header, message, and links */ CP.Error.prototype.render = function() { // header var header = this.renderHeader(); var message = this.renderMessage(); var links = this.renderLinks(); var textElement = jQuery("
").attr({ id: this.code, 'class': this.errorTextClass }); return jQuery(textElement).append(jQuery(header).after(jQuery(message))).after(jQuery(links)); } /** * @function {private} renderHeader * Renders the header text wrapped in the header tag. * * @return {object} jQuery object with the header wrapped in the header tag. */ CP.Error.prototype.renderHeader = function() { return this.renderElement(this.headerTag, this.header); } /** * @function {private} renderMessage * Renders the message text wrapped in the message tag. * * @return {object} jQuery object with the message wrapped in the message tag. */ CP.Error.prototype.renderMessage = function() { return this.renderElement(this.messageTag, this.message); } /** * @function {private} renderElement * Create a jQuery object with the tag and content (text). * * @param {String} tag A tag such as '
' or '

' * @param {String} content The content (text) to be set as the html * @return {object} jQuery object with the content wrapped in the tag. */ CP.Error.prototype.renderElement = function(tag, content) { return jQuery(tag).html(content); } /** * @function {private} renderLinks * Creates a jQuery object filled with links * * @return {object} jQuery object filled with links. */ CP.Error.prototype.renderLinks = function() { var links = jQuery('
'); for (var i = 0; i < this.links.length; i++) { if (this.links[i].type == 'img') { var img = jQuery('').attr({ src: this.links[i].label }); var link = jQuery('').attr({ id: this.links[i].id, href: this.links[i].href }); jQuery(links).append(jQuery(link).append(img)); } else { jQuery(links).append(jQuery('').attr('id', this.links[i].id).text(this.links[i].label)); } } return jQuery(links); }; if (typeof CP === 'undefined') { CP = {}; } (function($) { /** * @class Banner * This class is used to show Activation and Membership banners. * The client makes a call to an external JS function in external.js * which in turn creates a banner and executes the {@link CP.Banner.display() display()} * function. */ /** * @constructor Banner * Setup the render functions so the banner can be displayed later. * Here are the currently implemented banner render functions: *
    *
  1. {@link CP.Banner.renderActivation renderActivation()}
  2. *
  3. {@link CP.Banner.renderMembership renderMembership()}
  4. *
* @param {String} type The type of Banner. Possible values: 'membership', 'activation' * @param {object} options The options for the banner, E.g. {daysRemaining: 3} */ CP.Banner = function(type, options) { this.options = {}; $.extend(true, this.options, options); var self = this; /** * The type of banner, so far only 'activation' and 'membership' * @type {String} */ this.type = type; /** * These are the functions that will be called when rendering out each * different {@link CP.Banner.type type} of banner. * @type {Object} */ this.renderFunctions = { 'activation' : function(){self.renderActivation()}, 'membership' : function(){self.renderMembership()} }; this.bannerId = 'banner'; }; /** * @function {public} display * Starts to dsiplay the banner. Fires the following this this order: *
    *
  1. {@link CP.Banner.beforeRender beforeRender()}
  2. *
  3. {@link CP.Banner.render render()}
  4. *
  5. {@link CP.Banner.afterRender afterRender()}
  6. *
*/ CP.Banner.prototype.display = function() { if (this.beforeRender()) { this.render(); this.afterRender(); } }; /** * @function {private} beforeRender * Runs before the rendering of the Banner *
    *
  1. Shows the Banner Container
  2. *
* @return {Boolean} True if we should render the banner, False otherwise. */ CP.Banner.prototype.beforeRender = function() { this.cleanUp(); // $('#affiliateheaderforcp').height(28); //$('#club_penguin').height('95%'); // $('#hdrWrap').attr("style", "height:28px !important"); return true; }; /** * @function {private} render * Renders the banner function that was set earlier in the constructor. * Only will execute if we set the function earlier. */ CP.Banner.prototype.render = function() { if (this.renderFunctions[this.type] !== undefined) { this.renderFunctions[this.type](); } }; /** * @function {private} afterRender * Makes any final adjustments to the banner container */ CP.Banner.prototype.afterRender = function() { // if ($.browser.msie && parseInt($.browser.version, 10) === 7) { // $('#BannerContainer').height(28); // } else { // $('#BannerContainer').animate({height: '+28'}, 1000); // } }; /** * @function {private} cleanUp * Removes any content in the banner that already exists. * This is just in case the client makes two calls to the banners. */ CP.Banner.prototype.cleanUp = function() { $('#' + this.bannerId).empty(); $('#' + this.bannerId).show(); }; /** * @function {private} renderActivation * Render the pre-activation banner. It will attach the banner to the id specified by * {@link CP.Banner.bannerId bannerId}. This will be rendered if one of the following * conditions apply: *
    *
  1. It's the last day of the user's pre-activation
  2. *
  3. The user has a certain amount of days left in pre-activation status
  4. *
  5. The user has a certain amount of hours left in pre-activation status
  6. *
*/ CP.Banner.prototype.renderActivation = function() { var countDown = Drupal.settings.snowball_banner.preActivationLastDay; if (this.options.hoursRemaining > 24) { var daysRemaining = Math.ceil(this.options.hoursRemaining / 24); countDown = Drupal.settings.snowball_banner.preActivationDaysRemaining.replace('%daysRemaining%', daysRemaining); } else if (this.options.hoursRemaining > 1) { countDown = Drupal.settings.snowball_banner.preActivationHoursRemaining.replace('%hoursRemaining%', this.options.hoursRemaining); } $('#' + this.bannerId).append($("").html(countDown)); $('#' + this.bannerId).append($("
").attr({'id':'pre-activated-banner-btn', 'href':'javascript:void(0);'}).html(Drupal.settings.snowball_banner.preActivationAbout)); }; /** * @function {private} renderMembership * Render the membership banner. It will attach the banner to the id specified by * {@link CP.Banner.bannerId bannerId}. This will be rendered if one of the following * conditions apply: *
    *
  1. It's the last day of the user's membership
  2. *
  3. The user has a certain amount of days left in membership
  4. *
*/ CP.Banner.prototype.renderMembership = function() { var countDown = Drupal.settings.snowball_banner.membershipLastDay; if (this.options.daysRemaining > 1) { countDown = Drupal.settings.snowball_banner.membershipDaysRemaining.replace('%daysRemaining%', this.options.daysRemaining); } $('#' + this.bannerId).append($("").html(countDown)); $('#' + this.bannerId).append($("
").attr({'href':'https://secured.clubpenguin.com/membership/', 'target':'_blank'}).html(Drupal.settings.snowball_banner.membershipAbout)); }; })(window.jQuery);; //To allow cross sub domain scripting document.domain = window.location.hostname; var Disney = Disney || {}; Disney.Play = Disney.Play || {}; Disney.Membership = Disney.Play; //Alias used by lightbox close /* Definitions -----------------------------------------------------------------*/ (function($){ /* Disney CP -------------------------------------------------*/ Disney.CP = function(){ this.currentIndex = 0; }; /** * @function {public} showRules * This function will display the rules of the club penguin game. * * @param {String} baseUrl A url such as 'http://www.clubpenguin.com' */ Disney.CP.prototype.showRules = function(baseUrl) { var rulesUrl = '/club-penguin-rules'; var fullUrl = baseUrl + rulesUrl; Disney.Play.showModal(fullUrl); }; Disney.Play.initModal = function() { Disney.Play.modal = new CP.utils.Modal({ overlayClickClose: false, //too easy to accidentally close the lightbox with no way to reopen. contentCloseDelegate: '.modal-close', onOpenComplete: function() {}, onCloseComplete: function() {}, onCloseStart: function() {}, onOpenStart: function() {} }); }; Disney.Play.showModal = function(url) { var rdm = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8); return v.toString(16); }); html = ''; jQuery('.modal-close').css({"display": "none", "top": "12px", 'right': '39px'}); jQuery('#modal-content').html(html).css({'top': '-2000px', 'position': 'relative'}); jQuery('#modal-window').append(jQuery("#preload-gif").html()); jQuery('#modal-window img:last').css({'top': '47%', 'left': '47%', 'position': 'fixed'}); jQuery('iframe#modal-iframe').load(function() { jQuery('#modal-content').css({"top": "0", 'position': 'relative'}); jQuery('#modal-window img:last').remove(); jQuery('.modal-close').css({"display": "block", "top": "12px", 'right': '39px'}); }); Disney.Play.modal.showClose = false; Disney.Play.modal.open(null, null, Disney.Play.closeModalCallback); }; Disney.Play.closeModalCallback = function() { if (Disney.Play.newName && window.snowball) { try { window.snowball.handleNameResubmit(Disney.Play.newName, Disney.Play.newToken, Disney.Play.newLoginData); } catch(e){} } }; Disney.Play.get_browser = function() { var ua=navigator.userAgent,tem,M=ua.match(/(opr|opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || []; if(/trident/i.test(M[1])){ tem=/\brv[ :]+(\d+)/g.exec(ua) || []; return 'IE '+(tem[1]||''); } if(M[1]==='Chrome'){ tem=ua.match(/\bOPR\/(\d+)/) if(tem!=null) {return 'Opera '+tem[1];} } M=M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?']; if((tem=ua.match(/version\/(\d+)/i))!=null) {M.splice(1,1,tem[1]);} return M[0]; } Disney.Play.get_browser_version = function() { var ua=navigator.userAgent,tem,M=ua.match(/(opr|opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || []; if(/trident/i.test(M[1])){ tem=/\brv[ :]+(\d+)/g.exec(ua) || []; return 'IE '+(tem[1]||''); } if(M[1]==='Chrome'){ tem=ua.match(/\bOPR\/(\d+)/) if(tem!=null) {return 'Opera '+tem[1];} } M=M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?']; if((tem=ua.match(/version\/(\d+)/i))!=null) {M.splice(1,1,tem[1]);} return M[1]; } /* Document ready -----------------------------------------------------------------*/ $(document).ready(function(e){ window.cp = new Disney.CP(); //// Initializations Disney.Play.newName = false; Disney.Play.newLoginData = false; Disney.Play.newToken = false; Disney.Play.initModal(); }); })(window.jQuery); ; if (typeof CP === 'undefined') { CP = {}; } /** * @class CP.FlashClient */ /** * @constructor CP.FlashClient * @param {object} options An object with key value pairs from drupal. * @param {object} friendsClient A CP.FriendsClient object that we will use to load friends later. */ CP.FlashClient = function(options, friendsClient) { this.options = {}; jQuery.extend(true, this.options, options); /** * The friends (controller) client for the flash client * @var {private object} friendsClient */ this.friendsClient = friendsClient; /** * The ID for the swf that will be loaded * @var {private String} od */ this.id = "cp_flash"; /** * This logout class is the CSS class that is attached to the logout link. * We can show / hide this based on the state of the cpClient. * @type {Boolean} logoutClass */ this.logoutClass = 'logout'; /** * The DOM Element that holds the flash client * @var {private Object} domElement */ this.domElement = null; /** * This will monitor whether or not the flash client needs to be unloaded. * @type {Boolean} _cleanedUp */ this._cleanedUp = false; }; /** * @function {public} getElement * Creates the element that will be used to house the mp client * @return {object} a jQuery object that is a div with an ID set */ CP.FlashClient.prototype.getElement = function() { if (!this.domElement) { this.domElement = jQuery("
").attr('id', this.id); } return this.domElement; } /** * @function {public} load * Attempts to load the FlashClient *
    *
  • {@link CP.FlashClient.beforeRender beforeRender()}
  • *
  • {@link CP.FlashClient.render render()}
  • *
  • {@link CP.FlashClient.afterRender afterRender()}
  • *
* @param {Boolean} forceLoad Pass through to {@link CP.FlashClient.beforeRender beforeRender} * in order to accomodate bypassing flash checks * @return {Object} A {@link CP.Result CP.Result} object; */ CP.FlashClient.prototype.load = function(forceLoad) { var result = this.beforeRender(forceLoad); if (!result.hasError) { this.render(); this.afterRender(); } return result; }; /** * @function {private} beforeRender * Runs before rendering the Flash Client. Does the following: *
    *
  • {@link CP.FlashClient.validateFlashVersion validateFlashVersion(minimumVersion, recommendedVersion)}
  • *
  • load the swfaddress.js file into the <head>
  • *
  • tells the friendsClient to load
  • *
* * @param {Boolean} forceLoad True if we should skip checking the flash version. False otherwise. * @return {Object} A {@link CP.Result CP.Result} object; */ CP.FlashClient.prototype.beforeRender = function(forceLoad) { var result = new CP.Result(); if (!forceLoad) { result = CP.FlashClient.validateFlashVersion(this.options.minimumSwfVersion, this.options.recommendedSwfVersion); } if (!result.hasError) { this.friendsClient.load(); } this.loadContentVersion(); this.loadSwfAddressJS(); return result; }; /** * @function {private} loadContentVersion * Load the version of the client to the class */ CP.FlashClient.prototype.loadContentVersion = function () { jQuery.ajax({ url: 'https://media1.newcp.net/version.txt?v=' + new Date().getTime(), type: 'GET', async: false, success: response => jQuery.extend(this.options, JSON.parse(response)), error: function(jqXHR, textStatus, errorThrown) {} }); }; /** * @function {private} loadSwfAddressJS * Load the SwfAddress into the <head> of the document. * This is done like this because if we load it on the landing page, and then we change * the hash to say '/login', swfaddress doesn't like that there is no swf yet, since we * load the flash client dynamically and swfaddress will start saying, "oopz, errors!" */ CP.FlashClient.prototype.loadSwfAddressJS = function () { console.log("loading swf address"); var attributes = { 'type' : 'text/javascript', 'src' : this.options.swfAddressUrl } var scriptElement = jQuery("