├── FileToDataURI.mxml ├── FileToDataURI.swf ├── README.md ├── dist └── swfobject │ ├── expressInstall.swf │ ├── index.html │ ├── index_dynamic.html │ ├── src │ ├── expressInstall.as │ ├── expressInstall.fla │ └── swfobject.js │ ├── swfobject.js │ └── test.swf └── license.txt /FileToDataURI.mxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | = InitEncoreChar(); 23 | 24 | //File types which we want the user to open 25 | // other example [new FileFilter("Images", "*.jpg;*.png;*.gif")] 26 | private static const FILE_TYPES:Array = [new FileFilter("All Files", "*.*")]; 27 | 28 | // permits to customize the button label 29 | private var _buttonLabel:String = ExternalInterface.call("Flash.getButtonLabel"); 30 | private function returnButtonLabel():String { 31 | return _buttonLabel || "Load a file"; 32 | } 33 | 34 | //called when the user clicks the load file button 35 | private function onLoadFileClick():void 36 | { 37 | //create the FileReference instance 38 | fileRef = new FileReference(); 39 | 40 | //listen for when they select a file 41 | fileRef.addEventListener(Event.SELECT, onFileSelect); 42 | 43 | //listen for when then cancel out of the browse dialog 44 | fileRef.addEventListener(Event.CANCEL,onCancel); 45 | 46 | //open a native browse dialog that filters for the files 47 | fileRef.browse(FILE_TYPES); 48 | } 49 | 50 | /************ Browse Event Handlers **************/ 51 | //called when the user selects a file from the browse dialog 52 | private function onFileSelect(e:Event):void 53 | { 54 | //listen for when the file has loaded 55 | fileRef.addEventListener(Event.COMPLETE, onLoadComplete); 56 | 57 | //listen for any errors reading the file 58 | fileRef.addEventListener(IOErrorEvent.IO_ERROR, onLoadError); 59 | 60 | //load the content of the file 61 | fileRef.load(); 62 | } 63 | 64 | //called when the user cancels out of the browser dialog 65 | private function onCancel(e:Event):void 66 | { 67 | trace("File Browse Canceled"); 68 | fileRef = null; 69 | } 70 | 71 | /************ Select Event Handlers **************/ 72 | //called when the file has completed loading 73 | private function onLoadComplete(e:Event):void 74 | { 75 | //get the data from the file as a ByteArray 76 | var data:ByteArray = fileRef.data; 77 | 78 | // call external Javascript function and pass the base64 encoded data 79 | ExternalInterface.call(javascriptReceiver, encode(data)); 80 | 81 | //clean up the FileReference instance 82 | fileRef = null; 83 | } 84 | 85 | //called if an error occurs while loading the file contents 86 | private function onLoadError(e:IOErrorEvent):void 87 | { 88 | trace("Error loading file : " + e.text); 89 | } 90 | 91 | /* 92 | * Copyright (C) 2012 Jean-Philippe Auclair 93 | * Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php 94 | * Base64 library for ActionScript 3.0. 95 | * By: Jean-Philippe Auclair : http://jpauclair.net 96 | * Based on article: http://jpauclair.net/2010/01/09/base64-optimized-as3-lib/ 97 | * Benchmark: 98 | * This version: encode: 260ms decode: 255ms 99 | * Blog version: encode: 322ms decode: 694ms 100 | * as3Crypto encode: 6728ms decode: 4098ms 101 | * 102 | * Encode: com.sociodox.utils.Base64 is 25.8x faster than as3Crypto Base64 103 | * Decode: com.sociodox.utils.Base64 is 16x faster than as3Crypto Base64 104 | * 105 | * Optimize & Profile any Flash content with TheMiner ( http://www.sociodox.com/theminer ) 106 | */ 107 | public static function encode(data:ByteArray):String { 108 | var out:ByteArray = new ByteArray(); 109 | //Presetting the length keep the memory smaller and optimize speed since there is no "grow" needed 110 | out.length = (2 + data.length - ((data.length + 2) % 3)) * 4 / 3; //Preset length //1.6 to 1.5 ms 111 | var i:int = 0; 112 | var r:int = data.length % 3; 113 | var len:int = data.length - r; 114 | var c:uint; //read (3) character AND write (4) characters 115 | var outPos:int = 0; 116 | while (i < len) { 117 | //Read 3 Characters (8bit * 3 = 24 bits) 118 | c = data[int(i++)] << 16 | data[int(i++)] << 8 | data[int(i++)]; 119 | 120 | out[int(outPos++)] = _encodeChars[int(c >>> 18)]; 121 | out[int(outPos++)] = _encodeChars[int(c >>> 12 & 0x3f)]; 122 | out[int(outPos++)] = _encodeChars[int(c >>> 6 & 0x3f)]; 123 | out[int(outPos++)] = _encodeChars[int(c & 0x3f)]; 124 | } 125 | 126 | if (r == 1) { // Need two "=" padding 127 | //Read one char, write two chars, write padding 128 | c = data[int(i)]; 129 | 130 | out[int(outPos++)] = _encodeChars[int(c >>> 2)]; 131 | out[int(outPos++)] = _encodeChars[int((c & 0x03) << 4)]; 132 | out[int(outPos++)] = 61; 133 | out[int(outPos++)] = 61; 134 | } else if (r == 2) { //Need one "=" padding 135 | c = data[int(i++)] << 8 | data[int(i)]; 136 | 137 | out[int(outPos++)] = _encodeChars[int(c >>> 10)]; 138 | out[int(outPos++)] = _encodeChars[int(c >>> 4 & 0x3f)]; 139 | out[int(outPos++)] = _encodeChars[int((c & 0x0f) << 2)]; 140 | out[int(outPos++)] = 61; 141 | } 142 | 143 | return out.readUTFBytes(out.length); 144 | } 145 | 146 | public static function InitEncoreChar():Vector. { 147 | var encodeChars:Vector. = new Vector.(64, true); 148 | 149 | // We could push the number directly 150 | // but I think it's nice to see the characters (with no overhead on encode/decode) 151 | var chars:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 152 | for (var i:int = 0; i < 64; i++) { 153 | encodeChars[i] = chars.charCodeAt(i); 154 | } 155 | 156 | return encodeChars; 157 | } 158 | 159 | ]]> 160 | 161 | 162 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /FileToDataURI.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aymkdn/FileToDataURI/07111ab394660856dcff041bf0fdd15b559894a7/FileToDataURI.swf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | FileToDataURI 2 | ============= 3 | 4 | **EDIT**: [FileReader](https://developer.mozilla.org/docs/Web/API/FileReader) should now be [safe to use](https://caniuse.com/#search=FileReader) instead of involving Flash. 5 | 6 | A cross-browser solution to read a local file and provide the base64 encoded content with Flash. 7 | See the [example](http://aymkdn.github.com/FileToDataURI/) to know how to use it. 8 | The example provides a polyfill-like solution (based on this swf file and on the FileReader API when available). 9 | 10 | You'll need to define in your JavaScript the below code: 11 | ``` 12 | var Flash = { 13 | getFileData: function(base64) { 14 | /* this function is mandatory to deal with the base64 for the Flash version (old browser) */ 15 | }, 16 | getButtonLabel: function() { 17 | return "Load your file"; 18 | /* you can use this function if you want to customize the button label for the Flash version (old browser) */ 19 | } 20 | }; 21 | ``` 22 | 23 | Customization 24 | ============= 25 | 26 | 1. Do the changes you need in the mxml file (Flex); 27 | 2. Download the [Flex SDK](https://www.adobe.com/devnet/flex/flex-sdk-download.html); 28 | 3. Unzip and open a console; 29 | 4. Run the following command: 30 | ``` 31 | $ ./bin/mxmlc FileToDataURI.mxml 32 | ``` 33 | 34 | You'll have some warning messages as below: 35 | > Chargement du fichier de configuration D:\flex_sdk_4.6\frameworks\flex-config.xml 36 | > RSL requis : 37 | > http://fpdownload.adobe.com/pub/swz/flex/4.6.0.23201/framework_4.6.0.23201.swz avec 1 basculement. 38 | > http://fpdownload.adobe.com/pub/swz/tlf/2.0.0.232/textLayout_2.0.0.232.swz avec 1 basculement. 39 | > http://fpdownload.adobe.com/pub/swz/flex/4.6.0.23201/spark_4.6.0.23201.swz avec 1 basculement. 40 | > http://fpdownload.adobe.com/pub/swz/flex/4.6.0.23201/sparkskins_4.6.0.23201.swz avec 1 basculement. 41 | > http://fpdownload.adobe.com/pub/swz/flex/4.6.0.23201/mx_4.6.0.23201.swz avec 1 basculement. 42 | 43 | But it will work and you'll find the *FileToDataURI.swf* file in your working directory. 44 | 45 | Inspiration 46 | =========== 47 | 48 | Thanks to [Country/FileToDataURI](https://github.com/Country/FileToDataURI) for giving me the inspiration ! 49 | 50 | Note 51 | ==== 52 | 53 | For the first run, it's going to be a bit long to load the swf file. Actually the browser will connect to Adobe to download the swz files above. It's doing it just once, then no more download. 54 | -------------------------------------------------------------------------------- /dist/swfobject/expressInstall.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aymkdn/FileToDataURI/07111ab394660856dcff041bf0fdd15b559894a7/dist/swfobject/expressInstall.swf -------------------------------------------------------------------------------- /dist/swfobject/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SWFObject 2 static publishing example page 5 | 6 | 7 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 |
19 |

Alternative content

20 |

Get Adobe Flash player

21 |
22 | 23 |
24 | 25 |
26 |
27 | 28 | 29 | -------------------------------------------------------------------------------- /dist/swfobject/index_dynamic.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SWFObject 2 dynamic publishing example page 5 | 6 | 7 | 10 | 11 | 12 |
13 |

Alternative content

14 |

Get Adobe Flash player

15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /dist/swfobject/src/expressInstall.as: -------------------------------------------------------------------------------- 1 | /* SWFObject v2.2 is released under the MIT License 2 | Express Install Copyright (c) 2007-2008 Adobe Systems Incorporated and its licensors. All Rights Reserved. 3 | */ 4 | 5 | System.security.allowDomain("fpdownload.macromedia.com"); 6 | 7 | var time = 0; 8 | var timeOut = 5; // in seconds 9 | var delay = 10; // in milliseconds 10 | var int_id = setInterval(checkLoaded, delay); 11 | var old_si = null; 12 | var loaderClip = this.createEmptyMovieClip("loaderClip", 0); 13 | var updateSWF = "http://fpdownload.macromedia.com/pub/flashplayer/update/current/swf/autoUpdater.swf?" + Math.random(); 14 | loaderClip.loadMovie(updateSWF); 15 | 16 | function checkLoaded(){ 17 | time += delay / 1000; 18 | if (time > timeOut) { 19 | // updater did not load in time, abort load and force alternative content 20 | clearInterval(int_id); 21 | loaderClip.unloadMovie(); 22 | loadTimeOut(); 23 | } 24 | else if (loaderClip.startInstall.toString() == "[type Function]") { 25 | // updater has loaded successfully AND has determined that it can do the express install 26 | if (old_si == null) { 27 | old_si = loaderClip.startInstall; 28 | loaderClip.startInstall = function() { 29 | clearInterval(int_id); 30 | old_si(); 31 | } 32 | loadComplete(); 33 | } 34 | } 35 | } 36 | 37 | function loadTimeOut() { 38 | callbackSWFObject(); 39 | } 40 | 41 | function callbackSWFObject() { 42 | getURL("javascript:swfobject.expressInstallCallback();"); 43 | } 44 | 45 | function loadComplete() { 46 | loaderClip.redirectURL = _level0.MMredirectURL; 47 | loaderClip.MMplayerType = _level0.MMplayerType; 48 | loaderClip.MMdoctitle = _level0.MMdoctitle; 49 | loaderClip.startUpdate(); 50 | } 51 | 52 | function installStatus(statusValue) { 53 | switch (statusValue) { 54 | case "Download.Complete": 55 | // Installation is complete. 56 | // In most cases the browser window that this SWF is hosted in will be closed by the installer or otherwise it has to be closed manually by the end user. 57 | // The Adobe Flash installer will attempt to reopen the browser window and reload the page containing the SWF. 58 | break; 59 | case "Download.Cancelled": 60 | // The end user chose "NO" when prompted to install the new player. 61 | // By default the SWFObject callback function is called to force alternative content. 62 | callbackSWFObject(); 63 | break; 64 | case "Download.Failed": 65 | // The end user failed to download the installer due to a network failure. 66 | // By default the SWFObject callback function is called to force alternative content. 67 | callbackSWFObject(); 68 | break; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /dist/swfobject/src/expressInstall.fla: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aymkdn/FileToDataURI/07111ab394660856dcff041bf0fdd15b559894a7/dist/swfobject/src/expressInstall.fla -------------------------------------------------------------------------------- /dist/swfobject/src/swfobject.js: -------------------------------------------------------------------------------- 1 | /*! SWFObject v2.2 2 | is released under the MIT License 3 | */ 4 | 5 | var swfobject = function() { 6 | 7 | var UNDEF = "undefined", 8 | OBJECT = "object", 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", 14 | 15 | win = window, 16 | doc = document, 17 | nav = navigator, 18 | 19 | plugin = false, 20 | domLoadFnArr = [main], 21 | regObjArr = [], 22 | objIdArr = [], 23 | listenersArr = [], 24 | storedAltContent, 25 | storedAltContentId, 26 | storedCallbackFn, 27 | storedCallbackObj, 28 | isDomLoaded = false, 29 | isExpressInstallActive = false, 30 | dynamicStylesheet, 31 | dynamicStylesheetMedia, 32 | autoHideShow = true, 33 | 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 37 | */ 38 | ua = function() { 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], 47 | d = null; 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+ 51 | plugin = true; 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; 57 | } 58 | } 59 | else if (typeof win.ActiveXObject != UNDEF) { 60 | try { 61 | var a = new ActiveXObject(SHOCKWAVE_FLASH_AX); 62 | if (a) { // a will return null when ActiveX is disabled 63 | d = a.GetVariable("$version"); 64 | if (d) { 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)]; 68 | } 69 | } 70 | } 71 | catch(e) {} 72 | } 73 | return { w3:w3cdom, pv:playerVersion, wk:webkit, ie:ie, win:windows, mac:mac }; 74 | }(), 75 | 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 80 | */ 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(); 85 | } 86 | if (!isDomLoaded) { 87 | if (typeof doc.addEventListener != UNDEF) { 88 | doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, false); 89 | } 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(); 95 | } 96 | }); 97 | if (win == top) { // if not inside an iframe 98 | (function(){ 99 | if (isDomLoaded) { return; } 100 | try { 101 | doc.documentElement.doScroll("left"); 102 | } 103 | catch(e) { 104 | setTimeout(arguments.callee, 0); 105 | return; 106 | } 107 | callDomLoadFunctions(); 108 | })(); 109 | } 110 | } 111 | if (ua.wk) { 112 | (function(){ 113 | if (isDomLoaded) { return; } 114 | if (!/loaded|complete/.test(doc.readyState)) { 115 | setTimeout(arguments.callee, 0); 116 | return; 117 | } 118 | callDomLoadFunctions(); 119 | })(); 120 | } 121 | addLoadEvent(callDomLoadFunctions); 122 | } 123 | }(); 124 | 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); 130 | } 131 | catch (e) { return; } 132 | isDomLoaded = true; 133 | var dl = domLoadFnArr.length; 134 | for (var i = 0; i < dl; i++) { 135 | domLoadFnArr[i](); 136 | } 137 | } 138 | 139 | function addDomLoadEvent(fn) { 140 | if (isDomLoaded) { 141 | fn(); 142 | } 143 | else { 144 | domLoadFnArr[domLoadFnArr.length] = fn; // Array.push() is only available in IE5.5+ 145 | } 146 | } 147 | 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 151 | */ 152 | function addLoadEvent(fn) { 153 | if (typeof win.addEventListener != UNDEF) { 154 | win.addEventListener("load", fn, false); 155 | } 156 | else if (typeof doc.addEventListener != UNDEF) { 157 | doc.addEventListener("load", fn, false); 158 | } 159 | else if (typeof win.attachEvent != UNDEF) { 160 | addListener(win, "onload", fn); 161 | } 162 | else if (typeof win.onload == "function") { 163 | var fnOld = win.onload; 164 | win.onload = function() { 165 | fnOld(); 166 | fn(); 167 | }; 168 | } 169 | else { 170 | win.onload = fn; 171 | } 172 | } 173 | 174 | /* Main function 175 | - Will preferably execute onDomLoad, otherwise onload (as a fallback) 176 | */ 177 | function main() { 178 | if (plugin) { 179 | testPlayerVersion(); 180 | } 181 | else { 182 | matchVersions(); 183 | } 184 | } 185 | 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 192 | */ 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); 198 | if (t) { 199 | var counter = 0; 200 | (function(){ 201 | if (typeof t.GetVariable != UNDEF) { 202 | var d = t.GetVariable("$version"); 203 | if (d) { 204 | d = d.split(" ")[1].split(","); 205 | ua.pv = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)]; 206 | } 207 | } 208 | else if (counter < 10) { 209 | counter++; 210 | setTimeout(arguments.callee, 10); 211 | return; 212 | } 213 | b.removeChild(o); 214 | t = null; 215 | matchVersions(); 216 | })(); 217 | } 218 | else { 219 | matchVersions(); 220 | } 221 | } 222 | 223 | /* Perform Flash Player and SWF version matching; static publishing only 224 | */ 225 | function matchVersions() { 226 | var rl = regObjArr.length; 227 | if (rl > 0) { 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}; 232 | if (ua.pv[0] > 0) { 233 | var obj = getElementById(id); 234 | if (obj) { 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); 237 | if (cb) { 238 | cbObj.success = true; 239 | cbObj.ref = getObjectById(id); 240 | cb(cbObj); 241 | } 242 | } 243 | else if (regObjArr[i].expressInstall && canExpressInstall()) { // show the Adobe Express Install dialog if set by the web page author and if supported 244 | var att = {}; 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 251 | var par = {}; 252 | var p = obj.getElementsByTagName("param"); 253 | var pl = p.length; 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"); 257 | } 258 | } 259 | showExpressInstall(att, par, id, cb); 260 | } 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); } 264 | } 265 | } 266 | } 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); 269 | if (cb) { 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; 273 | cbObj.ref = o; 274 | } 275 | cb(cbObj); 276 | } 277 | } 278 | } 279 | } 280 | } 281 | 282 | function getObjectById(objectIdStr) { 283 | var r = null; 284 | var o = getElementById(objectIdStr); 285 | if (o && o.nodeName == "OBJECT") { 286 | if (typeof o.SetVariable != UNDEF) { 287 | r = o; 288 | } 289 | else { 290 | var n = o.getElementsByTagName(OBJECT)[0]; 291 | if (n) { 292 | r = n; 293 | } 294 | } 295 | } 296 | return r; 297 | } 298 | 299 | /* Requirements for Adobe Express Install 300 | - only one instance can be active at a time 301 | - fp 6.0.65 or higher 302 | - Win/Mac OS only 303 | - no Webkit engines older than version 312 304 | */ 305 | function canExpressInstall() { 306 | return !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312); 307 | } 308 | 309 | /* Show the Adobe Express Install dialog 310 | - Reference: http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=6a253b75 311 | */ 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); 317 | if (obj) { 318 | if (obj.nodeName == "OBJECT") { // static publishing 319 | storedAltContent = abstractAltContent(obj); 320 | storedAltContentId = null; 321 | } 322 | else { // dynamic publishing 323 | storedAltContent = obj; 324 | storedAltContentId = replaceElemIdStr; 325 | } 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=" + win.location.toString().replace(/&/g,"%26") + "&MMplayerType=" + pt + "&MMdoctitle=" + doc.title; 332 | if (typeof par.flashvars != UNDEF) { 333 | par.flashvars += "&" + fv; 334 | } 335 | else { 336 | par.flashvars = fv; 337 | } 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"; 346 | (function(){ 347 | if (obj.readyState == 4) { 348 | obj.parentNode.removeChild(obj); 349 | } 350 | else { 351 | setTimeout(arguments.callee, 10); 352 | } 353 | })(); 354 | } 355 | createSWF(att, par, replaceElemIdStr); 356 | } 357 | } 358 | 359 | /* Functions to abstract and display alternative content 360 | */ 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"; 369 | (function(){ 370 | if (obj.readyState == 4) { 371 | obj.parentNode.removeChild(obj); 372 | } 373 | else { 374 | setTimeout(arguments.callee, 10); 375 | } 376 | })(); 377 | } 378 | else { 379 | obj.parentNode.replaceChild(abstractAltContent(obj), obj); 380 | } 381 | } 382 | 383 | function abstractAltContent(obj) { 384 | var ac = createElement("div"); 385 | if (ua.win && ua.ie) { 386 | ac.innerHTML = obj.innerHTML; 387 | } 388 | else { 389 | var nestedObj = obj.getElementsByTagName(OBJECT)[0]; 390 | if (nestedObj) { 391 | var c = nestedObj.childNodes; 392 | if (c) { 393 | var cl = c.length; 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)); 397 | } 398 | } 399 | } 400 | } 401 | } 402 | return ac; 403 | } 404 | 405 | /* Cross-browser dynamic SWF creation 406 | */ 407 | function createSWF(attObj, parObj, id) { 408 | var r, el = getElementById(id); 409 | if (ua.wk && ua.wk < 312) { return r; } 410 | if (el) { 411 | if (typeof attObj.id == UNDEF) { // if no 'id' is defined for the object element, it will inherit the 'id' from the alternative content 412 | attObj.id = id; 413 | } 414 | if (ua.ie && ua.win) { // Internet Explorer + the HTML object element + W3C DOM methods do not combine: fall back to outerHTML 415 | var att = ""; 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]; 420 | } 421 | else if (i.toLowerCase() == "styleclass") { // 'class' is an ECMA4 reserved keyword 422 | att += ' class="' + attObj[i] + '"'; 423 | } 424 | else if (i.toLowerCase() != "classid") { 425 | att += ' ' + i + '="' + attObj[i] + '"'; 426 | } 427 | } 428 | } 429 | var par = ""; 430 | for (var j in parObj) { 431 | if (parObj[j] != Object.prototype[j]) { // filter out prototype additions from other potential libraries 432 | par += ''; 433 | } 434 | } 435 | el.outerHTML = '' + par + ''; 436 | objIdArr[objIdArr.length] = attObj.id; // stored to fix object 'leaks' on unload (dynamic publishing only) 437 | r = getElementById(attObj.id); 438 | } 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]); 446 | } 447 | else if (m.toLowerCase() != "classid") { // filter out IE specific attribute 448 | o.setAttribute(m, attObj[m]); 449 | } 450 | } 451 | } 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]); 455 | } 456 | } 457 | el.parentNode.replaceChild(o, el); 458 | r = o; 459 | } 460 | } 461 | return r; 462 | } 463 | 464 | function createObjParam(el, pName, pValue) { 465 | var p = createElement("param"); 466 | p.setAttribute("name", pName); 467 | p.setAttribute("value", pValue); 468 | el.appendChild(p); 469 | } 470 | 471 | /* Cross-browser SWF removal 472 | - Especially needed to safely and completely remove a SWF in Internet Explorer 473 | */ 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"; 479 | (function(){ 480 | if (obj.readyState == 4) { 481 | removeObjectInIE(id); 482 | } 483 | else { 484 | setTimeout(arguments.callee, 10); 485 | } 486 | })(); 487 | } 488 | else { 489 | obj.parentNode.removeChild(obj); 490 | } 491 | } 492 | } 493 | 494 | function removeObjectInIE(id) { 495 | var obj = getElementById(id); 496 | if (obj) { 497 | for (var i in obj) { 498 | if (typeof obj[i] == "function") { 499 | obj[i] = null; 500 | } 501 | } 502 | obj.parentNode.removeChild(obj); 503 | } 504 | } 505 | 506 | /* Functions to optimize JavaScript compression 507 | */ 508 | function getElementById(id) { 509 | var el = null; 510 | try { 511 | el = doc.getElementById(id); 512 | } 513 | catch (e) {} 514 | return el; 515 | } 516 | 517 | function createElement(el) { 518 | return doc.createElement(el); 519 | } 520 | 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 523 | */ 524 | function addListener(target, eventType, fn) { 525 | target.attachEvent(eventType, fn); 526 | listenersArr[listenersArr.length] = [target, eventType, fn]; 527 | } 528 | 529 | /* Flash Player and SWF content version matching 530 | */ 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; 537 | } 538 | 539 | /* Cross-browser dynamic CSS creation 540 | - Based on Bobby van der Sluis' solution: http://www.bobbyvandersluis.com/articles/dynamicCSS.php 541 | */ 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"; 547 | if (newStyle) { 548 | dynamicStylesheet = null; 549 | dynamicStylesheetMedia = null; 550 | } 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]; 559 | } 560 | dynamicStylesheetMedia = m; 561 | } 562 | // add style rule 563 | if (ua.ie && ua.win) { 564 | if (dynamicStylesheet && typeof dynamicStylesheet.addRule == OBJECT) { 565 | dynamicStylesheet.addRule(sel, decl); 566 | } 567 | } 568 | else { 569 | if (dynamicStylesheet && typeof doc.createTextNode != UNDEF) { 570 | dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}")); 571 | } 572 | } 573 | } 574 | 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; 580 | } 581 | else { 582 | createCSS("#" + id, "visibility:" + v); 583 | } 584 | } 585 | 586 | /* Filter to avoid XSS attacks 587 | */ 588 | function urlEncodeIfNecessary(s) { 589 | var regex = /[\\\"<>\.;]/; 590 | var hasBadChars = regex.exec(s) != null; 591 | return hasBadChars && typeof encodeURIComponent != UNDEF ? encodeURIComponent(s) : s; 592 | } 593 | 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) 595 | */ 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]); 603 | } 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]); 608 | } 609 | // cleanup library's main closures to avoid memory leaks 610 | for (var k in ua) { 611 | ua[k] = null; 612 | } 613 | ua = null; 614 | for (var l in swfobject) { 615 | swfobject[l] = null; 616 | } 617 | swfobject = null; 618 | }); 619 | } 620 | }(); 621 | 622 | return { 623 | /* Public API 624 | - Reference: http://code.google.com/p/swfobject/wiki/documentation 625 | */ 626 | registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) { 627 | if (ua.w3 && objectIdStr && swfVersionStr) { 628 | var regObj = {}; 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); 635 | } 636 | else if (callbackFn) { 637 | callbackFn({success:false, id:objectIdStr}); 638 | } 639 | }, 640 | 641 | getObjectById: function(objectIdStr) { 642 | if (ua.w3) { 643 | return getObjectById(objectIdStr); 644 | } 645 | }, 646 | 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 653 | heightStr += ""; 654 | var att = {}; 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 657 | att[i] = attObj[i]; 658 | } 659 | } 660 | att.data = swfUrlStr; 661 | att.width = widthStr; 662 | att.height = heightStr; 663 | var par = {}; 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 666 | par[j] = parObj[j]; 667 | } 668 | } 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]; 673 | } 674 | else { 675 | par.flashvars = k + "=" + flashvarsObj[k]; 676 | } 677 | } 678 | } 679 | if (hasPlayerVersion(swfVersionStr)) { // create SWF 680 | var obj = createSWF(att, par, replaceElemIdStr); 681 | if (att.id == replaceElemIdStr) { 682 | setVisibility(replaceElemIdStr, true); 683 | } 684 | callbackObj.success = true; 685 | callbackObj.ref = obj; 686 | } 687 | else if (xiSwfUrlStr && canExpressInstall()) { // show Adobe Express Install 688 | att.data = xiSwfUrlStr; 689 | showExpressInstall(att, par, replaceElemIdStr, callbackFn); 690 | return; 691 | } 692 | else { // show alternative content 693 | setVisibility(replaceElemIdStr, true); 694 | } 695 | if (callbackFn) { callbackFn(callbackObj); } 696 | }); 697 | } 698 | else if (callbackFn) { callbackFn(callbackObj); } 699 | }, 700 | 701 | switchOffAutoHideShow: function() { 702 | autoHideShow = false; 703 | }, 704 | 705 | ua: ua, 706 | 707 | getFlashPlayerVersion: function() { 708 | return { major:ua.pv[0], minor:ua.pv[1], release:ua.pv[2] }; 709 | }, 710 | 711 | hasFlashPlayerVersion: hasPlayerVersion, 712 | 713 | createSWF: function(attObj, parObj, replaceElemIdStr) { 714 | if (ua.w3) { 715 | return createSWF(attObj, parObj, replaceElemIdStr); 716 | } 717 | else { 718 | return undefined; 719 | } 720 | }, 721 | 722 | showExpressInstall: function(att, par, replaceElemIdStr, callbackFn) { 723 | if (ua.w3 && canExpressInstall()) { 724 | showExpressInstall(att, par, replaceElemIdStr, callbackFn); 725 | } 726 | }, 727 | 728 | removeSWF: function(objElemIdStr) { 729 | if (ua.w3) { 730 | removeSWF(objElemIdStr); 731 | } 732 | }, 733 | 734 | createCSS: function(selStr, declStr, mediaStr, newStyleBoolean) { 735 | if (ua.w3) { 736 | createCSS(selStr, declStr, mediaStr, newStyleBoolean); 737 | } 738 | }, 739 | 740 | addDomLoadEvent: addDomLoadEvent, 741 | 742 | addLoadEvent: addLoadEvent, 743 | 744 | getQueryParamValue: function(param) { 745 | var q = doc.location.search || doc.location.hash; 746 | if (q) { 747 | if (/\?/.test(q)) { q = q.split("?")[1]; } // strip question mark 748 | if (param == null) { 749 | return urlEncodeIfNecessary(q); 750 | } 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))); 755 | } 756 | } 757 | } 758 | return ""; 759 | }, 760 | 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"; } 770 | } 771 | if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); } 772 | } 773 | isExpressInstallActive = false; 774 | } 775 | } 776 | }; 777 | }(); 778 | -------------------------------------------------------------------------------- /dist/swfobject/swfobject.js: -------------------------------------------------------------------------------- 1 | /* SWFObject v2.2 2 | is released under the MIT License 3 | */ 4 | var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y0){for(var af=0;af0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad'}}aa.outerHTML='"+af+"";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab