1
/*! SWFObject v2.2 <http://code.google.com/p/swfobject/>
2
is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
5
var swfobject = function() {
7
var UNDEF = "undefined",
9
SHOCKWAVE_FLASH = "Shockwave Flash",
10
SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash",
11
FLASH_MIME_TYPE = "application/x-shockwave-flash",
12
EXPRESS_INSTALL_ID = "SWFObjectExprInst",
13
ON_READY_STATE_CHANGE = "onreadystatechange",
20
domLoadFnArr = [main],
29
isExpressInstallActive = false,
31
dynamicStylesheetMedia,
34
/* Centralized function for browser feature detection
35
- User agent string detection is only used when no good alternative is possible
36
- Is executed directly for optimal performance
39
var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF,
40
u = nav.userAgent.toLowerCase(),
41
p = nav.platform.toLowerCase(),
42
windows = p ? /win/.test(p) : /win/.test(u),
43
mac = p ? /mac/.test(p) : /mac/.test(u),
44
webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false, // returns either the webkit version or false if not webkit
45
ie = !+"\v1", // feature detection based on Andrea Giammarchi's solution: http://webreflection.blogspot.com/2009/01/32-bytes-to-know-if-your-browser-is-ie.html
46
playerVersion = [0,0,0],
48
if (typeof nav.plugins != UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] == OBJECT) {
49
d = nav.plugins[SHOCKWAVE_FLASH].description;
50
if (d && !(typeof nav.mimeTypes != UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) { // navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin indicates whether plug-ins are enabled or disabled in Safari 3+
52
ie = false; // cascaded feature detection for Internet Explorer
53
d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
54
playerVersion[0] = parseInt(d.replace(/^(.*)\..*$/, "$1"), 10);
55
playerVersion[1] = parseInt(d.replace(/^.*\.(.*)\s.*$/, "$1"), 10);
56
playerVersion[2] = /[a-zA-Z]/.test(d) ? parseInt(d.replace(/^.*[a-zA-Z]+(.*)$/, "$1"), 10) : 0;
59
else if (typeof win.ActiveXObject != UNDEF) {
61
var a = new ActiveXObject(SHOCKWAVE_FLASH_AX);
62
if (a) { // a will return null when ActiveX is disabled
63
d = a.GetVariable("$version");
65
ie = true; // cascaded feature detection for Internet Explorer
66
d = d.split(" ")[1].split(",");
67
playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
73
return { w3:w3cdom, pv:playerVersion, wk:webkit, ie:ie, win:windows, mac:mac };
76
/* Cross-browser onDomLoad
77
- Will fire an event as soon as the DOM of a web page is loaded
78
- Internet Explorer workaround based on Diego Perini's solution: http://javascript.nwbox.com/IEContentLoaded/
79
- Regular onload serves as fallback
81
onDomLoad = function() {
82
if (!ua.w3) { return; }
83
if ((typeof doc.readyState != UNDEF && doc.readyState == "complete") || (typeof doc.readyState == UNDEF && (doc.getElementsByTagName("body")[0] || doc.body))) { // function is fired after onload, e.g. when script is inserted dynamically
84
callDomLoadFunctions();
87
if (typeof doc.addEventListener != UNDEF) {
88
doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, false);
90
if (ua.ie && ua.win) {
91
doc.attachEvent(ON_READY_STATE_CHANGE, function() {
92
if (doc.readyState == "complete") {
93
doc.detachEvent(ON_READY_STATE_CHANGE, arguments.callee);
94
callDomLoadFunctions();
97
if (win == top) { // if not inside an iframe
99
if (isDomLoaded) { return; }
101
doc.documentElement.doScroll("left");
104
setTimeout(arguments.callee, 0);
107
callDomLoadFunctions();
113
if (isDomLoaded) { return; }
114
if (!/loaded|complete/.test(doc.readyState)) {
115
setTimeout(arguments.callee, 0);
118
callDomLoadFunctions();
121
addLoadEvent(callDomLoadFunctions);
125
function callDomLoadFunctions() {
126
if (isDomLoaded) { return; }
127
try { // test if we can really add/remove elements to/from the DOM; we don't want to fire it too early
128
var t = doc.getElementsByTagName("body")[0].appendChild(createElement("span"));
129
t.parentNode.removeChild(t);
131
catch (e) { return; }
133
var dl = domLoadFnArr.length;
134
for (var i = 0; i < dl; i++) {
139
function addDomLoadEvent(fn) {
144
domLoadFnArr[domLoadFnArr.length] = fn; // Array.push() is only available in IE5.5+
148
/* Cross-browser onload
149
- Based on James Edwards' solution: http://brothercake.com/site/resources/scripts/onload/
150
- Will fire an event as soon as a web page including all of its assets are loaded
152
function addLoadEvent(fn) {
153
if (typeof win.addEventListener != UNDEF) {
154
win.addEventListener("load", fn, false);
156
else if (typeof doc.addEventListener != UNDEF) {
157
doc.addEventListener("load", fn, false);
159
else if (typeof win.attachEvent != UNDEF) {
160
addListener(win, "onload", fn);
162
else if (typeof win.onload == "function") {
163
var fnOld = win.onload;
164
win.onload = function() {
175
- Will preferably execute onDomLoad, otherwise onload (as a fallback)
186
/* Detect the Flash Player version for non-Internet Explorer browsers
187
- Detecting the plug-in version via the object element is more precise than using the plugins collection item's description:
188
a. Both release and build numbers can be detected
189
b. Avoid wrong descriptions by corrupt installers provided by Adobe
190
c. Avoid wrong descriptions by multiple Flash Player entries in the plugin Array, caused by incorrect browser imports
191
- Disadvantage of this method is that it depends on the availability of the DOM, while the plugins collection is immediately available
193
function testPlayerVersion() {
194
var b = doc.getElementsByTagName("body")[0];
195
var o = createElement(OBJECT);
196
o.setAttribute("type", FLASH_MIME_TYPE);
197
var t = b.appendChild(o);
201
if (typeof t.GetVariable != UNDEF) {
202
var d = t.GetVariable("$version");
204
d = d.split(" ")[1].split(",");
205
ua.pv = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
208
else if (counter < 10) {
210
setTimeout(arguments.callee, 10);
223
/* Perform Flash Player and SWF version matching; static publishing only
225
function matchVersions() {
226
var rl = regObjArr.length;
228
for (var i = 0; i < rl; i++) { // for each registered object element
229
var id = regObjArr[i].id;
230
var cb = regObjArr[i].callbackFn;
231
var cbObj = {success:false, id:id};
233
var obj = getElementById(id);
235
if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) { // Flash Player version >= published SWF version: Houston, we have a match!
236
setVisibility(id, true);
238
cbObj.success = true;
239
cbObj.ref = getObjectById(id);
243
else if (regObjArr[i].expressInstall && canExpressInstall()) { // show the Adobe Express Install dialog if set by the web page author and if supported
245
att.data = regObjArr[i].expressInstall;
246
att.width = obj.getAttribute("width") || "0";
247
att.height = obj.getAttribute("height") || "0";
248
if (obj.getAttribute("class")) { att.styleclass = obj.getAttribute("class"); }
249
if (obj.getAttribute("align")) { att.align = obj.getAttribute("align"); }
250
// parse HTML object param element's name-value pairs
252
var p = obj.getElementsByTagName("param");
254
for (var j = 0; j < pl; j++) {
255
if (p[j].getAttribute("name").toLowerCase() != "movie") {
256
par[p[j].getAttribute("name")] = p[j].getAttribute("value");
259
showExpressInstall(att, par, id, cb);
261
else { // Flash Player and SWF version mismatch or an older Webkit engine that ignores the HTML object element's nested param elements: display alternative content instead of SWF
262
displayAltContent(obj);
263
if (cb) { cb(cbObj); }
267
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 alternative content)
268
setVisibility(id, true);
270
var o = getObjectById(id); // test whether there is an HTML object element or not
271
if (o && typeof o.SetVariable != UNDEF) {
272
cbObj.success = true;
282
function getObjectById(objectIdStr) {
284
var o = getElementById(objectIdStr);
285
if (o && o.nodeName == "OBJECT") {
286
if (typeof o.SetVariable != UNDEF) {
290
var n = o.getElementsByTagName(OBJECT)[0];
299
/* Requirements for Adobe Express Install
300
- only one instance can be active at a time
301
- fp 6.0.65 or higher
303
- no Webkit engines older than version 312
305
function canExpressInstall() {
306
return !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312);
309
/* Show the Adobe Express Install dialog
310
- Reference: http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=6a253b75
312
function showExpressInstall(att, par, replaceElemIdStr, callbackFn) {
313
isExpressInstallActive = true;
314
storedCallbackFn = callbackFn || null;
315
storedCallbackObj = {success:false, id:replaceElemIdStr};
316
var obj = getElementById(replaceElemIdStr);
318
if (obj.nodeName == "OBJECT") { // static publishing
319
storedAltContent = abstractAltContent(obj);
320
storedAltContentId = null;
322
else { // dynamic publishing
323
storedAltContent = obj;
324
storedAltContentId = replaceElemIdStr;
326
att.id = EXPRESS_INSTALL_ID;
327
if (typeof att.width == UNDEF || (!/%$/.test(att.width) && parseInt(att.width, 10) < 310)) { att.width = "310"; }
328
if (typeof att.height == UNDEF || (!/%$/.test(att.height) && parseInt(att.height, 10) < 137)) { att.height = "137"; }
329
doc.title = doc.title.slice(0, 47) + " - Flash Player Installation";
330
var pt = ua.ie && ua.win ? "ActiveX" : "PlugIn",
331
fv = "MMredirectURL=" + encodeURI(win.location).toString().replace(/&/g,"%26") + "&MMplayerType=" + pt + "&MMdoctitle=" + doc.title;
332
if (typeof par.flashvars != UNDEF) {
333
par.flashvars += "&" + fv;
338
// 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,
339
// because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work
340
if (ua.ie && ua.win && obj.readyState != 4) {
341
var newObj = createElement("div");
342
replaceElemIdStr += "SWFObjectNew";
343
newObj.setAttribute("id", replaceElemIdStr);
344
obj.parentNode.insertBefore(newObj, obj); // insert placeholder div that will be replaced by the object element that loads expressinstall.swf
345
obj.style.display = "none";
347
if (obj.readyState == 4) {
348
obj.parentNode.removeChild(obj);
351
setTimeout(arguments.callee, 10);
355
createSWF(att, par, replaceElemIdStr);
359
/* Functions to abstract and display alternative content
361
function displayAltContent(obj) {
362
if (ua.ie && ua.win && obj.readyState != 4) {
363
// 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,
364
// because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work
365
var el = createElement("div");
366
obj.parentNode.insertBefore(el, obj); // insert placeholder div that will be replaced by the alternative content
367
el.parentNode.replaceChild(abstractAltContent(obj), el);
368
obj.style.display = "none";
370
if (obj.readyState == 4) {
371
obj.parentNode.removeChild(obj);
374
setTimeout(arguments.callee, 10);
379
obj.parentNode.replaceChild(abstractAltContent(obj), obj);
383
function abstractAltContent(obj) {
384
var ac = createElement("div");
385
if (ua.win && ua.ie) {
386
ac.innerHTML = obj.innerHTML;
389
var nestedObj = obj.getElementsByTagName(OBJECT)[0];
391
var c = nestedObj.childNodes;
394
for (var i = 0; i < cl; i++) {
395
if (!(c[i].nodeType == 1 && c[i].nodeName == "PARAM") && !(c[i].nodeType == 8)) {
396
ac.appendChild(c[i].cloneNode(true));
405
/* Cross-browser dynamic SWF creation
407
function createSWF(attObj, parObj, id) {
408
var r, el = getElementById(id);
409
if (ua.wk && ua.wk < 312) { return r; }
411
if (typeof attObj.id == UNDEF) { // if no 'id' is defined for the object element, it will inherit the 'id' from the alternative content
414
if (ua.ie && ua.win) { // Internet Explorer + the HTML object element + W3C DOM methods do not combine: fall back to outerHTML
416
for (var i in attObj) {
417
if (attObj[i] != Object.prototype[i]) { // filter out prototype additions from other potential libraries
418
if (i.toLowerCase() == "data") {
419
parObj.movie = attObj[i];
421
else if (i.toLowerCase() == "styleclass") { // 'class' is an ECMA4 reserved keyword
422
att += ' class="' + attObj[i] + '"';
424
else if (i.toLowerCase() != "classid") {
425
att += ' ' + i + '="' + attObj[i] + '"';
430
for (var j in parObj) {
431
if (parObj[j] != Object.prototype[j]) { // filter out prototype additions from other potential libraries
432
par += '<param name="' + j + '" value="' + parObj[j] + '" />';
435
el.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + att + '>' + par + '</object>';
436
objIdArr[objIdArr.length] = attObj.id; // stored to fix object 'leaks' on unload (dynamic publishing only)
437
r = getElementById(attObj.id);
439
else { // well-behaving browsers
440
var o = createElement(OBJECT);
441
o.setAttribute("type", FLASH_MIME_TYPE);
442
for (var m in attObj) {
443
if (attObj[m] != Object.prototype[m]) { // filter out prototype additions from other potential libraries
444
if (m.toLowerCase() == "styleclass") { // 'class' is an ECMA4 reserved keyword
445
o.setAttribute("class", attObj[m]);
447
else if (m.toLowerCase() != "classid") { // filter out IE specific attribute
448
o.setAttribute(m, attObj[m]);
452
for (var n in parObj) {
453
if (parObj[n] != Object.prototype[n] && n.toLowerCase() != "movie") { // filter out prototype additions from other potential libraries and IE specific param element
454
createObjParam(o, n, parObj[n]);
457
el.parentNode.replaceChild(o, el);
464
function createObjParam(el, pName, pValue) {
465
var p = createElement("param");
466
p.setAttribute("name", pName);
467
p.setAttribute("value", pValue);
471
/* Cross-browser SWF removal
472
- Especially needed to safely and completely remove a SWF in Internet Explorer
474
function removeSWF(id) {
475
var obj = getElementById(id);
476
if (obj && obj.nodeName == "OBJECT") {
477
if (ua.ie && ua.win) {
478
obj.style.display = "none";
480
if (obj.readyState == 4) {
481
removeObjectInIE(id);
484
setTimeout(arguments.callee, 10);
489
obj.parentNode.removeChild(obj);
494
function removeObjectInIE(id) {
495
var obj = getElementById(id);
498
if (typeof obj[i] == "function") {
502
obj.parentNode.removeChild(obj);
506
/* Functions to optimize JavaScript compression
508
function getElementById(id) {
511
el = doc.getElementById(id);
517
function createElement(el) {
518
return doc.createElement(el);
521
/* Updated attachEvent function for Internet Explorer
522
- Stores attachEvent information in an Array, so on unload the detachEvent functions can be called to avoid memory leaks
524
function addListener(target, eventType, fn) {
525
target.attachEvent(eventType, fn);
526
listenersArr[listenersArr.length] = [target, eventType, fn];
529
/* Flash Player and SWF content version matching
531
function hasPlayerVersion(rv) {
532
var pv = ua.pv, v = rv.split(".");
533
v[0] = parseInt(v[0], 10);
534
v[1] = parseInt(v[1], 10) || 0; // supports short notation, e.g. "9" instead of "9.0.0"
535
v[2] = parseInt(v[2], 10) || 0;
536
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;
539
/* Cross-browser dynamic CSS creation
540
- Based on Bobby van der Sluis' solution: http://www.bobbyvandersluis.com/articles/dynamicCSS.php
542
function createCSS(sel, decl, media, newStyle) {
543
if (ua.ie && ua.mac) { return; }
544
var h = doc.getElementsByTagName("head")[0];
545
if (!h) { return; } // to also support badly authored HTML pages that lack a head element
546
var m = (media && typeof media == "string") ? media : "screen";
548
dynamicStylesheet = null;
549
dynamicStylesheetMedia = null;
551
if (!dynamicStylesheet || dynamicStylesheetMedia != m) {
552
// create dynamic stylesheet + get a global reference to it
553
var s = createElement("style");
554
s.setAttribute("type", "text/css");
555
s.setAttribute("media", m);
556
dynamicStylesheet = h.appendChild(s);
557
if (ua.ie && ua.win && typeof doc.styleSheets != UNDEF && doc.styleSheets.length > 0) {
558
dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1];
560
dynamicStylesheetMedia = m;
563
if (ua.ie && ua.win) {
564
if (dynamicStylesheet && typeof dynamicStylesheet.addRule == OBJECT) {
565
dynamicStylesheet.addRule(sel, decl);
569
if (dynamicStylesheet && typeof doc.createTextNode != UNDEF) {
570
dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}"));
575
function setVisibility(id, isVisible) {
576
if (!autoHideShow) { return; }
577
var v = isVisible ? "visible" : "hidden";
578
if (isDomLoaded && getElementById(id)) {
579
getElementById(id).style.visibility = v;
582
createCSS("#" + id, "visibility:" + v);
586
/* Filter to avoid XSS attacks
588
function urlEncodeIfNecessary(s) {
589
var regex = /[\\\"<>\.;]/;
590
var hasBadChars = regex.exec(s) != null;
591
return hasBadChars && typeof encodeURIComponent != UNDEF ? encodeURIComponent(s) : s;
594
/* Release memory to avoid memory leaks caused by closures, fix hanging audio/video threads and force open sockets/NetConnections to disconnect (Internet Explorer only)
596
var cleanup = function() {
597
if (ua.ie && ua.win) {
598
window.attachEvent("onunload", function() {
599
// remove listeners to avoid memory leaks
600
var ll = listenersArr.length;
601
for (var i = 0; i < ll; i++) {
602
listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]);
604
// cleanup dynamically embedded objects to fix audio/video threads and force open sockets and NetConnections to disconnect
605
var il = objIdArr.length;
606
for (var j = 0; j < il; j++) {
607
removeSWF(objIdArr[j]);
609
// cleanup library's main closures to avoid memory leaks
614
for (var l in swfobject) {
624
- Reference: http://code.google.com/p/swfobject/wiki/documentation
626
registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) {
627
if (ua.w3 && objectIdStr && swfVersionStr) {
629
regObj.id = objectIdStr;
630
regObj.swfVersion = swfVersionStr;
631
regObj.expressInstall = xiSwfUrlStr;
632
regObj.callbackFn = callbackFn;
633
regObjArr[regObjArr.length] = regObj;
634
setVisibility(objectIdStr, false);
636
else if (callbackFn) {
637
callbackFn({success:false, id:objectIdStr});
641
getObjectById: function(objectIdStr) {
643
return getObjectById(objectIdStr);
647
embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) {
648
var callbackObj = {success:false, id:replaceElemIdStr};
649
if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) {
650
setVisibility(replaceElemIdStr, false);
651
addDomLoadEvent(function() {
652
widthStr += ""; // auto-convert to string
655
if (attObj && typeof attObj === OBJECT) {
656
for (var i in attObj) { // copy object to avoid the use of references, because web authors often reuse attObj for multiple SWFs
660
att.data = swfUrlStr;
661
att.width = widthStr;
662
att.height = heightStr;
664
if (parObj && typeof parObj === OBJECT) {
665
for (var j in parObj) { // copy object to avoid the use of references, because web authors often reuse parObj for multiple SWFs
669
if (flashvarsObj && typeof flashvarsObj === OBJECT) {
670
for (var k in flashvarsObj) { // copy object to avoid the use of references, because web authors often reuse flashvarsObj for multiple SWFs
671
if (typeof par.flashvars != UNDEF) {
672
par.flashvars += "&" + k + "=" + flashvarsObj[k];
675
par.flashvars = k + "=" + flashvarsObj[k];
679
if (hasPlayerVersion(swfVersionStr)) { // create SWF
680
var obj = createSWF(att, par, replaceElemIdStr);
681
if (att.id == replaceElemIdStr) {
682
setVisibility(replaceElemIdStr, true);
684
callbackObj.success = true;
685
callbackObj.ref = obj;
687
else if (xiSwfUrlStr && canExpressInstall()) { // show Adobe Express Install
688
att.data = xiSwfUrlStr;
689
showExpressInstall(att, par, replaceElemIdStr, callbackFn);
692
else { // show alternative content
693
setVisibility(replaceElemIdStr, true);
695
if (callbackFn) { callbackFn(callbackObj); }
698
else if (callbackFn) { callbackFn(callbackObj); }
701
switchOffAutoHideShow: function() {
702
autoHideShow = false;
707
getFlashPlayerVersion: function() {
708
return { major:ua.pv[0], minor:ua.pv[1], release:ua.pv[2] };
711
hasFlashPlayerVersion: hasPlayerVersion,
713
createSWF: function(attObj, parObj, replaceElemIdStr) {
715
return createSWF(attObj, parObj, replaceElemIdStr);
722
showExpressInstall: function(att, par, replaceElemIdStr, callbackFn) {
723
if (ua.w3 && canExpressInstall()) {
724
showExpressInstall(att, par, replaceElemIdStr, callbackFn);
728
removeSWF: function(objElemIdStr) {
730
removeSWF(objElemIdStr);
734
createCSS: function(selStr, declStr, mediaStr, newStyleBoolean) {
736
createCSS(selStr, declStr, mediaStr, newStyleBoolean);
740
addDomLoadEvent: addDomLoadEvent,
742
addLoadEvent: addLoadEvent,
744
getQueryParamValue: function(param) {
745
var q = doc.location.search || doc.location.hash;
747
if (/\?/.test(q)) { q = q.split("?")[1]; } // strip question mark
749
return urlEncodeIfNecessary(q);
751
var pairs = q.split("&");
752
for (var i = 0; i < pairs.length; i++) {
753
if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {
754
return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1)));
761
// For internal usage only
762
expressInstallCallback: function() {
763
if (isExpressInstallActive) {
764
var obj = getElementById(EXPRESS_INSTALL_ID);
765
if (obj && storedAltContent) {
766
obj.parentNode.replaceChild(storedAltContent, obj);
767
if (storedAltContentId) {
768
setVisibility(storedAltContentId, true);
769
if (ua.ie && ua.win) { storedAltContent.style.display = "block"; }
771
if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); }
773
isExpressInstallActive = false;