diff --git a/static/contrib/mediaplayer b/static/contrib/mediaplayer new file mode 120000 index 0000000..4965ec7 --- /dev/null +++ b/static/contrib/mediaplayer @@ -0,0 +1 @@ +mediaplayer-3.15/ \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/README.HTML b/static/contrib/mediaplayer-3.15/README.HTML new file mode 100755 index 0000000..6fa9e1f --- /dev/null +++ b/static/contrib/mediaplayer-3.15/README.HTML @@ -0,0 +1,54 @@ + + + + + JW FLV Media Player + + + + + + +

Example

+

Here's a simple example of the JW FLV Media Player embedded in a page. Copy-paste the source code and put the files on your site to get started.

+ + + + +
Get the Flash Player to see this player.
+ + + + + +

Quickstart

+

The easiest way to get going with the mediaplayer is by using the setup wizard. Select an example, set the file or playlist you want to play and copy-paste the embed code to your site!

+ +

Licensing

+

The FLV Media Player is licensed under a Creative Commons License. It allows you to use, modify and redistribute the script for free for noncommercial purposes. For corporate use, please apply for a 20 euros commercial license!

+ +

Documentation

+
    +
  1. All supported flashvars (variables) you can set to customize the mediaplayer.
  2. +
  3. All supported playlist formats you can use, plus some implementation info.
  4. +
  5. A large list of all third-party plugins for the mediaplayer.
  6. +
  7. A tutorial on embedding the mediaplayer in your site.
  8. +
  9. A tutorial with all functions of the javascript API.
  10. +
  11. A tutorial on adding captions and an audiodescription (accessibility).
  12. +
+ + + \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/afraid.flv b/static/contrib/mediaplayer-3.15/afraid.flv new file mode 100755 index 0000000..51fa47d Binary files /dev/null and b/static/contrib/mediaplayer-3.15/afraid.flv differ diff --git a/static/contrib/mediaplayer-3.15/afraid.jpg b/static/contrib/mediaplayer-3.15/afraid.jpg new file mode 100755 index 0000000..b53abc3 Binary files /dev/null and b/static/contrib/mediaplayer-3.15/afraid.jpg differ diff --git a/static/contrib/mediaplayer-3.15/mediaplayer.html b/static/contrib/mediaplayer-3.15/mediaplayer.html new file mode 100755 index 0000000..4ae4807 --- /dev/null +++ b/static/contrib/mediaplayer-3.15/mediaplayer.html @@ -0,0 +1,46 @@ + + + + + + + +

Example

+

Here's a simple example of the mediaplayer embedded in a page. Copy-paste the code to get started.

+ + + +
Get the Flash Player to see this player.
+ + + + + +

Documentation

+

The easiest way to get going with the mediaplayer is by using the setup wizard. Select an example, set the file or playlist you want to play and copy-paste the embed code to your site! If you want to learn more, here's the complete documentation:

+
    +
  1. All supported flashvars (variables) you can set to customize the mediaplayer.
  2. +
  3. All supported playlist formats you can use, plus some implementation info.
  4. +
  5. A large list of all third-party plugins for the mediaplayer.
     
  6. +
  7. A tutorial on embedding the mediaplayer in your site.
  8. +
  9. A tutorial with all functions of the javascript API.
  10. +
  11. A tutorial on adding captions and an audiodescription (accessibility).
  12. +
+ + + + + \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/mediaplayer.swf b/static/contrib/mediaplayer-3.15/mediaplayer.swf new file mode 100755 index 0000000..cb103d5 Binary files /dev/null and b/static/contrib/mediaplayer-3.15/mediaplayer.swf differ diff --git a/static/contrib/mediaplayer-3.15/source/Kroeger_563.ttf b/static/contrib/mediaplayer-3.15/source/Kroeger_563.ttf new file mode 100755 index 0000000..b484157 Binary files /dev/null and b/static/contrib/mediaplayer-3.15/source/Kroeger_563.ttf differ diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/feeds/ASXParser.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/feeds/ASXParser.as new file mode 100644 index 0000000..fa1f907 --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/feeds/ASXParser.as @@ -0,0 +1,67 @@ +/** +* Parses ASX feeds and returns an indexed array with all elements +* +* @author Jeroen Wijering +* @version 1.0 +**/ + + +import com.jeroenwijering.feeds.AbstractParser; +import com.jeroenwijering.utils.StringMagic; + + +class com.jeroenwijering.feeds.ASXParser extends AbstractParser { + + + /** Contructor **/ + function ASXParser() { super(); }; + + + /** build an array with all regular elements **/ + private function setElements() { + elements = new Object(); + elements["title"] = "title"; + elements["author"] = "author"; + elements["abstract"] = "description"; + }; + + + /** Convert RSS structure to array **/ + private function parse(xml:XML):Array { + var arr = new Array(); + var tpl = xml.firstChild.firstChild; + while(tpl != null) { + if (tpl.nodeName.toLowerCase() == "entry") { + var obj = new Object(); + for(var j=0; j -1) { + var idx = dat.indexOf(" "); + dat = dat.substr(0,idx) + dat.substr(idx+1); + } + var myDate = new Date(dat.substr(0,4),dat.substr(5,2)-1, + dat.substr(8,2),dat.substr(11,2),dat.substr(14,2), + dat.substr(17,2)); + var stamp = Math.round(myDate.valueOf()/1000) - + myDate.getTimezoneOffset()*60; + if(dat.length > 20) { + var hr:Number = Number(dat.substr(20,2)); + var mn:Number = Number(dat.substr(23,2)); + if(dat.charAt(19) == "-") { + stamp = stamp - hr*3600 - mn*60; + } else { + stamp += hr*3600 + mn*60; + } + } + return stamp; + } else { + return dat; + } + }; + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/feeds/FeedListener.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/feeds/FeedListener.as new file mode 100755 index 0000000..a1face4 --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/feeds/FeedListener.as @@ -0,0 +1,19 @@ +/** +* Interface for all objects that need real-time feed updates. +* +* @author Jeroen Wijering +* @version 1.0 +**/ + + +import com.jeroenwijering.feeds.*; + + +interface com.jeroenwijering.feeds.FeedListener { + + + /** invoked when the feed object has updated **/ + function onFeedUpdate(typ:String); + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/feeds/FeedManager.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/feeds/FeedManager.as new file mode 100755 index 0000000..6980b1f --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/feeds/FeedManager.as @@ -0,0 +1,258 @@ +/** +* Parses RSS, ATOM and XSPF lists and returns them as a numerical array. +* +* @author Jeroen Wijering +* @version 1.7 +**/ + + +import com.jeroenwijering.feeds.*; + + +class com.jeroenwijering.feeds.FeedManager { + + + /** The array the XML is parsed into. **/ + public var feed:Array; + /** XML file **/ + private var feedXML:XML; + /** Flag for captions. **/ + public var captions:Boolean; + /** Flag for extra audiotrack. **/ + public var audio:Boolean; + /** Flag for all items in mp3 **/ + public var onlymp3s:Boolean; + /** Flag for chapter index **/ + public var ischapters:Boolean; + /** Flag for enclosures **/ + private var enclosures:Boolean; + /** Reference to the parser object **/ + private var parser:AbstractParser; + /** An array with objects listening to feed updates **/ + private var listeners:Array; + /** A prefix string for all files **/ + private var prefix:String = ""; + /** Stream to use **/ + private var stream:String; + /** Array with all file elements **/ + private var elements:Object = { + file:"", + fallback:"", + title:"", + link:"", + id:"", + image:"", + author:"", + captions:"", + audio:"", + category:"", + start:"", + type:"", + duration:"" + }; + /** array with all supported filetypes **/ + private var filetypes:Array = new Array( + "flv","mp3","rbs","jpg","gif","png","rtmp", + "swf","mp4","m4v","m4a","mov","3gp","3g2" + ); + + + /** Constructor. **/ + function FeedManager(enc:Boolean,jvs:String,pre:String,str:String) { + enc == true ? enclosures = true: enclosures = false; + if(jvs == "true") { enableJavascript(); } + pre == undefined ? null: prefix = pre; + str == undefined ? null: stream = "_"+str; + listeners = new Array(); + }; + + + /** Enable javascript access to loadFile command. **/ + private function enableJavascript() { + if(flash.external.ExternalInterface.available) { + flash.external.ExternalInterface.addCallback( + "loadFile",this,loadFile); + flash.external.ExternalInterface.addCallback( + "addItem",this,addItem); + flash.external.ExternalInterface.addCallback( + "removeItem",this,removeItem); + flash.external.ExternalInterface.addCallback( + "itemData",this,itemData); + flash.external.ExternalInterface.addCallback( + "getLength",this,getLength); + } + }; + + + /** Load an XML playlist or single media file. **/ + public function loadFile(obj:Object) { + for (var itm in elements) { + if(obj[itm] != undefined && obj[itm].indexOf('asfunction')==-1) { + _root[itm] = obj[itm]; + } else if(feed != undefined) { + delete _root[itm]; + } + } + feed = new Array(); + var ftp = "xml"; + for(var i = filetypes.length; --i >= 0;) { + if(obj['file'].substr(0,4).toLowerCase() == "rtmp") { + ftp = "rtmp"; + } else if(_root.type == filetypes[i] || + obj['file'].substr(-3).toLowerCase() == filetypes[i]) { + ftp = filetypes[i]; + } + } + if (ftp == "xml" && obj['file'].indexOf('asfunction') == -1) { + loadXML(unescape(obj['file'])); + } else { + feed[0] = new Object(); + feed[0]['type'] = ftp; + for(var cfv in elements) { + if(_root[cfv] != undefined) { + feed[0][cfv] = unescape(_root[cfv]); + } + } + playersPostProcess(); + } + }; + + + /** Parse an XML file, return the array when done. **/ + private function loadXML(url:String) { + var ref = this; + feedXML = new XML(); + feedXML.ignoreWhite = true; + feedXML.onLoad = function(scs:Boolean) { + if(scs) { + var fmt = this.firstChild.nodeName.toLowerCase(); + if( fmt == 'rss') { + ref.parser = new RSSParser(ref.prefix); + ref.feed = ref.parser.parse(this); + } else if (fmt == 'feed') { + ref.parser = new ATOMParser(ref.prefix); + ref.feed = ref.parser.parse(this); + } else if (fmt == 'playlist') { + ref.parser = new XSPFParser(ref.prefix); + ref.feed = ref.parser.parse(this); + } else if (fmt == 'asx') { + ref.parser = new ASXParser(ref.prefix); + ref.feed = ref.parser.parse(this); + } + if(_root.audio != undefined) { + ref.feed[0]["audio"] = unescape(_root.audio); + } + ref.playersPostProcess(url); + } + }; + if(_root._url.indexOf("file://") > -1) { feedXML.load(url); } + else if(url.indexOf('?') > -1) { feedXML.load(url+'&'+random(999)); } + else { feedXML.load(url+'?'+random(999)); } + }; + + + /** set a number of flags specifically used by the players **/ + private function playersPostProcess(url:String) { + onlymp3s = true; + feed.length > 1 ? ischapters = true: ischapters = false; + captions = false; + audio = false; + for(var i=0; i= feed.length) { + feed.push(obj); + } else { + var arr1 = feed.slice(0,idx); + var arr2 = feed.slice(idx); + arr1.push(obj); + feed = arr1.concat(arr2); + } + updateListeners('add'); + }; + + + /** Remove an item from the feed **/ + public function removeItem(idx:Number) { + if(feed.length == 1) { + return; + } else if(arguments.length == 0 || idx >= feed.length) { + feed.pop(); + } else { + feed.splice(idx,1); + } + updateListeners('remove'); + }; + + + /** Retrieve playlist data for a specific item **/ + public function itemData(idx:Number):Object { + return feed[idx]; + }; + + + /** Add a feed update listener. **/ + public function addListener(lst:Object) { + listeners.push(lst); + }; + + + /** Remove a feed update listener. **/ + public function removeListener(lst:Object) { + for(var i = listeners.length; --i >= 0; ) { + if(listeners[i] == lst) { + listeners.splice(i,1); + return; + } + } + }; + + + /** Notify all listeners of a feed update **/ + private function updateListeners(typ:String) { + for(var i = listeners.length; --i >= 0; ) { + listeners[i].onFeedUpdate(typ); + } + }; + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/feeds/RSSParser.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/feeds/RSSParser.as new file mode 100755 index 0000000..c56ca57 --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/feeds/RSSParser.as @@ -0,0 +1,128 @@ +/** +* Parses ATOM feeds and returns an indexed array with all elements +* +* @author Jeroen Wijering +* @version 1.5 +**/ + + +import com.jeroenwijering.feeds.AbstractParser; +import com.jeroenwijering.utils.StringMagic; + + +class com.jeroenwijering.feeds.RSSParser extends AbstractParser { + + + /** Contructor **/ + function RSSParser() { super(); }; + + + /** build an array with all regular elements **/ + private function setElements() { + elements = new Object(); + elements["title"] = "title"; + elements["guid"] = "id"; + elements["category"] = "category"; + elements["link"] = "link"; + elements["geo:lat"] = "latitude"; + elements["geo:long"] = "longitude"; + elements["geo:city"] = "city"; + }; + + + /** Convert RSS structure to array **/ + private function parse(xml:XML):Array { + var arr = new Array(); + var tpl = xml.firstChild.firstChild.firstChild; + var ttl; + while(tpl != null) { + if (tpl.nodeName.toLowerCase() == "item") { + var obj = new Object(); + for(var j=0; j 0 || + obj["file"].indexOf(".png") > 0 || + obj["file"].indexOf(".gif") > 0) { + obj["image"] = obj["file"]; + } + } + if(obj["author"] == undefined) { obj["author"] = ttl; } + arr.push(obj); + } else if (tpl.nodeName == "title") { + ttl = tpl.firstChild.nodeValue; + } + tpl = tpl.nextSibling; + } + return arr; + }; + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/feeds/XSPFParser.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/feeds/XSPFParser.as new file mode 100755 index 0000000..cafd311 --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/feeds/XSPFParser.as @@ -0,0 +1,75 @@ +/** +* Parses ATOM feeds and returns an indexed array with all elements. +* +* @author Jeroen Wijering +* @version 1.5 +**/ + + +import com.jeroenwijering.feeds.AbstractParser; +import com.jeroenwijering.utils.StringMagic; + + +class com.jeroenwijering.feeds.XSPFParser extends AbstractParser { + + + /** Contructor **/ + function XSPFParser() { super(); }; + + + /** build an array with all regular elements **/ + private function setElements() { + elements = new Object(); + elements["title"] = "title"; + elements["creator"] = "author"; + elements["info"] = "link"; + elements["image"] = "image"; + elements["identifier"] = "id"; + elements["album"] = "category"; + }; + + + /** Convert ATOM structure to array **/ + private function parse(xml:XML):Array { + var arr = new Array(); + var tpl = xml.firstChild.firstChild; + while(tpl != null) { + if (tpl.nodeName == 'trackList') { + for(var i=0; i 0) { + currentPosition = feeder.feed[idx]["start"]; + } + if(fnd == true) { + isActive = true; + sendUpdate("item",idx); + } else { + isActive = false; + } + }; + + + /** Start function. **/ + private function setStart(prm:Number) {}; + + + /** Pause function. **/ + private function setPause(prm:Number) {}; + + + /** Stop function. **/ + private function setStop() {}; + + + /** Set volume and pass through if active. **/ + private function setVolume(vol:Number) { + if(isActive == true) { sendUpdate("volume",vol); } + }; + + + /** Send updates to the views. **/ + private function sendUpdate(typ:String,prm:Number,pr2:Number) { + for(var i=0; iNumber(config["height"])) { + config["displayheight"] = config["height"]; + } + if (config["displaywidth"] == undefined) { + config["displaywidth"] = config["width"]; + } + config["bwstreams"] == undefined ? loadFile(): checkStream(); + }; + + + /** Placeholder function for bandwidth checking **/ + private function checkStream() {}; + + + /** Load the file or playlist **/ + private function loadFile(str:String) { + feeder = new FeedManager(true,config["enablejs"],config['prefix'],str); + feeder.addListener(this); + feeder.loadFile({file:config["file"]}); + }; + + + /** Invoked by the feedmanager **/ + public function onFeedUpdate(typ:String) { + if(controller == undefined) { + config["clip"]._visible = true; + config["clip"]._parent.activity._visible = false; + setupMCV(); + } + }; + + + /** Setup all necessary MCV blocks. **/ + private function setupMCV() { + controller = new AbstractController(config,feeder); + var asv = new AbstractView(controller,config,feeder); + var vws:Array = new Array(asv); + var asm = new AbstractModel(vws,controller,config,feeder); + var mds:Array = new Array(asm); + controller.startMCV(mds); + }; + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/AbstractView.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/AbstractView.as new file mode 100755 index 0000000..7897528 --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/AbstractView.as @@ -0,0 +1,91 @@ +/** +* Basic view class of the players MCV pattern, extended by all views. +* Create you own views by extending this one. +* +* @author Jeroen Wijering +* @version 1.2 +**/ + + +import com.jeroenwijering.players.*; + + +class com.jeroenwijering.players.AbstractView { + + + /** Controller reference **/ + private var controller:AbstractController; + /** reference to config Array **/ + private var config:Object; + /** reference to feed Array **/ + private var feeder:Object; + + + /** Constructor **/ + function AbstractView(ctr:AbstractController,cfg:Object,fed:Object) { + controller = ctr; + config = cfg; + feeder = fed; + }; + + + /** Receive updates from the models. **/ + public function getUpdate(typ:String,pr1:Number,pr2:Number):Void { + trace("view: "+typ+": "+pr1+","+pr2); + switch(typ) { + case "state": + setState(pr1); + break; + case "load": + setLoad(pr1); + break; + case "time": + setTime(pr1,pr2); + break; + case "item": + setItem(pr1); + break; + case "size": + setSize(pr1,pr2); + break; + case "volume": + setVolume(pr1); + break; + default: + trace("View: incompatible update received"); + break; + } + }; + + + /** Empty state handler **/ + private function setState(pr1:Number) {}; + + + /** Empty load handler **/ + private function setLoad(pr1:Number) {}; + + + /** Empty time handler **/ + private function setTime(pr1:Number,pr2:Number) {}; + + + /** Empty item handler **/ + private function setItem(pr1:Number) {}; + + + /** Empty item handler **/ + private function setSize(pr1:Number,pr2:Number) {}; + + + /** Empty volume handler **/ + private function setVolume(pr1:Number) {}; + + + /** Send event to the controller. **/ + private function sendEvent(typ:String,prm:Number) { + controller.getEvent(typ,prm); + }; + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/AudioView.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/AudioView.as new file mode 100755 index 0000000..05aa838 --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/AudioView.as @@ -0,0 +1,103 @@ +/** +* Extra audiotrack management of the players MCV pattern. +* +* @author Jeroen Wijering +* @version 1.1 +**/ + + +import com.jeroenwijering.players.*; + +class com.jeroenwijering.players.AudioView extends AbstractView { + + + /** The MovieClip to which the sounds will be attached **/ + private var audioClip:MovieClip; + /** The Sound object we'll use**/ + private var audioObject:Sound; + /** Currently active feeditem **/ + private var currentItem:Number; + /** The current elapsed time **/ + private var currentTime:Number = 0; + /** The last stop position **/ + private var stopTime:Number; + /** The current audio time **/ + private var audioTime:Number; + /** Save the current state **/ + private var currentState:Number; + /** Check whether an MP3 file is loaded **/ + private var isLoaded:String; + /** Sync the audio with emtry or not **/ + private var sync:Boolean; + + + /** Constructor, loads caption file. **/ + function AudioView(ctr:AbstractController,cfg:Object,fed:Object, + snc:Boolean) { + super(ctr,cfg,fed); + sync = snc; + var ref = this; + audioClip = config['clip'].createEmptyMovieClip('audio', + config['clip'].getNextHighestDepth()); + audioClip.setStart = function() { + if(ref.stopTime == undefined && ref.sync == false) { + ref.audioObject.loadSound(ref.feeder.feed[0]['audio'],true); + ref.audioObject.setVolume(Number(ref.config['volume'])); + ref.audioObject.start(0); + } else if (ref.sync == false) { + ref.audioObject.start(ref.stopTime); + } else if(ref.currentState == 2) { + ref.audioObject.start(ref.currentTime); + } + }; + audioClip.setStop = function() { + ref.audioObject.stop(); + ref.stopTime = ref.audioObject.position/1000; + }; + audioObject = new Sound (audioClip); + if(config['useaudio'] == "true" && sync == false) { + audioClip.setStart(); + } + if(sync == false) { + audioObject.onSoundComplete = function() { + this.start(); + }; + } + }; + + + private function setItem(idx:Number) { + currentItem = idx; + }; + + + private function setState(stt:Number) { + currentState = stt; + if(sync == false) { return; } + if(stt == 2 && config['useaudio'] == "true") { + audioObject.start(currentTime); + } else { + audioObject.stop(); + } + }; + + + private function setTime(elp:Number,rem:Number) { + if(sync == false) { return; } + if(Math.abs(elp-currentTime) > 1) { + currentTime = elp; + audioTime = audioObject.position/1000; + if(Math.abs(currentTime - audioTime) > 1 && + config['useaudio'] == "true") { + audioObject.start(currentTime); + } + } + if (isLoaded != feeder.feed[currentItem]['audio']) { + isLoaded = feeder.feed[currentItem]['audio']; + audioObject.loadSound(isLoaded,true); + audioObject.setVolume(Number(config['volume'])); + } + }; + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/CallbackView.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/CallbackView.as new file mode 100755 index 0000000..7294710 --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/CallbackView.as @@ -0,0 +1,93 @@ +/** +* Callback to serverside script for statistics handling. +* It sends the current file,title,id and state on start and complete. +* +* @author Jeroen Wijering +* @author Nate Hanna +* @version 1.7 +**/ + + +import com.jeroenwijering.players.*; + + +class com.jeroenwijering.players.CallbackView extends AbstractView { + + + /** Currently playing item **/ + private var currentItem:Number; + /** Currently playing item **/ + private var varsObject:LoadVars; + /** Boolean for if a start call has already been sent for an item. **/ + private var playSent:Boolean = false; + /** Small interval so both complete and play events won't be issued **/ + private var playSentInt:Number; + /** Timestamp of the start of the movie **/ + private var startStamp:Number; + + + /** Constructor **/ + function CallbackView(ctr:AbstractController,cfg:Object,fed:Object) { + super(ctr,cfg,fed); + if(config['callback'] != "analytics") { + varsObject = new LoadVars(); + } + }; + + + /** Send a callback on state change **/ + private function setState(pr1:Number) { + var dat = new Date(); + if(pr1 == 3) { + var dur = Math.round(dat.valueOf()/1000 - startStamp); + sendVars("stop",dur,true); + playSent = false; + } else if (pr1 == 2 && playSent == false) { + playSentInt = setInterval(this,"sendVars",500,"start",0); + playSent = true; + startStamp = dat.valueOf()/1000; + } + }; + + + /** save the currently playing item **/ + private function setItem(pr1:Number) { + if(playSent == true && currentItem != undefined) { + var dat = new Date(); + var dur = Math.round(dat.valueOf()/1000 - startStamp); + sendVars("stop",dur,false); + playSent = false; + } + currentItem = pr1; + }; + + + /** sending the current file,title,id,state,timestamp to callback **/ + private function sendVars(stt:String,dur:Number,cpl:Boolean) { + clearInterval(playSentInt); + if(config['callback'] == "urchin" || config['callback'] == "analytics") { + var fil = feeder.feed[currentItem]["file"]; + var fcn = "javascript:pageTracker._trackPageview"; + if(config['callback'] == "urchin") { + fcn = "javascript:urchinTracker"; + } + if(fil.indexOf('http') != undefined) { + fil = fil.substring(fil.indexOf('/',7)+1); + } + if(stt == "start") { + getURL(fcn+"('/start_stream/"+fil+"');"); + } else if (stt == "stop" && cpl == true) { + getURL(fcn+"('/end_stream/"+fil+"');"); + } + } else { + varsObject.file = feeder.feed[currentItem]["file"]; + varsObject.title = feeder.feed[currentItem]["title"]; + varsObject.id = feeder.feed[currentItem]["id"]; + varsObject.state = stt; + varsObject.duration = dur; + varsObject.sendAndLoad(config["callback"],varsObject,"POST"); + } + }; + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/CaptionsParser.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/CaptionsParser.as new file mode 100755 index 0000000..9ac924c --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/CaptionsParser.as @@ -0,0 +1,157 @@ +/** +* Parses SRT lists and W3C Timed Text captions. +* +* @author Jeroen Wijering +* @version 1.3 +**/ + + +import com.jeroenwijering.utils.StringMagic; + + +class com.jeroenwijering.players.CaptionsParser { + + + /** URL of the xml file to parse. **/ + private var parseURL:String; + /** The array the XML is parsed into **/ + public var parseArray:Array; + /** LoadVars Object the SRT file is loaded into. **/ + private var parseLV:LoadVars; + /** Flash XML object the TT file is loaded into. **/ + private var parseXML:XML; + + + /** Constructor. **/ + function CaptionsParser() {}; + + + /** Parse an XML list. **/ + public function parse(url:String):Void { + parseURL = url; + parseArray = new Array(); + parseURL.indexOf(".srt") == -1 ? parseTT(): parseSRT(); + }; + + + /** Convert SRT file to subtitle array **/ + private function parseSRT() { + var ref = this; + parseLV = new LoadVars(); + parseLV.onLoad = function(scs:Boolean) { + if(scs) { + var str = ""; + var j = -2; + while(j < unescape(this).length) { + var oj = j; + j = unescape(this).indexOf('=&',j+2); + j == -1 ? j = unescape(this).length: null; + str = "&"+unescape(this).substring(oj+2,j) + str; + } + var arr = str.split("\r\n\r\n"); + for(var i=0; i -1) { + var brp = arr[i].indexOf("\r\n",tst+5); + arr[i] = arr[i].substr(0,brp)+"
" + + arr[i].substr(brp+2); + } + obj["txt"] = arr[i].substr(tst+2); + if(!isNaN(obj['bgn'])) { + ref.parseArray.push(obj); + } + delete obj; + } + } else { + ref.parseArray.push( {txt:"File not found: " + + ref.parseURL,bgn:1,dur:5}); + } + if(ref.parseArray.length == 0) { + ref.parseArray.push({txt:"Empty file: " + + ref.parseURL,bgn:1,dur:5}); + } + delete ref.parseLV; + ref.onParseComplete(); + }; + if(_root._url.indexOf("file://") > -1) { + parseLV.load(parseURL); + } else if(parseURL.indexOf('?') > -1) { + parseLV.load(parseURL+'&'+random(999)); + } else { + parseLV.load(parseURL+'?'+random(999)); + } + }; + + + /** Covert TimedText file to subtitle array. **/ + private function parseTT():Void { + var ref = this; + parseXML = new XML(); + parseXML.ignoreWhite = true; + parseXML.onLoad = function(scs:Boolean) { + if(scs) { + if(this.firstChild.nodeName.toLowerCase() == "tt") { + var bdy = this.firstChild.childNodes[1]; + if(bdy.firstChild.firstChild.attributes.begin==undefined){ + for(var i=0; i -1) { + parseXML.load(parseURL); + } else if(parseURL.indexOf('?') > -1) { + parseXML.load(parseURL+'&'+random(999)); + } else { + parseXML.load(parseURL+'?'+random(999)); + } + }; + + + /** Invoked when parsing is completed. **/ + public function onParseComplete() { }; + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/CaptionsView.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/CaptionsView.as new file mode 100755 index 0000000..46964bd --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/CaptionsView.as @@ -0,0 +1,144 @@ +/** +* Captions display management of the players MCV pattern. +* +* @author Jeroen Wijering +* @version 1.4 +**/ + + +import com.jeroenwijering.players.*; +import flash.filters.DropShadowFilter; + + +class com.jeroenwijering.players.CaptionsView extends AbstractView { + + + /** The current volume **/ + private var parser:CaptionsParser; + /** The captions array **/ + private var captions:Array; + /** The current elapsed time **/ + private var currentTime:Number; + /** The captions textfield **/ + private var clip:MovieClip; + /** Boolean for captionate captions **/ + private var captionate:Boolean = false; + /** Time of last caption **/ + private var capTime:Number; + /** Captionate track to use **/ + private var capTrack:Number = 0; + + + /** Constructor, loads caption file. **/ + function CaptionsView(ctr:AbstractController,cfg:Object,fed:Object) { + super(ctr,cfg,fed); + var ref = this; + Stage.addListener(this); + parser = new CaptionsParser(); + parser.onParseComplete = function() { + this.parseArray.sortOn("bgn",Array.NUMERIC); + ref.captions = this.parseArray; + delete this; + } + clip = config["clip"].captions; + setDimensions(); + }; + + + /** onLoad override, sets capture sizes. **/ + private function setDimensions() { + clip.txt.autoSize = "center"; + clip.bck._height = clip.txt._height + 10; + if(Stage["displayState"] == "fullScreen") { + clip._width = Stage.width; + clip._yscale= clip._xscale; + clip._y = Stage.height - clip._height; + } else { + clip._width = config["displaywidth"]; + clip._yscale = clip._xscale; + clip._y = config["displayheight"] - clip._height; + } + if(System.capabilities.version.indexOf("7,0,") == -1) { + var blr = 2 + Math.round(clip._yscale/100); + var flt = new flash.filters.DropShadowFilter( + 0,0,0x000000,1,blr,blr,50,2); + clip.filters = new Array(flt); + } + }; + + + /** parse a new captions file every time an item is set **/ + private function setItem(idx:Number) { + captions = new Array(); + if(feeder.feed[idx]["captions"] == undefined) { + clip.bck._alpha = 0; + } else if(feeder.feed[idx]["captions"].indexOf("captionate") > -1 || + feeder.feed[idx]["captions"] == "true") { + captionate = true; + var tck = Number(feeder.feed[idx]["captions"].substr(-1)); + if(isNaN(tck)) { + capTrack = 0; + } else { + capTrack = tck; + } + } else { + parser.parse(feeder.feed[idx]["captions"]); + } + }; + + + /** Check elapsed time, evaluate captions every second. **/ + private function setTime(elp:Number,rem:Number) { + currentTime = elp; + if (captionate == false) { + setCaption(); + } + }; + + + /** Check if a new caption should be displayed **/ + private function setCaption() { + var nxt:Number = captions.length; + for (var i=0; i currentTime) { + nxt = i; + break; + } + } + if(captions[nxt-1]["bgn"] + captions[nxt-1]["dur"] > currentTime) { + clip.txt.htmlText = captions[nxt-1]["txt"]; + if(System.capabilities.version.indexOf("7,0,") > -1) { + clip.bck._alpha = 50; + clip.bck._height = Math.round(clip.txt._height + 10); + } else { + clip.bck._height = Math.round(clip.txt._height + 15); + } + if(Stage["displayState"] == "fullScreen") { + clip._y = Stage.height - clip._height; + } else { + clip._y = config["displayheight"] - clip._height; + } + } else { + clip.txt.htmlText = ""; + } + }; + + + /** Captionate input **/ + public function onCaptionate(cap:Array) { + clip.txt.htmlText = cap[capTrack]; + capTime = currentTime; + }; + + + /** OnResize Handler: catches stage resizing **/ + public function onResize() { setDimensions(); }; + + + /** Catches fullscreen escape **/ + public function onFullScreen(fs:Boolean) { + if(fs == false) { setDimensions(); } + }; + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/ControlbarView.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/ControlbarView.as new file mode 100755 index 0000000..8241389 --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/ControlbarView.as @@ -0,0 +1,444 @@ +/** +* Controlbar user interface management of the players MCV pattern. +* +* @author Jeroen Wijering +* @version 1.13 +**/ + + +import com.jeroenwijering.players.*; +import com.jeroenwijering.utils.*; +import com.jeroenwijering.feeds.FeedListener; + + +class com.jeroenwijering.players.ControlbarView extends AbstractView + implements FeedListener { + + + /** currently active item **/ + private var currentItem:Number; + /** full width of the scrubbars **/ + private var barWidths:Number; + /** duration of the currently playing item **/ + private var itemLength:Number; + /** progress of the currently playing item **/ + private var itemProgress:Number = 0 + /** do not rescale loadbar on rebuffering **/ + private var wasLoaded:Boolean = false; + /** interval for hiding the display **/ + private var hideInt:Number; + + + /** Constructor **/ + function ControlbarView(ctr:AbstractController,cfg:Object,fed:Object) { + super(ctr,cfg,fed); + setColorsClicks(); + setDimensions(); + Stage.addListener(this); + feeder.addListener(this); + Mouse.addListener(this); + }; + + + /** Sets up colors and clicks of all controlbar items. **/ + private function setColorsClicks() { + var ref = this; + var tgt = config["clip"].controlbar; + tgt.col = new Color(tgt.back); + tgt.col.setRGB(config["backcolor"]); + tgt.playpause.col1 = new Color(tgt.playpause.ply); + tgt.playpause.col1.setRGB(config["frontcolor"]); + tgt.playpause.col2 = new Color(tgt.playpause.pas); + tgt.playpause.col2.setRGB(config["frontcolor"]); + tgt.playpause.onRollOver = function() { + this.col1.setRGB(ref.config["lightcolor"]); + this.col2.setRGB(ref.config["lightcolor"]); + }; + tgt.playpause.onRollOut = function() { + this.col1.setRGB(ref.config["frontcolor"]); + this.col2.setRGB(ref.config["frontcolor"]); + }; + tgt.playpause.onRelease = function() { ref.sendEvent("playpause"); }; + tgt.stop.col = new Color(tgt.stop.icn); + tgt.stop.col.setRGB(config["frontcolor"]); + tgt.stop.onRollOver = function() { + this.col.setRGB(ref.config["lightcolor"]); + }; + tgt.stop.onRollOut = function() { + this.col.setRGB(ref.config["frontcolor"]); + }; + tgt.stop.onRelease = function() { ref.sendEvent("stop"); }; + tgt.prev.col = new Color(tgt.prev.icn); + tgt.prev.col.setRGB(config["frontcolor"]); + tgt.prev.onRollOver = function() { + this.col.setRGB(ref.config["lightcolor"]); + }; + tgt.prev.onRollOut = function() { + this.col.setRGB(ref.config["frontcolor"]); + }; + tgt.prev.onRelease = function() { ref.sendEvent("prev"); }; + tgt.next.col = new Color(tgt.next.icn); + tgt.next.col.setRGB(config["frontcolor"]); + tgt.next.onRollOver = function() { + this.col.setRGB(ref.config["lightcolor"]); + }; + tgt.next.onRollOut = function() { + this.col.setRGB(ref.config["frontcolor"]); + }; + tgt.next.onRelease = function() { ref.sendEvent("next"); }; + tgt.scrub.elpTxt.textColor = config["frontcolor"]; + tgt.scrub.remTxt.textColor = config["frontcolor"]; + tgt.scrub.col = new Color(tgt.scrub.icn); + tgt.scrub.col.setRGB(config["frontcolor"]); + tgt.scrub.col2 = new Color(tgt.scrub.bar); + tgt.scrub.col2.setRGB(config["frontcolor"]); + tgt.scrub.col3 = new Color(tgt.scrub.bck); + tgt.scrub.col3.setRGB(config["frontcolor"]); + tgt.scrub.bck.onRollOver = function() { + this._parent.col.setRGB(ref.config["lightcolor"]); + }; + tgt.scrub.bck.onRollOut = function() { + this._parent.col.setRGB(ref.config["frontcolor"]); + }; + tgt.scrub.bck.onPress= function() { + this.onEnterFrame = function() { + var xm = this._parent._xmouse; + if(xm < this._parent.bck._width + this._parent.bck._x && + xm > this._parent.bck._x) { + this._parent.icn._x = this._parent._xmouse - 1; + } + } + }; + tgt.scrub.bck.onRelease= tgt.scrub.bck.onReleaseOutside= function() { + var sec = (this._parent._xmouse-this._parent.bar._x) / + ref.barWidths*ref.itemLength; + ref.sendEvent("scrub",Math.round(sec)); + delete this.onEnterFrame; + }; + tgt.scrub.bck.tabEnabled = false; + tgt.fs.col1 = new Color(tgt.fs.ns); + tgt.fs.col2 = new Color(tgt.fs.fs); + tgt.fs.col.setRGB(ref.config["frontcolor"]); + tgt.fs.col2.setRGB(ref.config["frontcolor"]); + tgt.fs.onRollOver = function() { + this.col1.setRGB(ref.config["lightcolor"]); + this.col2.setRGB(ref.config["lightcolor"]); + }; + tgt.fs.onRollOut = function() { + this.col1.setRGB(ref.config["frontcolor"]); + this.col2.setRGB(ref.config["frontcolor"]); + }; + tgt.fs.onRelease = function() { + ref.sendEvent("fullscreen"); + this.col1.setRGB(ref.config["frontcolor"]); + this.col2.setRGB(ref.config["frontcolor"]); + }; + tgt.cc.col = new Color(tgt.cc.icn); + tgt.cc.col.setRGB(ref.config["frontcolor"]); + tgt.cc.onRollOver = function() { + this.col.setRGB(ref.config["lightcolor"]); + }; + tgt.cc.onRollOut = function() { + this.col.setRGB(ref.config["frontcolor"]); + }; + tgt.cc.onRelease = function() { + ref.sendEvent("captions"); + }; + tgt.au.col = new Color(tgt.au.icn); + tgt.au.col.setRGB(ref.config["frontcolor"]); + tgt.au.onRollOver = function() { + this.col.setRGB(ref.config["lightcolor"]); + }; + tgt.au.onRollOut = function() { + this.col.setRGB(ref.config["frontcolor"]); + }; + tgt.au.onRelease = function() { + ref.sendEvent("audio"); + }; + tgt.dl.col = new Color(tgt.dl.icn); + tgt.dl.col.setRGB(ref.config["frontcolor"]); + tgt.dl.onRollOver = function() { + this.col.setRGB(ref.config["lightcolor"]); + }; + tgt.dl.onRollOut = function() { + this.col.setRGB(ref.config["frontcolor"]); + }; + tgt.dl.onRelease = function() { + ref.sendEvent("getlink",ref.currentItem); + }; + tgt.vol.col = new Color(tgt.vol.bar); + tgt.vol.col.setRGB(config["frontcolor"]); + tgt.vol.col2 = new Color(tgt.vol.bck); + tgt.vol.col2.setRGB(config["frontcolor"]); + tgt.vol.col3 = new Color(tgt.vol.icn); + tgt.vol.col3.setRGB(config["frontcolor"]); + tgt.vol.onRollOver = function() { + this.col.setRGB(ref.config["lightcolor"]); + this.col3.setRGB(ref.config["lightcolor"]); + }; + tgt.vol.onRollOut = function() { + this.col.setRGB(ref.config["frontcolor"]); + this.col3.setRGB(ref.config["frontcolor"]); + }; + tgt.vol.onRelease = function() { + this.onEnterFrame = function() { + this.msk._width = this._xmouse-12; + }; + }; + tgt.vol.onRelease = tgt.vol.onReleaseOutside = function() { + ref.sendEvent("volume",(this._xmouse-12)*5); + delete this.onEnterFrame; + }; + }; + + + /** Sets up dimensions of all controlbar items. **/ + private function setDimensions() { + clearInterval(hideInt); + var tgt = config["clip"].controlbar; + var cbw = 400; + // overall position and width + if(Stage["displayState"] == "fullScreen") { + tgt._x = Math.round(Stage.width/2-200); + tgt._y = Stage.height - 40; + tgt._alpha = 100; + tgt.back._alpha = 50; + tgt.fs.fs._visible = false; + tgt.fs.ns._visible = true; + } else if(config["displayheight"] == config["height"]) { + tgt._y = config["displayheight"] - 40; + if(config["displaywidth"] > 450 && + config["displaywidth"] == config["width"]) { + tgt._x = Math.round(Stage.width/2-200); + } else { + tgt._x = 20; + cbw = config["displaywidth"] - 40; + } + tgt.back._alpha = 40; + tgt.fs.fs._visible = true; + tgt.fs.ns._visible = false; + } else { + tgt._x = 0; + tgt._y = config["displayheight"]; + cbw = config["width"]; + tgt._alpha = 100; + tgt.back._alpha = 100; + tgt.fs.fs._visible = true; + tgt.fs.ns._visible = false; + } + if(config["largecontrols"] == "true") { + tgt._xscale = tgt._yscale = 200; + if(Stage["displayState"] == "fullScreen") { + tgt._y = Stage.height - 60; + cbw = 300; + tgt._x = Math.round(Stage.width/2 - 300); + } else { + cbw /= 2; + } + } + tgt.back._width = cbw; + // all buttons + if(config["displayheight"] < config["height"] - 40 || + config["displaywidth"] < config["width"] - 40 || + cbw < 200 || feeder.feed.length < 2) { + tgt.prev._visible = tgt.next._visible = false; + tgt.scrub.shd._width = cbw-17; + tgt.scrub._x = 17; + } else { + tgt.prev._visible = tgt.next._visible = true; + tgt.scrub.shd._width = cbw-51; + tgt.scrub._x = 51; + } + if(config['showstop'] == 'true') { + tgt.scrub.shd._width -= 17; + tgt.scrub._x += 17; + } else { + tgt.stop._visible = false; + tgt.prev._x = 17; + tgt.next._x = 34; + } + var xp = cbw; + if(cbw > 50) { + xp -= 37; + tgt.scrub.shd._width -= 37; + tgt.vol._x = xp; + } else { + xp -= 1; + tgt.scrub.shd._width -= 1; + tgt.vol._x = xp; + } + if (feeder.audio == true) { + xp -= 17; + tgt.scrub.shd._width -= 17; + tgt.au._x = xp; + tgt.au._visible = true; + } else { + tgt.au._visible = false; + } + if (feeder.captions == true) { + xp -= 17; + tgt.scrub.shd._width -= 17; + tgt.cc._x = xp; + tgt.cc._visible = true; + } else { + tgt.cc._visible = false; + } + if (config["showdownload"] == "true") { + xp -= 17; + tgt.scrub.shd._width -= 17; + tgt.dl._x = xp; + } else { + tgt.dl._visible = false; + } + if((Stage["displayState"] == undefined || + config["usefullscreen"] == "false" || + feeder.onlymp3s == true) && + config["fsbuttonlink"] == undefined) { + tgt.fs._visible = false; + } else { + xp -= 18; + tgt.scrub.shd._width -= 18; + tgt.fs._x = xp; + } + if(config["showdigits"] == "false" || tgt.scrub.shd._width < 120 || + System.capabilities.version.indexOf("7,0,") > -1) { + tgt.scrub.elpTxt._visible = tgt.scrub.remTxt._visible = false; + tgt.scrub.bar._x = tgt.scrub.bck._x = tgt.scrub.icn._x = 5; + barWidths = tgt.scrub.bck._width = tgt.scrub.shd._width - 10; + } else { + tgt.scrub.elpTxt._visible = tgt.scrub.remTxt._visible = true; + tgt.scrub.bar._x = tgt.scrub.bck._x = tgt.scrub.icn._x = 42; + barWidths = tgt.scrub.bck._width = tgt.scrub.shd._width - 84; + tgt.scrub.remTxt._x = tgt.scrub.shd._width - 39; + } + tgt.scrub.bar._width = 0; + }; + + + /** Show and hide the play/pause button and show activity icon **/ + private function setState(stt:Number) { + var tgt = config["clip"].controlbar.playpause; + switch(stt) { + case 0: + tgt.ply._visible = true; + tgt.pas._visible = false; + break; + case 1: + tgt.pas._visible = true; + tgt.ply._visible = false; + break; + case 2: + tgt.pas._visible = true; + tgt.ply._visible = false; + break; + } + }; + + + /** Print current time to controlBar **/ + private function setTime(elp:Number,rem:Number) { + itemLength = elp + rem; + itemProgress = Math.round(rem/(itemLength)*100); + var tgt = config["clip"].controlbar.scrub; + var w = Math.floor(elp/(elp+rem)*barWidths) - 2; + if(rem > 0) { + tgt.icn._visible = true; + tgt.bar._visible = true; + elp == 0 || w < 2 ? tgt.bar._width = 0: tgt.bar._width = w - 2; + tgt.icn._x = tgt.bar._width + tgt.bar._x + 1; + } else { + tgt.icn._visible = false; + tgt.bar._visible = false; + } + tgt.elpTxt.text = StringMagic.addLeading(elp/60) + ":" + + StringMagic.addLeading(elp%60); + if(tgt.bck._width == barWidths) { + if(config['showdigits'] == "total") { + tgt.remTxt.text = StringMagic.addLeading((elp+rem)/60)+ ":" + + StringMagic.addLeading((elp+rem)%60); + } else { + tgt.remTxt.text = StringMagic.addLeading(rem/60)+ ":" + + StringMagic.addLeading(rem%60); + } + } + }; + + + /** New item is loaded **/ + private function setItem(prm:Number) { + wasLoaded = false; + currentItem = prm; + config["clip"].controlbar.scrub.icn._alpha = 100; + }; + + + /** Print current buffer amount to controlbar **/ + private function setLoad(pct:Number) { + var tgt = config["clip"].controlbar.scrub; + if(wasLoaded == false) { + tgt.bck._width = Math.round(barWidths*pct/100); + } + tgt.remTxt.text = Math.round(pct)+" %"; + pct == 100 ? wasLoaded = true: null; + }; + + + /** Reflect current volume in volumebar **/ + private function setVolume(pr1:Number) { + var tgt = config["clip"].controlbar.vol; + tgt.msk._width = Math.round(pr1/5); + if(pr1 == 0) { + tgt.icn._alpha = 40; + } else { + tgt.icn._alpha = 100; + } + }; + + + /** Catches stage resizing **/ + public function onResize() { + if(config['displayheight'] > config["height"]+10) { + config["height"] = config["displayheight"] = Stage.height; + config["width"] = config["displaywidth"] = Stage.width; + } + setDimensions(); + }; + + + /** Catches fullscreen escape **/ + public function onFullScreen(fs:Boolean) { + if(fs == false) { + setDimensions(); + Animations.fadeIn(config['clip'].controlbar); + } else { + hideInt = setInterval(this,"hideBar",500); + } + }; + + + /** after a delay, the controlbar is hidden **/ + private function hideBar() { + Animations.fadeOut(config['clip'].controlbar); + clearInterval(hideInt); + } + + + /** Mouse move shows controlbar **/ + public function onMouseMove() { + if(config["displayheight"] == config["height"] || + Stage["displayState"] == "fullScreen") { + Animations.fadeIn(config['clip'].controlbar); + clearInterval(hideInt); + if(!config["clip"].controlbar.hitTest(_root._xmouse,_root._ymouse)) { + hideInt = setInterval(this,"hideBar",500); + } + } + }; + + + public function onFeedUpdate(typ:String) { + setDimensions(); + }; + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/DisplayView.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/DisplayView.as new file mode 100755 index 0000000..14732cf --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/DisplayView.as @@ -0,0 +1,267 @@ +/** +* Display user interface management of the players MCV pattern. +* +* @author Jeroen Wijering +* @version 1.8 +**/ + + +import com.jeroenwijering.players.*; +import com.jeroenwijering.utils.*; + + +class com.jeroenwijering.players.DisplayView extends AbstractView { + + + /** reference to the imageloader object **/ + private var imageLoader:ImageLoader; + /** Reference to the currently active item **/ + private var currentItem; + /** Reference to the currently active item **/ + private var itemSize:Array; + /** Reference to the currently active item **/ + private var thumbSize:Array; + /** Starting position of the players **/ + private var startPos:Array; + + + /** Constructor **/ + function DisplayView(ctr:AbstractController,cfg:Object,fed:Object) { + super(ctr,cfg,fed); + Stage.addListener(this); + itemSize = new Array(config['displaywidth'],config['displayheight']); + thumbSize = new Array(config['displaywidth'],config['displayheight']); + var ref = this; + var tgt = config["clip"]; + imageLoader = new ImageLoader(tgt.display.thumb); + imageLoader.onLoadFinished = function() { + ref.thumbSize = new Array(this.targetClip._width, + this.targetClip._height); + ref.scaleClip(tgt.display.thumb,this.targetClip._width, + this.targetClip._height); + } + startPos = new Array(tgt._x,tgt._y); + setColorsClicks(); + setDimensions(); + }; + + + /** Sets up colors and clicks of all display items. **/ + private function setColorsClicks() { + var ref = this; + // background + var tgt = config["clip"].back; + tgt.col = new Color(tgt); + tgt.col.setRGB(config["backcolor"]); + // display items + tgt = config["clip"].display; + tgt.col = new Color(tgt.back); + tgt.col.setRGB(config["screencolor"]); + tgt.setMask(config["clip"].mask); + if(config["showicons"] == "false") { + tgt.playicon._visible = false; + tgt.muteicon._visible = false; + } + tgt.activity._visible = false; + tgt.back.tabEnabled = false; + if(config["autostart"] == "muted") { + tgt.back.onRelease = function() { + ref.sendEvent("volume",80); + ref.firstClick(); + }; + } else if (config["autostart"] == "false") { + tgt.muteicon._visible = false; + tgt.back.onRelease = function() { + ref.sendEvent("playpause"); + ref.firstClick(); + }; + } else { + ref.firstClick(); + } + if(config["logo"] != "undefined") { + var lll = new ImageLoader(tgt.logo,"none"); + lll.onLoadFinished = function() { + tgt.logo._x = ref.config["displaywidth"] - + tgt.logo._width - 10; + tgt.logo._y = 10; + }; + lll.loadImage(config["logo"]); + tgt.logo.onRelease = function() { + ref.sendEvent("getlink",ref.currentItem); + }; + } + }; + + + /** Sets up dimensions of all controlbar items. **/ + private function setDimensions() { + var tgt = config["clip"].back; + if(Stage["displayState"] == "fullScreen") { + config["clip"]._x = config["clip"]._y = 0; + tgt._width = Stage.width; + tgt._height = Stage.height; + } else { + config["clip"]._x = startPos[0]; + config["clip"]._y = startPos[1]; + tgt._width = config["width"]; + tgt._height = config["height"]; + if(config["displayheight"] >= config["height"] - + config['controlbar']) { tgt._height--; } + } + tgt = config["clip"].display; + scaleClip(tgt.thumb,thumbSize[0],thumbSize[1]); + scaleClip(tgt.image,itemSize[0],itemSize[1]); + scaleClip(tgt.video,itemSize[0],itemSize[1]); + if(Stage["displayState"] == "fullScreen") { + config["clip"].mask._width = + tgt.back._width = Stage.width; + config["clip"].mask._height = + tgt.back._height = Stage.height; + } else { + config["clip"].mask._width = + tgt.back._width = config["displaywidth"]; + config["clip"].mask._height = + tgt.back._height = config["displayheight"]; + } + tgt.playicon._x = tgt.activity._x = tgt.muteicon._x = + Math.round(tgt.back._width/2); + tgt.playicon._y = tgt.activity._y = tgt.muteicon._y = + Math.round(tgt.back._height/2); + if(Stage["displayState"] == "fullScreen") { + tgt.playicon._xscale = tgt.playicon._yscale = + tgt.muteicon._xscale = tgt.muteicon._yscale = + tgt.activity._xscale = tgt.activity._yscale = + tgt.logo._xscale = tgt.logo._yscale = 200; + tgt.logo._x = Stage.width - tgt.logo._width - 20; + tgt.logo._y = 20; + } else { + tgt.playicon._xscale = tgt.playicon._yscale = + tgt.muteicon._xscale = tgt.muteicon._yscale = + tgt.activity._xscale = tgt.activity._yscale = + tgt.logo._xscale = tgt.logo._yscale = 100; + if(tgt.logo._height > 1) { + tgt.logo._x= config["displaywidth"]-tgt.logo._width -10; + tgt.logo._y = 10; + } + } + }; + + + /** Show and hide the play/pause button and show activity icon **/ + private function setState(stt:Number) { + var tgt = config["clip"].display; + switch(stt) { + case 0: + if (config["linkfromdisplay"] == "false" && + config["showicons"] == "true") { + tgt.playicon._visible = true; + } + tgt.activity._visible = false; + break; + case 1: + tgt.playicon._visible = false; + if (config["showicons"] == "true") { + tgt.activity._visible = true; + } + break; + case 2: + tgt.playicon._visible = false; + tgt.activity._visible = false; + break; + } + }; + + + /** save size information and rescale accordingly **/ + private function setSize(wid:Number,hei:Number) { + itemSize = new Array (wid,hei); + var tgt = config["clip"].display; + scaleClip(tgt.image,itemSize[0],itemSize[1]); + scaleClip(tgt.video,itemSize[0],itemSize[1]); + }; + + + /** Scale movie according to overstretch setting **/ + private function scaleClip(tgt:MovieClip,wid:Number,hei:Number):Void { + var tcf = tgt.mc._currentframe; + tgt.mc.gotoAndStop(1); + var stw = config["displaywidth"]; + var sth = config["displayheight"]; + if(Stage["displayState"] == "fullScreen") { + stw = Stage.width; + sth = Stage.height; + } + var xsr = stw/wid; + var ysr = sth/hei; + var mxm = Math.max(xsr,ysr); + if ((Math.abs(xsr-ysr)/mxm < 0.1 && config["overstretch"] != "none") + || config["overstretch"] == "fit") { + tgt._width = stw; + tgt._height = sth; + } else if (xsr < ysr && config["overstretch"] == "false" || + ysr < xsr && config["overstretch"] == "true") { + tgt._width = wid*xsr; + tgt._height = hei*xsr; + } else if(config["overstretch"] == "none") { + tgt._width = wid; + tgt._height = hei; + } else { + tgt._width = wid*ysr; + tgt._height = hei*ysr; + } + tgt._x = stw/2 - tgt._width/2; + tgt._y = sth/2 - tgt._height/2; + tgt.mc.gotoAndPlay(tcf); + }; + + + /** Load Thumbnail image if available. **/ + private function setItem(idx:Number) { + currentItem = idx; + var tgt = config["clip"].display; + if(feeder.feed[idx]["image"] == "undefined") { + tgt.thumb.clear(); + tgt.thumb._visible = false; + } else { + imageLoader.loadImage(feeder.feed[idx]["image"]); + tgt.thumb._visible = true; + } + }; + + + /** OnResize Handler: catches stage resizing **/ + public function onResize() { + if(config['displayheight'] >= config["height"]) { + config["height"] = config["displayheight"] = Stage.height; + config["width"] = config["displaywidth"] = Stage.width; + } + setDimensions(); + }; + + + /** Catches fullscreen escape **/ + public function onFullScreen(fs:Boolean) { + if(fs == false) { setDimensions(); } + }; + + + /** Catches the first display click to reset unmute / displayclick **/ + private function firstClick() { + var ref = this; + var tgt = config["clip"].display; + tgt.playicon._visible = false; + tgt.muteicon._visible = false; + if(config["linkfromdisplay"] == "true") { + tgt.back.onRelease = function() { + ref.sendEvent("getlink",ref.currentItem); + }; + } else { + tgt.back.onRelease = function() { + ref.sendEvent("playpause",1); + }; + } + + }; + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/EqualizerView.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/EqualizerView.as new file mode 100755 index 0000000..2fd2e5d --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/EqualizerView.as @@ -0,0 +1,98 @@ +/** +* View for an actionscript-drawn equalizer (thanks to Brewer). +* The eq. is fake, but it considers playstate and volume. +* +* @author Jeroen Wijering +* @version 1.1 +**/ + + +import com.jeroenwijering.players.*; + + +class com.jeroenwijering.players.EqualizerView extends AbstractView { + + + /** EQ movieclip reference **/ + private var eqClip:MovieClip; + /** current volume **/ + private var currentVolume:Number; + /** number of stripes to display in the EQ **/ + private var eqStripes:Number; + + + /** Constructor; just inheriting. **/ + function EqualizerView(ctr:AbstractController,cfg:Object,fed:Object) { + super(ctr,cfg,fed); + setupEQ(); + Stage.addListener(this); + }; + + + /** setup EQ **/ + private function setupEQ() { + eqClip = config["clip"].equalizer; + eqClip._y = config["displayheight"] - 50; + eqStripes = Math.floor((config['displaywidth'] - 20)/6); + eqClip.stripes.duplicateMovieClip("stripes2",1); + eqClip.mask.duplicateMovieClip("mask2",3); + eqClip.stripes._width = eqClip.stripes2._width = + config['displaywidth']-20; + eqClip.stripes.top.col = new Color(eqClip.stripes.top); + eqClip.stripes.top.col.setRGB(config['lightcolor']); + eqClip.stripes.bottom.col = new Color(eqClip.stripes.bottom); + eqClip.stripes.bottom.col.setRGB(0xFFFFFF); + eqClip.stripes2.top.col = new Color(eqClip.stripes2.top); + eqClip.stripes2.top.col.setRGB(config['lightcolor']); + eqClip.stripes2.bottom.col = new Color(eqClip.stripes2.bottom); + eqClip.stripes2.bottom.col.setRGB(0xFFFFFF); + eqClip.stripes.setMask(eqClip.mask); + eqClip.stripes2.setMask(eqClip.mask2); + eqClip.stripes._alpha = eqClip.stripes2._alpha = 50; + setInterval(this,"drawEqualizer",100,eqClip.mask); + setInterval(this,"drawEqualizer",100,eqClip.mask2); + }; + + + /** Draw a random frame for the equalizer **/ + private function drawEqualizer(tgt:MovieClip) { + tgt.clear(); + tgt.beginFill(0x000000, 100); + tgt.moveTo(0,0); + var h = Math.round(currentVolume/4); + for (var j=0; j< eqStripes; j++) { + var z = random(h)+h/2 + 2; + if(j == Math.floor(eqStripes/2)) { z = 0; } + tgt.lineTo(j*6,-1); + tgt.lineTo(j*6,-z); + tgt.lineTo(j*6+4,-z); + tgt.lineTo(j*6+4,-1); + tgt.lineTo(j*6,-1); + } + tgt.lineTo(eqStripes*6,0); + tgt.lineTo(0,0); + tgt.endFill(); + }; + + + /** Change the height to reflect the volume **/ + private function setVolume(vol:Number) { currentVolume = vol; }; + + + /** Only display the eq if a song is playing **/ + private function setState(stt:Number) { + stt == 2 ? eqClip._visible = true: eqClip._visible = false; + }; + + + /** Hide the EQ on fullscreen view **/ + public function onFullScreen(fs:Boolean) { + if(fs == true) { + eqClip._visible = false; + } else { + eqClip._visible = true; + } + }; + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/FLVModel.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/FLVModel.as new file mode 100755 index 0000000..5ac8249 --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/FLVModel.as @@ -0,0 +1,329 @@ +/** +* FLV model class of the players MCV pattern. +* Handles playback of FLV files, HTTP streams and RTMP streams. +* +* @author Jeroen Wijering +* @version 1.13 +**/ + + +import com.jeroenwijering.players.*; + + +class com.jeroenwijering.players.FLVModel extends AbstractModel { + + + /** array with extensions used by this model **/ + private var mediatypes:Array = new Array( + "flv","rtmp","mp4","m4v","m4a","mov","3gp","3g2"); + /** NetConnection object reference **/ + private var connectObject:NetConnection; + /** NetStream object reference **/ + private var streamObject:NetStream; + /** Sound object reference **/ + private var soundObject:Sound; + /** interval ID of the buffer update function **/ + private var loadedInterval:Number; + /** current percentage of the video that's loaded **/ + private var currentLoaded:Number = 0; + /** interval ID of the position update function **/ + private var positionInterval:Number; + /** current state of the video that is playing **/ + private var currentState:Number; + /** Current volume **/ + private var currentVolume:Number; + /** MovieClip with "display" video Object **/ + private var videoClip:MovieClip; + /** object with keyframe times and positions, saved for PHP streaming **/ + private var metaKeyframes:Object = new Object(); + /** Boolean to check whether a stop event is fired **/ + private var stopFired:Boolean = false; + /** Boolean to check whether a flusk event is fired **/ + private var flushFired:Boolean = false; + /** Switch for FLV type currently played **/ + private var flvType:String; + /** check h264 for time offset **/ + private var isH264:Boolean; + /** check h264 for time offset **/ + private var timeOffset:Number = 0; + /** reference to the captions object for parsing captionate data **/ + public var capView:Object; + /** buffer iterator (prevents buffericon showing on slow PC's) **/ + public var bufferCount:Number = 0; + + + + /** Constructor **/ + function FLVModel(vws:Array,ctr:AbstractController,cfg:Object, + fed:Object,fcl:MovieClip) { + super(vws,ctr,cfg,fed); + connectObject = new NetConnection(); + videoClip = fcl; + if(config["smoothing"] == "false") { + videoClip.display.smoothing = false; + } else { + videoClip.display.smoothing = true; + } + videoClip.display.deblocking = config["deblocking"]; + videoClip.createEmptyMovieClip("snd",videoClip.getNextHighestDepth()); + soundObject = new Sound(videoClip.snd); + }; + + + /** Check which FLV type we use **/ + private function setItem(idx:Number) { + super.setItem(idx); + if(isActive == true) { + if(config["streamscript"] != undefined) { + flvType = "HTTP"; + } else if(feeder.feed[currentItem]["type"] == "rtmp") { + flvType = "RTMP"; + } else { + flvType = "FLV"; + } + } + }; + + + /** Start a specific video **/ + private function setStart(pos:Number) { + stopFired = false; + flushFired = false; + if (pos != undefined) { currentPosition = pos; } + if(pos < 1) { + pos = 0; + } else if (pos > feeder.feed[currentItem]["duration"] - 1) { + pos = feeder.feed[currentItem]["duration"] - 1; + } + if (flvType=="RTMP" && feeder.feed[currentItem]["id"] != currentURL) { + connectObject.connect(feeder.feed[currentItem]["file"]); + currentURL = feeder.feed[currentItem]["id"]; + setStreamObject(connectObject); + streamObject.play(currentURL); + } else if(flvType != "RTMP" && + feeder.feed[currentItem]["file"] != currentURL) { + connectObject.connect(null); + currentURL = feeder.feed[currentItem]["file"]; + if(flvType == "HTTP" ) { + setStreamObject(connectObject); + if(config["streamscript"] == "lighttpd") { + streamObject.play(currentURL); + } else { + streamObject.play(config["streamscript"] + + "?file=" + currentURL); + } + } else { + setStreamObject(connectObject); + streamObject.play(currentURL); + } + } else { + if(flvType == "HTTP" && pos != undefined) { + playKeyframe(currentPosition); + } else if (flvType != "HTTP" && pos != undefined) { + streamObject.seek(currentPosition); + } else if(flvType == "RTMP" && currentPosition > 0 && + feeder.feed[currentItem]["duration"] == 0) { + connectObject.connect(feeder.feed[currentItem]["file"]); + setStreamObject(connectObject); + streamObject.play(currentURL); + } else { + streamObject.pause(false); + } + } + videoClip._visible = true; + videoClip._parent.thumb._visible = false; + clearInterval(positionInterval); + positionInterval = setInterval(this,"updatePosition",100); + clearInterval(loadedInterval); + loadedInterval = setInterval(this,"updateLoaded",100); + }; + + + /** Read and broadcast the amount of the flv that's currently loaded **/ + private function updateLoaded() { + var pct:Number = Math.round(streamObject.bufferLength/ + streamObject.bufferTime*100); + if(flvType == "FLV") { + pct = Math.round(streamObject.bytesLoaded/ + streamObject.bytesTotal*100); + } + if(isNaN(pct)) { + currentLoaded = 0; + sendUpdate("load",0); + } else if (pct > 95) { + clearInterval(loadedInterval); + currentLoaded = 100; + sendUpdate("load",100); + } else if (pct != currentLoaded) { + currentLoaded= pct; + sendUpdate("load",currentLoaded); + } + }; + + + /** Read and broadcast the current position of the song **/ + private function updatePosition() { + var pos = streamObject.time + timeOffset; + if(pos == currentPosition && currentState != 1 && stopFired != true) { + if(bufferCount == 5) { + currentState = 1; + sendUpdate("state",1); + bufferCount = 0; + } else { + bufferCount++; + } + } else if (pos != currentPosition && currentState != 2) { + bufferCount = 0; + currentState = 2; + sendUpdate("state",2); + } else { + bufferCount = 0; + } + if (pos != currentPosition) { + currentPosition = pos; + sendUpdate("time",currentPosition, + Math.max(feeder.feed[currentItem]["duration"]-currentPosition,0)); + } else if (stopFired == true || + (flushFired == true && flvType != "RTMP" && bufferCount == 5)) { + currentState = 3; + videoClip._visible = false; + videoClip._parent.thumb._visible = true; + sendUpdate("state",3); + sendCompleteEvent(); + stopFired = false; + flushFired = false; + } + }; + + + /** Pause the video that's currently playing. **/ + private function setPause(pos:Number) { + if(pos < 1) { pos = 0; } + clearInterval(positionInterval); + if(pos != undefined) { + currentPosition = pos; + sendUpdate("time",currentPosition, + Math.abs(feeder.feed[currentItem]["duration"]-currentPosition)); + streamObject.seek(currentPosition); + } + streamObject.pause(true); + currentState = 0; + sendUpdate("state",0); + }; + + + /** Stop video and clear data. **/ + private function setStop(pos:Number) { + clearInterval(loadedInterval); + clearInterval(positionInterval); + videoClip._visible = false; + delete currentURL; + delete currentLoaded; + delete currentPosition; + delete metaKeyframes; + currentLoaded = 0; + stopFired = false; + timeOffset = 0; + streamObject.close(); + delete streamObject; + }; + + + /** Set volume of the sound object. **/ + private function setVolume(vol:Number) { + super.setVolume(vol); + currentVolume = vol; + soundObject.setVolume(vol); + }; + + + /** Connect a new stream object to video/audio/callbacks **/ + private function setStreamObject(cnt:NetConnection) { + _root.tf.text = 'metadata!'; + var ref = this; + currentLoaded = 0; + sendUpdate("load",0); + streamObject = new NetStream(cnt); + streamObject.setBufferTime(config["bufferlength"]); + streamObject.onMetaData = function(obj) { + if(obj.duration > 1) { + ref.feeder.feed[ref.currentItem]["duration"] = obj.duration; + } + if(obj.width > 10) { + ref.sendUpdate("size",obj.width,obj.height); + } + if(obj.seekpoints != undefined) { + ref.isH264 = true; + ref.metaKeyframes = new Object(); + ref.metaKeyframes.times = new Array(); + ref.metaKeyframes.filepositions = new Array(); + for (var j in obj.seekpoints) { + ref.metaKeyframes.times.unshift( + Number(obj.seekpoints[j]['time'])); + ref.metaKeyframes.filepositions.unshift( + Number(obj.seekpoints[j]['time'])); + } + } else { + ref.metaKeyframes = obj.keyframes; + } + if(ref.feeder.feed[ref.currentItem]['start'] > 0) { + if(ref.flvType == "HTTP") { + ref.playKeyframe(ref.feeder.feed[ref.currentItem]['start']); + } else if (ref.flvType == "RTMP") { + ref.setStart(ref.feeder.feed[ref.currentItem]['start']); + } + } + delete obj; + delete this.onMetaData; + }; + streamObject.onStatus = function(object) { + trace("status: "+object.code); + if(object.code == "NetStream.Play.Stop" && ref.flvType!='RTMP') { + ref.stopFired = true; + } else if (object.code == "NetStream.Play.StreamNotFound") { + ref.currentState = 3; + ref.videoClip._visible = false; + ref.sendUpdate("state",3); + ref.sendCompleteEvent(); + ref.stopFired = false; + ref.flushFired = false; + } else if (object.code == "NetStream.Buffer.Flush") { + ref.flushFired = true; + } + }; + streamObject.onPlayStatus = function(object) { + if( object.code == "NetStream.Play.Complete" || + object.code == "NetStream.Play.Stop") { + ref.stopFired = true; + } + }; + streamObject.onCaption = function(cap:Array) { + ref.capView.onCaptionate(cap); + }; + videoClip.display.attachVideo(streamObject); + videoClip.snd.attachAudio(streamObject); + }; + + + /** Play from keyframe position from metadata **/ + private function playKeyframe(pos:Number) { + for (var i=0; i< metaKeyframes.times.length; i++) { + if((metaKeyframes.times[i] <= pos) && + (metaKeyframes.times[i+1] >= pos)) { + if(config["streamscript"] == "lighttpd") { + streamObject.play(currentURL+"?start="+ + metaKeyframes.filepositions[i]); + if(isH264 == true) { + timeOffset = metaKeyframes.filepositions[i]; + } + } else { + streamObject.play(config["streamscript"]+"?file="+ + currentURL+"&pos="+metaKeyframes.filepositions[i]); + } + break; + } + } + }; + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/ImageModel.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/ImageModel.as new file mode 100755 index 0000000..73bb61a --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/ImageModel.as @@ -0,0 +1,151 @@ +/** +* Image model class of the players MCV pattern. +* +* @author Jeroen Wijering +* @version 1.5 +**/ + + +import com.jeroenwijering.players.*; +import com.jeroenwijering.utils.ImageLoader; + + +class com.jeroenwijering.players.ImageModel extends AbstractModel { + + + /** array with extensions used by this model **/ + private var mediatypes:Array = new Array("jpg","gif","png","swf"); + /** ImageLoader instance **/ + private var imageLoader:ImageLoader; + /** Clip to load the image into **/ + private var imageClip:MovieClip; + /** interval ID of image duration function **/ + private var positionInterval:Number; + /** current state **/ + private var currentState:Number; + /** boolean to check for current SWF **/ + private var isSWF:Boolean; + + + /** Constructor **/ + function ImageModel(vws:Array,ctr:AbstractController,cfg:Object, + fed:Object,imc:MovieClip,scl:Boolean) { + super(vws,ctr,cfg,fed); + imageClip = imc; + var ref = this; + if(arguments[5] == true) { + imageLoader = new ImageLoader(imageClip,config["overstretch"], + config["width"],config["height"]); + } else { + imageLoader = new ImageLoader(imageClip); + } + imageLoader.onLoadFinished = function() { + ref.currentState = 2; + ref.sendUpdate("state",2); + ref.sendUpdate("load",100); + }; + imageLoader.onLoadProgress = function(tgt,btl,btt) { + ref.sendUpdate("load",Math.round(btl/btt*100)); + }; + imageLoader.onMetaData = function() { + ref.sendUpdate("size",this.sourceWidth,this.sourceHeight); + if(this.sourceLength > ref.feeder.feed[ref.currentItem]["duration"]) { + ref.feeder.feed[ref.currentItem]["duration"] = this.sourceLength; + } + }; + }; + + + /** Start display interval for a specific image **/ + private function setStart(pos:Number) { + if(pos < 1 ) { + pos = 0; + } else if (pos > feeder.feed[currentItem]["duration"] - 1) { + pos = feeder.feed[currentItem]["duration"] - 1; + } + clearInterval(positionInterval); + if(feeder.feed[currentItem]["file"] != currentURL) { + imageClip._visible = true; + currentURL = feeder.feed[currentItem]["file"]; + if(feeder.feed[currentItem]["file"].indexOf(".swf") == -1) { + isSWF = false; + } else { + isSWF = true; + } + imageLoader.loadImage(feeder.feed[currentItem]["file"]); + currentState = 1; + sendUpdate("state",1); + sendUpdate("load",0); + } else { + currentState = 2; + sendUpdate("state",2); + } + if (pos != undefined) { + currentPosition = pos; + isSWF == true ? imageClip.mc.gotoAndPlay(pos*20): null; + if(pos == 0) {sendUpdate("time",0,feeder.feed[currentItem]["duration"]); } + } else { + isSWF == true ? imageClip.mc.play(): null; + } + positionInterval = setInterval(this,"updatePosition",100); + }; + + + /** Read and broadcast the current position of the song **/ + private function updatePosition() { + if(currentState == 2) { + currentPosition += 0.1; + if(currentPosition >= feeder.feed[currentItem]["duration"]) { + currentState = 3; + sendUpdate("state",3); + sendCompleteEvent(); + } else { + sendUpdate("time",currentPosition,feeder.feed[currentItem]["duration"]-currentPosition); + } + } + }; + + + /** stop the image display interval **/ + private function setPause(pos:Number) { + if(pos < 1 ) { + pos = 0; + } else if (pos > feeder.feed[currentItem]["duration"] - 1) { + pos = feeder.feed[currentItem]["duration"] - 1; + } + clearInterval(positionInterval); + currentState = 0; + sendUpdate("state",0); + if(pos != undefined) { + currentPosition = pos; + sendUpdate("time",currentPosition,feeder.feed[currentItem]["duration"]-currentPosition); + isSWF == true ? imageClip.mc.gotoAndStop(pos*20+1): null; + } else { + isSWF == true ? imageClip.mc.stop(): null; + } + }; + + + /** stop display of the item altogether **/ + private function setStop() { + delete currentURL; + clearInterval(positionInterval); + currentPosition = 0; + isSWF == true ? imageClip.mc.gotoAndStop(1): null; + if (imageClip.bg == undefined) { + imageClip.mc.removeMovieClip(); + imageClip.smc.removeMovieClip(); + imageClip._visible = false; + } + }; + + + /** set duration to rotatetime for images **/ + private function setItem(idx:Number) { + super.setItem(idx); + if(feeder.feed[currentItem]["duration"] == 0 && isActive == true) { + feeder.feed[currentItem]["duration"] = config['rotatetime']; + } + } + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/ImageRotator.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/ImageRotator.as new file mode 100755 index 0000000..b63feb4 --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/ImageRotator.as @@ -0,0 +1,82 @@ +/** +* Manages startup and overall control of the Flash Image Rotator +* +* @author Jeroen Wijering +* @version 1.7 +**/ + + +import com.jeroenwijering.players.*; + + +class com.jeroenwijering.players.ImageRotator extends AbstractPlayer { + + + /** Array with all config values **/ + public var config:Object = { + clip:undefined, + file:"playlist.xml", + height:200, + width:400, + transition:"random", + backcolor:0x000000, + frontcolor:0xffffff, + lightcolor:0xffffff, + screencolor:0x000000, + kenburns:"false", + logo:undefined, + overstretch:"false", + showicons:"true", + shownavigation:"true", + autostart:"true", + repeat:"true", + rotatetime:5, + shuffle:"true", + volume:80, + enablejs:"false", + javascriptid:undefined, + linkfromdisplay:"false", + linktarget:"_self", + useaudio:"true", + abouttxt:"JW Image Rotator 3.15", + aboutlnk:"http://www.jeroenwijering.com/?about=JW_Image_Rotator" + }; + + + /** Constructor **/ + function ImageRotator(tgt:MovieClip) { + super(tgt); + }; + + + /** Setup all necessary MCV blocks. **/ + private function setupMCV():Void { + controller = new RotatorController(config,feeder); + var rov = new RotatorView(controller,config,feeder); + var ipv = new InputView(controller,config,feeder); + var vws:Array = new Array(rov,ipv); + if(config["enablejs"] == "true") { + var jsv = new JavascriptView(controller,config,feeder); + vws.push(jsv); + } + if(feeder.audio == true) { + var bav = new AudioView(controller,config,feeder,false); + vws.push(bav); + } + config["displayheight"] = config["height"]; + var im1=new ImageModel(vws,controller,config,feeder, + config["clip"].img1,true); + var im2=new ImageModel(vws,controller,config,feeder, + config["clip"].img2,true); + var mds:Array = new Array(im1,im2); + controller.startMCV(mds); + }; + + + /** Application startup, used for MTASC compilation **/ + public static function main() { + var irt = new ImageRotator(_root.rotator); + } + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/InputView.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/InputView.as new file mode 100755 index 0000000..735697f --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/InputView.as @@ -0,0 +1,63 @@ +/** +* Keyboard input management of the players MCV pattern. +* SPACE: playpause,UP:prev,DOWN:next,LEFT:volume-10,RIGHT:volume+10 +* +* @author Jeroen Wijering +* @version 1.3 +**/ + + +import com.jeroenwijering.players.*; + + +class com.jeroenwijering.players.InputView extends AbstractView { + + + /** The current volume **/ + private var currentVolume:Number; + /** The current elapsed time **/ + private var currentTime:Number; + + + /** Constructor **/ + function InputView(ctr:AbstractController,cfg:Object,fed:Object) { + super(ctr,cfg,fed); + Key.addListener(this); + }; + + + /** Save current elapsed time **/ + private function setTime(elp:Number,rem:Number) { currentTime = elp; }; + + + /** Save current volume **/ + private function setVolume(vol:Number) { currentVolume = vol; }; + + + /** KeyDown handler, forwarded by Key object **/ + public function onKeyDown() { + if (Key.getCode() == 32) { + sendEvent("playpause"); + } else if (Key.getCode() == 37) { + if(feeder.feed.length == 1) { + sendEvent("scrub",currentTime-15); + } else { + sendEvent("prev"); + } + } else if (Key.getCode() == 39) { + if(feeder.feed.length == 1) { + sendEvent("scrub",currentTime+15); + } else { + sendEvent("next"); + } + } else if (Key.getCode() == 38) { + sendEvent("volume",currentVolume+10); + } else if (Key.getCode() == 40) { + sendEvent("volume",currentVolume-10); + } else if (Key.getCode() == 77) { + sendEvent("volume",0); + } + }; + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/JavascriptView.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/JavascriptView.as new file mode 100755 index 0000000..7214ecf --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/JavascriptView.as @@ -0,0 +1,90 @@ +/** +* Javascript user interface management of the players MCV pattern. +* +* @author Jeroen Wijering +* @version 1.5 +**/ + + +import com.jeroenwijering.players.*; +import flash.external.ExternalInterface; + + +class com.jeroenwijering.players.JavascriptView extends AbstractView { + + + /** Previous loading value **/ + private var loads:Number; + /** Previous elapsed value **/ + private var elaps:Number; + /** Previous remaining value **/ + private var remain:Number; + /** Previous state value **/ + private var state:Number = 4; + /** Status change abbreviations **/ + private var statuses:Array = new Array( + 'PAUSED', + 'BUFFERING', + 'PLAYING', + 'COMPLETE', + 'NOT STARTED' + ); + + + /** Constructor **/ + function JavascriptView(ctr:AbstractController,cfg:Object,fed:Object) { + super(ctr,cfg,fed); + if(ExternalInterface.available) { + ExternalInterface.addCallback("sendEvent",this,sendEvent); + } + }; + + + /** Override of the update receiver; forwarding all to javascript **/ + public function getUpdate(typ:String,pr1:Number,pr2:Number) { + if(ExternalInterface.available) { + switch(typ) { + case "load": + if(Math.round(pr1) != loads) { + loads = Math.round(pr1); + ExternalInterface.call("getUpdate",typ,loads,pr2, + config["javascriptid"]); + } + break; + case "time": + if(Math.round(pr1)!=elaps || Math.round(pr2)!=remain) { + elaps = Math.round(pr1); + remain = Math.round(pr2); + ExternalInterface.call("getUpdate",typ,elaps,remain, + config["javascriptid"]); + } + break; + case "item": + ExternalInterface.call("getUpdate",typ,pr1,pr2, + config["javascriptid"]); + break; + case "state": + sendStatusChange(pr1); + ExternalInterface.call("getUpdate",typ,pr1,pr2, + config["javascriptid"]); + break; + default: + ExternalInterface.call("getUpdate",typ,pr1,pr2, + config["javascriptid"]); + break; + } + } + }; + + + /** state change function for longtail **/ + private function sendStatusChange(stt) { + if(!(state == 3 && stt == 0)) { + ExternalInterface.call("playerStatusChange", + statuses[state],statuses[stt]); + } + state = stt; + }; + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/MP3Model.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/MP3Model.as new file mode 100755 index 0000000..1e53b2c --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/MP3Model.as @@ -0,0 +1,154 @@ +/** +* MP3 model class of the players MCV pattern. +* +* @author Jeroen Wijering +* @version 1.4 +**/ + + +import com.jeroenwijering.players.*; + + +class com.jeroenwijering.players.MP3Model extends AbstractModel { + + + /** array with extensions used by this model **/ + private var mediatypes:Array = new Array("mp3","rbs"); + /** Sound instance **/ + private var soundObject:Sound; + /** MovieClip to apply the sound object to **/ + private var soundClip:MovieClip; + /** interval ID of the buffer update function **/ + private var loadedInterval:Number; + /** currently loaded percentage **/ + private var currentLoaded:Number = 0; + /** interval ID of the position update function **/ + private var positionInterval:Number; + /** current state of the sound that is playing **/ + private var currentState:Number; + /** Current volume **/ + private var currentVolume:Number; + + + /** Constructor **/ + function MP3Model(vws:Array,ctr:AbstractController, + cfg:Object,fed:Object,scl:MovieClip) { + super(vws,ctr,cfg,fed); + soundClip = scl; + }; + + + /** Start a specific sound **/ + private function setStart(pos:Number) { + if(pos < 1 ) { + pos = 0; + } else if (pos > feeder.feed[currentItem]["duration"] - 1) { + pos = feeder.feed[currentItem]["duration"] - 1; + } + clearInterval(positionInterval); + if(feeder.feed[currentItem]["file"] != currentURL) { + var ref = this; + currentURL = feeder.feed[currentItem]["file"]; + soundObject = new Sound(soundClip); + soundObject.onSoundComplete = function() { + ref.currentState = 3; + ref.sendUpdate("state",3); + ref.sendCompleteEvent(); + }; + soundObject.onLoad = function(scs:Boolean) { + if(scs == false) { + ref.currentState = 3; + ref.sendUpdate("state",3); + ref.sendCompleteEvent(); + } + }; + soundObject.loadSound(currentURL,true); + soundObject.setVolume(currentVolume); + sendUpdate("load",0); + loadedInterval = setInterval(this,"updateLoaded",100); + } + if(pos != undefined) { + currentPosition = pos; + if(pos == 0) { sendUpdate("time",0,feeder.feed[currentItem]["duration"]); } + } + soundObject.start(currentPosition); + updatePosition(); + sendUpdate("size",0,0); + positionInterval = setInterval(this,"updatePosition",100); + }; + + + /** Read and broadcast the amount of the mp3 that's currently loaded **/ + private function updateLoaded() { + var pct:Number = Math.round(soundObject.getBytesLoaded() / + soundObject.getBytesTotal()*100); + if(isNaN(pct)) { + currentLoaded = 0; + sendUpdate("load",0); + } else if (pct != currentLoaded) { + sendUpdate("load",pct); + currentLoaded = pct; + } else if(pct >= 100) { + clearInterval(loadedInterval); + currentLoaded = 100; + sendUpdate("load",100); + } + }; + + + /** Read and broadcast the current position of the song **/ + private function updatePosition() { + var pos = soundObject.position/1000; + feeder.feed[currentItem]["duration"] = soundObject.duration/(10*currentLoaded); + if(pos == currentPosition && currentState != 1) { + currentState = 1; + sendUpdate("state",1); + } else if (pos != currentPosition && currentState != 2) { + currentState = 2; + sendUpdate("state",2); + } + if (pos != currentPosition) { + currentPosition = pos; + sendUpdate("time",currentPosition,feeder.feed[currentItem]["duration"]-currentPosition); + } + }; + + + /** Pause the sound that's currently playing. **/ + private function setPause(pos:Number) { + if(pos < 1) { + pos = 0; + } else if (pos > feeder.feed[currentItem]["duration"] - 1) { + pos = feeder.feed[currentItem]["duration"] - 1; + } + soundObject.stop(); + clearInterval(positionInterval); + currentState = 0; + sendUpdate("state",0); + if(pos != undefined) { + currentPosition = pos; + sendUpdate("time",currentPosition,feeder.feed[currentItem]["duration"]-currentPosition); + } + }; + + + /** stop and unload the sound **/ + private function setStop() { + soundObject.stop(); + clearInterval(positionInterval); + clearInterval(loadedInterval); + delete currentURL; + delete soundObject; + currentLoaded = 0; + }; + + + /** Set volume of the sound object. **/ + private function setVolume(vol:Number) { + super.setVolume(vol); + currentVolume = vol; + soundObject.setVolume(vol); + }; + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/MediaPlayer.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/MediaPlayer.as new file mode 100755 index 0000000..cdf0013 --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/MediaPlayer.as @@ -0,0 +1,177 @@ +/** +* Player that reads all media formats Flash can read. +* +* @author Jeroen Wijering +* @version 1.10 +**/ + + +import com.jeroenwijering.players.*; +import com.jeroenwijering.utils.BandwidthCheck; + + +class com.jeroenwijering.players.MediaPlayer extends AbstractPlayer { + + + /** Array with all config values **/ + private var config:Object = { + clip:undefined, + file:"video.flv", + height:260, + width:320, + controlbar:20, + displayheight:undefined, + frontcolor:0x000000, + backcolor:0xffffff, + lightcolor:0x000000, + screencolor:0x000000, + autoscroll:"false", + displaywidth:undefined, + largecontrols:"false", + logo:undefined, + showdigits:"true", + showdownload:"false", + showeq:"false", + showicons:"true", + shownavigation:"true", + showstop:"false", + thumbsinplaylist:"true", + usefullscreen:"true", + fsbuttonlink:undefined, + autostart:"false", + bufferlength:3, + deblocking:4, + overstretch:"false", + repeat:"false", + rotatetime:5, + shuffle:"true", + smoothing:"true", + volume:80, + bwfile:"100k.jpg", + bwstreams:undefined, + callback:undefined, + enablejs:"false", + javascriptid:"", + linkfromdisplay:"false", + linktarget:'_self', + prefix:"", + recommendations:undefined, + streamscript:undefined, + useaudio:"true", + usecaptions:"true", + usemute:"false", + usekeys:"true", + abouttxt:"JW FLV Media Player 3.15", + aboutlnk:"http://www.jeroenwijering.com/?about=JW_FLV_Media_Player" + }; + + + /** Constructor **/ + public function MediaPlayer(tgt:MovieClip) { + super(tgt); + }; + + + /** check bandwidth for streaming **/ + private function checkStream() { + var ref = this; + var str = config["bwstreams"].split(","); + var bwc = new BandwidthCheck(config["bwfile"]); + bwc.onComplete = function(kbps) { + trace("bandwidth: "+kbps); + var bwm = new ContextMenuItem("Detected bandwidth: "+kbps+" kbps"); + bwm.separatorBefore = true; + ref.manager.context.customItems.push(bwm); + if(ref.config['enablejs'] == "true" && + flash.external.ExternalInterface.available) { + flash.external.ExternalInterface.call("getBandwidth",kbps); + } + for (var i=1; i feeder.feed.length-1 ? itm = feeder.feed.length-1: null; + if(feeder.feed[currentItem]['file'] != feeder.feed[itm]['file']) { + sendChange("stop"); + } + currentItem = itm; + sendChange("item",itm); + + } + sendChange("start",feeder.feed[itm]["start"]); + currentURL = feeder.feed[itm]['file']; + isPlaying = true; + }; + + + /** Get url from an item if link exists, else playpause. **/ + private function setGetlink(idx:Number) { + if(feeder.feed[idx]["link"] == undefined) { + setPlaypause(); + } else { + getURL(feeder.feed[idx]["link"],config["linktarget"]); + } + }; + + + /** Determine what to do if an item is completed. **/ + private function setComplete() { + itemsPlayed++; + if(feeder.feed[currentItem]['type'] == "rtmp" || + config["streamscript"] != undefined) { + sendChange("stop"); + } + if(config["repeat"] == "false" || (config["repeat"] == "list" + && itemsPlayed >= feeder.feed.length)) { + sendChange("pause",0); + isPlaying = false; + itemsPlayed = 0; + } else { + var itm; + if(config["shuffle"] == "true") { + itm = randomizer.pick(); + } else if(currentItem == feeder.feed.length - 1) { + itm = 0; + } else { + itm = currentItem+1; + } + setPlayitem(itm); + } + }; + + + /** Fullscreen switch function. **/ + private function setFullscreen() { + if(Stage["displayState"] == "normal" && + config["usefullscreen"] == "true") { + Stage["displayState"] = "fullScreen"; + } else if (Stage["displayState"] == "fullScreen" && + config["usefullscreen"] == "true") { + Stage["displayState"] = "normal"; + } else if (config["fsbuttonlink"] != undefined) { + sendChange("stop"); + getURL(config["fsbuttonlink"],config["linktarget"]); + } + }; + + + /** Captions toggle **/ + private function setCaptions() { + if(config["usecaptions"] == "true") { + config["usecaptions"] = "false"; + config["clip"].captions._visible = false; + config["clip"].controlbar.cc.icn._alpha = 40; + } else { + config["usecaptions"] = "true"; + config["clip"].captions._visible = true; + config["clip"].controlbar.cc.icn._alpha = 100; + } + playerSO.data.usecaptions = config["usecaptions"]; + playerSO.flush(); + }; + + + /** Audiotrack toggle **/ + private function setAudio() { + if(config["useaudio"] == "true") { + config["useaudio"] = "false"; + config["clip"].audio.setStop(); + config["clip"].controlbar.au.icn._alpha = 40; + } else { + config["useaudio"] = "true"; + config["clip"].audio.setStart(); + config["clip"].controlbar.au.icn._alpha = 100; + } + playerSO.data.useaudio = config["useaudio"]; + playerSO.flush(); + }; + + + /** Check volume percentage and forward to models. **/ + private function setVolume(prm) { + if (prm < 0 ) { prm = 0; } else if (prm > 100) { prm = 100; } + if(prm == 0) { + if(muted == true) { + muted = false; + sendChange("volume",config['volume']); + } else { + muted = true; + sendChange("volume",0); + } + } else { + sendChange("volume",prm); + config['volume'] = prm; + playerSO.data.volume = config["volume"]; + playerSO.flush(); + muted = false; + } + }; + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/PlaylistView.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/PlaylistView.as new file mode 100755 index 0000000..fe69a0a --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/PlaylistView.as @@ -0,0 +1,239 @@ +/** +* Playlist view management of the players MCV pattern. +* +* @author Jeroen Wijering +* @version 1.9 +**/ + + +import com.jeroenwijering.players.*; +import com.jeroenwijering.utils.*; +import com.jeroenwijering.feeds.FeedListener; + + +class com.jeroenwijering.players.PlaylistView extends AbstractView + implements FeedListener { + + + /** ImageLoader **/ + private var thumbLoader:ImageLoader; + /** Scroller instance **/ + private var listScroller:Scroller; + /** Position of the playlist **/ + private var listRight:Boolean; + /** Position of the playlist **/ + private var listWidth:Number; + /** number of items in the playlist **/ + private var listLength:Number; + /** Currently highlighted playlist item **/ + private var currentItem:Number; + /** Save the current time **/ + private var currentTime:Number = -10; + + + + /** Constructor **/ + function PlaylistView(ctr:AbstractController,cfg:Object,fed:Object) { + super(ctr,cfg,fed); + if(config["displaywidth"] < config["width"]) { + listRight = true; + listWidth = config["width"]-config["displaywidth"]-1; + } else { + listRight = false; + listWidth = config["width"]; + } + setButtons(); + Stage.addListener(this); + feeder.addListener(this); + }; + + + /** OnLoad event handler; sets up the playlist sizes and colors. **/ + private function setButtons() { + var ref = this; + var tgt = config["clip"].playlist; + tgt.btn._visible = false; + // iterate playlist and setup each button + listLength = feeder.feed.length; + var num = 0; + for(var i=0; i:
"+ + feeder.feed[i]["title"]; + } else { + tgt["btn"+i].txt.htmlText = "" + + feeder.feed[i]["author"] + ":
" + + feeder.feed[i]["title"]; + } + if(feeder.feed[i]["image"] != undefined) { + tgt["btn"+i].txt._x += 60; + tgt["btn"+i].txt._width -= 60; + thumbLoader = + new ImageLoader(tgt["btn"+i].img,"true",60,40); + thumbLoader.loadImage(feeder.feed[i]["image"]); + tgt["btn"+i].img.setMask(tgt["btn"+i].msk); + } else { + tgt["btn"+i].msk._height = 10; + tgt["btn"+i].img._visible = false; + tgt["btn"+i].msk._visible = false; + } + } else { + tgt["btn"+i]._y = num*23; + if(feeder.feed[i]["author"] == undefined) { + tgt["btn"+i].txt.htmlText = feeder.feed[i]["title"]; + } else { + tgt["btn"+i].txt.htmlText = feeder.feed[i]["author"] + + " - " + feeder.feed[i]["title"]; + } + tgt["btn"+i].msk._height = 10; + tgt["btn"+i].img._visible = + tgt["btn"+i].msk._visible = false; + } + tgt["btn"+i].txt.textColor = config["frontcolor"]; + // set link icon + if(feeder.feed[i]["link"] != undefined) { + tgt["btn"+i].txt._width -= 20; + tgt["btn"+i].icn._x = listWidth - 24; + tgt["btn"+i].icn.onRollOver = function() { + this._parent.col2.setRGB(ref.config["lightcolor"]); + }; + tgt["btn"+i].icn.onRollOut = function() { + if(ref.currentItem == this._parent.getDepth()) { + this._parent.col2.setRGB(ref.config["backcolor"]); + } else { + this._parent.col2.setRGB(ref.config["frontcolor"]); + } + }; + tgt["btn"+i].icn.onRelease = function() { + ref.sendEvent("getlink",this._parent.getDepth()); + }; + } else { + tgt["btn"+i].icn._visible = false; + } + num++; + } + } + // setup mask and scrollbar if needed + var msk = config["clip"].playlistmask; + if(listRight == true) { + msk._x = tgt._x = Number(config["displaywidth"]) + 1; + msk._y = tgt._y = 0; + msk._height = config["displayheight"]; + } else { + msk._y = tgt._y = Number(config["displayheight"]) + + Number(config["controlbar"]) - 1; + msk._height = Number(config["height"]) + 1 - + Number(config["controlbar"])-Number(config["displayheight"]); + } + msk._width = listWidth; + tgt.setMask(msk); + if(tgt._height > msk._height + 2 && feeder.feed.length > 1) { + if(config["autoscroll"] == "false") { + msk._width -= 10; + for(var i=0; i 5) { + currentTime = elp; + for (var i=0; i currentTime) { + if(i != currentItem+1) { setItem(i-1); } + break; + } + } + } + }; + + + /** Hide the scrollbar on fullscreen **/ + public function onFullScreen(fs:Boolean) { + if(listScroller == undefined) { + break; + } else if(fs == true) { + config["clip"].scrollbar._visible = false; + } else { + config["clip"].scrollbar._visible = true; + } + }; + + + /** Render a new playlist when the feed updates **/ + public function onFeedUpdate(typ:String) { + listScroller.purgeScrollbar(); + delete listScroller; + var tgt = config["clip"].playlist; + for(var i=0; i<999; i++) { + tgt["btn"+i].removeMovieClip(); + } + setButtons(); + setItem(currentItem); + }; + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/RecommendationsView.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/RecommendationsView.as new file mode 100644 index 0000000..eac7b81 --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/RecommendationsView.as @@ -0,0 +1,204 @@ +/** +* Thumbnailbar with recommended videos. +* +* @author Jeroen Wijering +* @version 1.0 +**/ + + +import com.jeroenwijering.utils.ImageLoader; +import com.jeroenwijering.utils.Animations; +import com.jeroenwijering.utils.XMLParser; +import com.jeroenwijering.players.AbstractController; +import com.jeroenwijering.players.AbstractView; + + +class com.jeroenwijering.players.RecommendationsView extends AbstractView { + + + /** reference to config Array **/ + private var config:Object; + /** reference to feed Array **/ + private var feeder:Object; + /** Reference to the movieclip **/ + private var clip:MovieClip; + /** XML parser reference **/ + private var parser:XMLParser; + /** Recommendations array **/ + private var recommendations:Array; + /** Current show offset **/ + private var offset:Number = 0; + /** Number of thumbs maximum on screen **/ + private var maximum:Number; + + + + /** Constructor **/ + function RecommendationsView(ctr:AbstractController, + cfg:Object,fed:Object) { + config = cfg; + feeder = fed; + clip = config["clip"].recommendations; + var ref = this; + parser = new XMLParser(); + parser.onComplete = function() { + ref.loadRecommendations(this.output); + }; + Stage.addListener(this); + setButtons(); + }; + + + /** Set the colors, clicks and dimensions of the buttons. **/ + private function setButtons() { + var ref = this; + maximum = Math.floor((config['displaywidth']-44)/70); + clip._visible = false; + clip.txt._x = 10; + clip.txt._width = config['displaywidth'] -20; + clip.txt.textColor = config['backcolor']; + clip.prv._x = config['displaywidth']/2 - maximum*35; + clip.nxt._x = config['displaywidth']/2 + maximum*35; + clip.prv.col = new Color(clip.prv); + clip.prv.col.setRGB(config['backcolor']); + clip.prv.onRelease = function() { + this.col.setRGB(ref.config['backcolor']); + ref.showRecommendations(ref.offset - ref.maximum); + }; + clip.prv._visible = false; + clip.nxt.col = new Color(clip.nxt); + clip.nxt.col.setRGB(config['backcolor']); + clip.nxt.onRelease = function() { + this.col.setRGB(ref.config['backcolor']); + ref.showRecommendations(ref.offset + ref.maximum); + }; + clip.nxt._visible = false; + clip.itm._visible = false; + for(var i=0; i= recommendations.length-maximum ? clip.nxt._visible = false: clip.nxt._visible = true; + for(var i=0; i= config["height"]) { + config["height"] = config["displayheight"] = Stage.height; + config["width"] = config["displaywidth"] = Stage.width; + } + showRecommendations(); + }; + + + /** Catches fullscreen escape. **/ + public function onFullScreen(fs:Boolean) { + showRecommendations(); + }; + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/RotatorController.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/RotatorController.as new file mode 100755 index 0000000..b5cb4ab --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/RotatorController.as @@ -0,0 +1,180 @@ +/** +* Rotator extension of the controller. +* +* @author Jeroen Wijering +* @version 1.6 +**/ + + +import com.jeroenwijering.players.AbstractController; +import com.jeroenwijering.utils.Randomizer; + + +class com.jeroenwijering.players.RotatorController extends AbstractController{ + + + /** Which one of the models to send the changes to **/ + private var currentModel:Number; + /** use SharedObject to save current file, item and volume **/ + private var playerSO:SharedObject; + + + /** Constructor, inherited from super **/ + function RotatorController(car:Object,ply:Object) { + super(car,ply); + playerSO = SharedObject.getLocal("com.jeroenwijerin.players", "/"); + if(playerSO.data.volume != undefined && _root.volume == undefined) { + config["volume"] = playerSO.data.volume; + } + if(playerSO.data.useaudio != undefined && + _root.useaudio == undefined) { + config["useaudio"] = playerSO.data.useaudio; + } + }; + + + /** Complete the build of the MCV cycle and start flow of events. **/ + public function startMCV(mar:Array) { + if(mar != undefined) { registeredModels = mar; } + itemsPlayed = 0; + if(config["shuffle"] == "true") { + randomizer = new Randomizer(feeder.feed); + currentItem = randomizer.pick(); + } else { + currentItem = 0; + } + sendChange("item",currentItem); + if(config["autostart"] == "false") { + sendChange("start",0); + sendChange("pause",0); + isPlaying = false; + } else { + sendChange("start",0); + isPlaying = true; + } + }; + + + /** PlayPause switch **/ + private function setPlaypause() { + if(isPlaying == true) { + isPlaying = false; + sendChange("pause"); + } else { + isPlaying = true; + sendChange("start"); + } + }; + + + /** Play previous item. **/ + private function setPrev() { + if(currentItem == 0) { + setPlayitem(feeder.feed.length - 1); + } else { + setPlayitem(currentItem-1); + } + }; + + + /** Play next item. **/ + private function setNext() { + if(currentItem == feeder.feed.length - 1) { + setPlayitem(0); + } else { + setPlayitem(currentItem+1); + } + }; + + + /** Stop and clear item. **/ + private function setStop() { + sendChange("pause",0); + sendChange("stop"); + sendChange("item",currentItem); + isPlaying = false; + }; + + + /** Forward scrub number to model. **/ + private function setScrub(prm) { + isPlaying == true ? sendChange("start",prm): sendChange("pause",prm); + }; + + + /** Play a new item. **/ + private function setPlayitem(itm:Number) { + if(itm != currentItem) { + sendChange("stop"); + itm > feeder.feed.length-1 ? itm = feeder.feed.length-1: null; + currentItem = itm; + sendChange("item",itm); + } + if(feeder.feed[itm]["start"] == undefined) { + sendChange("start",0); + } else { + sendChange("start",feeder.feed[itm]["start"]); + } + currentURL = feeder.feed[itm]['file']; + isPlaying = true; + }; + + + /** Get url from an item if link exists, else playpause. **/ + private function setGetlink(idx:Number) { + if(feeder.feed[idx]["link"] == undefined) { + setPlaypause(); + } else { + getURL(feeder.feed[idx]["link"],config["linktarget"]); + } + }; + + + /** Determine what to do if an item is completed. **/ + private function setComplete() { + itemsPlayed++; + if(config["repeat"]=="false" || (config["repeat"] == "list" + && itemsPlayed >= feeder.feed.length)) { + sendChange("pause",0); + isPlaying = false; + itemsPlayed = 0; + } else { + if(config["shuffle"] == "true") { + setPlayitem(randomizer.pick()); + } else if(currentItem == feeder.feed.length - 1) { + setPlayitem(0); + } else { + setPlayitem(currentItem+1); + } + } + }; + + + /** Audiotrack toggle **/ + private function setAudio() { + if(config["useaudio"] == "true") { + config["useaudio"] = "false"; + config["clip"].audio.setStop(); + config["clip"].navigation.audioBtn.icnOff._visible = true; + config["clip"].navigation.audioBtn.icnOn._visible = false; + } else { + config["useaudio"] = "true"; + config["clip"].audio.setStart(); + config["clip"].navigation.audioBtn.icnOff._visible = false; + config["clip"].navigation.audioBtn.icnOn._visible = true; + } + playerSO.data.useaudio = config["useaudio"]; + playerSO.flush(); + }; + + + /** Switch active model and send changes. **/ + private function sendChange(typ:String,prm:Number):Void { + if(typ == "item") { + currentModel == 0 ? currentModel = 1: currentModel = 0; + } + registeredModels[currentModel].getChange(typ,prm); + }; + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/RotatorView.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/RotatorView.as new file mode 100755 index 0000000..6a8048a --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/players/RotatorView.as @@ -0,0 +1,521 @@ +/** +* Rotator user interface View of the MCV cycle. +* +* @author Jeroen Wijering +* @version 1.5 +**/ + + +import com.jeroenwijering.players.*; +import com.jeroenwijering.utils.ImageLoader; +import com.jeroenwijering.utils.Animations; +import flash.geom.Transform; +import flash.geom.ColorTransform; + +class com.jeroenwijering.players.RotatorView extends AbstractView { + + + /** full width of the scrubbars **/ + private var currentItem:Number; + /** clip that's currently active **/ + private var upClip:MovieClip; + /** clip that's currently inactive **/ + private var downClip:MovieClip; + /** boolean for whether to use the title display **/ + private var useTitle:Boolean; + /** boolean to see if the transition is done **/ + private var transitionDone:Boolean = false; + /** boolean to detect first run **/ + private var firstRun:Boolean = true; + /** interval for hiding the display **/ + private var hideInt:Number; + /** array with all transitions **/ + private var allTransitions:Array = new Array( + "bgfade", + "blocks", + "bubbles", + "circles", + "fade", + "flash", + "fluids", + "lines", + "slowfade" + ); + + + /** Constructor **/ + function RotatorView(ctr:AbstractController,cfg:Object,fed:Object) { + super(ctr,cfg,fed); + setColorsClicks(); + if(config["shownavigation"] == "true") { + Mouse.addListener(this); + } + }; + + + /** Sets up visibility, sizes and colors of all display items **/ + private function setColorsClicks() { + var ref = this; + var tgt:MovieClip = config["clip"]; + tgt.button._width = config["width"]; + tgt.button._height = config["height"]; + if(config['overstretch']=='true' || config['overstretch']=='fit') { + tgt.img1.bg._visible = tgt.img2.bg._visible = false; + } else { + tgt.img1.bg._width = tgt.img2.bg._width = config["width"]; + tgt.img1.bg._height = tgt.img2.bg._height = config["height"]; + tgt.img1.col = new Color(tgt.img1.bg); + tgt.img1.col.setRGB(config["screencolor"]); + tgt.img2.col = new Color(tgt.img2.bg); + tgt.img2.col.setRGB(config["screencolor"]); + } + if(config["linkfromdisplay"] == "true") { + tgt.button.onRelease = function() { + ref.sendEvent("getlink",ref.currentItem); + }; + tgt.playicon._visible = false; + } else { + tgt.button.onRelease = function() { + ref.sendEvent("next"); + }; + } + tgt.img1.swapDepths(1); + tgt.img2.swapDepths(2); + tgt.playicon.swapDepths(4); + tgt.activity.swapDepths(5); + tgt.navigation.swapDepths(6); + tgt.logo.swapDepths(7); + tgt.playicon._x=tgt.activity._x = Math.round(config["width"]/2); + tgt.playicon._y=tgt.activity._y = Math.round(config["height"]/2); + if(config["logo"] != undefined) { + var lll = new ImageLoader(tgt.logo,"none"); + lll.onLoadFinished = function() { + ref.config['clip'].logo._x = ref.config["displaywidth"] - + ref.config['clip'].logo._width -10; + ref.config['clip'].logo._y = 10; + }; + lll.loadImage(config["logo"]); + tgt.logo.onRelease = function() { + ref.sendEvent("getlink",ref.currentItem); + }; + } + tgt = config["clip"].navigation; + if (config["shownavigation"] == "true") { + tgt._y = config["height"] - 40; + tgt._x = config["width"]/2 - 50; + tgt.prevBtn.col1 = new Color(tgt.prevBtn.bck); + tgt.prevBtn.col1.setRGB(config["backcolor"]); + tgt.prevBtn.col2 = new Color(tgt.prevBtn.icn); + tgt.prevBtn.col2.setRGB(config["frontcolor"]); + tgt.itmBtn.col1 = new Color(tgt.itmBtn.bck); + tgt.itmBtn.col1.setRGB(config["backcolor"]); + tgt.itmBtn.txt.textColor = config["frontcolor"]; + tgt.nextBtn.col1 = new Color(tgt.nextBtn.bck); + tgt.nextBtn.col1.setRGB(config["backcolor"]); + tgt.nextBtn.col2 = new Color(tgt.nextBtn.icn); + tgt.nextBtn.col2.setRGB(config["frontcolor"]); + tgt.prevBtn.onRollOver = tgt.nextBtn.onRollOver = function() { + this.col2.setRGB(ref.config["lightcolor"]); + }; + tgt.prevBtn.onRollOut = tgt.nextBtn.onRollOut = function() { + this.col2.setRGB(ref.config["frontcolor"]); + }; + tgt.itmBtn.onRollOver = function() { + this.txt.textColor = ref.config["lightcolor"]; + }; + tgt.itmBtn.onRollOut = function() { + this.txt.textColor = ref.config["frontcolor"]; + }; + tgt.prevBtn.onRelease = function() { + ref.sendEvent("prev"); + this.col2.setRGB(ref.config["frontcolor"]); + }; + tgt.itmBtn.onRelease = function() { ref.sendEvent("playpause"); }; + tgt.nextBtn.onRelease = function() { + ref.sendEvent("next"); + this.col2.setRGB(ref.config["frontcolor"]); + }; + // set sizes, colors and buttons for image title + var len = 0; + for(var i=0; i len) { + len = feeder.feed[i]['title'].length; + } + } + if(len == 0) { + useTitle = false; + tgt.titleBtn._visible = false; + } else { + useTitle = true; + tgt.titleBtn._x = 74; + tgt.titleBtn.col1 = new Color(tgt.titleBtn.left); + tgt.titleBtn.col1.setRGB(config["backcolor"]); + tgt.titleBtn.col2 = new Color(tgt.titleBtn.mid); + tgt.titleBtn.col2.setRGB(config["backcolor"]); + tgt.titleBtn.col3 = new Color(tgt.titleBtn.right); + tgt.titleBtn.col3.setRGB(config["backcolor"]); + tgt.titleBtn.tf._width = len*6; + tgt.titleBtn.tf.textColor = config["frontcolor"]; + if(feeder.feed[0]["link"] != undefined) { + tgt.titleBtn.onRollOver = function() { + this.tf.textColor = ref.config["lightcolor"]; + }; + tgt.titleBtn.onRollOut = function() { + this.tf.textColor = ref.config["frontcolor"]; + }; + tgt.titleBtn.onRelease = function() { + ref.sendEvent("getlink",ref.currentItem); + }; + }; + tgt.titleBtn.mid._width = len*6; + tgt.titleBtn.right._x = len*6+4; + tgt.nextBtn._x = len*6 + 79; + } + if(feeder.audio == true) { + tgt.audioBtn.col1 = new Color(tgt.audioBtn.bck); + tgt.audioBtn.col2 = new Color(tgt.audioBtn.icnOn); + tgt.audioBtn.col3 = new Color(tgt.audioBtn.icnOff); + tgt.audioBtn.col1.setRGB(config["backcolor"]); + tgt.audioBtn.col2.setRGB(config["frontcolor"]); + tgt.audioBtn.col3.setRGB(config["frontcolor"]); + tgt.audioBtn.onRollOver = function() { + this.col2.setRGB(ref.config["lightcolor"]); + this.col3.setRGB(ref.config["lightcolor"]); + }; + tgt.audioBtn.onRollOut = function() { + this.col2.setRGB(ref.config["frontcolor"]); + this.col3.setRGB(ref.config["frontcolor"]); + }; + tgt.audioBtn.onRelease = function() { + ref.sendEvent("audio"); + this.col2.setRGB(ref.config["frontcolor"]); + this.col3.setRGB(ref.config["frontcolor"]); + }; + if(config['useaudio'] == "true") { + tgt.audioBtn.icnOff._visible = false; + } else { + tgt.audioBtn.icnOn._visible = false; + } + tgt.audioBtn._x = len*6 + 104; + } else { + tgt.audioBtn._x = 0; + tgt.audioBtn._visible = false; + } + tgt._x = Math.round(config["width"]/2 - tgt._width/2); + } else { + tgt._visible = false; + } + }; + + + /** New item: switch clips and ready transition **/ + private function setItem(pr1) { + currentItem = pr1; + transitionDone = false; + var tgt = config["clip"]; + tgt.navigation.itmBtn.txt.text = (currentItem+1) + " / " + + feeder.feed.length; + if (useTitle == true) { + tgt.navigation.titleBtn.tf.text=feeder.feed[currentItem]["title"]; + } + tgt.img1.swapDepths(tgt.img2); + downClip = upClip; + if (upClip == tgt.img1) { + upClip = tgt.img2; + } else { + upClip = tgt.img1; + } + }; + + + /** State switch; start the transition **/ + private function setState(stt:Number) { + switch(stt) { + case 0: + if(config["showicons"] == "true") { + config["clip"].playicon._visible = true; + } + config["clip"].activity._visible = false; + break; + case 1: + config["clip"].playicon._visible = false; + if(config["showicons"] == "true") { + config["clip"].activity._visible = true; + } + break; + case 2: + config["clip"].playicon._visible = false; + config["clip"].activity._visible = false; + if(transitionDone == false) { + doTransition(); + if(config["kenburns"] == "true") { + moveClip(); + } + } + break; + } + }; + + + /** (Re)set the ken burns fade **/ + private function moveClip() { + var dir = random(4); + var clp = upClip.smc; + if(upClip.smc == undefined) { clp = upClip.mc; } + clp._xscale *= config['rotatetime']/20 + 1; + clp._yscale *= config['rotatetime']/20 + 1; + if(dir == 0) { + clp._x = 0; + } else if (dir == 1) { + clp._y = 0; + } else if (dir == 2) { + clp._x = config['width'] - upClip._width; + } else { + clp._y = config['height'] - upClip._height; + } + clp.onEnterFrame = function() { + if(dir == 0) { + this._x -= 0.3; + } else if (dir == 1) { + this._y -= 0.3; + } else if (dir == 2) { + this._x += 0.3; + } else { + this._y += 0.3; + } + }; + }; + + + /** Start a transition **/ + private function doTransition() { + transitionDone = true; + if(firstRun == true) { + config["clip"].img1._alpha = 100; + config["clip"].img2._alpha = 0; + firstRun = false; + } else { + var trs = config["transition"]; + if(trs == "random") { + trs = allTransitions[random(allTransitions.length)]; + } + switch (trs) { + case "bgfade": + doBGFade(); + break; + case "blocks": + doBlocks(); + break; + case "bubbles": + doBubbles(); + break; + case "circles": + doCircles(); + break; + case "fade": + doFade(); + break; + case "flash": + doFlash(); + break; + case "fluids": + doFluids(); + break; + case "lines": + doLines(); + break; + case "slowfade": + doSlowfade(); + break; + default: + doFade(); + break; + } + } + }; + + + /** Function for the fade transition **/ + private function doFade() { + upClip.ref = this; + upClip._alpha = 0; + upClip.onEnterFrame = function() { + this._alpha +=5; + if(this._alpha >= 100) { + delete this.onEnterFrame; + this.ref.downClip._alpha = 0; + } + }; + }; + + + /** Function for the bgfade transition **/ + private function doBGFade() { + downClip.ref = upClip.ref = this; + downClip.onEnterFrame = function() { + this._alpha -=5; + if(this._alpha <= 0) { + delete this.onEnterFrame; + this.ref.upClip.onEnterFrame = function() { + if(this._alpha >= 100) { + delete this.onEnterFrame; + } else { + this._alpha +=5; + } + }; + } + }; + }; + + + /** Function for the blocks transition **/ + private function doBlocks() { + upClip._alpha = 100; + config["clip"].attachMovie("blocksMask","mask",3); + var msk:MovieClip = config["clip"].mask; + if (config["width"] > config["height"]) { + msk._width = msk._height = config["width"]; + } else { + msk._width = msk._height = config["height"]; + } + msk._rotation = random(4)*90; + msk._rotation == 90 ? msk._x = config["width"]: null; + msk._rotation == 180 ? msk._x = config["width"]: null; + msk._rotation == 180 ? msk._y = config["height"]: null; + msk._rotation == -90 ? msk._y = config["height"]: null; + upClip.setMask(msk); + playClip(msk); + }; + + + /** Function for the bubbles transition **/ + private function doBubbles() { + upClip._alpha = 100; + config["clip"].attachMovie("bubblesMask","mask",3); + var msk:MovieClip = config["clip"].mask; + upClip.setMask(msk); + if (config["width"] > config["height"]) { + msk._width = msk._height = config["width"]; + msk._y = config["height"]/2 - msk._height/2; + } else { + msk._width = msk._height = config["height"]; + msk._x = config["width"]/2- msk._width/2; + } + if(random(2) == 1) { + msk._xscale = -msk._xscale; + msk._x += config['width']; + } + playClip(msk); + }; + + + /** Function for the circles transition **/ + private function doCircles() { + upClip._alpha = 100; + config["clip"].attachMovie("circlesMask","mask",3); + var msk:MovieClip = config["clip"].mask; + upClip.setMask(msk); + if (config["width"] > config["height"]) { + msk._width = msk._height = config["width"]; + } else { + msk._width = msk._height = config["height"]; + } + msk._x = config["width"]/2; + msk._y = config["height"]/2; + playClip(msk,10); + }; + + + /** Function for the flash transition **/ + private function doFlash() { + upClip._alpha = 100; + upClip.col = new Color(upClip); + upClip.ctf = new Object({rb:255,gb:255,bb:255}); + upClip.col.setTransform(upClip.ctf); + upClip.onEnterFrame = function() { + if(this.ctf.rb < 1) { + this.ctf = new Object({rb:0,gb:0,bb:0}); + this.col.setTransform(this.ctf); + delete this.onEnterFrame; + } else { + this.ctf.rb /= 1.05; + this.ctf.gb /= 1.05; + this.ctf.bb /= 1.05; + this.col.setTransform(this.ctf); + } + }; + }; + + /** Function for the fluids transition **/ + private function doFluids() { + upClip._alpha = 100; + config["clip"].attachMovie("fluidsMask","mask",3); + var msk:MovieClip = config["clip"].mask; + upClip.setMask(msk); + msk._width = config["width"]; + msk._height = config["height"]; + playClip(msk); + }; + + + /** Function for the lines transition **/ + private function doLines() { + upClip._alpha = 100; + config["clip"].attachMovie("linesMask","mask",3); + var msk:MovieClip = config["clip"].mask; + upClip.setMask(msk); + msk._width = config["width"]; + msk._height = config["height"]; + playClip(msk); + }; + + + /** Function for the fade transition **/ + private function doSlowfade() { + upClip.ref = this; + upClip._alpha = 0; + upClip.onEnterFrame = function() { + this._alpha+=2; + if(this._alpha >= 100) { + delete this.onEnterFrame; + this.ref.downClip._alpha = 0; + } + }; + }; + + + /** Play a specific Movieclip and remove it once it's finished **/ + private function playClip(tgt:MovieClip,rot:Number) { + tgt.ref = this; + tgt.onEnterFrame = function() { + this.nextFrame(); + rot == undefined ? null: this._rotation +=rot; + if(this._currentframe == this._totalframes) { + this.ref.downClip._alpha = 0; + this.clear(); + this.unloadMovie(); + this.removeMovieClip(); + } + }; + }; + + + /** after a delay, the controlbar is hidden **/ + private function hideBar() { + Animations.fadeOut(config['clip'].navigation); + clearInterval(hideInt); + } + + + /** Mouse move shows controlbar **/ + public function onMouseMove() { + Animations.fadeIn(config['clip'].navigation); + clearInterval(hideInt); + if(!config["clip"].navigation.hitTest(_root._xmouse,_root._ymouse)) { + hideInt = setInterval(this,"hideBar",500); + } + }; + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/utils/Animations.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/utils/Animations.as new file mode 100755 index 0000000..eb832e2 --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/utils/Animations.as @@ -0,0 +1,134 @@ +/** +* A couple of commonly used animation functions. +* +* @author Jeroen Wijering +* @version 1.12 +**/ + + +class com.jeroenwijering.utils.Animations { + + + /** + * Fadein function for MovieClip. + * + * @param tgt The Movieclip to fade in. + * @param end The final alpha value. + * @param spd The amount of alpha change per frame. + **/ + public static function fadeIn(tgt:MovieClip,end:Number,spd:Number) { + arguments.length < 3 ? spd = 20: null; + arguments.length < 2 ? end = 100: null; + tgt._visible = true; + tgt.onEnterFrame = function() { + if(this._alpha > end-spd) { + delete this.onEnterFrame; + this._alpha = end; + } else { + this._alpha += spd; + } + }; + }; + + + /** + * Fadeout function for MovieClip. + * + * @param tgt The Movieclip to fade out. + * @param end The final alpha value. + * @param spd The amount of alpha change per frame. + * @param rmv Removing the clip off stage switch. + **/ + public static function fadeOut(tgt:MovieClip,end:Number, + spd:Number,rmv:Boolean) { + arguments.length < 4 ? rmv = false: null; + arguments.length < 3 ? spd = 20: null; + arguments.length < 2 ? end = 0: null; + tgt.onEnterFrame = function() { + if(this._alpha < end+spd) { + delete this.onEnterFrame; + this._alpha = end; + end == 0 ? this._visible = false: null; + rmv == true ? this.removeMovieClip(): null; + } else { + this._alpha -= spd; + } + }; + }; + + + /** + * Crossfade a given MovieClip through 0. + * + * @param tgt The Movieclip to crossfade. + * @param alp The final alpha value. + **/ + public static function crossfade(tgt:MovieClip, alp:Number) { + var phs = "out"; + var pct = alp/5; + tgt.onEnterFrame = function() { + if(phs == "out") { + this._alpha -= pct; + if (this._alpha < 1) { phs = "in"; } + } else { + this._alpha += pct; + this._alpha >= alp ? delete this.onEnterFrame : null; + } + }; + }; + + + /** + * Smoothly move a Movielip to a certain position. + * + * @param tgt The Movielip to move. + * @param xps The x destination. + * @param yps The y destination. + * @param spd The movement speed (1 - 2). + **/ + public static function easeTo(tgt:MovieClip,xps:Number,yps:Number, + spd:Number) { + arguments.length < 4 ? spd = 1.3: null; + tgt.onEnterFrame = function() { + this._x = xps-(xps-this._x)/(1+1/spd); + this._y = yps-(yps-this._y)/(1+1/spd); + if (this._x>xps-1 && this._xyps-1 && this._y 1) { + config['width'] = Stage.width; + config['height'] = Stage.height; + config["clip"]._parent.activity._x = Stage.width/2; + config["clip"]._parent.activity._y = Stage.height/2; + config["clip"]._parent.activity._alpha = 100; + } + _root['config'] == undefined ? loadCookies(): loadFile(); + }; + + + /** Load configuration data from external XML file **/ + private function loadFile() { + var ref = this; + parser = new XMLParser(); + parser.onComplete = function(obj) { + var ret = new Object(); + for(var i=0; i 1 ? overStretch = String(ost): null; + if(arguments.length > 2) { + targetWidth = wid; + targetHeight = hei; + } + mcLoader = new MovieClipLoader(); + mcLoader.addListener(this); + }; + + + /** Switch image with bitmaparray if possible. **/ + public function onLoadInit(inTarget:MovieClip):Void { + if(useSmoothing == 'true') { + var bmp = new flash.display.BitmapData(targetClip.mc._width, + targetClip.mc._height, true, 0x000000); + bmp.draw(targetClip.mc); + var bmc:MovieClip = targetClip.createEmptyMovieClip("smc", + targetClip.getNextHighestDepth()); + bmc.attachBitmap(bmp, bmc.getNextHighestDepth(),"auto",true); + targetClip.mc.unloadMovie(); + targetClip.mc.removeMovieClip(); + delete targetClip.mc; + scaleImage(targetClip.smc); + onLoadFinished(); + } else { + targetClip.mc.forceSmoothing = true; + if(sourceURL.toLowerCase().indexOf(".swf") == -1) { + scaleImage(targetClip.mc); + } + onLoadFinished(); + } + }; + + + /** Scale the image while maintaining aspectratio **/ + private function scaleImage(tgt:MovieClip):Void { + targetClip._xscale = targetClip._yscale = 100; + var tcf = tgt._currentframe; + tgt.gotoAndStop(1); + sourceWidth = tgt._width; + sourceHeight = tgt._height; + sourceLength = tgt._totalframes/20; + var xsr = targetWidth/sourceWidth; + var ysr = targetHeight/sourceHeight; + if (overStretch == "fit" || Math.abs(xsr-ysr) < 0.1) { + tgt._width = targetWidth; + tgt._height = targetHeight; + } else if ((overStretch == "true" && xsr > ysr) || + (overStretch == "false" && xsr < ysr)) { + tgt._xscale = tgt._yscale = xsr*100; + } else if(overStretch == "none") { + tgt._xscale = tgt._yscale = 100; + } else { + tgt._xscale = tgt._yscale = ysr*100; + } + if(targetWidth != undefined) { + tgt._x = targetWidth/2 - tgt._width/2; + tgt._y = targetHeight/2 - tgt._height/2; + } + tgt.gotoAndPlay(tcf); + onMetaData(); + }; + + + /** Start loading an image. **/ + public function loadImage(img:String):Void { + sourceURL = img; + targetClip.mc.clear(); + targetClip.smc.unloadMovie(); + targetClip.smc.removeMovieClip(); + delete targetClip.smc; + checkSmoothing(img); + var raw:MovieClip = targetClip.createEmptyMovieClip("mc",1); + mcLoader.loadClip(img,raw); + if(img.toLowerCase().indexOf(".swf") > -1) { + metaInt = setInterval(this,"setSWFMeta",200); + } + }; + + + /** Check whether smoothing can be enabled. **/ + private function checkSmoothing(img:String):Void { + var idx:Number = _root._url.indexOf("/",8); + var rot:String = _root._url.substring(0,idx); + if(System.capabilities.version.indexOf("7,0,") > -1 || + img.toLowerCase().indexOf(".swf") > -1 || + _root._url.indexOf("file://") > -1 || + (img.indexOf(rot) == -1 && img.indexOf('http://') == 0)) { + useSmoothing = false; + } else { + useSmoothing = true; + } + }; + + + /** Check when to set the SWF metadata **/ + private function setSWFMeta() { + if(targetClip.mc._currentframe > 0) { + clearInterval(metaInt); + scaleImage(targetClip.mc); + } + }; + + + /** Event handler; invoked when loading. **/ + public function onLoadProgress(tgt:MovieClip,btl:Number,btt:Number) {}; + + + /** Event handler; invoked when image is completely loaded. **/ + public function onLoadFinished() {}; + + + /** Event handler; invoked when metadata is received. **/ + public function onMetaData() {}; + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/utils/Randomizer.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/utils/Randomizer.as new file mode 100755 index 0000000..a8446aa --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/utils/Randomizer.as @@ -0,0 +1,43 @@ +/** +* Pick random array indexes without having the same picked twice times. +* +* @author Jeroen Wijering +* @version 1.2 +**/ + + +class com.jeroenwijering.utils.Randomizer { + + + /** a reference of the original array **/ + private var originalArray:Array; + /** a copy of the original array **/ + private var bufferArray:Array; + + + /** + * Constructor. + * + * @param arr Array to randomize. + **/ + public function Randomizer(arr:Array) { + originalArray = arr; + bufferArray = new Array(); + }; + + + /** Randomly pick an index from the array given. **/ + public function pick():Number { + if(bufferArray.length == 0) { + for(var k=0; k 2 ? autoScroll = asc: null; + arguments.length > 3 ? frontColor = fcl: null; + arguments.length > 4 ? lightColor = hcl: null; + sizeRatio = maskClip._height/targetClip._height; + if(autoScroll == false) { + drawScrollbar(); + } else { + scrollInterval = setInterval(this,"doAutoscroll",50); + } + if(System.capabilities.os.toLowerCase().indexOf("mac") == -1) { + Mouse.addListener(this); + } + }; + + + /** Draw the scrollbar. **/ + private function drawScrollbar() { + targetClip._parent.createEmptyMovieClip("scrollbar", + targetClip._parent.getNextHighestDepth()); + SCROLLER_CLIP = targetClip._parent.scrollbar; + SCROLLER_CLIP._x = maskClip._x+maskClip._width - 1; + SCROLLER_CLIP._y = maskClip._y+3; + SCROLLER_CLIP.createEmptyMovieClip("back",0); + SCROLLER_CLIP.back._alpha = 0; + SCROLLER_CLIP.back._y = -3; + drawSquare(SCROLLER_CLIP.back,12,maskClip._height,frontColor); + SCROLLER_CLIP.createEmptyMovieClip("bar",1); + SCROLLER_CLIP.bar._x = 4; + SCROLLER_CLIP.bar._alpha = 50; + drawSquare(SCROLLER_CLIP.bar,4,maskClip._height-5,frontColor); + SCROLLER_CLIP.createEmptyMovieClip("front",2); + SCROLLER_CLIP.front._x = 3; + drawSquare(SCROLLER_CLIP.front,6, + SCROLLER_CLIP.bar._height*sizeRatio,frontColor); + SCROLLER_CLIP.front.createEmptyMovieClip("bg",1); + SCROLLER_CLIP.front.bg._x = -3; + SCROLLER_CLIP.front.bg._alpha = 0; + drawSquare(SCROLLER_CLIP.front.bg,12, + SCROLLER_CLIP.front._height,frontColor); + SCROLLER_FRONT_COLOR = new Color(SCROLLER_CLIP.front); + setScrollbarEvents(); + }; + + + /** Set use of mousewheel to scroll playlist. **/ + public function onMouseWheel(dta:Number) { + scrollTo(currentScroll-dta*20); + }; + + + /** Set autoscroll events. **/ + private function doAutoscroll() { + if (maskClip._xmouse>0 && maskClip._xmouse0 && + maskClip._ymouse this._parent.front._y + + this._parent.front._height) { + instance.scrollTo(instance.currentScroll + + instance.maskClip._height/2); + } else if (this._ymouse < this._parent.front._y) { + instance.scrollTo(instance.currentScroll - + instance.maskClip._height/2); + } + }; + SCROLLER_CLIP.front.onPress = function() { + this.startDrag(false,3,0,3,instance.SCROLLER_CLIP.bar._height - + this._height); + instance.scrollInterval = setInterval(instance,"scrollTo",100); + }; + SCROLLER_CLIP.front.onRelease = + SCROLLER_CLIP.front.onReleaseOutside = function() { + this.stopDrag(); + clearInterval(instance.scrollInterval); + }; + scrollTo(maskClip._y - targetClip._y); + }; + + + /** Scroll the MovieClip to a given Y position. **/ + public function scrollTo(yps:Number):Void { + if(arguments.length == 0 && autoScroll == false) { + yps = SCROLLER_CLIP.front._y*maskClip._height / + SCROLLER_CLIP.front._height; + } + if(yps<5) { + yps=0; + } else if (yps>targetClip._height-maskClip._height-5) { + yps = targetClip._height - maskClip._height; + } + Animations.easeTo(targetClip,targetClip._x,maskClip._y - yps); + SCROLLER_CLIP.front._y = yps*SCROLLER_CLIP.front._height / + maskClip._height; + currentScroll = yps; + }; + + + /** Remove the scrollbar from stage **/ + public function purgeScrollbar() { + clearInterval(scrollInterval); + Mouse.removeListener(this); + scrollTo(0); + SCROLLER_CLIP.removeMovieClip(); + }; + + + /** Draw a square in a given movieclip. **/ + private function drawSquare(tgt:MovieClip,wth:Number,hei:Number, + clr:Number) { + tgt.clear(); + tgt.beginFill(clr,100); + tgt.moveTo(0,0); + tgt.lineTo(wth,0); + tgt.lineTo(wth,hei); + tgt.lineTo(0,hei); + tgt.lineTo(0,0); + tgt.endFill(); + }; + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/utils/StringMagic.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/utils/StringMagic.as new file mode 100755 index 0000000..29221ee --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/utils/StringMagic.as @@ -0,0 +1,92 @@ +/** +* A couple of commonly used string operations. +* +* @author Jeroen Wijering +* @version 1.3 +**/ + + +class com.jeroenwijering.utils.StringMagic { + + + /** Strip tags and breaks from a string. **/ + static function stripTagsBreaks(str:String):String { + if(str.length == 0 || str == undefined) { return ""; } + var tmp:Array = str.split("\n"); + str = tmp.join(""); + tmp = str.split("\r"); + str = tmp.join(""); + var i:Number = str.indexOf("<"); + while(i != -1) { + var j = str.indexOf(">",i+1); + j == -1 ? j = str.length-1: null; + str = str.substr(0,i) + str.substr(j+1,str.length); + i = str.indexOf("<",i); + } + return str; + }; + + + /** + * Chop string into a number of lines. + * + * @param str The string to chop. + * @param cap The maximum number of characters per line. + * @param nbr The maximum number of lines. + **/ + static function chopString(str:String,cap:Number,nbr:Number):String { + for(var i=cap; i 0) { + str = str.substr(0,str.indexOf(" ",i-3)) + "\n" + + str.substr(str.indexOf(" ",i-3)+1); + } + } + return str; + }; + + + /** Add a leading zero and convert number to string. **/ + static function addLeading(nbr:Number):String { + if(nbr < 10) { + return "0"+Math.floor(nbr); + } else { + return Math.floor(nbr).toString(); + } + }; + + + /** + * Convert a string to seconds, with these formats supported: + * 00:03:00.1 / 03:00.1 / 180.1s / 3.2m / 3.2h + **/ + static function toSeconds(str:String):Number { + var arr = str.split(':'); + var sec; + if (str.substr(-1) == 's') { + sec = Number(str.substr(0,str.length-2)); + } else if (str.substr(-1) == 'm') { + sec = Number(str.substr(0,str.length-2))*60; + } else if(str.substr(-1) == 'h') { + sec = Number(str.substr(0,str.length-2))*3600; + } else if(arr.length > 1) { + sec = Number(arr[arr.length-1]); + sec += Number(arr[arr.length-2])*60; + sec += Number(arr[arr.length-3])*3600; + } else { + sec = Number(str); + } + if(isNaN(sec)) { + return 0; + } else { + return sec; + } + }; + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/utils/XMLParser.as b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/utils/XMLParser.as new file mode 100755 index 0000000..e87fba1 --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/com/jeroenwijering/utils/XMLParser.as @@ -0,0 +1,84 @@ +/** +* Parse XML file and return a simple, associative array. +* +* @author Jeroen Wijering +* @version 1.2 +**/ + + +class com.jeroenwijering.utils.XMLParser { + + + /** Flash XML object the file is loaded into. **/ + private var input:XML; + /** The object the XML is parsed into **/ + private var output:Object; + + + /** Constructor, sets up XML object **/ + function XMLParser() {}; + + + /** Start parsing **/ + public function parse(lnk:String) { + var ref = this; + input = new XML(); + output = new Object(); + input.ignoreWhite = true; + input.onLoad = function(scs:Boolean) { + if(scs) { + ref.processRoot(); + } else { + ref.onError(); + } + }; + if(_root._url.indexOf("file://") > -1) { + input.load(lnk); + } else if(lnk.indexOf('?') > -1) { + input.load(lnk+'&'+random(999)); + } else { + input.load(lnk+'?'+random(999)); + } + }; + + + /** Process the root XML node **/ + private function processRoot() { + processNode(input.firstChild,output); + delete input; + onComplete(output); + }; + + + /** Process a specific node **/ + private function processNode(nod:XMLNode,obj:Object) { + obj['name'] = nod.nodeName; + for(var att in nod.attributes) { + obj[att] = nod.attributes[att]; + } + if(nod.childNodes.length < 2 && nod.firstChild.nodeName == null) { + obj['value'] = nod.firstChild.nodeValue; + } else { + obj['childs'] = new Array(); + var chn = nod.firstChild; + var i = 0; + while(chn != undefined) { + var cob = new Object(); + processNode(chn,cob); + obj['childs'].push(cob); + chn = chn.nextSibling; + i++; + } + } + }; + + + /** Invoked when parsing is completed. **/ + public function onComplete(obj:Object) {}; + + + /** Invoked when parsing is completed. **/ + public function onError() {}; + + +} \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/source/mediaplayer.fla b/static/contrib/mediaplayer-3.15/source/mediaplayer.fla new file mode 100755 index 0000000..9b5c9af Binary files /dev/null and b/static/contrib/mediaplayer-3.15/source/mediaplayer.fla differ diff --git a/static/contrib/mediaplayer-3.15/source/mediaplayer.pdf b/static/contrib/mediaplayer-3.15/source/mediaplayer.pdf new file mode 100644 index 0000000..34a1f44 --- /dev/null +++ b/static/contrib/mediaplayer-3.15/source/mediaplayer.pdf @@ -0,0 +1,1679 @@ +%PDF-1.4 % +1 0 obj <> endobj 1129 0 obj <>stream + + + + + 2006-07-12T13:07:58Z + 2008-01-11T16:36:17+01:00 + Adobe Illustrator CS3 + 2008-01-11T16:36:17+01:00 + + + + 256 + 172 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgArAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A6db/AJIa9babY6VbebJI rGzube+dhA6zyzxwLBMC8c8XGOQeodviq1SxIqVUun/5x41qajDzfNExiSFlSBlVUS2aLigSZNvW EclD/LTbFU28t/klqWiazYaj/iaW7FrJaSTJJE4Mn1WJ4mO0xWsqsoLFSwFRXiaYq9WxV2KuxV2K uxV2KuxV2KuxVjP5heVNU8z6Cmm6bqp0e4S5iuhdrGZDyt6yRDirxbCYIx36CnfFWDW35CXun2bx 6b5mnFxNA9rJLcRlkCTWMlrI6pE8PxrJMZI6tRBsBXkzKqw/JHVX1C2nuPMXrWcAWOWye3d0lX60 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 + + + + + + application/pdf + + + uuid:424ad26a-0391-3e47-a0ac-110085b31b58 + uuid:a1ec6a83-7e4f-654b-b671-93a86e5b3c39 + + + 1 + False + False + + 841.889771 + 595.275574 + Points + + + + + HelveticaNeue + Helvetica Neue + Regular + TrueType + 5.0d1 + False + HelveticaNeue.dfont + + + HelveticaNeue-CondensedBold + Helvetica Neue + Condensed Bold + TrueType + 5.01d + False + HelveticaNeue.dfont + + + HelveticaNeue-Bold + Helvetica Neue + Bold + TrueType + 5.0d1 + False + HelveticaNeue.dfont + + + MyriadPro-Bold + Myriad Pro + Bold + Open Type + Version 2.007;PS 002.000;Core 1.0.38;makeotf.lib1.7.9032 + False + MyriadPro-Bold.otf + + + MyriadPro-Regular + Myriad Pro + Regular + Open Type + Version 2.007;PS 002.000;Core 1.0.38;makeotf.lib1.7.9032 + False + MyriadPro-Regular.otf + + + + + + Cyan + Magenta + Yellow + Black + grey + New Color Swatch 2 + New Color Swatch 1 + + + + + + Default Swatch Group + 0 + + + + New Color Swatch 1 + SPOT + 100.000000 + RGB + 203 + 0 + 0 + + + New Color Swatch 2 + SPOT + 100.000000 + RGB + 0 + 0 + 0 + + + grey + SPOT + 100.000000 + RGB + 102 + 102 + 102 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + endstream endobj 2 0 obj <> endobj 5 0 obj <>/ArtBox[52.1289 57.0234 796.124 551.148]/MediaBox[0.0 0.0 841.89 595.276]/TrimBox[0.0 0.0 841.89 595.276]/Resources<>/Font<>/ProcSet[/PDF/Text]/Properties<>>>/ExtGState<>>>/Type/Page/LastModified(D:20080111163617+01'00')>> endobj 1122 0 obj <>stream +HW[8~WG˾%d7SLf2Ԕ팱 6=mMRՀtwM-zv}ыWhDz7 qt [U5R&rDLhJ(F 4 +nHi( +M9㉔r/}a$HHs773w-q/}6a>[Gҫ%I֣߾z>{;t3췏&)% 6[Ư>ϧo2mW4/$'鯞2[!'u0z0b/]ˬ/1Zww6[p8ѱe@V![w8$I])wb,PJ'R"eD7OYU'OWfsݜӕ=b |ABS*DXb8It׼cS @M&=ww_:]1Tv2eQr= X'Ex肿cA%01^q`^5Y[\`8YD y*21P#a{ƴz~w, +]yeY|ȠV1#^)4ENk[gk{&L0h" ten0yϖĐܗn=L^6ԗ3u:/ XB6Oxb6_<| _>왔 (NP<+IX"cIavh{޷'L`y, NHm-n-QT蚧<*7DQ V꺐1x:B{5} LBykUN8F[;Z tsPпA$B8MMv.jaWj^i~͝0;pLƚ=[ȯt^샻w8q].l$`ꦢz-eJFK5w|+ ށvw^R -j!aCzSVY}x; 0Tǚy~nK[&JPfh?q B#8=)$dOB چ]; DHC[$1麠gmLH)\30Cfr)|Bn%t +:}H]2x4G*G!=GpTS {6gݧaTvDvDvDvW7z5 >ߜ3xP2уx >5}WOBpJ0Hnҗݤ/I_v :l$a/H_2W7h_H\S!}G?Y^[?,Q0`iW-յQcRREј$fXO0>QR%02NU΀; 6B<"d!h}ꙃaVL\9)B80j=hR4GH0&X{wp$K{h\^͕i* >}Jwth ӝ?c[O~;=j#u<0(=O_wb!bM HǔLA6+HqYLN3*dտ&~iMɟ=ݤ?-G~<^o'-9uM \qa'l0̑?YLllI`Ϗ &U6XmV@:e*;n!n]P滵 +Bt`&o5=tG Ba?&7ǔļTqv>_ rXLC@_|"M]#NO1B A}Gs`X{B^ J + EV&0MR9) wwpfc)%: +J i` TLK2aaXP +u$&fe楓 +YX^ endstream endobj 1108 0 obj <> endobj 1111 0 obj <> endobj 1113 0 obj <> endobj 1115 0 obj <> endobj 1118 0 obj <> endobj 1120 0 obj <> endobj 1121 0 obj <> endobj 1128 0 obj <>stream +H|U{TWf2'.f<3+P+"+1OJq#C/`[8AN6m&K@^)JHOKLM;T{D!sRy<ƽBsѝfHF8hm'S͞(CzC9 0y 1H# r9l8|lo0U%&3jQʠ1hKxBnF2Rz2Տ.gt܁*⨐Yi[r݇;ۮpmzڱu4"<dg?>>`A|8!|-~v{ ΋_"^9~[G~W\%@(aԾ-S(T4U"RM +_`8@v^A{cNƃGa7lL +c9MN/FMV]v}T! \Ki32sơK`L])SY!+ ^ÁϋQ3l=Q$JH([25(>}LV=M#tMJ2r 6JKG'%6BF; ЏM'A5" lO]*VsJF59}xJG`+GY7'NVfܐPT9t***L#5nZ[r,P L8}nWYV<S ` 溪s 9J~$eai w!|?PdUUW0+0~w&/>Uw^misxqun}uAǿ:.+hfn!@lDuqwtvqo6^/tJLo`E + c 3߆ endstream endobj 1119 0 obj <> endobj 1127 0 obj <>stream +H|TmPGޅ8옙1A\8&UZ +"(,qdC`ˮ\?"~DsR+RWwq9ʲb*pM]/]uORC"JoaY!}ZEr5nDY8O&.fJtll_ sXxHWqfVvrÅϊ.C+$2h ¦t|^] B; $j Z=-8)XHQ+U+V +r Zkr0^ +j6O/2CZafJ$R$D)DyH6zHd$B`/$q-SR_i2۞g2 ;F؉q2$eTI} SVm4pK/No3raCD+գ^strH##mQZnr͹z-sgV +57!12gYlD z[e>A?߿vb"/ {wm<5l08& Rt"iZK<6 SMh%Ύe׮#%-]{JqLT&,L\zyv^vsП_@WNULJo_vzf؝^PO- +1>y4lvq?6*#-{½72y&҂bd +r^^&d^%䑭Wwld(-R;p'C55|\}:xK~x?HL2԰Y#w us +٬[J@pkspiˣV<#uʲPVbHERs XB& gX.oM%2ƫ9YW>5+PSq*uFSnFx)Qc3H%\?;^aoxԆ;箰g3xԄ{$QPV^Eq>WPiѡ + yǸs32}w"GG)[ό{~>~WFlQ{>v5}3ιⵏ?ٙ[aʯ |^5@*vB' U +]WSx"xWBQ$aGDN}mߎZoxvxWq;!~9R[oFYD$,S8 6=X%v1Vg?]>z&yKf:Zb gףg +F?Vo]˞nT9yX,*Kش(=|OwIڞNI _`gi?,y]X>> w*[*Ϸ+.k~&NhHd5'Mbd^/*޽gkiGH̅S ?1c!JG7z 7֜h '[QcdH +ɩ> q׳( +&AADMyh9g07)Ѳ1j #-JT 5CtAt +bQ!AwUdeOyOY&(@57RuNn;w"r+cLa'8wBk0nꥤm7%+޳滥åé⇼lWI T5]HLΩN':]uӆRL5͵Yx; +1m;jo@>6o +1`S7 endstream endobj 1116 0 obj <> endobj 1126 0 obj <>stream +HlU XSW{!{/ +B"Dŀk%QAP@ԭZkkZ7:ͅjm]j1m~cGSȜP7/ߟw{.?4etap.<' Ք0`YQ7?F|ӫWW} P~ߩ,/- > +oj_vʚ9Q~y@ 3t :^vjKkSS{!Q7s~bX7H +0?<|qf>o(x9lhPS8d#A)> +HF1,4[ 1'c/\,eBVb;]|*D 1$ a#%1N$(KQR( Jض]9Q}ğ +X /"C!Z/s3uuͳP.Tz!DȞ;typqu]lr+ιiN[={}ы+ ezɎֆ9yO>u^Z_a AP#!WaD&cЋT!AވE}@9GR)[L4Ì xD;l Fr!a0 +1(@!bca"&a2(_i(C9؅ш_k[. +8o6`56UU۰?&WruT(ۿƷ8op70})9Őj4KK70'3Y :lO?p&O)):+f<]]S;Y̝l [^\e_nk+VZfo{s[6e-ooݶ}Φ]׽x;A[?Ͽ8z/O~ߜ_헜;\񧟩ZG4;zfZڜ))I`zAȭqjpzr$dz!Xu6.؇م<̡unK(VXشrm(dn# 3 DI#ocu4hV\Gkњm6|)UEt܃bV&Q':ZvVfnT63KˢC'DÖC\D%QqR>AB+bZTUV Us.B8ȵWT +/<_zP[A-4 +up!UL!<3E-&麹?Muʛ;ԙe q2Ĺnps?Pi릋 BIpB!GO #,##4IWDG, +LI*ɶ2ȐLɼN +Bc813NJeR;= ,h0L\R][`T34mxrXXi bfI41>#b"%G5Wi>r<KY} /IG겇꒪_RY!ynO-Cjڤ6Џ:^ϭŵu]^k +cʗ4-76'MVaA&Si"o2" } a0Hxpp_a 2u]"ך1r\[N$Q8"fSh8߻;RΈJ1s k?"mݳ3}4PT1p`"Q*E_M +  %Pz 4 CZ`'{9,d ,wT?a-Z{sܧלz<  :VnAZt0?:m_]65av~Wz+Yc]36Y@7x=<.c ֧KrlPсyV=M<ڊg +xUp70o $yz\p۾g+e(_x>}NO-=A"zW Z-2؎<}} ![@F;2k׎Cl0B&`] Ns%U1VXuPeT+=z^_+:|B%mE]Ӿ&'}Isho;Wlo_4[+B@:bg@w&WW$,C䕬(*7)m%_Y%W;u,d7mŽ[J㸯dj5J֘Yd 8[ P @6熱ťŅCӇ]88tx{98.>ȃes-_WgG#t:Y80jOlDRt2 wgrm2ݳ%l&Ggr5SFrHkN=4De5Ѷɡ&ѩqf<bv,lʒӁv]SL +vdԚ@IޭRçm:[qܖ=S,08X_9։XUjɒ%‹vV2K,U!.2j{ 堺"/>h3}(Q,׎!]wCRBB:Aznu!b&Z~*Mt식ITG⬲2[-niNͼӍuimն:~}쬆x!W@[Yt 7Ê*TXZ+oݐE?q@eiGgdG锲ٹ-[7y-6Aet DvĒ`LNV8*\OTnfdZ'LI~,]nM6ZYfL5hײ#fXz:%f׹-[As:M>G+zï~%]E^>ҝ`s__#<"QOHAC c3ﳘ^+m9$ +$d^=D=8zAՒ6I@^=L8O|t6} kl+\Mrc:FK,XKG8Z3Ygij u摥!²^`LHYA f@ru*+6x[pEZqb8XmI&_퍅zcV1:J?׳C?Ea]t;hS6ط '#$C)8Ƿq;N3n~w^{^8 &Yx!-|\ly8?'xx.q93L\,<ո|/ċb/r:\pc7x^x^7xތxގwxލxޏ[~}| |§||_—|_ |·|?i?M0~_O-~/=%_W#~mѦ)ѩiB_jn+Mgq<_.G/UGvJo{AU)*S2luWyC1_oi4K'c'ͣi5o/fnUtdY噬T,G&yK]zW2GY餲):J)]ֹW\? endstream endobj 1114 0 obj <> endobj 1125 0 obj <>stream +HlV TT9 3 +>3 "&((LKԼi7uYH4ͷ]QknP\Z@MYX<$a7gs6~Wq cfϬ5۳K_9fl;XPfUWT/ɘYt6Ǒj7VmxΩxqz #j+%Ep`0o 6 @;m~eHC0w=c +1% %>Ht +! %3fG0L0L% B\(/J(bit@#d쐣r-RJCt:z:z9"v Gc:߯elng i_F#y RMru~z~/_v.:eB6y=uW﷼Z#a U(Џ +1**pHD!.` bYCq` P c$" *HF +##HG3QA.܏0(8G1J0Q2x0 Y/S1 JT^7؂ЌX^: <V<e?_|؃pockY'ap a6,+<c.<iE-01 0 ?`)kzVQJjx?qOh׸v\Wh{88<=3; HzI1]n{=-^CBo +gdT+f`져CKHLR)SGLu_vNn^~<0h K<&?X>e괊U՘1sVέx^ i\xeW4=Ub'zz lݳ6?l /qK/kw7wOҞ_oo{<#G?qGr3q֋m/_]T#E"USiTÓMe9dxy8(ZA p,(ŪDYrIh(l0 +׌!IGFy o,9 E4n47Emfvڻ#4SyVw{,d'q&f!4.50l`+˗ϛymyu?GΩBd)[Mo"4 jM_@pZC-=OIK;N3`m%.^A5Xt9$SvxwdPpuԪa!֢[dVה ±(>$1JK~hյ-j j j j j j jZZnTF`nՕ2S)mTLTLTLTLTLTL̄z‹!Hs vChYt:^t48f*!ت$DF&(`!v&,䔱Iv\򈌌~22"b*KJ+]<ew~Q .UT- *Ym!S "W4KDP$ٻg .K5Y\[Tx[M#4RM#4RM#4RM#4RM#4RM#4RM~pw kx o^Aq[Q3fR̢ʸ*㪌2ʸ*㪌2ʸ*㪌2ʸ^6e2&֘$y]짲~E+gxZSR#,!U'yyu3bgڣ]@ȴjRKG̾N6mp:.) +ƈ%̝ȊMQR gb8~q\c{8Oxؓ{&6mB"ujij"-@jR+"^*VVP P\ߜqxDΉO9;IHkT)mDzC!Y=A+ik'?!ϘCF4o&D7f"L䛉|3o&l曉|3q D p' I9Eg*Ƭ6Ǭb*Ƭ:&u;hw@{ }4b%s9inofT@)O~D}.39* Eh@,.ĽS"H.ȖužNmOd'OJb5=Wj?}k~)P +}J(zqZzv$򼙞*%W'3hf(F OQ/ +__X_6~ʿw`=|19+㟦i*O~TMϯ37<{C7R[C~I"Ԃ"Ǹh)Dw΍]{e(uAm.NW*su'd +e랤%^}CIZE8>'qL3kwhTa;T +wϗWޗ^][=xiޔ6_ŠZ}wXxh/ e/7ٗ e/}`_2ؗ e/}hO OI̴VQ\S81IJO;ݸuLN<OjC"Ig!J=SNGtz3:NGt:tD#:NGt:)ʼnu8f@̀t&ӓBU ?Nuy`aw3=ڤ Ji:Y :8 G6#p`l8 G6#MGSy1O ྨ ?PQh) +Q D]9fO^D-CraI7Λ4ӼwR[?Kj%;#yH>U -515뢦C9{ &4-+*o;1l |K(tuZBȠ^:Y[xk(F vN {u\w\w9/l I|g1nAz7Hnhh hhE{-{h6zQad誟ʆQ\R=h[|Z?MdY:F1\۬%ڦmmE%^ djz( 1=LƓցKʥAH:ee*>kSop;u"T@2Ld* S +T@2LI2Q];rcVȣU#u Ά0&ǶkowfaMcf0ZXR01{|*/-fbx lҸ>ݼf!nf!nf!nf͸Ɣ8Fm'.?P:͢NƜleT:!ʩ[o$yf6$ެ=qpË9KC'=h|O[ -gs9w<` {]gb1 ;{Edxo'(2"sEU6"ȡef:Ըw+)KL?hwᦰMZKY:7.E V-gu˓玱}&c>$՘'[B۪3hʅbM!jp*SÕ-};74QٮuD/k +϶{5ZG݃K @˷ƀOPZPyX?0/? XopAy^*8*ĩ˙G( {ޔCe2|=t.XzBp~H]Y=ͺ##;K֞X{Ƴmr_ Ńx_@E(pS޻2ִk"jz+>9BV󫵱inY9Q5yMMHېO4]44 x4 Al4 Al4 Pf .fƨQڗ{LtGH+,{½֮]v_o`&5L55`2s`y@&3:Jvveϲֶd `K["Q 7eqzm;M|n.HZhn[ߎ"zkV;.ڍs.7|9ܤu%uPr?ZX:5=vb{rxW_}E|[OIOÖR!PhyܦvN<0N/ݞkukʃN +wm$zi?ɷ ݣRR[r-lR$X}@|E~\_)p/>BCFH +D!c%#[d_9MZīG!  6vshKmav/ڇ qmTSmL{9F@8d3jS.AV/ 7: p`C?ZR|OЇ/ĻAw0(a0j~nZ\&?hL: hPv/IbIl{& ܃9` F~6) +* OJx0Y[ECFž5nq៷z`qpW=g;`C5;=cc$8lHbX;A(ԣ8܀,HA4?k_/ ? +m}mz+}C{A mLc&ԇ5l&l^p&J]qAt  +k!Yr !\G<_XMigTXeXγ!>c}rN;kU*6e;TJ<(P啻Ǘ6h\*zfʞp;?p=gox4O3y/[}Y-see .#b +(T* +\HR.S`vVЭtTČKXq]Wz sJwB?kxKJ̩M9kc+Q|6m,:x^ok025=51:r$<:=ytԆg&φFfL3% L߭SӳǏA9032sQT!y +FT L^.aXLu-Lstme-:#N dԚ@IB;mn&^w}!څp=cCFјEc~ FDv8myeXT ZV``M g`Gώk,,^3SqPI_jGug4oȧSat!pRl}skcycbsb<ǑDիGi '؎$-&r~92zh?I6TɹR^PphJWWsqhɗ40fQ7 qwh5H +xTmQrEқ<"29N +5`Z޹ 䡉(4-xbZΰ2$k1pʣ{ť՚)52?#}̳= Fc +#z6j~̌[ +w/W?NW;G.ЊÑ:o-ȇ3~6Wjc>?WoᏍfnuɭ"c;S@6ۄT6tlg,rwy]g㮸{'Υۈc;=%8p>.O=؋{޸ Ed?܏ύ2< <C0<#(<X#'l1F9>8~'x')x*t<ijl<|/ċp%^x^Wx^*W'q-x^7xތxގwxxޏ‡|4 | gY|E| _WU| _7M| w]|C?OS c9~_?3~_M!N6&'%)ɩmӒӓ33WxffvCʗ5E hxthaBud*tŕ5S|UZdZ0ؔjVE;gC1_Yo`mMD-▓2e&s1l;ԢnUv\VAg*#tRվ:\nʎ+uupyc endstream endobj 1112 0 obj <> endobj 1124 0 obj <>stream +HtV xLW{畄d&\y1D&B=tIHT"ghLmKVJjՎGQH>If rs;u[8\%)(,~WX@QPRS-VR@CgVͪl-:ƻiM9g;6 xX^V\>mLIIja4T^Y]{B4O#+),)*^`^[\YϦQ/z{`+MϮZPVu|HN |);D,A{t4*H^!@s9$p4G"_~ρEiH +샃Ű1,ZmNrx#E Q )B`49c53eam?;sX/'\;^{.|?!X/2~#^2>s8]::8fPEuwu}^u[Iu\{ck @džڎE%qW~P_RwƋ3g&gr kcaWxN#o@ |G +@ )HQ4pD Q!0a(!Cx$ Id`$Fa4Re<c4283Fr|L(s0Âe:P(A)`:[qVlǨzt5l o$ƿ>/n8O0jm TPyŗ8[K8o+he\TbӽY]XEF ^bb ,^>*X#]tw| |Kt` Mh)4x':K,>lRi<<|C(⠰ȨCLCEOHL2rԧ<96kg&L49;'7/ʳϙ-Ͽ0p%e9bs*Ϋ`aj/YlVjW_[o`{ko~gwl?=??ihlj>tіcN\ӄx0k1j>mhI2+2쬈 MX;66,Z`_j +ťvED-ؑof?Y,)p2B]eEJ·s =-â7L{Kޒ7X,JRjWlVͪ8Q ,Vką-VJR>,SiA/)Dh ;,ao$K DQcrRhs<7S-c :CΠcM=u4얦GpD p&õ[!VoWp.pBS&TBMx31BT~lj&&æì/K9w'nLGw]k_3񙊌m3MJ_8iĴ 8K"9I@F{Q ( +RIz9ZFbRP " I"PTF"UyZC`H$B0.~'P..6KI1KO%E +y,r||r,16`_1areRlҌuykgě&dEK*͝X> ܗr|'yhxʳn!^rs&m6y&N+H|9B%`HKرlKOn9Ěz +d7S9QKOI +BEV&yZ>ONd55pzO}e3ܧzi%8Ti.8/'ۣJS벓~"bm6[l\[MMZ۔h*+5p)_֑L'&l0J$7)t'ӇH Rt dp,pS\11]Ljh!4ZgxQLO<~yHD~54EU'}jξk5'v$qAGwtH">?Z2J%3& 'IEw8^*]^" +!"I&Q%S^΄H3V* bhJb%tN +5>n2!2!}L|d9!npAu@ DݭM 7wH-+.6 +ߙ8z;:^up842{'ݝYffnxD' $oHϩ*}H*HJ@4Hw]'iBx>sϜs=;z{'*?\<g-ķMHQCb*mG:$MRJVZb4T/Uf(TJ _G$ PdفH)PũᓇPEb&ڙ!DH+IܯkZFaۉ~.F/"ju,5+v/)h$A]f4P^ +q)~OLg K*yBL l|dbH *spPUT5<>AٳG ; 7FM֫-|w.eQGq~ɰ(J~ +70MFv%Q$(ß_D^("cmp!!7S9'C>8\Q&"o!tpSȜ2'%2g*' BJRkGO0}r?0ϖ?1b'{p}?ZtX_sfgo L&}-SHhGL|>=۝83Em}`ϟqPåկɘ@`Bn8RmS[/="bbafp-BguJD~B#pr/O]Ղb\14/ m]u(- ώM|rkeOb} GA᡹GAgEL>@g?y«?: ԃn{o>|a硿+]?W;jl +=u q;o\q{c=}>v_ZTuwS}2̾\f 5؎@ۣbMJA8)gu3ls&E{Bo6jK kBdch7}Ӟk{¦vI>}ft[}f@`h@! 9@A;B`~ج\W¿U} +HV%ֽB<mAjB"߱=ğ'*Tu! iW |ԏX/ŏr>8"(n ĞuO;<CBjS[,d$bY +=)󩲉v7!_LXL-RnaMx.\i1k~3a +>1+ۺ +*PWi= Tٷ8ƞvOd"~(ڍh`K_B sFiA<RӨ6WFj됼Z}Wg$:/ N!,02uu7(O%$ccwI J^e;B)XkhFA:.' 7ּfٖc3cqzgZy0~zt\{ ĕ%lF\Y? c:۫V̕i۴L&ܞL!7{[d + L 4J"8Y ayqz1 +6ÙdzyC,,O,A0-[Imu=hF-XEw8 \a&sW<8:D#r3nR#f?eh^ ʟ0W}f.`}먢(P\7*l٬a&[e91ΆYW6gƏŧgiKfd jA E|_eh@ec/!+V[dy!־fG_d oP kb$~QcM&; JtiI}Y'{zyUDQ["q Sp! 8d}0 j~3J(BBo І{`/]=9 Џ}ws޷gǨDs#yY'ca#cS v~JcpE!pZb.|zA[eˇZY^<Ww( 1v8łLғT|)#~!թ6/-ie7. h.xDbѢZiji매j^:=?9 mVfLUb^k.AU֪U9T-C=J~0ꭳ([msYz| n, endstream endobj 1109 0 obj [/Separation/grey/DeviceRGB<>] endobj 1110 0 obj [/Separation/New#20Color#20Swatch#202/DeviceRGB<>] endobj 1117 0 obj [/Separation/New#20Color#20Swatch#201/DeviceRGB<>] endobj 1100 0 obj <> endobj 1101 0 obj <> endobj 1102 0 obj <>stream +%!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 13.0 %%AI8_CreatorVersion: 13.0.0 %%For: (Jeroen Wijering) () %%Title: (mediaplayer.pdf) %%CreationDate: 1/11/08 4:36 PM %%BoundingBox: 52 -539 797 -44 %%HiResBoundingBox: 52.1289 -538.252 796.124 -44.127 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 9.0 %AI12_BuildNumber: 406 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%DocumentCustomColors: (New Color Swatch 1) %%+ (New Color Swatch 2) %%+ (grey) %%RGBCustomColor: 0.79999 0 0 (New Color Swatch 1) %%+ 0 0 0 (New Color Swatch 2) %%+ 0.4 0.4 0.4 (grey) %%RGBProcessColor: 0 0 0 ([Registration]) %AI3_TemplateBox: 421.5 -298.5 421.5 -298.5 %AI3_TileBox: 17.9448 -577.1377 800.9453 -18.1377 %AI3_DocumentPreview: None %AI5_ArtSize: 841.8898 595.2756 %AI5_RulerUnits: 2 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI9_OpenToView: -125.3335 -6.6665 1.5 1402 965 26 1 0 50 75 0 0 1 1 1 0 1 %AI5_OpenViewLayers: 7 %%PageOrigin:-141 -492.2754 %AI7_GridSettings: 10 1 10 1 1 0 0.8 0.8 0.8 0.9 0.9 0.9 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 1103 0 obj <>stream +%%BoundingBox: 52 -539 797 -44 %%HiResBoundingBox: 52.1289 -538.252 796.124 -44.127 %AI7_Thumbnail: 128 88 8 %%BeginData: 10184 Hex Bytes %0000330000660000990000CC0033000033330033660033990033CC0033FF %0066000066330066660066990066CC0066FF009900009933009966009999 %0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 %00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 %3333663333993333CC3333FF3366003366333366663366993366CC3366FF %3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 %33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 %6600666600996600CC6600FF6633006633336633666633996633CC6633FF %6666006666336666666666996666CC6666FF669900669933669966669999 %6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 %66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF %9933009933339933669933999933CC9933FF996600996633996666996699 %9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 %99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF %CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 %CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 %CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF %CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC %FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 %FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 %FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 %000011111111220000002200000022222222440000004400000044444444 %550000005500000055555555770000007700000077777777880000008800 %000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB %DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF %00FF0000FFFFFF0000FF00FFFFFF00FFFFFF %524C4552A8A8527D5252527D527DA8FD26FFA8525252FD057D527D52527D %7D5252527D527DFD0452FD35FF277D275252522727275227A8FD26FF7D27 %277DFD0452277D5252F87D527D275227527D52275227FD36FFA8FD31FFA8 %FFFFFFA8FFA8FFFFFFA8FD07FFA8FDFCFFFDF5FFFD047D527D7DA8527D52 %A8527D7D7DA8FD38FFA8FFA8A87D7DFD04A87DFD04A8FD07FFCAFFA8A87D %527DA87DA8A8A87DA8A8A8FD0EFFA8FFA8A87DA87DA87DA8A87D7DA87DA8 %7DA87DA8A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFFFFF %CAFFA87D7D5252FD047D527D7DFD08FFCACAFF7D522752527D7DA87D7D52 %7D52FD0DFFA8FFA8FD11FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFFFCAFFFD04A87DFD07A8FD0AFFFD04A87DFD06A8FD0FFF %A8FFA8FFA8A8A8FFA8FFA8A87DA8FFFFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFFFFFCAFFA8275227FD057D527D7D %FD08FFCACAFF52522752277D7D7D52A8FD10FFA8FFFFA8F82727275252F8 %27F8522752A8FFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFF %FFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8 %FFFFFFA8FD06FFA8FD2DFFA8FFA8FFA87D527D52FD057D277D7DFFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFCAFFA8 %7D5227A8FD067DA8FD08FFCBCAFF527D527D7D7D527D7DA87D7D52A87DFD %0BFFA8FFA8FD0DFFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FD04FFA8A87DFD05A87DA87DA8FD08FFCAFFA8FD047DA8 %7DA8A8A87DA87DA87DA8A8FD09FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF %FFFFCAFFA827A8FD047DA8A87DFD0AFFCACAFF527D7DA87D7D7DA87DA8FD %5DFFA8FFA87D7DA87DA87DA87DA8A8FD09FFCBFFA87D7DA87DA87DA87DA8 %A8FD0FFFA8FD15FFA8A87D7D7DA87D7DA8FD19FFA8FFA8FFFFFFA8FFFFFF %A8FFFFFFA8FFA8FFA8FFA8FFCAFFA8527D527DA8A87D7D7DA87DFD09FFCA %FF7D7D527D7D7D52A8527DA8A87D7DA8FD21FFA8A87DA8A8A87DFD1CFFA8 %A8FF7DA87DA8A8FFA8FFA8FD07FFA8A8FFA87D52527DA87DA87DA87DA8A8 %FD07FFCAFFAF7D7DA87DA87D7D527D52A87DA87DA8FD0AFFA8FFFFFFA827 %2752F827F827525227A8FFCAA8CAA8CAA8FFCACACAFFCAFFA8CAA8CAA8CA %A8CAA8FFCACAA8FFCACAA8FFCACAA8FFCAC3A1FFFFFF5252275227272752 %2727F827A8FD07FFCAFFA87DA87DA87D7D7DA8FD0CFFCAFFFD067DA8A87D %A87DA87DFD11FF527D527D527D7D52527DFFFFCAFFCAFFCAFFA8FFCACAA8 %CACAFFCAFFCAFFCAFFCACACBFD0DFFCAFD05FFA8FFFFA8A8FFFFFFA8A8FD %08FFA8A2FFFD097DFD0BFFA8FFAFA87D7D525252A87DA87DA87D7D7DFD0B %FFA8FD15FFA87D527D527D527DA8FD07FFCAFD0DFFA8FFFFFFA8FFFFFFA8 %FFFFFFA8FD05FFA8FFA8FFA8FFA8FD18FFCAFF7DA87D7D52FD077DA8A8A8 %7D7DA87DA8FD1CFFA8FD05FFA8FD1CFFA87DA87DA87DA87DA87DA8A8A87D %FD1CFFA8FFFF7D527D7D7D527D7D7D527D52A87DA87DA87D7D7DFD05FFA8 %FD25FFCAFD0DFFA8FD05FFFD057DA87DA87DA87DA87D7DA8FD05FFCAFFA8 %7DA87D7D527DA8A87D7D7DA8FD08FFCAFF7DA87D7D7DFD07A87DA87DA8FD %4EFFA8FFFFFFA8FFFFFFA8A1FF7D52527D527D52A8FD047DA8FD07FFA8CA %A87D7D52527D52A827A8FD077DFD09FFA8FD25FFA1CAFD0CFFA8CAA8FFA8 %FF7DA8FFA87DA8FFFFA8FFA8FFA8FFFFFFA8FFFFA8FFFFA87DA87DA87DFD %05A87D7D7DFD09FF7DA87DFFA8A87DFD04A8FD34FFCACAFD0DFFA1C3FFFF %FF7DFD0527522752277DFD08FFA8A1FFA85252FD047DA8FD067DA8FD05FF %CACAAF5252FD077D52A8FD0EFFA8FD3BFFFD06A87D7DA8FD0BFFA87D7D7D %A87DA8A8A87DA87DA8A8FD67FFA8FD05FFA8FFA8A1FF7D2727527D5252A8 %527D527D527DA8FD21FFA8FD37FFA8FF52527D7D527D527D527D527D5252 %52A8FFFFA8FD6EFFA8FFA8FFA8FFFD05A8FFA8FD06FFA1FF7D7D52522752 %52527D7D7DFD04527DFD20FFA8FD4FFFA87DA87DA8A8A87DFFA8FFFD05A8 %FD3DFFA8FFA8FFA8FFA8FFA8FFFFFFA8FFFFFFA8FFA8FFA8FD4EFFA8FD1C %FFA8A8FF7DFFA8FFA8FFFD07A8FFA8FFA8A8A8FD52FF7D7DFD07A8FD0BFF %CAFFFFFFA8FF7DF8272752272727F827272752FD05FFA8FFCACACAFD04FF %A87DA87DFD06A8FD0AFFA1FF7D5252A8FD077DFD25FFA8FFFFFFA852F87D %2752277D52A8FD08FFA8FFCAFFA8FFFFFFA8A87D7D52A87D7D527D7D7D52 %A8A8FFA8FFA8FFFFCAA1FFA8FFFFFF272727525252272727A8FD0DFF527D %FD04A87DA8A8A8FD2AFFA8FFFFA8A8FD13FFA8FD11FFA8FFA8FD08FFA852 %A8A87D7DFFA8FD0CFFA1FF7D7DFD0552FD057DA8FD23FFA8FFFFFFA87D7D %A87D7D7DFD0BFFCAFD05FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FD05FFCAFFFFFFA8A8A8FFA8A8A8FD0BFFA8FD04FF7DA87DA87D7DA8 %A87DA87DFD29FF7D7D7DA87D7D7DFD15FFA8FD18FFA87DA8A8FF7DA87DFD %0CFFA8FF7D7D52FD057DA8A87DA8FD24FFA8FFFFFFA8A87DA87DFFA8FD0B %FFCAFD08FFA827522727277D5252A8FD0DFFCAFFFFFF7D7D7DA87D7D7DA8 %A8FD0BFFCAFFA87D7D7DA87DA87DA87D7DA8FD29FF7DA8A8A87DFF7D7D7D %A8A8FD0FFFA87DA8FF7DA87DA87DFD12FFA87DA8FD047DA8FD3EFFA8FFFF %FFA87D7DA87DA87DA87D7DA8FD07FFA8FD08FFA87DA87DA8A8FF7DA8FD0A %FFA8FFFFFFA8FFFFFFA8FFA8A8A8FFA8FFA8FD42FF7D7D7DA87D7DA8FD13 %FFA87D52522752522752FD12FFA87DA8FD057DA8A8FD0AFFA8FFA852527D %7D527DA87DA87DA8FD24FFA8FFFFFFA8FFA8FFA8FFA8FFFFFFA8FFA8FFA8 %FFFFFFA8FD0FFFA8FD0FFFA8FFFFFF7D7D7DFFA8FD0FFFCAFFA8FD047D52 %FD057DA8FD29FFA8A87DA87D7D52A87DA87D7D527DFD0CFF7D527D7D7D52 %277D5252A8FD10FFA87DA8FD11FFCAFD05FFA8FD2BFFA8FFFFFFA8FD047D %A8FD047DA8FFFFFFA8FFFFFFCAFD05FFA8FFFFA8527D27FD04527D52A8FD %0CFFCAFD15FFA8FFCAFFA8FD0452275252A87D7D7DFD29FF7DA8A8A87D7D %A8A87DFD40FFCAFFFD05A87D7DA8A8FF7DA8A8FD23FFA8FD15FFCAFD07FF %A8FD11FFA8FD05FFCAFD17FFCAFFA8FD05527D525227527D52527DA8FD35 %FFCACAFD09FFA87DFD06A87DA8A87DA87DA8FD1FFFCAFFA8A87DA87DA8A8 %FFA8A8A8FFA8A8A8FD21FFA8FD14FFCA9AFD09FF7D7D527D527D7D7D52FD %067DFD07FFA8FD17FFCAFFA82752527D527D52527DA87D7DA8FD70FFCAFF %FD08A87DA8A8FFA8FD23FFA8FD05FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 %FFA8FFA8FFA8FD19FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FD3E %FFA8FFA8FFFFFFA8FD05FFA8FFA8FFA8FFA8FFA8FFA8FD17FFA8FFA8FFA8 %FFA8FFA8FFFFFFA8FFA8FFA8FFA8FFA8FD0EFFA8FD29FFA8FFFFFFA8FFA8 %FF7DFFA8A8A8FF7DA8A8FFA8FFA8FFA8FFA8FFA8FD05FFCAFFFFFFCAFFFF %FFCAFFFFFFCAFFFFFFCAFFFFA8A8FFFD05A8FFA8A8A8FFA8FFA8A8A8FFA8 %FFA8FFFFFFA8FFCAFFA85252527D7D52527D7D7DA8FD29FFA8FF52F82727 %27522727F827277DFD04FFA8FFFFFFA8FFCAFFCAFFCAFFCAFFCAFFCAFFCA %FFCAFFCAFFCAC3A1FFA8FFA827F8275252FD0827F827A8FFA8FD06FFCAFF %A87DA87D7DA8A8A87DA8A8FD25FFA8FD05FFA8A87D7D7DA87D7D7DA87D7D %A8FFA8FFA8FFA8FFA8FD15FFCAFFFFFFA8FF7D7D7DA87D7D7DA87D7D7DA8 %7D7D7DFFA8FFA8FD05FFCAFFA8277DFD06527DA87D7D527D7D7DFD24FFA8 %FD0DFFA8FFA8FFFFFFA8FD06FF7D27522727FD0452277DFD08FFA8FFA8FD %0FFFA8FFA8FD06FFA8FFA87D7DA87DA87D5252A87DFD05A87DFD1FFFA8FD %04FFA8A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FD05FF7D7D52 %7D7DA87DA87DA87DFD08FFFD08A8FFFD0DA8FD05FFCAFFA8527D527D7D7D %52527DA87D7D7DA87DA8FD3FFFA87DA8A8FD17FFA8FD12FFA8FFA87D7DA8 %7D7D7DA87DA8A8A87DFD04A8FD1FFFA8FD06FFA8277D52522727277DFD10 %FFA8A8A8FFA8FD11FF27FD04527D525227522752A8FD05FFA8FD05FFCAFF %A852A852527D7D52FD047DA87D7D7DFD27FFA8A87DA87DA87D7DA8FD0FFF %A8A852A87D7DFD0EFFA8FFFFFF7D7D7DA87DA8A8A87DA87DFD0CFFA8FFA8 %7D7D7D527D7D7D527D7DA87D7D7DA8A8FD1FFFA8FFFFFFA8FFFFA87DA87D %FFA8A87D7DA8FD0FFFFD047D52A8FD0EFFA8FD13FFA8FFFFFFA8FD3AFFA8 %7D272752522752522752FD0FFFFD05A8FD0DFFA8FD13FFA8FD38FFA8FD07 %FFA8FD17FF7DA8A87DA8A87DA8A8FD0DFFFD097DA87DA87D7D7DFD0EFFA8 %FFA8FFA8FD2FFFA87D527D527D7DFD0452FD0DFFA87D7DFD06A8FD0EFFA8 %7DA87DA87DA87DA8A87D7DA87DA8FD09FFA1FF592727277D7D527D527D52 %7DFD24FFA8FD06FFA87D527DA87DA87DA8527DFD08FFA8FD05FFA87D7DFD %2EFFA8A8A8FFA8FFA8FFA8FD2DFFA87D7D7D527D7DA87D52527DA8FD0CFF %A87DA87D7DA8A87DA8FD25FFA1FF7D52525227277D7D52527DFD25FFA8FD %07FFFD057DA8527D7D7D52A8FD0CFF7DA8A8A87DFD04A8FD27FFFD06A8FF %FD04A8FD2CFFA8A8FFFFA8FFA8A8FD11FFA8A8A87DA8A8FD28FFA1FF7D52 %525227525227527D52FD25FFA8FFFFFFA8FFFF7D5252FD0427522752FD0F %FFFD067DA8FD25FFA8FD04FFA8FFA8FFA8A87DFFA8FD2DFFA8FFFFA8A8A8 %FFFFA8FD10FF7D7DA8FD2BFFA1FF7D7D275252527D7D7DFD27FFA8FD06FF %A852A8A87D527D527D527DA8FD0DFFA8FFFFFFA8FD2BFFA87D7DA8A87DA8 %A8FD2FFFA852527D527D277D7D5227A8FD0DFFA87D7DA87D7D7D52A8FD25 %FFA1FF7DFD04527D7D7D52527D7D52A8FD22FFA8FD0BFFA8FD0DFFA8FD05 %FF7D7D7DFFA8FFA8FFA8FD28FFA8FFA8A8A8FFA8FFA8FFA8A8A8FD29FF7D %52277D27522752A8FD10FFA852A8FD2BFFA1FF7DFD0452A8527D7DFD27FF %A8FD07FFA8A8A8FFA8A8A8FD11FFFD06A87DA8A8FD28FF7DA87DFD05A8FD %2FFFFD05A87DA8527D7DA8A8FD0CFFA87DA8FD057DA8A8FD24FFA1FF7D52 %27522752527D7D52A8FD25FFA8FFFFFFA8FFFFA827FD0552277D522727A8 %FD38FFA8FD04FFA8A87DFD04A8FFA8FD2DFF7D7DA8A87DA87D7DA8FD3EFF %CAFFA8A8A87D7DFFA8FFA8FD27FFA8FD06FFA87D272752277D272752FD3D %FFCAFF7D527D27527D7D527DFD75FFA8FFA8A87DA8A8A87DA8A8FD27FFA8 %FD06FF7DF8FD055227525252275252272752277DA8FD33FFCAFFA8527D52 %527D7D52FD2FFFA8A87DA87DA87DA87DA87DA87DA87DA87D7D7DFD38FFA8 %FFFFFFA8FD29FFA8FD9AFFA8FD64FFA8FD06FFA8527D7DA8FD097DFFFFFF %A8FD33FFA8FD3AFFA8A87D7D7DA87DA87DA87DA87DA8FD6BFFA8FD80FFA8 %FD80FFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFF %FFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8 %FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFF %%EndData endstream endobj 1104 0 obj <>stream +HWr8;>&Mɖli7&n2#6RR$eYk\ҋG >7Fի},O  +QdҤ]! +Aޤ*2a;@IH/P<풝]\r9[\Ĩ-Qϣnv'4FM{Oit.i>'4V/^ݰ_ ໋BoeT$#%#Ȳ})dRrfaOB^=/5w2KyĎƾLcH3ϛFLVs WVX͉khpz  ?)jiRhH ЄJ;̚oL rMo@S- .N HO҆ +vCiv:px"!Z3KnPJiVf>$*>i~6 +s3*R՞pX1yiQ-'?H}tTH1KY^m8(^,sү!C]q:S2:9(dt*ݏ +qt9`Œ6"0O)[c<3ʣr0+ +5QDU-0¤FCJ5ҚRXhaТl6Ec4Fo堄"H (.X)J$,/FI*Em1lSPkC5]3y S:8LlT O5h^BJ6ٹ[x +;aYT=Xٿi'cyRK'fx˙w͘aHܞzd#; _hϳb d+_TIc4Bb^&1Fj`uњn1:AU1*fWPXj*ی:N9:\L8u^ˠ2 ea8tPKуfAe܁ ͡ZЂ5}+qfgu5g2Nkv!) E lIۊvHgL`Eu;1sNL3 >LN3GG{bAI}#ǎG$1QZ=te9U.c:"ݶMOfE{s,xCw^}UfoModt )^+7˜!H/Қ/vw}\}xn(\_Y8G1ETɩ&2$ƿ9FF 6wg*gπ̗}qǜyt,;&{[l%lQFDK<&TI-lz^F˄3 +1L@ 9[173i,X;W*u~v%YZ4}{w y7Η=8_)̀чTm%@^;t+K!^{f۞p^v9.K|tE|rD?$FY7]d{l#w +d|hNZftT ajCmC[я_=;xY>}2{;_h!;*na9RY!Ϗ[[N陟)(V{Xmv*n>fzA\>ܦ;zZ&,nE.~tC{5{RdzZB߿g`ّV1ګ +1>bwgq G3kYh$[Q@e9s^MjG<9Ҏ?}<1|Cv"/ZZCJ\ +Riz_eGM.`tvzDjz.da%ٍ/*`}xȬׯ ar!?6NlI_F{4[مm>sGEJWb˭S1}{ضu S4^ <{q#hA'þ.Ys7ߠ׬^əRf&oxϷ>W~ͷyUړ.d睏0͇qʼt,T{U6D +KdxrdVvJMMA$$q\mC)~\_7ݯ_7XOQwGp _/Gّ01G'=i;wp%XVޖ+G!-'K' +<$D7",ovڞKEĻW).S̢ī:e3EF"UzR ~Z$Ew$=bKW+)E}Te%N0C=GOyVX'ߨàvgiz _2`}p R3betId< Bm81$B-}gf RQ? f~l`$ XWtxbq&:V5E<`5Oҵt^U2qbC+&rBa ]TEdR8Krg\ Jq + cFq"7kNgBdGjvyDME?}"߈f6n]*k xҋIΪbjHdo~ͧ+ǼD/wN]&;y߷I\.3";A_@ןj|M1^ 0JX\&̘c.swx2G9rh8׿֜o /п +'Z0I熠Fz-EakOh<>~AO%K9Al檀Y'fO)]-N1#C.)zlqFUt] 0qRI\x̙^uհ{mV&2yI* LS1I = +JbTb1[cY/ƾzf o.r'@Necun(o:P3M8vY`rzDH+ g1P[MDx…Tijŏ =|r:ʨO)N'{KklxstPnPP]O(JTeM +M-~$Z$a[>/*x7Xȁ@H EkȄy/A6Q[[vQ-SbPr7/9\b9ªj t"]ȝ!_ k7~"ٽ$mJ qx:X{eara)y7]- +gAjOj^*j ݋UG;V`_/#!O}4z2Tm#J'_#w v0^0%Q(*@)NL)0C)J`F^dcCTr!`tbdn5.J^$,EA0~` +[K)klC}- +Zn8&}J uiѵ ,nMkh`]r9 ߶ \u"+Aј1^]T4f|>]0Gz ~}~ +_zF +Ӷvϣ6z&*Kf ?iVT}ɔ^%ĭ!_ZNB\=&HbyN؁J<̍*c.7uui%z=p~9p]zs+2Œ2 ր^`ҩ:e Lgcaav$ $N^$g =aQ0"ؖuyоM#ǨToHЅas 5}Ck. ];k(!g4mGY[{.M湰kt\>ZzHBIT{-WKhVQ/{ZL8~Aןz"!h?fk<$bvO Yĸ|2bEZ +͊my3MᔼW _YtA{]f +"M(|Twrq3DBkNksi9D': +JɐȃP8KF|}ZI+YFoz'{XD3\aF4IQď)%ߑ ;Pǭw$R\ >GUyN-\n#{&?/z"L[^uQo$NeT\Q5a;v OBqqJXg̞^٪wfe`E-M',=ck %F-=C^:!_>OyAO{-irR5;fnl_tPjkz!%'CS-?7;lT 5nRSYacQee2 H gT!mOUZQ3isa^|CxG1#LT4|ރnņJnM%j {5k+(11gο?"~o}n<"kaޞ;0)oO F@2T͆Ʈ]) +؁ f} EC}5ogΡy ImL1Xtn;5kGi܀ :`Aۙ& eNRxs܁0m7>gaۍ^=.@ ew~ Z0|L}I-C19"!Yw&lL'R\W?2N WǔM +/6Hб<~ic?jONs3a? C8^[pc1յɿg`/[m~Z6Cmez P#͜^IX[?u+xN_M[҄eܩnk/EqCKjGM*r/zc钻MWOr ܥ2ybqGa?2Lp[,(vqry<%HyZcHx4 caE=9Ū{qFz7gM%̺1L8}j.J.ыDU63aOqBC۫7+c=*c 9>ڴ3ň5rvԆhM7>:hf}\D7)Db#"?&S +k| ŀ<¨/*R!S)9@I٫!&Nj` $<Z5 z_+hC=;L:Fפ)MÅ<z\=,?'_iZܾ!Uc0[%d]5"-}Q[tMqS~]KEA| 4}}}*pJ/C.Y~k7Zp8ypEUADFȭ11lZ( ;` d?@ +x6VZ{ΜxB(_8a]rxak-ؐk8S%>QOӕLCT1P \s\>2I3-q~%OFF{!/'F1 :L*. ů=k.LAT9X%E h#LWTgF:j8h@J`x-6-_7]@DwJq6_= .n鑀{!28V_jn[BWt%lezi9S@_ޥΦnlK7CK\jS\V{Vŏ[淯'}kT%nnK,%UB:_=4yTFW*kzQ)-O.7dAԣR'AuD :E$ a1#%;h3"cp`9XU(PA,Pi$AZ@Sa1U۴&AhЂDQJ߰0o 2MQ:Y +nHjp@KmgXx.```M?zg읏W/s%{;zrE X>ey7r'r9z{X։gsƺv t΀[/͂4^>r4_{qq~Ba/XПT⪽l+nB!Y@޾d5P t +Zƨ0I5g8ܔ氱u^JM7\v` no֟[8i/x41qbS^nw[*t1$]Zt-5uYXR1ۑ + +|#̵Bp&kzOх[0C6pY@ M5Y'iwG3EKd=kFY5ӹ&z}fb) ;31Khg$Zvw~|<ٽvժVNtVĵgդ 9_xpNH2KaI|Ècl*m +6bq YHx40ύ3jHʬyχ;Fʶ=^!?#[҂:\T=6c!+2i4t#mkD=j hĭ{/^_' rls}vz|ʧo;$tZ'n ËݱN%#1+BgC*"sr=sCY,J]u4vN-A ; z`{&ĹL6&[Z 0W>ac c >\o'T@?L-czs^g%-٧Lfm&:q1Y}DLdy$8j0^^Lژkm7NNq\B$:!SR;IjDMK;vy̐$?wGFkq.@%Ȓ9s~/=¾nz]/CQi*x>7iDI?f,/p pT˕|DPkQK +0/qf1d*\iP 2;SWg-\CM477ܳLΜn/^M|#t:/{ +x)ǤHρ"u⮯FJ׳K_ +.'ap.|utm?/s6-оfLP;% V E3hIua"!5S|bm>oW(owD`>e G6ԏ 5Qu98=޳K;NѮPڿt@Vh ճL瘃y2)L^ NQz8G}':}:{.I*l()+k+(ML8٢[K`p.%@kVtG)} weLrlNgHrf +PXK-x %n`!-J/~woT?:4+/ѕQrfp +;Uޣm\(^oAD3u]Y^~$|Bn;`wdB7^NupJx.D9]9[ñ2}rNߟ"/Kjlr}^Lm1A&k`Y,Zz ,I}BN|6'KZX.? fj +h~ ȤN."q1&NqMS>6~iQ[sOޓ䡒hC/ +M秽Spho:أ7h7mo"/˶ Mvԩ o!xv5 RI@Rg60yWo7pQk_pQvJ=kQI aq>ӒQjU`sO^8*061 Q)r]>Xjo +UC ȫo{.Mm_ ֦t?M ?Gs ;BK5{Cp>03 +RM2"aV͕l_$nTz5<_%priLCFSncvS^h}@5mdk*R-krGAMc9Yu~N\E&}TCspg,Umt3$]F >ߞu(ʈ ά@_;P|i̓RW&]d%v1Мj椩fBdy)FGtLy_p{xToMD +f)bot ~Y$ &;q9ˢ 1R]D™z6mچ觕1B%Q8b9~ mvD +&H/ 2Xܖ7Guߐ饱0؏gZW +nc9arCN.b]jvfdQ|淾CdeB<7O?\cUi|1i܊O)IUN;]سnX`X ݯ(<`g.K1(2NIxAE@DQqAѸ5Fs_sӠ .0sf)/ӵtuUW\ϼכ>{r0S;ibիh!ڰG_AMB@_^Wf87ޭJN9 +^HV.9-ZZ!A 䁋WrOE+89yNh+G69b,gCt&6ߥOIP +C^j܁B\8G潁q6Ogn A,Ֆ GErй6SV#fձN\K h0%-ۅv)Pqmih?NRkA`tpnvQPux6<Gi S'GչWRoPoq6NGM\ -TTX뷦(56»t} {#ۆutX8+h?Nj>-'fJ<}\a͇,:v4?yKBP.s1ZJ@Bc +0SM1}ff %+Yssܵ_\kKU{j>L1# j7dvkBr49e >U`(Z< +XoH +sTjMi i :RA%i l "7a|=r3wӬ_L~Lto~I͘AhLQf|zͲrÈ' pje<[4-^ +s{ONa4dDӆ)-?i4@[Wej!+ftSz@BeQ;tctN2z,\VS)ks[ JQ'K߷ N46Q̸<`oR|KaG_BٯdB5=kfdɠTGB5ۢ dX/n :JQZ"rHy8w[m"ȓ񽲠 Ǩ5M(8pZT+4nЅ6 =#26 * 彨 2NPJJ3.Po34:5%rV=k;BKK?s  +rVsoB/V`6j??Cĥ]d/=:Qq1?z|SXGh-}PycT;֝}NP,r>+y7h!Z]ڟgA^5rrvKd NL 6~vtfwN`̱'[@䃎P+C JLaX `] TՂzkMVQ/M/g<ߠDІl5VYXɠ#4 %^C5 M|9NN j- RBU#Yy*SrbB'((v*]l(XX+]m&*wpL[>XiBPTs4ay0;yvzY@V,k)yhemyd?bIcJy{^txCc.ap(P/*W9F\;VqM ąFM6Oaǘr;Kko{hCҔx5 LErn1c`c"rH,zYnO4X;lɱ76X`QצPcT7x3rDϳ[l)(c`gܭ}A̮ٞJrLj8͜$w*ߌ|uƳ[j/1nj7@5E

 ŎGcp2)x^'lW6Bx@X,*XaLHm).@(AcO]|*Ak06_ ESVkk9H;2]5<]pw|9>|]s })=\/)BuuO +Tf.:0$?ra: +"Gr5FHC]3^&uF5W ௤Z]dxD|x6. Iv=Fk">5 Uj}܆qWPsk-c=FbeŦM}^XTz(晲x8EŕwdP,ևi~\"ƪeqJ]Q6|Ճ;"+ VAxcۈyY[sQ;o!.Mn" j]"Z"GD}NnOm]5i Nlo2UMHalгrOD=|ӝ 5VgcN +UU8d}/bcѻˈw &2&&almqR5:P'c;Pe3Mmxz +-.+ +:9l+sflJ=`K;@P!-Y!^\iN1/%CFrSXAmBQvDS"$>Gx"ZՖVr5Q˖1>@~@PG > +t2$}yMi+N%YaR#"^g[‡Zx3_7Kާ} 3NjhjLj}KoJ*lx^̖t;ZF !Y-Vf;aXWL_rghq$ y'MpiRDv÷9ymD^ߣ.F ԅ]B@WINUuxw@.k yI^u7/Vc#6'q&˘F<z73PryW'g+ţ5# +kRA=)1eF¨bvғHpMNP{XH^< +:;ɀ9Ui-C{rMz- /Gp $͐N!\PRh0C!C-_I6$d.ݳ FG" +e@0v*愈Ͷ'Dhڈibiɔ^N{먈],M)owT !8`!QWmO(o {B+VmN8&LsZQ7_[]<Ǯb9Űp>ýKVs>qeA4i:|Hxv|i_o1n"('˪xP7U uK+nbS-rm +LUyv4X +\aEO +L72kf Y6c=,'!CcP7 ÛƓvz9kҔf/ń W[a*1)5 "nZcV&|`AqvE+ Sme * a7lȼЧU,]3XEwerbReS w}N)v2 +-bMg1c-2Rsl|O֗0H)GBKKA AKD~Tu-#<ڱf1&xx^-DN6rJjNͼM9%6  k˷` endstream endobj 1105 0 obj <>stream +HWZ;}y63ZiA*Pr>VZA.0$$ '~ֺZu;9&쪭Njҹ5i57_z*)OQ<j6D.rZxp(*Y~Q^bE#4(r8xjk#3RhTP,NJdUZğo]+BVW麗 R?68\q$OJfGVJ[GJ=V`!Z8YuygIGKķU0xJuZ Y$SݧM`dA)*[01zLa@cH+cPR(^C +C&lla {az-}#tɮ)gr]HO`{pM- )3}옍wnM%s,?|m]zP.L03b*#tB1CT Jگ8 o [ykE2%x;VΛ=(SHa!B^`R +:2bƒ o[< 8 fV\0(ʮK!˘`X&3g]_a +* h)ڳW`IHCJu! 1aړжop7de#}B@" P61,+͖|ؽ*+3Za&\eۚL\Mg\P +Y`_2ˁ,S';BS3ήFŖ~qrrVog֕Ks_qT͌j%U O7vs[?i'U냇s6V +cSo$!sg;2Z@@c=}]R8/Rz?8iy`\trT0FlSFNFfOÑnct5 +9Q+| #pbF%pI3Kp,t'x/h>7[Bx[:a51:QF7kENF藆z=* ?[}QɚF_SOd1CWeK|?% ?XN& +N0IQrpcuZeTu",HIrOUkvJQby]\Bkg=ݭ0fuTTPK vQN ?[a'"OmR*S`yJ^'{yy Q.aViN.fj6ĂBj?Ig+a0 -Tr.pd \>i^M%vI2Lra]W^5 ]E{daj)q9N:ʓw8rܑ3Ɍ1նc9'!+(r{$hy9^p;/ZQ{Y1|cZP;M[JI1BC*-HL k~'/a$qHPenKmqh!fw~TH5 +-q+ VRq]0@,k˾+i\"e]{p@\vEl!qlV$ g_0qcwW2Q qz~-^j(|k4ƇZ|mHKrrɳru͟K +A' *xC*QAY,~ #i(1. iˡ $[3F2Z ^!N>[M.XIܝ$g~7BV$ 1JCέ}|y](81cOw'cse϶)Ųa(*y0Tl99)O)>]~ #i!5~d(2vʅ 9H%zS)C,kK>~H <9WPGA֎m?&&.k.]ou]]-!y\R\xbvb,ԖĄ]y; +>N+߮uOכZS`PLqf=-|`3,Zp2AfjEwpVRQnZ!<4cDpP#AEPX+L̩:OB;!tuԯ!GxTw碫-VJnhJVr0m & c0ctdCzJÁ}BC(ga`PRV3yc1eiXGh Ƙ4L2GbI2*F3FωEydr@!ъi"i1>"{0VupZ6n?X/.WՊZM[o%],7>$8-߇Su)FRV{gf)R7NngL#:Gi7?K[4NgIgxAvNCibNӍ i>]z9}vBsG+GQӬL+m +z1ǩyV$SgKqFWt +ys sR~dNӍ-i3tJ:ҝotP5Z.p3[ӜXM۽ɞ"o,F뛉M&]['=:CP5&\qI"ke&)zzWHlh唣A. + SgU$^zU%6K' *O~z" oRcVzoIF4PIE#A kn!A JKL3vЫXG1)d9luh`*SbX*c60{p}f$ EW✶Ű oYu9?٪>p\ +Vk JLeC}b~oSc` ?j!+K,F,oǞZ etD*% "1 +iSiCj̾dL$G?O&hd|'f[3Z (pn\H `XAïN8TҖ_:$>M6`m.&˙/_Db1~~yUfJNZnDwf4־`߹e0\'lrws=͙v$ WͲ0=>pxB T!YX.޴vsIlF jc6Q<:AW/&t{OڦbX@l7lBN:4U ɨdsv&ؗMG[}d9 ;%u3U{P#oUwc1L_6RSkOj jj!mBM7kY\+ʿƁ q9䄸 0 :V ^M [d*+I)p[z̗ +]|8{IՑ +D)sVP40؝{?! 3vddY|B$ό FH2_qׇ!f>ǨkX "qP kHQſc ^5tY!sVKaioJCF#C3f 0D|$vO`NLdnX6VjjGn\HD!^"-+{ˁvXp3`8+R<[)Q$5(Sy,\!4>U7YBLøװOa1s ]Kak QH)AV7tdxJYgI:yϘir,TGh[Yl%MT;w%:iY!;ъi"ds%. $iaX(4?;Pyb(/1[(\i"_A/$TޗXכ XWYij!c0#[my& W%yx17I& 9\/ _z -'푃sӖ0dl]'Pv4B6V˰m2[,*DOi1k^.v'Tҟy.]u{t򑾙 jO`ablUOOCؒ7n)쾌U]?3ֵƅ2Yf~IYBb+.?C)3+Wi8P}CY +[בyɕc<[ZK f"$2Cxy_/KUCdD.Cq+kFoZ^Oj(UASʦٱɍ{d9+j{+}<\(o^5C۞6q+lXѬ3GRhN[.ߠ(I 7* eF>OR+&yǁM4ov6Hi~J4(s ]Te7v8?dGt/n@ Αp:PbQXB]Vⓦf@!yY+hW&j#i-tRVYjMA~:_B m4G"=JH)t,bn& cUe +抉{M.v]CnoU=5gN.[i@[K0ڀm׎ؼ_}ٖbE'cH<3+-*B 8Yyi\ eP4QWҖZxI4p=5R`0ȋ+fUWSFzHP< S%PiM4EjXTYlMZЕ_Pif0+J/4Z sulIJLn;ũ-MBy:PL|«BPL1 v E0#xFWuGN [籱R*_;XՓ`.bujP,CցSg𯪂8_%$1$,38S~ӨӽjN8LQ:1R}8a OP19 +@@qv9TуpT8?_2fM;}}w"')x&YK)%/:5N$Sny42O1&(;>a #rJ*1,?,tLTZ^h +iA|R ȥ[XEr$U"zBtWPHA_$/T]u fjɔ3ؑMg].L+HI3!@~;w4M$/@."+IY>׵o?Ed^M1>y񗊫W\ +K>v&aqa!ͤʛxXJ2c:»i T*΄rӒc`ښ{a>++/Kdd%5 4"(ے7/ַNl*&n~Sq+~861npBvi)r>@u`{7`?Fy g`2Ī{ExO6"Wi,a:O`7)gzmDW2B-ga \. ! +9"R^ *7o1e!bqhpSwP a5f.VlGenZs6X/ɧJQd-֨&1,A?$" < +T2RYW c7jeipM!F ͅWy㜣G83b`n>`?/Q\ ,xAmN<I,*X +v闷>e\iک8I4,d*` (@&G;slA>*b6rEfD(S( ٌQwocoMfjPTf%u8dI|u.VDh#%EӁe@zxޤCN+Yea/CH1D&\9l#&jȑx0vi!\ $3q 9K2lsJ Bwl`Vz.+g>4( +rx_*\+ȓ휻# +fcR;XG61?N(Օw'~ xa%y@+.ɉ )l!Jmi_`GU W(!? `]HìEGadW^(ֻMXokP v{$3[- ɍ-wW;b)/cr_PyUn=ikz՛Z +v7:||U` +]6 +fK/vFHtʝ VBw|f#50Ss ڞtQժ`;Oaٿ{'ϙY#;σwu5Y#些.r!AC 1ӔhmQ2<1B?+B~~8/͢rQ|{Yh6W^~L>w<^fxCfwP4Z~AQpN9s cӠ.Fn}1bȥdpLOD/{w3h1j̈́v1X%hOP&{%h̍>J_Ѧ|f;̷9n~}Zex2{(?q);Gzls>!&5#mYmI%`ƄiJ(+Bj:g'P]n"xr67nP>=EG+)*¬-ILzǖFD@̴E$ Ug[`!gUB:c̥^~s6wxo& gH>^Rߪx>YPo7&4(y{GPOٗ{[]/x/84<1Ҝ) xܥ0Q'<4oh#Ͳ +7̣x?(„fQVz,6JOEqNj% EۓE}h4r; G欥pQ' +J3j{W0α%)2VEiVOKlJ٨%a."&cyk!ym ?ad Q"Q|=-YkW&Htm 2ˎq ;s1_{S~ lnS\d=Ͼ7ZyɹU)^g6 sGʨxw.oAr r^);-`xymXc.;{ Xy6J|{7JYv=*=U35=W5btKʥdZuY?NFM{(b ILpt`_pi44.+V<)jKZEz?0TPP{Xt[ ">B;"j"e>ɠqs>D6YbZ:O*2l#&V*L*׳O:zj!avl#]hCs+My-BDc z5~^.F_X+c5JR~´!!x&y.L]DN檳yriHIȔ!DOZip fCE| vEqlsl[/ZRǓGj}؀+Ag,z0b)Bftp[pַ{ #8N(٧U>]P6 Jd"&0󥛙ʱs&E *K 56l!>B)PXͪuaɳm؈(q҆;JH)=;h)]>\ٟap=s SBPMj|n@4>,7 ]IX*׫ 2Y; +&[ k o,~Z)c2iq7498|,k0^E> i9K'g%$:n=U =*~\"0,W5 Z4`=UX|fzd?(ެq殡)(Uc[RQM=Y46Ç e9miq2 M2oIh.#J8/Q6 +ac4Zc@$, ~rY'@k=F4n|I( +)yڻF K/WU+e"UROЈOŲY vwZ~*nE/ˍmc !1 Rr+A2Mwb 82 ur'ɌkZ!H1t`Z[SS3 6:aб_YR~Kx +i4^̊? tWm'_L߰%Z!]| %ѥ'ٱ06&՝ahH`?UvM>ue' @BJZbJx +@01;#Mw}_)pFSGɏ$H*XJLWJ'{7d½4w_QMoC2qs\(w +d% 8d[-s,X*?I +d懡:idMhz[0ЗEj8=TA2ʒ.>9B`&*I +ޒДXҿJ.Hd\' 7tWdAo0XTL&3m4j_4o ]ΫYh[걕#_ө5b Y&`fBK U8UC>[+`k}Ս6iZ8wJ:GTERCV{6ҜPdKyglsϡL6{d~ߴ +E_=|MA& ]Xeef/K:@lG:JFyVȱH:$Y{I:{Q 2"P~ln!B{X ~Db 5 Uօ5w<)(M<{ABDxVk1/2 Bi<$:~rXC{|2'5Wc?tb bò]%#j b +u1#Pq;.ٷnm*I~axxP>>kZiDt-W)$Dm `VaQ;9L;3$бpbhf_-( FVteFs>nKtOb;62Fڽ6rf !5I?\)ջ@Ȉ+.1? yC endstream endobj 1106 0 obj <>stream +HWZL/- $a @ &0$3}T:d%ԋ")~X +8j@F})[@`QJ1#*[\;<28GiG +OiNřYH +2ֻ[Sz18"yQ1,nd#F46UFkVƣBx.L8[^kpXdI(ζc Nc5g!N}Jg83Dk\r#+V]#(18Kb- + M>QL[oq&땁X-iDC`(K$CqdWQvG +̚AXԛtł*SA XhA? )`Powej؄lrNFTʋN !XMx拪Xl{1?EAI*D> B |1ʙٷBLxnUI{Z'y'X{G.Oz%1̼OFlca6p, 8kxEKxFV:` IܴDk +Ͻ-nw;)+/usa Gs14#?u^|FNI%c(&ÎJe{ϑ-^:|FgeYt& 7Nvv˘[Wg!|#c Uq(AfL|`H`Ծ,t*#r.a-`L|w:(E:aer_ܜm[`-) "%G`H{LX +wVϐaT +]Hǔ{)^\ $Lgzj$ sx(q$/}V +791 ͟lF{yXUHe-7)xOauxHOۻ"R4qn[~T~ %<%Ej/QߟJ )e ߸\i +s`?#OopKR~z$]$|mz&\&!29*0 ĉvÃRT],]l)"M6pKhIck̬GW0{1(\xJ]:/c;i+Me׻S@dF +`9v ߖ9o]Y'XQ^k8-"]@TҚs뭻waid^hL=VnU'Y\&(ޫ)^TrIk 0w%r~aoC|)mJ~܇\X`~䝍&:rD#eʇ~ܧws =җq~?:rߝ"g g8!EmwWkIw +SաEû Q#jKx/w>|m0N782r} /v4ي2x|7YD & 0@Ѳ~{1HpCϷ]wFtكϬ, MpOөD k11$!LvV&-"kx{^ڎ2pFXD  0cAM ԾIUॳ  a+ +^Q ]И)_'{%㩦S4vRNp3cyOGǷEB~LiYj;.q1& g=UK4ـ>AscpiF߬c<%Tg^K+]"Iq>kQ4+F<`=|9 }yIto`ήSg/|$.?;*Nub`nu)2M1~_pE\-14:,OMG䱏lm 7R-An7 +j2P5EgœIJ߬^smōGp`d#o"֖%չgŻmB)?Rari4 lI=iV҂*_e;12 Š(@u1 +[ t4Lah rPC.AC]] $;`2 RHo|rͮ8$/6 +"-/з7y-س]'M'\!UVgBK m +iKL_O\_xrl +^b4ҵQ1KA\b|;ګ$nP :0cgqbp<(0-΍ŤA'N~.MeGo`.W$~Pl1Br0kJk䥄JׄbRAc$Nz=9~pVO(N8ύHܨr#=WnnN]uSrTXrsMIV h Xg6% ڶm?TX#"}r㫺T AbH3[Q_ut@":65R ?ŷMg#4o$C·!ؾC^k=ɭ&[jр 9ߝV[|84PxuS;)Pd?n]kM߾< dhC==[Cm#9|.ST_y|¹mOK&ioʥX|^o]7F[̼> ,+>]) C͜=rrC:2mێ@3S ȲXdMEeqPsOLOSUQЗYn9(*$peЃ⮱Pn1. o^\6iI,Ko71i%D<;P9|1ޮbXO+ o^;/O99l0!Oov/2tKҫi͠6fM>H"O^t?gil$07:zU3zˁ*r 5^[zUZGu!8w=ՉW*0E %7q@ ;(J{"yrsg=~wm{ڊէ\`^6)ѷtYtZz +dT [,ab-ks?%/ގs̉@x#б1G,Y`{3=~FFէ fg|f"ę!rd_>b}ȯbC&)9Gk?iZ{Sr&-r@킘_3?d#)gmWևqfa==̿ g̾`M~\>~/lm4tX +պy,Z&͆`N*Xϳ&߮@cP8VuIglJ)L^, tdT9&K9"E_摧nٖ҇1~j%;BNӺbiP\تQ\$mi"& fOQ ^_Wd.#-w3Ʒ/ ]!IpdZ*槀|A痪}JNowjsEiQ)/mj'GW'/ @R6g#d/ zw"nqZ5NNR=d tzB̏ ]MQxʻnY'INĜ+pVI p*8g~>s^V:X[ܴm !x|*&k. BD1uh>P%d0ٳ2IJіg8ɾ@N&C r +|8QK2]&Ӣ-V Ww#"<==&;}H`UɅ|& c5krɵ"'\%L|!;,š}OXJ/XV/c q 6aM`.wFŨ9bI1-s. B(V,fЃ2,_ķ|0 mn~w@eƝq֝?IƈH]֟xiM>#rӯ&)bL[x,=IBHçXKSN֜wfe@70x  +g `r*xIg:̊^{2_Z_H~w2pٹci^B[~R;LuFqiY"Хj^/Y2&i#]֋< d`yb?M\HhJFi^,j$J H]hZA:]ʰ厡h jtC ·HN.L-&,\m"+iHdexIL}X+Z>n 19ܴS* %[+*0km<%A9d̚Dѵ*_]M wq70HB?YY f Rê/&U $,e+hm +D< 1D\$J>Lrj!p_V>kм|ZU\,AzKMd'H.&/"AD߁EJcI7[at0~#Aha)mg :|E7-/ZcfE~}ժa/=Us^Au^ ^TO;! .{0eD9p#?Y(AX9]vs~Oe%\%}bo=z (?K+D4qiУaa*{4P㦛L#?>.[jc!cm4 ejV%.T8se-(7j_0.Z9ShpB -ip}+-e [?$g`^ϒy %NQXLV2vꝏBKW꟬fTR_ג۬CCiecB1_)Te}NH{`9e zg)2l -$ +EsA!bA ^#;u-٘{Q8|p@ +>0#GtztG;jc~*'b~F@RyØv`ţw!—g8~ Ok 'l8.{k)>d~:8:5oeͧwaA(fpE*]KWEX828JY̩:&vZ4+;_|Dz;Fȶy;bHq)>Ѣ*JWmj_ &SrVhqc: +-.J̭݄*ʡ 8:<6]F e TMp UG)'hOW.V|zTܼpD#2;\(p7i~vg ޹vWc /~)b|WdkÕ*OLjG34V32{:.lp|0oq=V`LLFOSbCfIг>b7GG f;<" i,qz0 + @Q!npctmB~!#G*0Tc]4PhH׳^`+FT76"gubڐ8"BG +*_ǰʎ7b\ +>o +o.:F4}nI3JG@w˙y֎XuDv序)*m`{ +휎e# SD'H3l# +Dk94NI3Jg i܃8ws3\"|(ddPl9Gq+KG`sP"L]CpdV,MMkYNJpֿMؕd7HMST66kD)HJ4@P=R=ޅv" 4 mBCup>"}%D:Gh](-uZNͦhu' -,G7ix[2( +{4Vďttl #Mtڞ0~TOtao/TB~濔sdf9(#kuv)<*tO#*b.Q-]l1x _k_f $zԃԌ Pm' ޅی#<1WNAZUe2y(Ow kmIE1o_f$%"40 Zsa,BC>$)9갞l/.t>:I{9Q2/_\<>2+SL[4%Lz,I >Ds#+zC ϗ4?̟7T_;q[u7au{4//Ja6$Y•faj QWvfe"ruڂ[W +T|C[1@?(v2oDGL\!^3^?e\Uf/("ꉤ6OYl8. +ӫ0t3x#+4;4 nkjUW][,szCпVI!cI*r`d!+ǣS {#.e>~0Ѷ=-y j aNj+ÍXo Nt 9d֑lK'6Uə-棽WO5kMgl/' q[􊼒L;V6o:,ѻ)K= Y}3_"!KmFEM3AcNWU+B(ԝ09t~ 0A|nÌb8T 582uǞ1rMK~]cy0y|}%] 9փˇ1|;I$K.i9<+.Ms;U/J5 #U#b&AEg [*JT4RvnR)%^={:.7C &,į[MV=Ub89[M u6 `+/dJxsy)ڃΩ%(7jT#N2i 2㢙 nW\VI;0Vi ga]x\v~.6sgr͎]d6yg]JbvXҹm;U Ј叜G໴'`ڶ`Yky{Z +o} E0i[`5~(Qa}]Ɏ*{z7Q[cUbXϞ\d/k|"1e6p4b1vkIBf*0?Js kOG">1igX$%|nOw? + @CHy!MkdQI3Ȕ)=EG$`4˝U=Om8aFR)m%r?;G eVRrt6ԮH2vHO[\jݭ1=M:|QPʉQS[0_*U.noδ+e؂e/A^cMIoU%_ֻY zWz7JmU_a-QT,f/IRW'S8vzڟ9R59.73#XŘLog c_rtT7b*Q#TWGV7w ˞jfz4§N՝_ ZVe*pYh+B!!k) H%H_*.T(AgOh;X<#c-v|9v=ay֥d ܅2j" t\? E:O\_m=(xFn.*ڬaZ3 *3Z?7b*3 [zXoMSA9r9krûN`n_|6T`r/`; ~<8xϕFCC~i_mpFw& }Y@cC۶74}F*鯖(, 3Z䛾}@5>:|i !$cnG]}~Z\kYR68NpVܮGr(DǕxhc??`*rΆbMe~,Dec-k4Yc2\* ԻsP^UPZI0|5$Rpb D̝CLi\M'72%JZ d>p?.UA?w viytT]Ԕ4PPOHȤnOg)_@k=nudVi! `&ĎF gꜢayAξE\۵!݈Xa}e0B; tL*DA +qgLGs0&@D>bwSn&@LV|x0[u̞bd\dLw0d^bbpyG>hBy6@_^d8NvD.!#Rg%h5o 0L6 C%RnC#z40S'S(_zm&h.ݑCOCQrAP3\$;fIdQb1%@3:4{KV=iie+"$ք$l" + N9:s1K-o}} 2Vw9ЁnMm~џɰ~@`"ErebtcB?]*vp8nF'bǃY=Ӻr*3r2L\!+lٕLb;.-nj!(lR +zx?ya:B-|<$,jBߴaG_HF̾f/~׉8Ք6A(L+3TY9VLBΗ +ˁn։Zn,WnC SŞMfbcQzXBR(ƭY>]6|_5N*(7\0oNFRKz]Zvn-u"OA4aP Лb+f_PMwOj'"pL+ۜG9뮓eū мÙHL:#N&+tP{WvarEū-zŢk  wa2ťĮFG0<~ٻE8-ֹdFcE2Ù+._ſ czuԸA~X/9m]BG>+Znh8.cv_$F˭ֽHh w;/P @r.£ϲ́fՆ{@3}{C^1>,Q,7RO8kdRkTvC[d#V&#RLl6!^#OF^m ?Aco(چ+TIQeʨ8'#5?q(2KMp.^yݯ%msRB夰ǧX +X,}Κ#\5G5mk /+;ְth˚_jckm4Q$AeCKF5wX`^+x2. 9rߪkX*' sČHt^ ٚEG"f~7gJD^<4* dR +n +L%QOT{4Jiq{>Ir|{ʈ@r*9CyԊWqy۫炂Q^Z2pslӕ%WmU%'Ԟo6jkg2h(L>ErW+ |Q|ŸX?G%yl!?lFڐ\v4G@''JA +V@+g;5uqPxQj6 +;y +cZ=>ޏbb].'9+:, : (:,1T(@' ;E)*%Uѭ8@1jxR$#KcN@ )‐yQċGNL ].x)]ğAtuN4;; +Ǯ_4ݷS`aRKvbc_C 'CqYB%L&LԮj;XY6s0;o9Oyî2Xcq.3be% +,JptA)_lQD"o8pbغ8ܾ !:bJB/L)Y &O~`tNOx_`+@Guj[456dδ, \+.Zax*JYwy +3+ϓ. t Zf> '`8;QR<଼~ ODyBq'>ŒsKkׂ ,q-Ai_y'gnUdH |XG +P'X)IPPpI_Z\@ײ~|!bę[\A|X*?8!Pl?%.} _F0ݗ!NE}i|e{nGd|n⿥WlH|| )v"G$4rx&|aEZn} )&%v'{WƼkhw󣵂Y +sέW0;(r~UE!Ⱦ;NU˫͖H +pCvU`pCT3h9'c᷆;9cW+RuW]8\$hRI~he=vj&S; k z YA +ĬPagnEOxXɛgkӛA:Z RK'EW- +ϾpDGpm5LUfjiXX%FK ++/ +G.'ńYm;sԮbMZ81;s A8eդU"F9/"m0j\F],D:el-b[DGf΂8_V5oռ9<:qxa$TLjysA8rA-^58P룍Ayȯ6]-izPEܘ2[svm?gںH3w{lG[ѩ5+ϻÁ[7p*SB4ZnSvлv}*)nrI6nWm)qF҂K"T?zy;zz]ך'>@ +G6sN‚^%B#9R#kuaSK4-s$%xTV5)+`Š2[>{A2yx@LK!GQL4C2pQl^*TC՚2<^o,ti|~_⦔A<}qS 9闗R涓/l)t`uE/{8X\s,x{,JNSa#ԝ~ܲku؟SH.vUFxx +JݖH貴U$}wwJ"\3Lp#aˑMÀℼ0XOX3vvf^̭I׶òzVi/%{zZQ݈9nMyK2j́F7ZepH};)#H 14^o\ +`א=\ŽK )hXg.yļܱ}dpRj?_h3x2B 묙$, `֛W*ͤW0im0y. + DjŇJQ|/ok7p;RR~OotoS*Bwu1.\k#y!rx_QxaqBea4< kV?C{7B?#+p?.3^ã~k: rdTT(9JDԅ'C8GQn8=rdoZ eN ǩ@}r{8Va(9x4mr oTn -Ox,Ȱ`Y(7Nƻq!nS-O%UrcH^ &Tn8OȑP +%ZU3eUEiqPAG +kz*8+O!1~:^7UD]>`L_Pb! j9J,l99_i~zz^U띝ϊ8o[$karhqT'Pφ >֖8twDzȓ1F&m3LQ/4]=Z $S蓮iZϡ"J!c1h⁴$x&2iO\XLj$|j<]w<^NL39}+O2[4Nz|YADhբp]')B>NAR +q~7qef% LћJe5H+w# DR(H-;ljj)̔U˜Mj J7pLv0UR94~)MOS , K\lmgĻ27)"8 FjMF_ `FaJt8sY6gzzیfas +.ʟW&hOvXf{ݕ3ҹNԜ-\QOB_-:~We#ԚSV.]\يw^hcj\]ҙŊA[1P8axkzM^_jw}V p}xnNbH28,t +![wn4YW'\/}EPXm+枤zʩ; |cr1$`C8Ӹ]ahCgt\<KR^h+/ (O5,bv]1ag閃Z],^X(i{wމQ>_ܮe<ע0|\J)IB( aPDErgu1.I(bC&%Qy #2< +_## /+T4oPoh+ r~z)sk)<>3Mja7Z@镯<S6ceHLyX,M CF'܅44C~@JNGYC$\voJθ^͐졎JGv:?ܝ_$P0 GH@8%RZHPh2L16+&7/"+M D%EI ^*zXE"U@ltUdMl)C؊EhS5`T- aqOg tܗ?_.4mRPWҽzUnՋO^_S!z[;r  `"d\rӵdr|s{S7Wg +`H}Cd8,IuIJ'NQ㺓4$N˓ȘY+cY<#\㌸P`gi*&A0ڊε '-eA2:ҹzg`+-7!2gs)5}Gউ1zO$-FuP$'H>TX6AϟrtAD– E ;. 7%Gy+wFqsӾ}#aK (x$gKWC>L#k˗.H¸ PDBłN3XqP;[V5_(V.W~h v|{Aࢮn#(v%}z$i$"gƂ wgҩ v|>lYIw4%>t%E/~4_=pVɵ_s^:Xo۔Y/ :^s}[]ofhFk2.iyw"7G"D$|0UH Dm A/|7~Q$@ % 92-X再A8I %f9vZ"oŒ +0~͋-i庒P:UZi(W3 #PZ4.CJ+j)XVzڨT%BD~%=؅?G@([7W*c]b>VR]yzJj;nѥ,E"b3NN3NAKmᒵp%.:l RohȢ' 4xeIc'P?N"CRߟy/fKYcS?t,0'Ƚ=My +RMwKy~6k=ЋmҔ|8R2h~D>Ӻ?%1ΰnɛwB]åtWs 9=v /dy +,0BA{GlRL d" +3݀)zo2x קּK\\f%N0N÷ Ictx@-w݄Ҭ aX6PVoQhO=BWXecš୊%5y<9LMxh-19)wZxP^ +nJmIPǟ92!u1=^&U1[ToBƠ@KAe *xng|gk"hj(ESFo%kLO"yYLX\?P@F6'[DyfĨjgJg"HNR\ 5vfZʶmM6{uJI`vu^/l˫ :!AG[h!ha1'5CB}EchCBff#lP y|X ^K{)~)b֢y)=7w@B )Rx;' `q=gڙLT-(b0ceYVУ=l3?%BO @^  +jU_veɶR*V|Ӣ1,SF6w"&ԝ*1@H%0WҀh#OPNԽ9\vMdD ϖL @0C ΄1Lŕuj9E~lV7Q"L2/GL0MP̛R5Өl[/5bS[" F٫087^=f(d2RB?Ëgp7-I2F6Zmmfbjh~Ǽ&Q ̭,1YZjZH@ѐ9k r\0X{BYNO4]ҐzK^ؐh9%/lH-NI-yaC"N>%6$Z/G[.LD7'6{In<5/-< + ciT +BMtM~Py%4-^y@ %It9|~5e"nUYBYwU?D^8Q^,a8fThpPu399ģTmtLՁ)3D/9I nIHh?kTO{mN_bYZVS 8?Aqll{t6h,.|0_W& ڡzu"&ܥ^Cqlû a{aM}+"b vH}~Mls54PΜ <&@@nLfNZ9qXⴍsȌ{91tGKSbA4,/}n2@!W;?yZnb9\hba9;cMJ`;g endstream endobj 1107 0 obj <>stream +HWZJ~B!; @ž&8NȢxt>0:j F&ɒЦiVt0V +-2r2ȴ{t)KÕ Z61e)Dٚ4 xPY0%`ZA^t} O/5#VCm)ndi<2y29wUpXl{9\W1$7߯^],%zW·9HHJD=$ut>n䑖+V8J)dT d2[x5PmW;nOK}.5~ee(1Bϣ գ]?ӏ*DepY|58>%CwU:0zV au2='JGJDRIG_Y^$YQJH6`A(*% iNrjX ÉՈ%p0[OREi9ɍ_*eލ.wQKx~Ƥ<+ŗC>ɷJu$nOCJIS!:,- 5*?UlCSK8P&O+Mӟ C,ZRk!* A{4847+ kvAfsq$ŞvUl?>l>n?,){L P)JŲ[wy) +8x ?o.%R'N-.,RɋB\[b3${Az].ƕHy +K^LCzׇNRa|mKEލLa~lG#;= rMs.RΐP|Wb>$c늯lMwJ]ƀS"O9D[wR +98k xP`bKLM8C& zB.r41vqDC?srqfip )Ui;=f V᝙mMg+L9uY>m{4^g !~Fa%Y":#\ZH4Eذ-ċorӋ̖ :f'iY +F~UZ/ -eo @)S[P|D + PP=K7Qap[/!&%Ԕ+J,`)CKMˬ +6Ws^'"9)9W˧Cʒ|ɼ%ª.5X;VbomtZ%,]l)o K@|` +_Fo[uKL~Y[3R]i{S@Ƭ8:t|՞>Tb03E=;K VI"^Ξ%79t[6%:~4z785[6/xaJ^LIWXȫ0xbQ'<ڻج8JtmҸXraPuH'G|`,S49;s@]Rҗ[?_~#؈ڦ (HA9J8v>^*!Y*c i)xE^oc lV0!<XU@ѦPz9ك N4QN1` +9g&n70} yw⌤6r"*EefS1:[bފk;>i*`ڠyI6ɍ=l[Im@:l(jTMkQsts+ +O0Y/_"x?ӪDAzzVx8=,BYqz(W\Y!ӷ{xga1[.lqq я*l+"Ycүb)Tgdtd#-&+LqP#M@ZӤ÷l%i]M)yNG$ٽij*tY|x6ߊg/B" 䣳_twuӑfYcrsTq JPc-U LFYTF?EhP1{s>kN #iJ:!YRKBN:UCB0}DH!$A!e=!?%$DhC'$Ccs e +S~62BQ6U˄01]:U =6݀InLrT׮Ajq 3lbN1vOQUnslLMtV :Kp' /ߝߜS: AA2NUQ+M6cS(W@nkQxIch@wI\+3T؞1ѶXf7̧Sh+ ةYH}cetARj縷& +!j6h +4V$Ϊ# St %%,՟ڳr̾UА;r.OTRK_ t(ЪDݣ;v?TQM~)Q7=Y:q<(=y@^ +dǢ/|x_P2V5J-v +yѿ-f ]_H^='`{*̱/Ϟ%ob +|~~jWŷrX됼<0$~=UȗJ-${Ɠ2+wڨ& 9/`WDzSYPW~j>Vz38 z'%^X&TL!iW͌V6hNKze$|KA̢bw)[/9RNJu|KŽ`Uj +V*.b2]fWzFRѵϾcJ%@Nx^<Ϗ#tQ)\EfݏY\}Zr+s̼.L +rƻEQF}dbw0-kz\͚A4Ymj +tIX+r%a@@ަՒ2Nw,"#5u*/b!- +SWm$>~_M"n&b%~YW`l^H4( FU2pBUuϗh9%C/WzKEɅlKUR]D/f*h7q}H~QrQKn*P1m[aA/s9۫8𕜖$e=枣zvvrtBQ֚CP NC(*f:4~9VYf3VS0{ɖ/]z4W2封՛[W nW<3vC&\3كR,{,z}GPXTP@7;@oOC?tI0C>]j3`NM;\;}`Ad +"56Up} }L3 l +JaN|IWuWª5խV)SIV3;!0Yg}y;(}%P!b9#V99+/zW D~vf?묔\pOY\ɩR׆F GBr֬QY hOk?{"KT ı3T9+X} +ko![ }K>:ЋvqZTsk3 sqep |_[:hO}KA,m O1}Bv3u!#L>ib:A; =G1$%4AHolo& | !vji`MY:u2x8QLh4'B r{<*B +?:c? +OCdpQjX1 %_ 3ԃ! Oԭ<T?o!Z~Ī ~a8vԤ?ecB3ЋYˆ p7UV ̩3˓|e X{Kf֭#vzބƊ#ok{p-ߧ߫zyY{Y}L'%[z +K.*9e+%~g(?:)UcW443Zվ±] {)~ԨtR#_L#k#)-Hhn__tdhU%lG+?W&LcǨ*3%=b0ͬWK@f?ُLؾXWRUITQaܐ/'a=n(֏}gFNØQihXown +nqө: M'dx{ 5Wu/tWv77͟^党{Ώfy?zEkc y->|<[2;bzhlcӟ>{-^KX/ܙ>{;:|ɯ'oΊd_d#*C{vPmcz85?x P`sC}xm FwA3V齊9Wo3ЋxiL5uOzrHl7ZM^9~m^Y={1O_<[޽m~&he4lx j7rz7i 'q/nTK_McD(=2SCC٫d}V٣uLk/Յ~Իѓrg~|:[&kkLlVLՇmrR5hDM0-fhk9;^guzNz?AaG)#(a|Ǘ𳟰LYVh|`9U;8]L>8au`^!:LU2=KO~bȸPt.֦Q+PAځ5TR[Er^^D0=N#q"W@eb`78:<'RQsjF6HImX:zNN@Owg'+x`9_\7/Ib0~-v-T! -[&t l¿:_u%A:ڞ~?NLn4p`BP9 +V:E4ۍZZH4P;P4B*DLAdc[|L?Wc- 1Vӌg23q[ [1)}^0}T3%n^v-&_lEx ;V$@8*#u4JU0vl=-a[L23nV~\M7J˷9KU[`dLfLX :`AJ#`4[Gl|o +1^/qZ]edJ6.s6Ɗ2֎mfV}=*f\e +AWaUS0fZSj6XcH>⒋\oOvjzn"=,?a5̳\1Y +gTL`B_]E=[<‰wd0ǿ!JrJ:xx*FwojuvU0471XA6~ a+KQ vDX=L;^al+V~ (׹Kl-Uq:#茚L9EgԎNƔBUpBg'f"d,ӹaͩ?n7d*FP QQyͯ-pe*.R "%o0RV j>@%q-q@* 988hF :hAu8h8ЄE48@%# +Œ"b-DDDluD2 +"9D >"%Q{]/Z&"LQ/VPVfVS^KbkuՎmEuh|$G^L}þao{ط=m}þazw})ҤhiR4)Zm_Rt4):M&žFb"9M9I'I1@E8E$ @%q(AJj;@GVAN(K%}Kd QDE*TD @%q 9d*EHP@TR[ȁ&$: P PLr(r`)EdEdEdEdW$+Z$+Z$+Z$+Z$"Y"Y"Y"Y"YɊɊɊɊɪHVHVHVHVHVY K"aSK 6gjzn"=,?|0OD)5̌1Ѻ}-ڸ58(qȫGG[^-b:}7;?Uodz|q$& !iJ+ > endobj xref 0 1130 0000000003 65535 f +0000000016 00000 n +0000028251 00000 n +0000000004 00000 f +0000000006 00000 f +0000028302 00000 n +0000000007 00000 f +0000000008 00000 f +0000000009 00000 f +0000000010 00000 f +0000000011 00000 f +0000000012 00000 f +0000000013 00000 f +0000000014 00000 f +0000000015 00000 f +0000000016 00000 f +0000000017 00000 f +0000000018 00000 f +0000000019 00000 f +0000000020 00000 f +0000000021 00000 f +0000000022 00000 f +0000000023 00000 f +0000000024 00000 f +0000000025 00000 f +0000000026 00000 f +0000000027 00000 f +0000000028 00000 f +0000000029 00000 f +0000000030 00000 f +0000000031 00000 f +0000000032 00000 f +0000000033 00000 f +0000000034 00000 f +0000000035 00000 f +0000000036 00000 f +0000000037 00000 f +0000000038 00000 f +0000000039 00000 f +0000000040 00000 f +0000000041 00000 f +0000000042 00000 f +0000000043 00000 f +0000000044 00000 f +0000000045 00000 f +0000000046 00000 f +0000000047 00000 f +0000000048 00000 f +0000000049 00000 f +0000000050 00000 f +0000000051 00000 f +0000000052 00000 f +0000000053 00000 f +0000000054 00000 f +0000000055 00000 f +0000000056 00000 f +0000000057 00000 f +0000000058 00000 f +0000000059 00000 f +0000000060 00000 f +0000000061 00000 f +0000000062 00000 f +0000000063 00000 f +0000000064 00000 f +0000000065 00000 f +0000000066 00000 f +0000000067 00000 f +0000000068 00000 f +0000000069 00000 f +0000000070 00000 f +0000000071 00000 f +0000000072 00000 f +0000000073 00000 f +0000000074 00000 f +0000000075 00000 f +0000000076 00000 f +0000000077 00000 f +0000000078 00000 f +0000000079 00000 f +0000000080 00000 f +0000000081 00000 f +0000000082 00000 f +0000000083 00000 f +0000000084 00000 f +0000000085 00000 f +0000000086 00000 f +0000000087 00000 f +0000000088 00000 f +0000000089 00000 f +0000000090 00000 f +0000000091 00000 f +0000000092 00000 f +0000000093 00000 f +0000000094 00000 f +0000000095 00000 f +0000000096 00000 f +0000000097 00000 f +0000000098 00000 f +0000000099 00000 f +0000000100 00000 f +0000000101 00000 f +0000000102 00000 f +0000000103 00000 f +0000000104 00000 f +0000000105 00000 f +0000000106 00000 f +0000000107 00000 f +0000000108 00000 f +0000000109 00000 f +0000000110 00000 f +0000000111 00000 f +0000000112 00000 f +0000000113 00000 f +0000000114 00000 f +0000000115 00000 f +0000000116 00000 f +0000000117 00000 f +0000000118 00000 f +0000000119 00000 f +0000000120 00000 f +0000000121 00000 f +0000000122 00000 f +0000000123 00000 f +0000000124 00000 f +0000000125 00000 f +0000000126 00000 f +0000000127 00000 f +0000000128 00000 f +0000000129 00000 f +0000000130 00000 f +0000000131 00000 f +0000000132 00000 f +0000000133 00000 f +0000000134 00000 f +0000000135 00000 f +0000000136 00000 f +0000000137 00000 f +0000000138 00000 f +0000000139 00000 f +0000000140 00000 f +0000000141 00000 f +0000000142 00000 f +0000000143 00000 f +0000000144 00000 f +0000000145 00000 f +0000000146 00000 f +0000000147 00000 f +0000000148 00000 f +0000000149 00000 f +0000000150 00000 f +0000000151 00000 f +0000000152 00000 f +0000000153 00000 f +0000000154 00000 f +0000000155 00000 f +0000000156 00000 f +0000000157 00000 f +0000000158 00000 f +0000000159 00000 f +0000000160 00000 f +0000000161 00000 f +0000000162 00000 f +0000000163 00000 f +0000000164 00000 f +0000000165 00000 f +0000000166 00000 f +0000000167 00000 f +0000000168 00000 f +0000000169 00000 f +0000000170 00000 f +0000000171 00000 f +0000000172 00000 f +0000000173 00000 f +0000000174 00000 f +0000000175 00000 f +0000000176 00000 f +0000000177 00000 f +0000000178 00000 f +0000000179 00000 f +0000000180 00000 f +0000000181 00000 f +0000000182 00000 f +0000000183 00000 f +0000000184 00000 f +0000000185 00000 f +0000000186 00000 f +0000000187 00000 f +0000000188 00000 f +0000000189 00000 f +0000000190 00000 f +0000000191 00000 f +0000000192 00000 f +0000000193 00000 f +0000000194 00000 f +0000000195 00000 f +0000000196 00000 f +0000000197 00000 f +0000000198 00000 f +0000000199 00000 f +0000000200 00000 f +0000000201 00000 f +0000000202 00000 f +0000000203 00000 f +0000000204 00000 f +0000000205 00000 f +0000000206 00000 f +0000000207 00000 f +0000000208 00000 f +0000000209 00000 f +0000000210 00000 f +0000000211 00000 f +0000000212 00000 f +0000000213 00000 f +0000000214 00000 f +0000000215 00000 f +0000000216 00000 f +0000000217 00000 f +0000000218 00000 f +0000000219 00000 f +0000000220 00000 f +0000000221 00000 f +0000000222 00000 f +0000000223 00000 f +0000000224 00000 f +0000000225 00000 f +0000000226 00000 f +0000000227 00000 f +0000000228 00000 f +0000000229 00000 f +0000000230 00000 f +0000000231 00000 f +0000000232 00000 f +0000000233 00000 f +0000000234 00000 f +0000000235 00000 f +0000000236 00000 f +0000000237 00000 f +0000000238 00000 f +0000000239 00000 f +0000000240 00000 f +0000000241 00000 f +0000000242 00000 f +0000000243 00000 f +0000000244 00000 f +0000000245 00000 f +0000000246 00000 f +0000000247 00000 f +0000000248 00000 f +0000000249 00000 f +0000000250 00000 f +0000000251 00000 f +0000000252 00000 f +0000000253 00000 f +0000000254 00000 f +0000000255 00000 f +0000000256 00000 f +0000000257 00000 f +0000000258 00000 f +0000000259 00000 f +0000000260 00000 f +0000000261 00000 f +0000000262 00000 f +0000000263 00000 f +0000000264 00000 f +0000000265 00000 f +0000000266 00000 f +0000000267 00000 f +0000000268 00000 f +0000000269 00000 f +0000000270 00000 f +0000000271 00000 f +0000000272 00000 f +0000000273 00000 f +0000000274 00000 f +0000000275 00000 f +0000000276 00000 f +0000000277 00000 f +0000000278 00000 f +0000000279 00000 f +0000000280 00000 f +0000000281 00000 f +0000000282 00000 f +0000000283 00000 f +0000000284 00000 f +0000000285 00000 f +0000000286 00000 f +0000000287 00000 f +0000000288 00000 f +0000000289 00000 f +0000000290 00000 f +0000000291 00000 f +0000000292 00000 f +0000000293 00000 f +0000000294 00000 f +0000000295 00000 f +0000000296 00000 f +0000000297 00000 f +0000000298 00000 f +0000000299 00000 f +0000000300 00000 f +0000000301 00000 f +0000000302 00000 f +0000000303 00000 f +0000000304 00000 f +0000000305 00000 f +0000000306 00000 f +0000000307 00000 f +0000000308 00000 f +0000000309 00000 f +0000000310 00000 f +0000000311 00000 f +0000000312 00000 f +0000000313 00000 f +0000000314 00000 f +0000000315 00000 f +0000000316 00000 f +0000000317 00000 f +0000000318 00000 f +0000000319 00000 f +0000000320 00000 f +0000000321 00000 f +0000000322 00000 f +0000000323 00000 f +0000000324 00000 f +0000000325 00000 f +0000000326 00000 f +0000000327 00000 f +0000000328 00000 f +0000000329 00000 f +0000000330 00000 f +0000000331 00000 f +0000000332 00000 f +0000000333 00000 f +0000000334 00000 f +0000000335 00000 f +0000000336 00000 f +0000000337 00000 f +0000000338 00000 f +0000000339 00000 f +0000000340 00000 f +0000000341 00000 f +0000000342 00000 f +0000000343 00000 f +0000000344 00000 f +0000000345 00000 f +0000000346 00000 f +0000000347 00000 f +0000000348 00000 f +0000000349 00000 f +0000000350 00000 f +0000000351 00000 f +0000000352 00000 f +0000000353 00000 f +0000000354 00000 f +0000000355 00000 f +0000000356 00000 f +0000000357 00000 f +0000000358 00000 f +0000000359 00000 f +0000000360 00000 f +0000000361 00000 f +0000000362 00000 f +0000000363 00000 f +0000000364 00000 f +0000000365 00000 f +0000000366 00000 f +0000000367 00000 f +0000000368 00000 f +0000000369 00000 f +0000000370 00000 f +0000000371 00000 f +0000000372 00000 f +0000000373 00000 f +0000000374 00000 f +0000000375 00000 f +0000000376 00000 f +0000000377 00000 f +0000000378 00000 f +0000000379 00000 f +0000000380 00000 f +0000000381 00000 f +0000000382 00000 f +0000000383 00000 f +0000000384 00000 f +0000000385 00000 f +0000000386 00000 f +0000000387 00000 f +0000000388 00000 f +0000000389 00000 f +0000000390 00000 f +0000000391 00000 f +0000000392 00000 f +0000000393 00000 f +0000000394 00000 f +0000000395 00000 f +0000000396 00000 f +0000000397 00000 f +0000000398 00000 f +0000000399 00000 f +0000000400 00000 f +0000000401 00000 f +0000000402 00000 f +0000000403 00000 f +0000000404 00000 f +0000000405 00000 f +0000000406 00000 f +0000000407 00000 f +0000000408 00000 f +0000000409 00000 f +0000000410 00000 f +0000000411 00000 f +0000000412 00000 f +0000000413 00000 f +0000000414 00000 f +0000000415 00000 f +0000000416 00000 f +0000000417 00000 f +0000000418 00000 f +0000000419 00000 f +0000000420 00000 f +0000000421 00000 f +0000000422 00000 f +0000000423 00000 f +0000000424 00000 f +0000000425 00000 f +0000000426 00000 f +0000000427 00000 f +0000000428 00000 f +0000000429 00000 f +0000000430 00000 f +0000000431 00000 f +0000000432 00000 f +0000000433 00000 f +0000000434 00000 f +0000000435 00000 f +0000000436 00000 f +0000000437 00000 f +0000000438 00000 f +0000000439 00000 f +0000000440 00000 f +0000000441 00000 f +0000000442 00000 f +0000000443 00000 f +0000000444 00000 f +0000000445 00000 f +0000000446 00000 f +0000000447 00000 f +0000000448 00000 f +0000000449 00000 f +0000000450 00000 f +0000000451 00000 f +0000000452 00000 f +0000000453 00000 f +0000000454 00000 f +0000000455 00000 f +0000000456 00000 f +0000000457 00000 f +0000000458 00000 f +0000000459 00000 f +0000000460 00000 f +0000000461 00000 f +0000000462 00000 f +0000000463 00000 f +0000000464 00000 f +0000000465 00000 f +0000000466 00000 f +0000000467 00000 f +0000000468 00000 f +0000000469 00000 f +0000000470 00000 f +0000000471 00000 f +0000000472 00000 f +0000000473 00000 f +0000000474 00000 f +0000000475 00000 f +0000000476 00000 f +0000000477 00000 f +0000000478 00000 f +0000000479 00000 f +0000000480 00000 f +0000000481 00000 f +0000000482 00000 f +0000000483 00000 f +0000000484 00000 f +0000000485 00000 f +0000000486 00000 f +0000000487 00000 f +0000000488 00000 f +0000000489 00000 f +0000000490 00000 f +0000000491 00000 f +0000000492 00000 f +0000000493 00000 f +0000000494 00000 f +0000000495 00000 f +0000000496 00000 f +0000000497 00000 f +0000000498 00000 f +0000000499 00000 f +0000000500 00000 f +0000000501 00000 f +0000000502 00000 f +0000000503 00000 f +0000000504 00000 f +0000000505 00000 f +0000000506 00000 f +0000000507 00000 f +0000000508 00000 f +0000000509 00000 f +0000000510 00000 f +0000000511 00000 f +0000000512 00000 f +0000000513 00000 f +0000000514 00000 f +0000000515 00000 f +0000000516 00000 f +0000000517 00000 f +0000000518 00000 f +0000000519 00000 f +0000000520 00000 f +0000000521 00000 f +0000000522 00000 f +0000000523 00000 f +0000000524 00000 f +0000000525 00000 f +0000000526 00000 f +0000000527 00000 f +0000000528 00000 f +0000000529 00000 f +0000000530 00000 f +0000000531 00000 f +0000000532 00000 f +0000000533 00000 f +0000000534 00000 f +0000000535 00000 f +0000000536 00000 f +0000000537 00000 f +0000000538 00000 f +0000000539 00000 f +0000000540 00000 f +0000000541 00000 f +0000000542 00000 f +0000000543 00000 f +0000000544 00000 f +0000000545 00000 f +0000000546 00000 f +0000000547 00000 f +0000000548 00000 f +0000000549 00000 f +0000000550 00000 f +0000000551 00000 f +0000000552 00000 f +0000000553 00000 f +0000000554 00000 f +0000000555 00000 f +0000000556 00000 f +0000000557 00000 f +0000000558 00000 f +0000000559 00000 f +0000000560 00000 f +0000000561 00000 f +0000000562 00000 f +0000000563 00000 f +0000000564 00000 f +0000000565 00000 f +0000000566 00000 f +0000000567 00000 f +0000000568 00000 f +0000000569 00000 f +0000000570 00000 f +0000000571 00000 f +0000000572 00000 f +0000000573 00000 f +0000000574 00000 f +0000000575 00000 f +0000000576 00000 f +0000000577 00000 f +0000000578 00000 f +0000000579 00000 f +0000000580 00000 f +0000000581 00000 f +0000000582 00000 f +0000000583 00000 f +0000000584 00000 f +0000000585 00000 f +0000000586 00000 f +0000000587 00000 f +0000000588 00000 f +0000000589 00000 f +0000000590 00000 f +0000000591 00000 f +0000000592 00000 f +0000000593 00000 f +0000000594 00000 f +0000000595 00000 f +0000000596 00000 f +0000000597 00000 f +0000000598 00000 f +0000000599 00000 f +0000000600 00000 f +0000000601 00000 f +0000000602 00000 f +0000000603 00000 f +0000000604 00000 f +0000000605 00000 f +0000000606 00000 f +0000000607 00000 f +0000000608 00000 f +0000000609 00000 f +0000000610 00000 f +0000000611 00000 f +0000000612 00000 f +0000000613 00000 f +0000000614 00000 f +0000000615 00000 f +0000000616 00000 f +0000000617 00000 f +0000000618 00000 f +0000000619 00000 f +0000000620 00000 f +0000000621 00000 f +0000000622 00000 f +0000000623 00000 f +0000000624 00000 f +0000000625 00000 f +0000000626 00000 f +0000000627 00000 f +0000000628 00000 f +0000000629 00000 f +0000000630 00000 f +0000000631 00000 f +0000000632 00000 f +0000000633 00000 f +0000000634 00000 f +0000000635 00000 f +0000000636 00000 f +0000000637 00000 f +0000000638 00000 f +0000000639 00000 f +0000000640 00000 f +0000000641 00000 f +0000000642 00000 f +0000000643 00000 f +0000000644 00000 f +0000000645 00000 f +0000000646 00000 f +0000000647 00000 f +0000000648 00000 f +0000000649 00000 f +0000000650 00000 f +0000000651 00000 f +0000000652 00000 f +0000000653 00000 f +0000000654 00000 f +0000000655 00000 f +0000000656 00000 f +0000000657 00000 f +0000000658 00000 f +0000000659 00000 f +0000000660 00000 f +0000000661 00000 f +0000000662 00000 f +0000000663 00000 f +0000000664 00000 f +0000000665 00000 f +0000000666 00000 f +0000000667 00000 f +0000000668 00000 f +0000000669 00000 f +0000000670 00000 f +0000000671 00000 f +0000000672 00000 f +0000000673 00000 f +0000000674 00000 f +0000000675 00000 f +0000000676 00000 f +0000000677 00000 f +0000000678 00000 f +0000000679 00000 f +0000000680 00000 f +0000000681 00000 f +0000000682 00000 f +0000000683 00000 f +0000000684 00000 f +0000000685 00000 f +0000000686 00000 f +0000000687 00000 f +0000000688 00000 f +0000000689 00000 f +0000000690 00000 f +0000000691 00000 f +0000000692 00000 f +0000000693 00000 f +0000000694 00000 f +0000000695 00000 f +0000000696 00000 f +0000000697 00000 f +0000000698 00000 f +0000000699 00000 f +0000000700 00000 f +0000000701 00000 f +0000000702 00000 f +0000000703 00000 f +0000000704 00000 f +0000000705 00000 f +0000000706 00000 f +0000000707 00000 f +0000000708 00000 f +0000000709 00000 f +0000000710 00000 f +0000000711 00000 f +0000000712 00000 f +0000000713 00000 f +0000000714 00000 f +0000000715 00000 f +0000000716 00000 f +0000000717 00000 f +0000000718 00000 f +0000000719 00000 f +0000000720 00000 f +0000000721 00000 f +0000000722 00000 f +0000000723 00000 f +0000000724 00000 f +0000000725 00000 f +0000000726 00000 f +0000000727 00000 f +0000000728 00000 f +0000000729 00000 f +0000000730 00000 f +0000000731 00000 f +0000000732 00000 f +0000000733 00000 f +0000000734 00000 f +0000000735 00000 f +0000000736 00000 f +0000000737 00000 f +0000000738 00000 f +0000000739 00000 f +0000000740 00000 f +0000000741 00000 f +0000000742 00000 f +0000000743 00000 f +0000000744 00000 f +0000000745 00000 f +0000000746 00000 f +0000000747 00000 f +0000000748 00000 f +0000000749 00000 f +0000000750 00000 f +0000000751 00000 f +0000000752 00000 f +0000000753 00000 f +0000000754 00000 f +0000000755 00000 f +0000000756 00000 f +0000000757 00000 f +0000000758 00000 f +0000000759 00000 f +0000000760 00000 f +0000000761 00000 f +0000000762 00000 f +0000000763 00000 f +0000000764 00000 f +0000000765 00000 f +0000000766 00000 f +0000000767 00000 f +0000000768 00000 f +0000000769 00000 f +0000000770 00000 f +0000000771 00000 f +0000000772 00000 f +0000000773 00000 f +0000000774 00000 f +0000000775 00000 f +0000000776 00000 f +0000000777 00000 f +0000000778 00000 f +0000000779 00000 f +0000000780 00000 f +0000000781 00000 f +0000000782 00000 f +0000000783 00000 f +0000000784 00000 f +0000000785 00000 f +0000000786 00000 f +0000000787 00000 f +0000000788 00000 f +0000000789 00000 f +0000000790 00000 f +0000000791 00000 f +0000000792 00000 f +0000000793 00000 f +0000000794 00000 f +0000000795 00000 f +0000000796 00000 f +0000000797 00000 f +0000000798 00000 f +0000000799 00000 f +0000000800 00000 f +0000000801 00000 f +0000000802 00000 f +0000000803 00000 f +0000000804 00000 f +0000000805 00000 f +0000000806 00000 f +0000000807 00000 f +0000000808 00000 f +0000000809 00000 f +0000000810 00000 f +0000000811 00000 f +0000000812 00000 f +0000000813 00000 f +0000000814 00000 f +0000000815 00000 f +0000000816 00000 f +0000000817 00000 f +0000000818 00000 f +0000000819 00000 f +0000000820 00000 f +0000000821 00000 f +0000000822 00000 f +0000000823 00000 f +0000000824 00000 f +0000000825 00000 f +0000000826 00000 f +0000000827 00000 f +0000000828 00000 f +0000000829 00000 f +0000000830 00000 f +0000000831 00000 f +0000000832 00000 f +0000000833 00000 f +0000000834 00000 f +0000000835 00000 f +0000000836 00000 f +0000000837 00000 f +0000000838 00000 f +0000000839 00000 f +0000000840 00000 f +0000000841 00000 f +0000000842 00000 f +0000000843 00000 f +0000000844 00000 f +0000000845 00000 f +0000000846 00000 f +0000000847 00000 f +0000000848 00000 f +0000000849 00000 f +0000000850 00000 f +0000000851 00000 f +0000000852 00000 f +0000000853 00000 f +0000000854 00000 f +0000000855 00000 f +0000000856 00000 f +0000000857 00000 f +0000000858 00000 f +0000000859 00000 f +0000000860 00000 f +0000000861 00000 f +0000000862 00000 f +0000000863 00000 f +0000000864 00000 f +0000000865 00000 f +0000000866 00000 f +0000000867 00000 f +0000000868 00000 f +0000000869 00000 f +0000000870 00000 f +0000000871 00000 f +0000000872 00000 f +0000000873 00000 f +0000000874 00000 f +0000000875 00000 f +0000000876 00000 f +0000000877 00000 f +0000000878 00000 f +0000000879 00000 f +0000000880 00000 f +0000000881 00000 f +0000000882 00000 f +0000000883 00000 f +0000000884 00000 f +0000000885 00000 f +0000000886 00000 f +0000000887 00000 f +0000000888 00000 f +0000000889 00000 f +0000000890 00000 f +0000000891 00000 f +0000000892 00000 f +0000000893 00000 f +0000000894 00000 f +0000000895 00000 f +0000000896 00000 f +0000000897 00000 f +0000000898 00000 f +0000000899 00000 f +0000000900 00000 f +0000000901 00000 f +0000000902 00000 f +0000000903 00000 f +0000000904 00000 f +0000000905 00000 f +0000000906 00000 f +0000000907 00000 f +0000000908 00000 f +0000000909 00000 f +0000000910 00000 f +0000000911 00000 f +0000000912 00000 f +0000000913 00000 f +0000000914 00000 f +0000000915 00000 f +0000000916 00000 f +0000000917 00000 f +0000000918 00000 f +0000000919 00000 f +0000000920 00000 f +0000000921 00000 f +0000000922 00000 f +0000000923 00000 f +0000000924 00000 f +0000000925 00000 f +0000000926 00000 f +0000000927 00000 f +0000000928 00000 f +0000000929 00000 f +0000000930 00000 f +0000000931 00000 f +0000000932 00000 f +0000000933 00000 f +0000000934 00000 f +0000000935 00000 f +0000000936 00000 f +0000000937 00000 f +0000000938 00000 f +0000000939 00000 f +0000000940 00000 f +0000000941 00000 f +0000000942 00000 f +0000000943 00000 f +0000000944 00000 f +0000000945 00000 f +0000000946 00000 f +0000000947 00000 f +0000000948 00000 f +0000000949 00000 f +0000000950 00000 f +0000000951 00000 f +0000000952 00000 f +0000000953 00000 f +0000000954 00000 f +0000000955 00000 f +0000000956 00000 f +0000000957 00000 f +0000000958 00000 f +0000000959 00000 f +0000000960 00000 f +0000000961 00000 f +0000000962 00000 f +0000000963 00000 f +0000000964 00000 f +0000000965 00000 f +0000000966 00000 f +0000000967 00000 f +0000000968 00000 f +0000000969 00000 f +0000000970 00000 f +0000000971 00000 f +0000000972 00000 f +0000000973 00000 f +0000000974 00000 f +0000000975 00000 f +0000000976 00000 f +0000000977 00000 f +0000000978 00000 f +0000000979 00000 f +0000000980 00000 f +0000000981 00000 f +0000000982 00000 f +0000000983 00000 f +0000000984 00000 f +0000000985 00000 f +0000000986 00000 f +0000000987 00000 f +0000000988 00000 f +0000000989 00000 f +0000000990 00000 f +0000000991 00000 f +0000000992 00000 f +0000000993 00000 f +0000000994 00000 f +0000000995 00000 f +0000000996 00000 f +0000000997 00000 f +0000000998 00000 f +0000000999 00000 f +0000001000 00000 f +0000001001 00000 f +0000001002 00000 f +0000001003 00000 f +0000001004 00000 f +0000001005 00000 f +0000001006 00000 f +0000001007 00000 f +0000001008 00000 f +0000001009 00000 f +0000001010 00000 f +0000001011 00000 f +0000001012 00000 f +0000001013 00000 f +0000001014 00000 f +0000001015 00000 f +0000001016 00000 f +0000001017 00000 f +0000001018 00000 f +0000001019 00000 f +0000001020 00000 f +0000001021 00000 f +0000001022 00000 f +0000001023 00000 f +0000001024 00000 f +0000001025 00000 f +0000001026 00000 f +0000001027 00000 f +0000001028 00000 f +0000001029 00000 f +0000001030 00000 f +0000001031 00000 f +0000001032 00000 f +0000001033 00000 f +0000001034 00000 f +0000001035 00000 f +0000001036 00000 f +0000001037 00000 f +0000001038 00000 f +0000001039 00000 f +0000001040 00000 f +0000001041 00000 f +0000001042 00000 f +0000001043 00000 f +0000001044 00000 f +0000001045 00000 f +0000001046 00000 f +0000001047 00000 f +0000001048 00000 f +0000001049 00000 f +0000001050 00000 f +0000001051 00000 f +0000001052 00000 f +0000001053 00000 f +0000001054 00000 f +0000001055 00000 f +0000001056 00000 f +0000001057 00000 f +0000001058 00000 f +0000001059 00000 f +0000001060 00000 f +0000001061 00000 f +0000001062 00000 f +0000001063 00000 f +0000001064 00000 f +0000001065 00000 f +0000001066 00000 f +0000001067 00000 f +0000001068 00000 f +0000001069 00000 f +0000001070 00000 f +0000001071 00000 f +0000001072 00000 f +0000001073 00000 f +0000001074 00000 f +0000001075 00000 f +0000001076 00000 f +0000001077 00000 f +0000001078 00000 f +0000001079 00000 f +0000001080 00000 f +0000001081 00000 f +0000001082 00000 f +0000001083 00000 f +0000001084 00000 f +0000001085 00000 f +0000001086 00000 f +0000001087 00000 f +0000001088 00000 f +0000001089 00000 f +0000001090 00000 f +0000001091 00000 f +0000001092 00000 f +0000001093 00000 f +0000001094 00001 f +0000001095 00000 f +0000001096 00000 f +0000001097 00000 f +0000001098 00000 f +0000001099 00000 f +0000000000 00000 f +0000061265 00000 n +0000061343 00000 n +0000061589 00000 n +0000062768 00000 n +0000073154 00000 n +0000089171 00000 n +0000103838 00000 n +0000126350 00000 n +0000031715 00000 n +0000060764 00000 n +0000060926 00000 n +0000031830 00000 n +0000054651 00000 n +0000032148 00000 n +0000045311 00000 n +0000032585 00000 n +0000038610 00000 n +0000061093 00000 n +0000032905 00000 n +0000036312 00000 n +0000033282 00000 n +0000033680 00000 n +0000028893 00000 n +0000134602 00000 n +0000054933 00000 n +0000045575 00000 n +0000038884 00000 n +0000036574 00000 n +0000033944 00000 n +0000000079 00000 n +trailer <]>> startxref 134721 %%EOF \ No newline at end of file diff --git a/static/contrib/mediaplayer-3.15/swfobject.js b/static/contrib/mediaplayer-3.15/swfobject.js new file mode 100755 index 0000000..e7edd42 --- /dev/null +++ b/static/contrib/mediaplayer-3.15/swfobject.js @@ -0,0 +1,8 @@ +/** + * SWFObject v1.5: Flash Player detection and embed - http://blog.deconcept.com/swfobject/ + * + * SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License: + * http://www.opensource.org/licenses/mit-license.php + * + */ +if(typeof deconcept=="undefined"){var deconcept=new Object();}if(typeof deconcept.util=="undefined"){deconcept.util=new Object();}if(typeof deconcept.SWFObjectUtil=="undefined"){deconcept.SWFObjectUtil=new Object();}deconcept.SWFObject=function(_1,id,w,h,_5,c,_7,_8,_9,_a){if(!document.getElementById){return;}this.DETECT_KEY=_a?_a:"detectflash";this.skipDetect=deconcept.util.getRequestParameter(this.DETECT_KEY);this.params=new Object();this.variables=new Object();this.attributes=new Array();if(_1){this.setAttribute("swf",_1);}if(id){this.setAttribute("id",id);}if(w){this.setAttribute("width",w);}if(h){this.setAttribute("height",h);}if(_5){this.setAttribute("version",new deconcept.PlayerVersion(_5.toString().split(".")));}this.installedVer=deconcept.SWFObjectUtil.getPlayerVersion();if(!window.opera&&document.all&&this.installedVer.major>7){deconcept.SWFObject.doPrepUnload=true;}if(c){this.addParam("bgcolor",c);}var q=_7?_7:"high";this.addParam("quality",q);this.setAttribute("useExpressInstall",false);this.setAttribute("doExpressInstall",false);var _c=(_8)?_8:window.location;this.setAttribute("xiRedirectUrl",_c);this.setAttribute("redirectUrl","");if(_9){this.setAttribute("redirectUrl",_9);}};deconcept.SWFObject.prototype={useExpressInstall:function(_d){this.xiSWFPath=!_d?"expressinstall.swf":_d;this.setAttribute("useExpressInstall",true);},setAttribute:function(_e,_f){this.attributes[_e]=_f;},getAttribute:function(_10){return this.attributes[_10];},addParam:function(_11,_12){this.params[_11]=_12;},getParams:function(){return this.params;},addVariable:function(_13,_14){this.variables[_13]=_14;},getVariable:function(_15){return this.variables[_15];},getVariables:function(){return this.variables;},getVariablePairs:function(){var _16=new Array();var key;var _18=this.getVariables();for(key in _18){_16[_16.length]=key+"="+_18[key];}return _16;},getSWFHTML:function(){var _19="";if(navigator.plugins&&navigator.mimeTypes&&navigator.mimeTypes.length){if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","PlugIn");this.setAttribute("swf",this.xiSWFPath);}_19="0){_19+="flashvars=\""+_1c+"\"";}_19+="/>";}else{if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","ActiveX");this.setAttribute("swf",this.xiSWFPath);}_19="";_19+="";var _1d=this.getParams();for(var key in _1d){_19+="";}var _1f=this.getVariablePairs().join("&");if(_1f.length>0){_19+="";}_19+="";}return _19;},write:function(_20){if(this.getAttribute("useExpressInstall")){var _21=new deconcept.PlayerVersion([6,0,65]);if(this.installedVer.versionIsValid(_21)&&!this.installedVer.versionIsValid(this.getAttribute("version"))){this.setAttribute("doExpressInstall",true);this.addVariable("MMredirectURL",escape(this.getAttribute("xiRedirectUrl")));document.title=document.title.slice(0,47)+" - Flash Player Installation";this.addVariable("MMdoctitle",document.title);}}if(this.skipDetect||this.getAttribute("doExpressInstall")||this.installedVer.versionIsValid(this.getAttribute("version"))){var n=(typeof _20=="string")?document.getElementById(_20):_20;n.innerHTML=this.getSWFHTML();return true;}else{if(this.getAttribute("redirectUrl")!=""){document.location.replace(this.getAttribute("redirectUrl"));}}return false;}};deconcept.SWFObjectUtil.getPlayerVersion=function(){var _23=new deconcept.PlayerVersion([0,0,0]);if(navigator.plugins&&navigator.mimeTypes.length){var x=navigator.plugins["Shockwave Flash"];if(x&&x.description){_23=new deconcept.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/,"").replace(/(\s+r|\s+b[0-9]+)/,".").split("."));}}else{if(navigator.userAgent&&navigator.userAgent.indexOf("Windows CE")>=0){var axo=1;var _26=3;while(axo){try{_26++;axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+_26);_23=new deconcept.PlayerVersion([_26,0,0]);}catch(e){axo=null;}}}else{try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");}catch(e){try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");_23=new deconcept.PlayerVersion([6,0,21]);axo.AllowScriptAccess="always";}catch(e){if(_23.major==6){return _23;}}try{axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");}catch(e){}}if(axo!=null){_23=new deconcept.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(","));}}}return _23;};deconcept.PlayerVersion=function(_29){this.major=_29[0]!=null?parseInt(_29[0]):0;this.minor=_29[1]!=null?parseInt(_29[1]):0;this.rev=_29[2]!=null?parseInt(_29[2]):0;};deconcept.PlayerVersion.prototype.versionIsValid=function(fv){if(this.majorfv.major){return true;}if(this.minorfv.minor){return true;}if(this.rev=0;i--){_2f[i].style.display="none";for(var x in _2f[i]){if(typeof _2f[i][x]=="function"){_2f[i][x]=function(){};}}}};if(deconcept.SWFObject.doPrepUnload){if(!deconcept.unloadSet){deconcept.SWFObjectUtil.prepUnload=function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){};window.attachEvent("onunload",deconcept.SWFObjectUtil.cleanupSWFs);};window.attachEvent("onbeforeunload",deconcept.SWFObjectUtil.prepUnload);deconcept.unloadSet=true;}}if(!document.getElementById&&document.all){document.getElementById=function(id){return document.all[id];};}var getQueryParamValue=deconcept.util.getRequestParameter;var FlashObject=deconcept.SWFObject;var SWFObject=deconcept.SWFObject; \ No newline at end of file