r43394 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r43393‎ | r43394 | r43395 >
Date:20:33, 11 November 2008
Author:dale
Status:old
Tags:
Comment:
* smil editor style updates
* "pause" ui updates for stream view
* updated category links to just be an image link
* upgraded to new flowplayer 3.x
* moved to its own folder with GPL license etc
* supports reporting buffer state
* supports archive.org mp4 h264 streams served via lightpd mod_h264_sreaming extension
Modified paths:
  • /trunk/extensions/MetavidWiki/includes/MV_ImageGallery.php (modified) (history)
  • /trunk/extensions/MetavidWiki/includes/MV_Title.php (modified) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/FlowPlayerDark.swf (deleted) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/embedLibs/mv_flashEmbed.js (modified) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/embedLibs/mv_vlcEmbed.js (modified) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/example_usage/sample_page.php (modified) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/example_usage/sample_playlists.php (modified) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer (added) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer-3.0.0-rc2.swf (deleted) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer.controls-3.0.0-beta5.swf (deleted) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer/LICENSE.txt (added) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer/README.txt (added) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer/flowplayer-3.0.0-rc2.js (added) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer/flowplayer-3.0.0-rc2.min.js (added) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer/flowplayer-3.0.0-rc2.swf (added) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer/flowplayer.controls-3.0.0-beta5.swf (added) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/mv_embed.js (modified) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/mv_playlist.js (modified) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/mv_remote_media_search.js (modified) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/mv_sequencer.js (modified) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_embed/skins/mvpcf/styles.css (modified) (history)
  • /trunk/extensions/MetavidWiki/skins/mv_stream.js (modified) (history)

Diff [purge]

Index: trunk/extensions/MetavidWiki/includes/MV_ImageGallery.php
@@ -67,11 +67,10 @@
6868 # handlers since they may emit block-level elements as opposed to simple <img> tags.
6969 # ref http://css-discuss.incutio.com/?page=CenteringBlockElement
7070 . '<div style="margin-left: auto; margin-right: auto; width: ' . htmlspecialchars( $this->mWidths ) . 'px;">'
71 - . $mvTitle->getEmbedVideoHtml( array('size'=>$vidRes ) )
72 - // . '<img width="'.$this->mWidths.'" src="'.$mvTitle->getStreamImageURL() . '">'
 71+ . $sk->makeKnownLinkObj( $nt, '<img title="'. htmlspecialchars($mvTitle->getStreamNameText()) .'"'
 72+ . ' width="160" height="120" src="'.$mvTitle->getStreamImageURL('160x120') . '">')
7373 . '</div>' .
7474 '</div>' .
75 - '<div style="clear:both;"></div>' .
7675 // @@todo clean up link
7776 '<span class="gallerytext" style="float:left">' .
7877 $sk->makeKnownLinkObj( $nt, $mvTitle->getStreamNameText() . ' ' . $mvTitle->getTimeDesc() ) .
Index: trunk/extensions/MetavidWiki/includes/MV_Title.php
@@ -358,7 +358,7 @@
359359 }*/
360360 $o .= '<' . htmlspecialchars( $tag ) . ' ';
361361 $o .= ( $vid_id == '' ) ? '':' id="' . htmlspecialchars( $vid_id ) . '" ';
362 - $o .= 'thumbnail="' . $this->getStreamImageURL( $size, null, $force_server ) . '" ' .
 362+ $o .= 'poster="' . $this->getStreamImageURL( $size, null, $force_server ) . '" ' .
363363 'roe="' . $roe_url . '" ';
364364 $o .= ($showmeta)?'show_meta_link="true" ':'show_meta_link="false" ' ;
365365
Index: trunk/extensions/MetavidWiki/skins/mv_stream.js
@@ -239,37 +239,32 @@
240240 mvdOver:function(mvd_id){
241241 js_log('f:mvdOver' + mvd_id );
242242 var vid_elm = $j('#embed_vid').get(0);
243 - if( mv_lock_vid_updates ){
244 - js_log('f:mvdOver' + mvd_id + ' updates locked');
245 - if(!vid_elm.onClipDone_disp){
246 - this.delay_cur_mvd_id= mvd_id;
247 - setTimeout("mv_stream_interface.delayDoVidMvdUpdate()", 250);
248 - }
249 - }else{
250 - this.cur_mvd_id=this.delay_cur_mvd_id=mvd_id;
251 - do_video_mvd_update(mvd_id);
252 - }
 243+ //never do mvdOver while video is playing:
 244+ if( vid_elm.isPlaying() ){
 245+ return false;
 246+ }
 247+ //stop the video if not already stopped
 248+ vid_elm.stop();
 249+ mv_lock_vid_updates=false;
 250+ //set the onClipDone_disp to false:
 251+ this.cur_mvd_id=this.delay_cur_mvd_id=mvd_id;
 252+ do_video_mvd_update(mvd_id);
253253 highlight_tl_ts(mvd_id);
254 - highlight_fd(mvd_id);
 254+ highlight_fd(mvd_id);
255255 },
256 - mvdOut:function(mvd_id){
257 - js_log('do out ' + mvd_id );
258 - this.cur_mvd_id='base';
259 - de_highlight_tl_ts(mvd_id);
260 - de_highlight_fd(mvd_id);
261 - js_log('calling interface restore: ');
262 - setTimeout('mv_stream_interface.doRestore()',500);
263 - //activiate over on time restore
264 - /*$j('#mv_stream_time').hoverIntent({
265 - interval:200, //polling interval
266 - timeout:200, //delay before onMouseOut
267 - over:function(){
268 - mv_stream_interface.doRestore();
269 - },
270 - out:function(){
271 -
272 - }
273 - });*/
 256+ mvdOut:function(mvd_id){
 257+ var vid_elm = $j('#embed_vid').get(0);
 258+ //only proccess out if in "stoped" state
 259+ if( vid_elm.isStoped() ){
 260+ js_log('do out ' + mvd_id );
 261+ this.cur_mvd_id='base';
 262+ de_highlight_tl_ts(mvd_id);
 263+ de_highlight_fd(mvd_id);
 264+ js_log('calling interface restore: ');
 265+ setTimeout('mv_stream_interface.doRestore()',500);
 266+ }else{
 267+ setTimeout('mv_stream_interface.mvdOut(\''+mvd_id+'\')',100);
 268+ }
274269 },
275270 //delay video updates until we are not playing the clip and clipEnd is not displayed
276271 delayDoVidMvdUpdate:function(){
@@ -1017,7 +1012,7 @@
10181013 //get the current thumbnail
10191014 var vid_elm = document.getElementById('embed_vid');
10201015 if(!vid_elm)return '';
1021 - //make the play button visable again (if its hidden) :
 1016+ //make the play button vissable again (if its hidden) :
10221017 $j('#big_play_link_embed_vid').show();
10231018 do_video_time_update(time_ary[1], time_ary[2],mvd_id);
10241019 }
Index: trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer-3.0.0-rc2.swf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer.controls-3.0.0-beta5.swf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/extensions/MetavidWiki/skins/mv_embed/FlowPlayerDark.swf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: trunk/extensions/MetavidWiki/skins/mv_embed/mv_sequencer.js
@@ -100,8 +100,6 @@
101101 for(var i in sequencerDefaultValues){
102102 this[ i ] = sequencerDefaultValues[i];
103103 }
104 - //@@todo deal with multi-dimensional object updates
105 - // (ie one word in wfMsg does not replace the whole wfMsg default set)
106104 for(var i in initObj){
107105 //js_log('on '+ i + ' :' + initObj[i]);
108106 if(sequencerDefaultValues[i]){ //make sure its a valid property
@@ -152,7 +150,8 @@
153151
154152 js_log('set: '+this.sequence_container_id + ' html to:'+ "\n"+
155153 $j('#'+this.sequence_container_id).html()
156 - );
 154+ );
 155+
157156 //add src based pl:
158157 if( this.mv_pl_src != 'null' ) {
159158 js_log( ' pl src:: '+ this.mv_pl_src );
@@ -339,7 +338,7 @@
340339 var track_height=this.track_clipThumb_height;
341340 //add in play box and container tracks
342341 $j('#'+this.timeline_id).append(''+
343 - '<div id="container_track_'+i+'" style="position:absolute;top:'+top_pos+'px;height:'+(track_height+20)+'px;left:10px;right:0px;" class="container_track">' +
 342+ '<div id="container_track_'+i+'" style="position:absolute;top:20px;height:'+(track_height+20)+'px;left:10px;right:0px;" class="container_track">' +
344343 '</div>'
345344 );
346345 top_pos+=track_height+20;
Index: trunk/extensions/MetavidWiki/skins/mv_embed/mv_playlist.js
@@ -64,7 +64,7 @@
6565 seq_thumb:.25, //size for thumbnails (same as seq by default)
6666 seq_nav:0, //for a nav bar at the base (currently disabled)
6767 //some pl_layout info:
68 - title_bar_height:20,
 68+ title_bar_height:17,
6969 control_height:29
7070 },
7171 init : function(element){
Index: trunk/extensions/MetavidWiki/skins/mv_embed/example_usage/sample_playlists.php
@@ -60,7 +60,7 @@
6161 <table border="1" cellpadding="6" width="600">
6262 <? foreach ( $sample_embed as $key => $aval ) {
6363 // $key!=8
64 - if ( $key != 9 )continue;
 64+ if ( $key != 9 && $key != 8)continue;
6565 ?>
6666 <tr>
6767 <td valign="top"><?=$aval['tag']?></td>
Index: trunk/extensions/MetavidWiki/skins/mv_embed/example_usage/sample_page.php
@@ -43,7 +43,7 @@
4444 $sample_embed[1]['tag'] = '<video roe="http://metavid.org/wiki/index.php?title=Special:MvExportStream&feed_format=roe&stream_name=Senate_proceeding_06-06-06_1&t=0:07:50/0:09:06">';
4545 $sample_embed[1]['desc'] = 'Demo of json ROE attribute';
4646
47 -$sample_embed[3]['tag'] = '<video roe="http://metavid.org/mvw-exp/index.php?title=Special:MvExportStream&feed_format=roe&stream_name=Senate_proceeding_08-01-07&t=0:11:40/0:12:20" ></video>';
 47+$sample_embed[3]['tag'] = '<video roe="http://metavid.org/w/index.php?title=Special:MvExportStream&feed_format=roe&stream_name=Senate_proceeding_08-01-07&t=0:11:40/0:12:20" ></video>';
4848 $sample_embed[3]['desc'] = 'Demo of ROE only attribute';
4949
5050
Index: trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer/README.txt
@@ -0,0 +1,52 @@
 2+Version history:
 3+
 4+RC2
 5+---
 6+- fixed: setting the screen height in configuration did not have any effect
 7+
 8+RC1
 9+-----
 10+- better error message if plugin loading fails, shows the URL used
 11+- validates our redesigned multidomain license key correctly
 12+- fix to prevent the play button going visible when the onBufferEmpty event occurs
 13+- the commercial swf now correctly loads the controls using version information
 14+- fixed: the play button overlay became invisible with long fadeOutSpeeds
 15+
 16+beta6
 17+-----
 18+- removed the onFirstFramePause event
 19+- playing a clip for the second time caused a doubled sound
 20+- pausing on first frame did not work on some FLV files
 21+
 22+beta5
 23+-----
 24+- logo only uses percentage scaling if it's a SWF file (there is ".swf" in it's url)
 25+- context menu now correctly builds up from string entries in configuration
 26+-always closes the previous connection before starting a new clip
 27+
 28+beta4
 29+-----
 30+- now it's possible to load a plugin into the panel without specifying any position/dimensions
 31+ information, the plugin is placed to left: "50%", top: "50%" and using the plugin DisplayObject's width & height
 32+- The Flowplayer API was not fully initialized when onLoad was invoked on Flash plugins
 33+
 34+beta3
 35+-----
 36+- tweaking logo placement
 37+- "play" did not show up after repeated pause/resume
 38+- player now loads the latest controls SWF version, right now the latest SWF is called 'flowplayer.controls-3.0.0-beta2.swf'
 39+
 40+beta2
 41+-----
 42+- fixed support for RTMP stream groups
 43+- changed to loop through available fonts in order to find a suitable font also in IE
 44+- Preloader was broken on IE: When the player SWf was in browser's cache it did not initialize properly
 45+- Context menu now correctly handles menu items that are configured by their string labels only (not using json objects)
 46+- fixed custom logo positioning (was moved to the left edge of screen in fullscreen)
 47+- "play" now always follows the position and size of the screen
 48+- video was stretched below the controls in fullscreen when autoHide: 'never'
 49+- logo now takes 6.5% of the screen height, width is scaled so that the aspect ratio is preserved
 50+
 51+beta1
 52+-----
 53+- First public beta release
Index: trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer/flowplayer.controls-3.0.0-beta5.swf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer/flowplayer.controls-3.0.0-beta5.swf
___________________________________________________________________
Added: svn:mime-type
154 + application/octet-stream
Index: trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer/flowplayer-3.0.0-rc2.js
@@ -0,0 +1,1520 @@
 2+/**
 3+ * flowplayer.js 3.0.0-rc2. The Flowplayer API.
 4+ *
 5+ * This file is part of Flowplayer, http://flowplayer.org
 6+ *
 7+ * Author: Tero Piirainen, <support@flowplayer.org>
 8+ * Copyright (c) 2008 Flowplayer Ltd
 9+ *
 10+ * Released under the MIT License:
 11+ * http://www.opensource.org/licenses/mit-license.php
 12+ *
 13+ * Version: 3.0.0-rc2 - Fri Nov 07 2008 16:50:59 GMT-0000 (GMT+00:00)
 14+ */
 15+(function() {
 16+
 17+/*
 18+ FEATURES
 19+ --------
 20+ - handling multiple instances
 21+ - Flowplayer programming API
 22+ - Flowplayer event model
 23+ - player loading / unloading
 24+ - $f() function
 25+ - jQuery support
 26+*/
 27+
 28+
 29+/*jslint glovar: true, browser: true */
 30+/*global flowplayer, $f */
 31+
 32+// {{{ private utility methods
 33+
 34+ function log(args) {
 35+
 36+ // write into opera console
 37+ if (typeof opera == 'object') {
 38+ opera.postError("$f.fireEvent: " + args.join(" | "));
 39+
 40+
 41+ } else if (typeof console == 'object') {
 42+ console.log("$f.fireEvent", [].slice.call(args));
 43+ }
 44+ }
 45+
 46+
 47+ // thanks: http://keithdevens.com/weblog/archive/2007/Jun/07/javascript.clone
 48+ function clone(obj) {
 49+ if (!obj || typeof obj != 'object') { return obj; }
 50+ var temp = new obj.constructor();
 51+ for (var key in obj) {
 52+ if (obj.hasOwnProperty(key)) {
 53+ temp[key] = clone(obj[key]);
 54+ }
 55+ }
 56+ return temp;
 57+ }
 58+
 59+ // stripped from jQuery, thanks John Resig
 60+ function each(obj, fn) {
 61+ if (!obj) { return; }
 62+
 63+ var name, i = 0, length = obj.length;
 64+
 65+ // object
 66+ if (length === undefined) {
 67+ for (name in obj) {
 68+ if (fn.call(obj[name], name, obj[name]) === false) { break; }
 69+ }
 70+
 71+ // array
 72+ } else {
 73+ for (var value = obj[0];
 74+ i < length && fn.call( value, i, value ) !== false; value = obj[++i]) {
 75+ }
 76+ }
 77+
 78+ return obj;
 79+ }
 80+
 81+
 82+ // convenience
 83+ function el(id) {
 84+ return document.getElementById(id);
 85+ }
 86+
 87+
 88+ // used extensively. a very simple implementation.
 89+ function extend(to, from, skipFuncs) {
 90+ if (to && from) {
 91+ each(from, function(name, value) {
 92+ if (!skipFuncs || typeof value != 'function') {
 93+ to[name] = value;
 94+ }
 95+ });
 96+ }
 97+ }
 98+
 99+ // var arr = select("elem.className");
 100+ function select(query) {
 101+ var index = query.indexOf(".");
 102+ if (index != -1) {
 103+ var tag = query.substring(0, index) || "*";
 104+ var klass = query.substring(index + 1, query.length);
 105+ var els = [];
 106+ each(document.getElementsByTagName(tag), function() {
 107+ if (this.className && this.className.indexOf(klass) != -1) {
 108+ els.push(this);
 109+ }
 110+ });
 111+ return els;
 112+ }
 113+ }
 114+
 115+ // fix event inconsistencies across browsers
 116+ function stopEvent(e) {
 117+ e = e || window.event;
 118+
 119+ if (e.preventDefault) {
 120+ e.stopPropagation();
 121+ e.preventDefault();
 122+
 123+ } else {
 124+ e.returnValue = false;
 125+ e.cancelBubble = true;
 126+ }
 127+ return false;
 128+ }
 129+
 130+ // push an event listener into existing array of listeners
 131+ function bind(to, evt, fn) {
 132+ to[evt] = to[evt] || [];
 133+ to[evt].push(fn);
 134+ }
 135+
 136+
 137+ // generates an unique id
 138+ function makeId() {
 139+ return "_" + ("" + Math.random()).substring(2, 10);
 140+ }
 141+
 142+//}}}
 143+
 144+
 145+// {{{ Clip
 146+
 147+ var Clip = function(json, index, player) {
 148+
 149+ // private variables
 150+ var self = this;
 151+ var cuepoints = {};
 152+ var listeners = {};
 153+ this.index = index;
 154+
 155+ // instance variables
 156+ if (typeof json == 'string') {
 157+ json = {url:json};
 158+ }
 159+
 160+ extend(this, json, true);
 161+
 162+ // event handling
 163+ each(("Start*,MetaData,Pause*,Resume*,Seek*,Stop*,Finish,LastSecond,Update,BufferFull,BufferEmpty").split(","),
 164+ function() {
 165+
 166+ var evt = "on" + this;
 167+
 168+ // before event
 169+ if (evt.indexOf("*") != -1) {
 170+ evt = evt.substring(0, evt.length -1);
 171+ var before = "onBefore" + evt.substring(2);
 172+
 173+ self[before] = function(fn) {
 174+ bind(listeners, before, fn);
 175+ return self;
 176+ };
 177+ }
 178+
 179+ self[evt] = function(fn) {
 180+ bind(listeners, evt, fn);
 181+ return self;
 182+ };
 183+
 184+
 185+ // set common clip event listeners to player level
 186+ if (index == -1) {
 187+ if (self[before]) {
 188+ player[before] = self[before];
 189+ }
 190+ if (self[evt]) {
 191+ player[evt] = self[evt];
 192+ }
 193+ }
 194+
 195+ });
 196+
 197+ extend(this, {
 198+
 199+
 200+ onCuepoint: function(points, fn) {
 201+
 202+ // embedded cuepoints
 203+ if (arguments.length == 1) {
 204+ cuepoints.embedded = [null, points];
 205+ return self;
 206+ }
 207+
 208+ if (typeof points == 'number') {
 209+ points = [points];
 210+ }
 211+
 212+ var fnId = makeId();
 213+ cuepoints[fnId] = [points, fn];
 214+
 215+ if (player.isLoaded()) {
 216+ player._api().fp_addCuepoints(points, index, fnId);
 217+ }
 218+
 219+ return self;
 220+ },
 221+
 222+ update: function(json) {
 223+ extend(self, json);
 224+
 225+ if (player.isLoaded()) {
 226+ player._api().fp_updateClip(json, index);
 227+ }
 228+ var conf = player._config();
 229+ var clip = (index == -1) ? conf.clip : conf.playlist[index];
 230+ extend(clip, json, true);
 231+ },
 232+
 233+
 234+ // internal event for performing clip tasks. should be made private someday
 235+ _fireEvent: function(evt, arg1, arg2, target) {
 236+
 237+ if (evt == 'onLoad') {
 238+ each(cuepoints, function(key, val) {
 239+ player._api().fp_addCuepoints(val[0], index, key);
 240+ });
 241+ return false;
 242+ }
 243+
 244+ // target clip we are working against
 245+ if (index != -1) {
 246+ target = self;
 247+ }
 248+
 249+ if (evt == 'onCuepoint') {
 250+ var fn = cuepoints[arg1];
 251+ if (fn) {
 252+ return fn[1].call(player, target, arg2);
 253+ }
 254+ }
 255+
 256+ if (evt == 'onMetaData' || evt == 'onUpdate') {
 257+
 258+ extend(target, arg1);
 259+
 260+ if (!target.duration) {
 261+ target.duration = arg1.metaData.duration;
 262+ } else {
 263+ target.fullDuration = arg1.metaData.duration;
 264+ }
 265+ }
 266+
 267+ var ret = true;
 268+ each(listeners[evt], function() {
 269+ ret = this.call(player, target, arg1);
 270+ });
 271+ return ret;
 272+ }
 273+
 274+ });
 275+
 276+
 277+ // get cuepoints from config
 278+ if (json.onCuepoint) {
 279+ self.onCuepoint.apply(self, json.onCuepoint);
 280+ delete json.onCuepoint;
 281+ }
 282+
 283+ // get other events
 284+ each(json, function(key, val) {
 285+ if (typeof val == 'function') {
 286+ bind(listeners, key, val);
 287+ delete json[key];
 288+ }
 289+ });
 290+
 291+
 292+ // setup common clip event callbacks for Player object too (shortcuts)
 293+ if (index == -1) {
 294+ player.onCuepoint = this.onCuepoint;
 295+ }
 296+
 297+ };
 298+
 299+//}}}
 300+
 301+
 302+// {{{ Plugin
 303+
 304+ var Plugin = function(name, json, player, fn) {
 305+
 306+ var listeners = {};
 307+ var self = this;
 308+ var hasMethods = false;
 309+
 310+ if (fn) {
 311+ extend(listeners, fn);
 312+ }
 313+
 314+ // custom callback functions in configuration
 315+ each(json, function(key, val) {
 316+ if (typeof val == 'function') {
 317+ listeners[key] = val;
 318+ delete json[key];
 319+ }
 320+ });
 321+
 322+ // core plugin methods
 323+ extend(this, {
 324+
 325+ animate: function(props, speed, fn) {
 326+ if (!props) {
 327+ return self;
 328+ }
 329+
 330+ if (typeof speed == 'function') {
 331+ fn = speed;
 332+ speed = 500;
 333+ }
 334+
 335+ if (typeof props == 'string') {
 336+ var key = props;
 337+ props = {};
 338+ props[key] = speed;
 339+ speed = 500;
 340+ }
 341+
 342+ if (fn) {
 343+ var fnId = makeId();
 344+ listeners[fnId] = fn;
 345+ }
 346+
 347+ if (speed === undefined) { speed = 500; }
 348+ json = player._api().fp_animate(name, props, speed, fnId);
 349+ return self;
 350+ },
 351+
 352+ css: function(props, val) {
 353+ if (val !== undefined) {
 354+ var css = {};
 355+ css[props] = val;
 356+ props = css;
 357+ }
 358+ json = player._api().fp_css(name, props);
 359+ extend(self, json);
 360+ return self;
 361+ },
 362+
 363+ show: function() {
 364+ this.display = 'block';
 365+ player._api().fp_showPlugin(name);
 366+ return self;
 367+ },
 368+
 369+ hide: function() {
 370+ this.display = 'none';
 371+ player._api().fp_hidePlugin(name);
 372+ return self;
 373+ },
 374+
 375+ toggle: function() {
 376+ this.display = player._api().fp_togglePlugin(name);
 377+ return self;
 378+ },
 379+
 380+ fadeTo: function(o, speed, fn) {
 381+
 382+ if (typeof speed == 'function') {
 383+ fn = speed;
 384+ speed = 500;
 385+ }
 386+
 387+ if (fn) {
 388+ var fnId = makeId();
 389+ listeners[fnId] = fn;
 390+ }
 391+ this.display = player._api().fp_fadeTo(name, o, speed, fnId);
 392+ this.opacity = o;
 393+ return self;
 394+ },
 395+
 396+ fadeIn: function(speed, fn) {
 397+ return self.fadeTo(1, speed, fn);
 398+ },
 399+
 400+ fadeOut: function(speed, fn) {
 401+ return self.fadeTo(0, speed, fn);
 402+ },
 403+
 404+ getName: function() {
 405+ return name;
 406+ },
 407+
 408+
 409+ // internal method not meant to be used by clients
 410+ _fireEvent: function(evt, arg) {
 411+
 412+
 413+ // update plugins properties & methods
 414+ if (evt == 'onUpdate') {
 415+ var json = arg || player._api().fp_getPlugin(name);
 416+ if (!json) { return; }
 417+
 418+ extend(self, json);
 419+ delete self.methods;
 420+
 421+ if (!hasMethods) {
 422+ each(json.methods, function() {
 423+ var method = "" + this;
 424+
 425+ self[method] = function() {
 426+ var a = [].slice.call(arguments);
 427+ var ret = player._api().fp_invoke(name, method, a);
 428+ return ret == 'undefined' ? self : ret;
 429+ };
 430+ });
 431+ hasMethods = true;
 432+ }
 433+ }
 434+
 435+ // plugin callbacks
 436+ var fn = listeners[evt];
 437+
 438+ if (fn) {
 439+
 440+ fn.call(self, arg);
 441+
 442+ // "one-shot" callback
 443+ if (evt.substring(0, 1) == "_") {
 444+ delete listeners[evt];
 445+ }
 446+ }
 447+ }
 448+
 449+ });
 450+
 451+ };
 452+
 453+
 454+//}}}
 455+
 456+
 457+function Player(wrapper, params, conf) {
 458+
 459+ // private variables (+ arguments)
 460+ var
 461+ self = this,
 462+ api = null,
 463+ html,
 464+ commonClip,
 465+ playlist = [],
 466+ plugins = {},
 467+ listeners = {},
 468+ playerId,
 469+ apiId,
 470+ activeIndex,
 471+ swfHeight;
 472+
 473+
 474+// {{{ public methods
 475+
 476+ extend(self, {
 477+
 478+ id: function() {
 479+ return playerId;
 480+ },
 481+
 482+ isLoaded: function() {
 483+ return (api !== null);
 484+ },
 485+
 486+ getParent: function() {
 487+ return wrapper;
 488+ },
 489+
 490+ hide: function() {
 491+ if (api) { api.style.height = "0px"; }
 492+ return self;
 493+ },
 494+
 495+ show: function() {
 496+ if (api) { api.style.height = swfHeight + "px"; }
 497+ return self;
 498+ },
 499+
 500+ isHidden: function() {
 501+ return api && parseInt(api.style.height, 10) === 0;
 502+ },
 503+
 504+
 505+ load: function(fn) {
 506+
 507+ if (!api && self._fireEvent("onBeforeLoad") !== false) {
 508+
 509+ // unload all instances
 510+ each(players, function() {
 511+ this.unload();
 512+ });
 513+
 514+ html = wrapper.innerHTML;
 515+ flashembed(wrapper, params, {config: conf});
 516+
 517+ // function argument
 518+ if (fn) {
 519+ fn.cached = true;
 520+ bind(listeners, "onLoad", fn);
 521+ }
 522+ }
 523+
 524+ return self;
 525+ },
 526+
 527+ unload: function() {
 528+
 529+ if (api && html.replace(/\s/g, '') !== '' && !api.fp_isFullscreen() &&
 530+ self._fireEvent("onBeforeUnload") !== false) {
 531+ api.fp_close();
 532+ wrapper.innerHTML = html;
 533+ self._fireEvent("onUnload");
 534+ api = null;
 535+ }
 536+
 537+ return self;
 538+ },
 539+
 540+ getClip: function(index) {
 541+ if (index === undefined) {
 542+ index = activeIndex;
 543+ }
 544+ return playlist[index];
 545+ },
 546+
 547+
 548+ getCommonClip: function() {
 549+ return commonClip;
 550+ },
 551+
 552+ getPlaylist: function() {
 553+ return playlist;
 554+ },
 555+
 556+ getPlugin: function(name) {
 557+ var plugin = plugins[name];
 558+
 559+ // create plugin if nessessary
 560+ if (!plugin && self.isLoaded()) {
 561+ var json = self._api().fp_getPlugin(name);
 562+ if (json) {
 563+ plugin = new Plugin(name, json, self);
 564+ plugins[name] = plugin;
 565+ }
 566+ }
 567+ return plugin;
 568+ },
 569+
 570+ getScreen: function() {
 571+ return self.getPlugin("screen");
 572+ },
 573+
 574+ getControls: function() {
 575+ return self.getPlugin("controls");
 576+ },
 577+
 578+ getConfig: function() {
 579+ return clone(conf);
 580+ },
 581+
 582+ getFlashParams: function() {
 583+ return params;
 584+ },
 585+
 586+ loadPlugin: function(name, url, props, fn) {
 587+
 588+ // properties not supplied
 589+ if (typeof props == 'function') {
 590+ fn = props;
 591+ props = {};
 592+ }
 593+
 594+ // if fn not given, make a fake id so that plugin's onUpdate get's fired
 595+ var fnId = fn ? makeId() : "_";
 596+ self._api().fp_loadPlugin(name, url, props, fnId);
 597+
 598+ // create new plugin
 599+ var arg = {};
 600+ arg[fnId] = fn;
 601+ var p = new Plugin(name, null, self, arg);
 602+ plugins[name] = p;
 603+ return p;
 604+ },
 605+
 606+
 607+ getState: function() {
 608+ return api ? api.fp_getState() : -1;
 609+ },
 610+
 611+ // "lazy" play
 612+ play: function(clip) {
 613+
 614+ function play() {
 615+ if (clip !== undefined) {
 616+ self._api().fp_play(clip);
 617+ } else {
 618+ self._api().fp_play();
 619+ }
 620+ }
 621+
 622+ if (api) {
 623+ play();
 624+
 625+ } else {
 626+ self.load(function() {
 627+ play();
 628+ });
 629+ }
 630+
 631+ return self;
 632+ },
 633+
 634+ getVersion: function() {
 635+ var js = "flowplayer.js 3.0.0-rc2";
 636+ if (api) {
 637+ var ver = api.fp_getVersion();
 638+ ver.push(js);
 639+ return ver;
 640+ }
 641+ return js;
 642+ },
 643+
 644+ _api: function() {
 645+ if (!api) {
 646+ throw "Flowplayer " +self.id()+ " not loaded. Try moving your call to player's onLoad event";
 647+ }
 648+ return api;
 649+ },
 650+
 651+ _config: function() {
 652+ return conf;
 653+ }
 654+
 655+ });
 656+
 657+
 658+ // event handlers
 659+ each(("Click*,Load*,Unload*,Keypress*,Volume*,Mute*,Unmute*,PlaylistReplace,Fullscreen*,FullscreenExit,Error").split(","),
 660+ function() {
 661+ var name = "on" + this;
 662+
 663+ // before event
 664+ if (name.indexOf("*") != -1) {
 665+ name = name.substring(0, name.length -1);
 666+ var name2 = "onBefore" + name.substring(2);
 667+ self[name2] = function(fn) {
 668+ bind(listeners, name2, fn);
 669+ return self;
 670+ };
 671+ }
 672+
 673+ // normal event
 674+ self[name] = function(fn) {
 675+ bind(listeners, name, fn);
 676+ return self;
 677+ };
 678+ }
 679+ );
 680+
 681+
 682+ // core API methods
 683+ each(("pause,resume,mute,unmute,stop,toggle,seek,getStatus,getVolume,setVolume,getTime,isPaused,isPlaying,startBuffering,stopBuffering,isFullscreen,reset").split(","),
 684+ function() {
 685+ var name = this;
 686+
 687+ self[name] = function(arg) {
 688+ if (!api) { return self; }
 689+ var ret = (arg === undefined) ? api["fp_" + name]() : api["fp_" + name](arg);
 690+ return ret == 'undefined' ? self : ret;
 691+ };
 692+ }
 693+ );
 694+
 695+//}}}
 696+
 697+
 698+// {{{ public method: _fireEvent
 699+
 700+ self._fireEvent = function(evt, arg0, arg1, arg2) {
 701+
 702+ if (conf.debug) {
 703+ log(arguments);
 704+ }
 705+
 706+ // internal onLoad
 707+ if (evt == 'onLoad' && !api) {
 708+
 709+ api = api || el(apiId);
 710+ swfHeight = api.clientHeight;
 711+
 712+ each(playlist, function() {
 713+ this._fireEvent("onLoad");
 714+ });
 715+
 716+ each(plugins, function(name, p) {
 717+ p._fireEvent("onUpdate");
 718+ });
 719+
 720+
 721+ commonClip._fireEvent("onLoad");
 722+ }
 723+
 724+ if (evt == 'onContextMenu') {
 725+ each(conf.contextMenu[arg0], function(key, fn) {
 726+ fn.call(self);
 727+ });
 728+ return;
 729+ }
 730+
 731+ if (evt == 'onPluginEvent') {
 732+ var name = arg0.name || arg0;
 733+ var p = plugins[name];
 734+ if (p) {
 735+ if (arg0.name) {
 736+ p._fireEvent("onUpdate", arg0);
 737+ }
 738+ p._fireEvent(arg1);
 739+ }
 740+ return;
 741+ }
 742+
 743+ // onPlaylistReplace
 744+ if (evt == 'onPlaylistReplace') {
 745+ playlist = [];
 746+ var index = 0;
 747+ each(arg0, function() {
 748+ playlist.push(new Clip(this, index++));
 749+ });
 750+ }
 751+
 752+ var ret = true;
 753+
 754+ // clip event
 755+ if (arg0 === 0 || (arg0 && arg0 >= 0)) {
 756+
 757+ activeIndex = arg0;
 758+ var clip = playlist[arg0];
 759+
 760+ if (!clip || clip._fireEvent(evt, arg1, arg2) !== false) {
 761+
 762+ // clip argument is given for common clip, because it behaves as the target
 763+ ret = commonClip._fireEvent(evt, arg1, arg2, clip);
 764+ }
 765+ }
 766+
 767+ // player event
 768+ var i = 0;
 769+ each(listeners[evt], function() {
 770+ ret = this.call(self, arg0);
 771+
 772+ // remove cached entry
 773+ if (this.cached) {
 774+ listeners[evt].splice(i, 1);
 775+ }
 776+
 777+ // break loop
 778+ if (ret === false) { return false; }
 779+ i++;
 780+
 781+ });
 782+
 783+ return ret;
 784+ };
 785+
 786+//}}}
 787+
 788+
 789+// {{{ init
 790+
 791+ function init() {
 792+
 793+ if ($f(wrapper)) {
 794+ return null;
 795+ }
 796+
 797+ // register this player into global array of instances
 798+ players.push(self);
 799+
 800+
 801+ // flashembed parameters
 802+ if (typeof params == 'string') {
 803+ params = {src: params};
 804+ }
 805+
 806+ // playerId
 807+ playerId = wrapper.id || "fp" + makeId();
 808+ apiId = params.id || playerId + "_api";
 809+ params.id = apiId;
 810+ conf.playerId = playerId;
 811+
 812+
 813+ // plain url is given as config
 814+ if (typeof conf == 'string') {
 815+ conf = {clip:{url:conf}};
 816+ }
 817+
 818+ // common clip is always there
 819+ conf.clip = conf.clip || {};
 820+ commonClip = new Clip(conf.clip, -1, self);
 821+
 822+
 823+ // wrapper href as playlist
 824+ if (wrapper.getAttribute("href")) {
 825+ conf.playlist = [{url:wrapper.getAttribute("href", 2)}];
 826+ }
 827+
 828+ // playlist
 829+ conf.playlist = conf.playlist || [conf.clip];
 830+
 831+ var index = 0;
 832+ each(conf.playlist, function() {
 833+
 834+ var clip = this;
 835+
 836+ // clip is an array, we don't allow that
 837+ if (typeof clip == 'object' && clip.length) {
 838+ clip = "" + clip;
 839+ }
 840+
 841+ if (!clip.url && typeof clip == 'string') {
 842+ clip = {url: clip};
 843+ }
 844+
 845+ // populate common clip properties to each clip
 846+ extend(clip, conf.clip, true);
 847+
 848+ // modify configuration playlist
 849+ conf.playlist[index] = clip;
 850+
 851+ // populate playlist array
 852+ clip = new Clip(clip, index, self);
 853+ playlist.push(clip);
 854+ index++;
 855+ });
 856+
 857+
 858+ // event listeners
 859+ each(conf, function(key, val) {
 860+ if (typeof val == 'function') {
 861+ bind(listeners, key, val);
 862+ delete conf[key];
 863+ }
 864+ });
 865+
 866+
 867+ // plugins
 868+ each(conf.plugins, function(name, val) {
 869+ if (val) {
 870+ plugins[name] = new Plugin(name, val, self);
 871+ }
 872+ });
 873+
 874+
 875+ // setup controlbar plugin if not explicitly defined
 876+ if (!conf.plugins || conf.plugins.controls === undefined) {
 877+ plugins.controls = new Plugin("controls", null, self);
 878+ }
 879+
 880+ // Flowplayer uses black background by default
 881+ params.bgcolor = params.bgcolor || "#000000";
 882+
 883+
 884+ // setup default settings for express install
 885+ params.version = params.version || [9,0];
 886+ params.expressInstall = 'http://www.flowplayer.org/swf/expressinstall.swf';
 887+
 888+
 889+ // click function
 890+ function doClick(e) {
 891+ if (self._fireEvent("onBeforeClick") !== false) {
 892+ self.load();
 893+ }
 894+ return stopEvent(e);
 895+ }
 896+
 897+ // defer loading upon click
 898+ html = wrapper.innerHTML;
 899+ if (html.replace(/\s/g, '') !== '') {
 900+
 901+ if (wrapper.addEventListener) {
 902+ wrapper.addEventListener("click", doClick, false);
 903+
 904+ } else if (wrapper.attachEvent) {
 905+ wrapper.attachEvent("onclick", doClick);
 906+ }
 907+
 908+ // player is loaded upon page load
 909+ } else {
 910+
 911+ // prevent default action from wrapper (safari problem) loaded
 912+ if (wrapper.addEventListener) {
 913+ wrapper.addEventListener("click", stopEvent, false);
 914+ }
 915+
 916+ // load player
 917+ self.load();
 918+ }
 919+
 920+ }
 921+
 922+ // possibly defer initialization until DOM get's loaded
 923+ if (typeof wrapper == 'string') {
 924+ flashembed.domReady(function() {
 925+ var node = el(wrapper);
 926+
 927+ if (!node) {
 928+ throw "Flowplayer cannot access element: " + wrapper;
 929+ } else {
 930+ wrapper = node;
 931+ init();
 932+ }
 933+ });
 934+
 935+ // we have a DOM element so page is already loaded
 936+ } else {
 937+ init();
 938+ }
 939+
 940+
 941+//}}}
 942+
 943+
 944+}
 945+
 946+
 947+// {{{ flowplayer() & statics
 948+
 949+// container for player instances
 950+var players = [];
 951+
 952+
 953+// this object is returned when multiple player's are requested
 954+function Iterator(arr) {
 955+
 956+ this.length = arr.length;
 957+
 958+ this.each = function(fn) {
 959+ each(arr, fn);
 960+ };
 961+
 962+ this.size = function() {
 963+ return arr.length;
 964+ };
 965+}
 966+
 967+// these two variables are the only global variables
 968+window.flowplayer = window.$f = function() {
 969+
 970+ var instance = null;
 971+ var arg = arguments[0];
 972+
 973+
 974+ // $f()
 975+ if (!arguments.length) {
 976+ each(players, function() {
 977+ if (this.isLoaded()) {
 978+ instance = this;
 979+ return false;
 980+ }
 981+ });
 982+
 983+ return instance || players[0];
 984+ }
 985+
 986+ if (arguments.length == 1) {
 987+
 988+ // $f(index);
 989+ if (typeof arg == 'number') {
 990+ return players[arg];
 991+
 992+
 993+ // $f(wrapper || 'containerId' || '*');
 994+ } else {
 995+
 996+ // $f("*");
 997+ if (arg == '*') {
 998+ return new Iterator(players);
 999+ }
 1000+
 1001+ // $f(wrapper || 'containerId');
 1002+ each(players, function() {
 1003+ if (this.id() == arg.id || this.id() == arg || this.getParent() == arg) {
 1004+ instance = this;
 1005+ return false;
 1006+ }
 1007+ });
 1008+
 1009+ return instance;
 1010+ }
 1011+ }
 1012+
 1013+ // instance builder
 1014+ if (arguments.length > 1) {
 1015+
 1016+ var swf = arguments[1];
 1017+ var conf = (arguments.length == 3) ? arguments[2] : {};
 1018+
 1019+ if (typeof arg == 'string') {
 1020+
 1021+ // select arg by classname
 1022+ if (arg.indexOf(".") != -1) {
 1023+ var instances = [];
 1024+
 1025+ each(select(arg), function() {
 1026+ instances.push(new Player(this, clone(swf), clone(conf)));
 1027+ });
 1028+
 1029+ return new Iterator(instances);
 1030+
 1031+ // select node by id
 1032+ } else {
 1033+ var node = el(arg);
 1034+ return new Player(node !== null ? node : arg, swf, conf);
 1035+ }
 1036+
 1037+
 1038+ // arg is a DOM element
 1039+ } else if (arg) {
 1040+ return new Player(arg, swf, conf);
 1041+ }
 1042+
 1043+ }
 1044+
 1045+ return null;
 1046+};
 1047+
 1048+extend(window.$f, {
 1049+
 1050+ // called by Flash External Interface
 1051+ fireEvent: function(id, evt, a0, a1, a2) {
 1052+ var p = $f(id);
 1053+ return p ? p._fireEvent(evt, a0, a1, a2) : null;
 1054+ },
 1055+
 1056+
 1057+ // create plugins by modifying Player's prototype
 1058+ addPlugin: function(name, fn) {
 1059+ Player.prototype[name] = fn;
 1060+ return $f;
 1061+ },
 1062+
 1063+ // utility methods for plugin developers
 1064+ each: each,
 1065+
 1066+ extend: extend
 1067+
 1068+});
 1069+
 1070+//}}}
 1071+
 1072+
 1073+//{{{ jQuery support
 1074+
 1075+if (typeof jQuery == 'function') {
 1076+
 1077+ jQuery.prototype.flowplayer = function(params, conf) {
 1078+
 1079+ // select instances
 1080+ if (!arguments.length || typeof arguments[0] == 'number') {
 1081+ var arr = [];
 1082+ this.each(function() {
 1083+ var p = $f(this);
 1084+ if (p) {
 1085+ arr.push(p);
 1086+ }
 1087+ });
 1088+ return arguments.length ? arr[arguments[0]] : new Iterator(arr);
 1089+ }
 1090+
 1091+ // create flowplayer instances
 1092+ return this.each(function() {
 1093+ $f(this, clone(params), conf ? clone(conf) : {});
 1094+ });
 1095+
 1096+ };
 1097+
 1098+}
 1099+
 1100+//}}}
 1101+
 1102+
 1103+})();
 1104+/**
 1105+ * flashembed 0.33. Adobe Flash embedding script
 1106+ *
 1107+ * http://flowplayer.org/tools/flash-embed.html
 1108+ *
 1109+ * Copyright (c) 2008 Tero Piirainen (support@flowplayer.org)
 1110+ *
 1111+ * Released under the MIT License:
 1112+ * http://www.opensource.org/licenses/mit-license.php
 1113+ *
 1114+ * >> Basically you can do anything you want but leave this header as is <<
 1115+ *
 1116+ * first version 0.01 - 03/11/2008
 1117+ * version 0.33 - Mon Nov 03 2008 15:37:15 GMT-0000 (GMT+00:00)
 1118+ */
 1119+(function() {
 1120+
 1121+//{{{ utility functions
 1122+
 1123+var jQ = typeof jQuery == 'function';
 1124+
 1125+
 1126+// from "Pro JavaScript techniques" by John Resig
 1127+function isDomReady() {
 1128+ if (domReady.done) { return false; }
 1129+
 1130+ var d = document;
 1131+ if (d && d.getElementsByTagName && d.getElementById && d.body) {
 1132+ clearInterval(domReady.timer);
 1133+ domReady.timer = null;
 1134+
 1135+ for (var i = 0; i < domReady.ready.length; i++) {
 1136+ domReady.ready[i].call();
 1137+ }
 1138+
 1139+ domReady.ready = null;
 1140+ domReady.done = true;
 1141+ }
 1142+}
 1143+
 1144+// if jQuery is present, use it's more effective domReady method
 1145+var domReady = jQ ? jQuery : function(f) {
 1146+
 1147+ if (domReady.done) {
 1148+ return f();
 1149+ }
 1150+
 1151+ if (domReady.timer) {
 1152+ domReady.ready.push(f);
 1153+
 1154+ } else {
 1155+ domReady.ready = [f];
 1156+ domReady.timer = setInterval(isDomReady, 13);
 1157+ }
 1158+};
 1159+
 1160+
 1161+// override extend params function
 1162+function extend(to, from) {
 1163+ if (from) {
 1164+ for (key in from) {
 1165+ if (from.hasOwnProperty(key)) {
 1166+ to[key] = from[key];
 1167+ }
 1168+ }
 1169+ }
 1170+}
 1171+
 1172+
 1173+function concatVars(vars) {
 1174+ var out = "";
 1175+
 1176+ for (var key in vars) {
 1177+ if (vars[key]) {
 1178+ out += [key] + '=' + toString(vars[key]) + '&';
 1179+ }
 1180+ }
 1181+ return out.substring(0, out.length -1);
 1182+}
 1183+
 1184+
 1185+
 1186+// JSON.toString() function
 1187+function toString(obj) {
 1188+
 1189+ switch (typeOf(obj)){
 1190+ case 'string':
 1191+ obj = obj.replace(new RegExp('(["\\\\])', 'g'), '\\$1');
 1192+
 1193+ // flash does not handle %- characters well. transforms "50%" to "50pct" (a dirty hack, I admit)
 1194+ obj = obj.replace(/^\s?(\d+)%/, "$1pct");
 1195+ return '"' +obj+ '"';
 1196+
 1197+ case 'array':
 1198+ return '['+ map(obj, function(el) {
 1199+ return toString(el);
 1200+ }).join(',') +']';
 1201+
 1202+ case 'function':
 1203+ return '"function()"';
 1204+
 1205+ case 'object':
 1206+ var str = [];
 1207+ for (var prop in obj) {
 1208+ if (obj.hasOwnProperty(prop)) {
 1209+ str.push('"'+prop+'":'+ toString(obj[prop]));
 1210+ }
 1211+ }
 1212+ return '{'+str.join(',')+'}';
 1213+ }
 1214+
 1215+ // replace ' --> " and remove spaces
 1216+ return String(obj).replace(/\s/g, " ").replace(/\'/g, "\"");
 1217+}
 1218+
 1219+
 1220+// private functions
 1221+function typeOf(obj) {
 1222+ if (obj === null || obj === undefined) { return false; }
 1223+ var type = typeof obj;
 1224+ return (type == 'object' && obj.push) ? 'array' : type;
 1225+}
 1226+
 1227+
 1228+// version 9 bugfix: (http://blog.deconcept.com/2006/07/28/swfobject-143-released/)
 1229+if (window.attachEvent) {
 1230+ window.attachEvent("onbeforeunload", function() {
 1231+ __flash_unloadHandler = function() {};
 1232+ __flash_savedUnloadHandler = function() {};
 1233+ });
 1234+}
 1235+
 1236+function map(arr, func) {
 1237+ var newArr = [];
 1238+ for (var i in arr) {
 1239+ if (arr.hasOwnProperty(i)) {
 1240+ newArr[i] = func(arr[i]);
 1241+ }
 1242+ }
 1243+ return newArr;
 1244+}
 1245+
 1246+//}}}
 1247+
 1248+
 1249+window.flashembed = function(root, userParams, flashvars) {
 1250+
 1251+
 1252+//{{{ getHTML
 1253+
 1254+ function getHTML() {
 1255+
 1256+ var html = "";
 1257+ if (typeof flashvars == 'function') { flashvars = flashvars(); }
 1258+
 1259+
 1260+ // sometimes ie fails to load flash if it's on cache
 1261+ params.src += ((params.src.indexOf("?") != -1 ? "&" : "?") + Math.random());
 1262+
 1263+
 1264+ // mozilla
 1265+ if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) {
 1266+
 1267+ html = '<embed type="application/x-shockwave-flash" ';
 1268+
 1269+ if (params.id) {
 1270+ extend(params, {name:params.id});
 1271+ }
 1272+
 1273+ for (var key in params) {
 1274+ if (params[key] !== null) {
 1275+ html += [key] + '="' +params[key]+ '"\n\t';
 1276+ }
 1277+ }
 1278+
 1279+ if (flashvars) {
 1280+ html += 'flashvars=\'' + concatVars(flashvars) + '\'';
 1281+ }
 1282+
 1283+ // thanks Tom Price (07/17/2008)
 1284+ html += '/>';
 1285+
 1286+ // ie
 1287+ } else {
 1288+
 1289+ html = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" ';
 1290+ html += 'width="' + params.width + '" height="' + params.height + '"';
 1291+
 1292+ // force id for IE. otherwise embedded Flash object cannot be returned
 1293+ if (!params.id && document.all) {
 1294+ params.id = "_" + ("" + Math.random()).substring(5);
 1295+ }
 1296+
 1297+ if (params.id) {
 1298+ html += ' id="' + params.id + '"';
 1299+ }
 1300+
 1301+ html += '>';
 1302+ html += '\n\t<param name="movie" value="'+ params.src +'" />';
 1303+
 1304+ params.id = params.src = params.width = params.height = null;
 1305+
 1306+ for (var k in params) {
 1307+ if (params[k] !== null) {
 1308+ html += '\n\t<param name="'+ k +'" value="'+ params[k] +'" />';
 1309+ }
 1310+ }
 1311+
 1312+ if (flashvars) {
 1313+ html += '\n\t<param name="flashvars" value=\'' + concatVars(flashvars) + '\' />';
 1314+ }
 1315+
 1316+ html += "</object>";
 1317+ if (debug) {
 1318+ alert(html);
 1319+ }
 1320+
 1321+ }
 1322+
 1323+ return html;
 1324+ }
 1325+
 1326+ //}}}
 1327+
 1328+
 1329+//{{{ construction
 1330+
 1331+ // setup params
 1332+ var params = {
 1333+
 1334+ // very common params
 1335+ src: '#',
 1336+ width: '100%',
 1337+ height: '100%',
 1338+
 1339+ // flashembed specific options
 1340+ version:null,
 1341+ onFail:null,
 1342+ expressInstall:null,
 1343+ debug: false,
 1344+
 1345+ // flashembed defaults
 1346+ // bgcolor: 'transparent',
 1347+ allowfullscreen: true,
 1348+ allowscriptaccess: 'always',
 1349+ quality: 'high',
 1350+ type: 'application/x-shockwave-flash',
 1351+ pluginspage: 'http://www.adobe.com/go/getflashplayer'
 1352+ };
 1353+
 1354+
 1355+ if (typeof userParams == 'string') {
 1356+ userParams = {src: userParams};
 1357+ }
 1358+
 1359+ extend(params, userParams);
 1360+
 1361+ var version = flashembed.getVersion();
 1362+ var required = params.version;
 1363+ var express = params.expressInstall;
 1364+ var debug = params.debug;
 1365+
 1366+
 1367+ if (typeof root == 'string') {
 1368+ var el = document.getElementById(root);
 1369+ if (el) {
 1370+ root = el;
 1371+ } else {
 1372+ domReady(function() {
 1373+ flashembed(root, userParams, flashvars);
 1374+ });
 1375+ return;
 1376+ }
 1377+ }
 1378+
 1379+ if (!root) { return; }
 1380+
 1381+
 1382+ // is supported
 1383+ if (!required || flashembed.isSupported(required)) {
 1384+ params.onFail = params.version = params.expressInstall = params.debug = null;
 1385+
 1386+ // root.innerHTML may cause broplems: http://domscripting.com/blog/display/99
 1387+ // thanks to: Ryan Rud
 1388+ // var tmp = document.createElement("extradiv");
 1389+ // tmp.innerHTML = getHTML();
 1390+ // root.appendChild(tmp);
 1391+
 1392+ root.innerHTML = getHTML();
 1393+
 1394+ // return our API
 1395+ return root.firstChild;
 1396+
 1397+ // custom fail event
 1398+ } else if (params.onFail) {
 1399+ var ret = params.onFail.call(params, flashembed.getVersion(), flashvars);
 1400+ if (ret === true) { root.innerHTML = ret; }
 1401+
 1402+
 1403+ // express install
 1404+ } else if (required && express && flashembed.isSupported([6,65])) {
 1405+
 1406+ extend(params, {src: express});
 1407+
 1408+ flashvars = {
 1409+ MMredirectURL: location.href,
 1410+ MMplayerType: 'PlugIn',
 1411+ MMdoctitle: document.title
 1412+ };
 1413+
 1414+ root.innerHTML = getHTML();
 1415+
 1416+ // not supported
 1417+ } else {
 1418+
 1419+ // minor bug fixed here 08.04.2008 (thanks JRodman)
 1420+
 1421+ if (root.innerHTML.replace(/\s/g, '') !== '') {
 1422+ // custom content was supplied
 1423+
 1424+ } else {
 1425+ root.innerHTML =
 1426+ "<h2>Flash version " + required + " or greater is required</h2>" +
 1427+ "<h3>" +
 1428+ (version[0] > 0 ? "Your version is " + version : "You have no flash plugin installed") +
 1429+ "</h3>" +
 1430+ "<p>Download latest version from <a href='" + params.pluginspage + "'>here</a></p>";
 1431+ }
 1432+ }
 1433+
 1434+ return root;
 1435+
 1436+//}}}
 1437+
 1438+
 1439+};
 1440+
 1441+
 1442+//{{{ static methods
 1443+
 1444+extend(window.flashembed, {
 1445+
 1446+ // arr[major, minor, fix]
 1447+ getVersion: function() {
 1448+
 1449+ var version = [0, 0];
 1450+
 1451+ if (navigator.plugins && typeof navigator.plugins["Shockwave Flash"] == "object") {
 1452+ var _d = navigator.plugins["Shockwave Flash"].description;
 1453+ if (typeof _d != "undefined") {
 1454+ _d = _d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
 1455+ var _m = parseInt(_d.replace(/^(.*)\..*$/, "$1"), 10);
 1456+ var _r = /r/.test(_d) ? parseInt(_d.replace(/^.*r(.*)$/, "$1"), 10) : 0;
 1457+ version = [_m, _r];
 1458+ }
 1459+
 1460+ } else if (window.ActiveXObject) {
 1461+
 1462+ try { // avoid fp 6 crashes
 1463+ var _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
 1464+
 1465+ } catch(e) {
 1466+ try {
 1467+ _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
 1468+ version = [6, 0];
 1469+ _a.AllowScriptAccess = "always"; // throws if fp < 6.47
 1470+
 1471+ } catch(ee) {
 1472+ if (version[0] == 6) { return; }
 1473+ }
 1474+ try {
 1475+ _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
 1476+ } catch(eee) {
 1477+
 1478+ }
 1479+
 1480+ }
 1481+
 1482+ if (typeof _a == "object") {
 1483+ _d = _a.GetVariable("$version"); // bugs in fp 6.21 / 6.23
 1484+ if (typeof _d != "undefined") {
 1485+ _d = _d.replace(/^\S+\s+(.*)$/, "$1").split(",");
 1486+ version = [parseInt(_d[0], 10), parseInt(_d[2], 10)];
 1487+ }
 1488+ }
 1489+ }
 1490+
 1491+ return version;
 1492+ },
 1493+
 1494+ isSupported: function(version) {
 1495+ var now = flashembed.getVersion();
 1496+ var ret = (now[0] > version[0]) || (now[0] == version[0] && now[1] >= version[1]);
 1497+ return ret;
 1498+ },
 1499+
 1500+ domReady: domReady,
 1501+
 1502+ // returns a String representation from JSON object
 1503+ toString: toString
 1504+
 1505+});
 1506+
 1507+//}}}
 1508+
 1509+
 1510+// setup jquery support
 1511+if (jQ) {
 1512+
 1513+ jQuery.prototype.flashembed = function(params, flashvars) {
 1514+ return this.each(function() {
 1515+ flashembed(this, params, flashvars);
 1516+ });
 1517+ };
 1518+
 1519+}
 1520+
 1521+})();
Index: trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer/LICENSE.txt
@@ -0,0 +1,674 @@
 2+ GNU GENERAL PUBLIC LICENSE
 3+ Version 3, 29 June 2007
 4+
 5+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
 6+ Everyone is permitted to copy and distribute verbatim copies
 7+ of this license document, but changing it is not allowed.
 8+
 9+ Preamble
 10+
 11+ The GNU General Public License is a free, copyleft license for
 12+software and other kinds of works.
 13+
 14+ The licenses for most software and other practical works are designed
 15+to take away your freedom to share and change the works. By contrast,
 16+the GNU General Public License is intended to guarantee your freedom to
 17+share and change all versions of a program--to make sure it remains free
 18+software for all its users. We, the Free Software Foundation, use the
 19+GNU General Public License for most of our software; it applies also to
 20+any other work released this way by its authors. You can apply it to
 21+your programs, too.
 22+
 23+ When we speak of free software, we are referring to freedom, not
 24+price. Our General Public Licenses are designed to make sure that you
 25+have the freedom to distribute copies of free software (and charge for
 26+them if you wish), that you receive source code or can get it if you
 27+want it, that you can change the software or use pieces of it in new
 28+free programs, and that you know you can do these things.
 29+
 30+ To protect your rights, we need to prevent others from denying you
 31+these rights or asking you to surrender the rights. Therefore, you have
 32+certain responsibilities if you distribute copies of the software, or if
 33+you modify it: responsibilities to respect the freedom of others.
 34+
 35+ For example, if you distribute copies of such a program, whether
 36+gratis or for a fee, you must pass on to the recipients the same
 37+freedoms that you received. You must make sure that they, too, receive
 38+or can get the source code. And you must show them these terms so they
 39+know their rights.
 40+
 41+ Developers that use the GNU GPL protect your rights with two steps:
 42+(1) assert copyright on the software, and (2) offer you this License
 43+giving you legal permission to copy, distribute and/or modify it.
 44+
 45+ For the developers' and authors' protection, the GPL clearly explains
 46+that there is no warranty for this free software. For both users' and
 47+authors' sake, the GPL requires that modified versions be marked as
 48+changed, so that their problems will not be attributed erroneously to
 49+authors of previous versions.
 50+
 51+ Some devices are designed to deny users access to install or run
 52+modified versions of the software inside them, although the manufacturer
 53+can do so. This is fundamentally incompatible with the aim of
 54+protecting users' freedom to change the software. The systematic
 55+pattern of such abuse occurs in the area of products for individuals to
 56+use, which is precisely where it is most unacceptable. Therefore, we
 57+have designed this version of the GPL to prohibit the practice for those
 58+products. If such problems arise substantially in other domains, we
 59+stand ready to extend this provision to those domains in future versions
 60+of the GPL, as needed to protect the freedom of users.
 61+
 62+ Finally, every program is threatened constantly by software patents.
 63+States should not allow patents to restrict development and use of
 64+software on general-purpose computers, but in those that do, we wish to
 65+avoid the special danger that patents applied to a free program could
 66+make it effectively proprietary. To prevent this, the GPL assures that
 67+patents cannot be used to render the program non-free.
 68+
 69+ The precise terms and conditions for copying, distribution and
 70+modification follow.
 71+
 72+ TERMS AND CONDITIONS
 73+
 74+ 0. Definitions.
 75+
 76+ "This License" refers to version 3 of the GNU General Public License.
 77+
 78+ "Copyright" also means copyright-like laws that apply to other kinds of
 79+works, such as semiconductor masks.
 80+
 81+ "The Program" refers to any copyrightable work licensed under this
 82+License. Each licensee is addressed as "you". "Licensees" and
 83+"recipients" may be individuals or organizations.
 84+
 85+ To "modify" a work means to copy from or adapt all or part of the work
 86+in a fashion requiring copyright permission, other than the making of an
 87+exact copy. The resulting work is called a "modified version" of the
 88+earlier work or a work "based on" the earlier work.
 89+
 90+ A "covered work" means either the unmodified Program or a work based
 91+on the Program.
 92+
 93+ To "propagate" a work means to do anything with it that, without
 94+permission, would make you directly or secondarily liable for
 95+infringement under applicable copyright law, except executing it on a
 96+computer or modifying a private copy. Propagation includes copying,
 97+distribution (with or without modification), making available to the
 98+public, and in some countries other activities as well.
 99+
 100+ To "convey" a work means any kind of propagation that enables other
 101+parties to make or receive copies. Mere interaction with a user through
 102+a computer network, with no transfer of a copy, is not conveying.
 103+
 104+ An interactive user interface displays "Appropriate Legal Notices"
 105+to the extent that it includes a convenient and prominently visible
 106+feature that (1) displays an appropriate copyright notice, and (2)
 107+tells the user that there is no warranty for the work (except to the
 108+extent that warranties are provided), that licensees may convey the
 109+work under this License, and how to view a copy of this License. If
 110+the interface presents a list of user commands or options, such as a
 111+menu, a prominent item in the list meets this criterion.
 112+
 113+ 1. Source Code.
 114+
 115+ The "source code" for a work means the preferred form of the work
 116+for making modifications to it. "Object code" means any non-source
 117+form of a work.
 118+
 119+ A "Standard Interface" means an interface that either is an official
 120+standard defined by a recognized standards body, or, in the case of
 121+interfaces specified for a particular programming language, one that
 122+is widely used among developers working in that language.
 123+
 124+ The "System Libraries" of an executable work include anything, other
 125+than the work as a whole, that (a) is included in the normal form of
 126+packaging a Major Component, but which is not part of that Major
 127+Component, and (b) serves only to enable use of the work with that
 128+Major Component, or to implement a Standard Interface for which an
 129+implementation is available to the public in source code form. A
 130+"Major Component", in this context, means a major essential component
 131+(kernel, window system, and so on) of the specific operating system
 132+(if any) on which the executable work runs, or a compiler used to
 133+produce the work, or an object code interpreter used to run it.
 134+
 135+ The "Corresponding Source" for a work in object code form means all
 136+the source code needed to generate, install, and (for an executable
 137+work) run the object code and to modify the work, including scripts to
 138+control those activities. However, it does not include the work's
 139+System Libraries, or general-purpose tools or generally available free
 140+programs which are used unmodified in performing those activities but
 141+which are not part of the work. For example, Corresponding Source
 142+includes interface definition files associated with source files for
 143+the work, and the source code for shared libraries and dynamically
 144+linked subprograms that the work is specifically designed to require,
 145+such as by intimate data communication or control flow between those
 146+subprograms and other parts of the work.
 147+
 148+ The Corresponding Source need not include anything that users
 149+can regenerate automatically from other parts of the Corresponding
 150+Source.
 151+
 152+ The Corresponding Source for a work in source code form is that
 153+same work.
 154+
 155+ 2. Basic Permissions.
 156+
 157+ All rights granted under this License are granted for the term of
 158+copyright on the Program, and are irrevocable provided the stated
 159+conditions are met. This License explicitly affirms your unlimited
 160+permission to run the unmodified Program. The output from running a
 161+covered work is covered by this License only if the output, given its
 162+content, constitutes a covered work. This License acknowledges your
 163+rights of fair use or other equivalent, as provided by copyright law.
 164+
 165+ You may make, run and propagate covered works that you do not
 166+convey, without conditions so long as your license otherwise remains
 167+in force. You may convey covered works to others for the sole purpose
 168+of having them make modifications exclusively for you, or provide you
 169+with facilities for running those works, provided that you comply with
 170+the terms of this License in conveying all material for which you do
 171+not control copyright. Those thus making or running the covered works
 172+for you must do so exclusively on your behalf, under your direction
 173+and control, on terms that prohibit them from making any copies of
 174+your copyrighted material outside their relationship with you.
 175+
 176+ Conveying under any other circumstances is permitted solely under
 177+the conditions stated below. Sublicensing is not allowed; section 10
 178+makes it unnecessary.
 179+
 180+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
 181+
 182+ No covered work shall be deemed part of an effective technological
 183+measure under any applicable law fulfilling obligations under article
 184+11 of the WIPO copyright treaty adopted on 20 December 1996, or
 185+similar laws prohibiting or restricting circumvention of such
 186+measures.
 187+
 188+ When you convey a covered work, you waive any legal power to forbid
 189+circumvention of technological measures to the extent such circumvention
 190+is effected by exercising rights under this License with respect to
 191+the covered work, and you disclaim any intention to limit operation or
 192+modification of the work as a means of enforcing, against the work's
 193+users, your or third parties' legal rights to forbid circumvention of
 194+technological measures.
 195+
 196+ 4. Conveying Verbatim Copies.
 197+
 198+ You may convey verbatim copies of the Program's source code as you
 199+receive it, in any medium, provided that you conspicuously and
 200+appropriately publish on each copy an appropriate copyright notice;
 201+keep intact all notices stating that this License and any
 202+non-permissive terms added in accord with section 7 apply to the code;
 203+keep intact all notices of the absence of any warranty; and give all
 204+recipients a copy of this License along with the Program.
 205+
 206+ You may charge any price or no price for each copy that you convey,
 207+and you may offer support or warranty protection for a fee.
 208+
 209+ 5. Conveying Modified Source Versions.
 210+
 211+ You may convey a work based on the Program, or the modifications to
 212+produce it from the Program, in the form of source code under the
 213+terms of section 4, provided that you also meet all of these conditions:
 214+
 215+ a) The work must carry prominent notices stating that you modified
 216+ it, and giving a relevant date.
 217+
 218+ b) The work must carry prominent notices stating that it is
 219+ released under this License and any conditions added under section
 220+ 7. This requirement modifies the requirement in section 4 to
 221+ "keep intact all notices".
 222+
 223+ c) You must license the entire work, as a whole, under this
 224+ License to anyone who comes into possession of a copy. This
 225+ License will therefore apply, along with any applicable section 7
 226+ additional terms, to the whole of the work, and all its parts,
 227+ regardless of how they are packaged. This License gives no
 228+ permission to license the work in any other way, but it does not
 229+ invalidate such permission if you have separately received it.
 230+
 231+ d) If the work has interactive user interfaces, each must display
 232+ Appropriate Legal Notices; however, if the Program has interactive
 233+ interfaces that do not display Appropriate Legal Notices, your
 234+ work need not make them do so.
 235+
 236+ A compilation of a covered work with other separate and independent
 237+works, which are not by their nature extensions of the covered work,
 238+and which are not combined with it such as to form a larger program,
 239+in or on a volume of a storage or distribution medium, is called an
 240+"aggregate" if the compilation and its resulting copyright are not
 241+used to limit the access or legal rights of the compilation's users
 242+beyond what the individual works permit. Inclusion of a covered work
 243+in an aggregate does not cause this License to apply to the other
 244+parts of the aggregate.
 245+
 246+ 6. Conveying Non-Source Forms.
 247+
 248+ You may convey a covered work in object code form under the terms
 249+of sections 4 and 5, provided that you also convey the
 250+machine-readable Corresponding Source under the terms of this License,
 251+in one of these ways:
 252+
 253+ a) Convey the object code in, or embodied in, a physical product
 254+ (including a physical distribution medium), accompanied by the
 255+ Corresponding Source fixed on a durable physical medium
 256+ customarily used for software interchange.
 257+
 258+ b) Convey the object code in, or embodied in, a physical product
 259+ (including a physical distribution medium), accompanied by a
 260+ written offer, valid for at least three years and valid for as
 261+ long as you offer spare parts or customer support for that product
 262+ model, to give anyone who possesses the object code either (1) a
 263+ copy of the Corresponding Source for all the software in the
 264+ product that is covered by this License, on a durable physical
 265+ medium customarily used for software interchange, for a price no
 266+ more than your reasonable cost of physically performing this
 267+ conveying of source, or (2) access to copy the
 268+ Corresponding Source from a network server at no charge.
 269+
 270+ c) Convey individual copies of the object code with a copy of the
 271+ written offer to provide the Corresponding Source. This
 272+ alternative is allowed only occasionally and noncommercially, and
 273+ only if you received the object code with such an offer, in accord
 274+ with subsection 6b.
 275+
 276+ d) Convey the object code by offering access from a designated
 277+ place (gratis or for a charge), and offer equivalent access to the
 278+ Corresponding Source in the same way through the same place at no
 279+ further charge. You need not require recipients to copy the
 280+ Corresponding Source along with the object code. If the place to
 281+ copy the object code is a network server, the Corresponding Source
 282+ may be on a different server (operated by you or a third party)
 283+ that supports equivalent copying facilities, provided you maintain
 284+ clear directions next to the object code saying where to find the
 285+ Corresponding Source. Regardless of what server hosts the
 286+ Corresponding Source, you remain obligated to ensure that it is
 287+ available for as long as needed to satisfy these requirements.
 288+
 289+ e) Convey the object code using peer-to-peer transmission, provided
 290+ you inform other peers where the object code and Corresponding
 291+ Source of the work are being offered to the general public at no
 292+ charge under subsection 6d.
 293+
 294+ A separable portion of the object code, whose source code is excluded
 295+from the Corresponding Source as a System Library, need not be
 296+included in conveying the object code work.
 297+
 298+ A "User Product" is either (1) a "consumer product", which means any
 299+tangible personal property which is normally used for personal, family,
 300+or household purposes, or (2) anything designed or sold for incorporation
 301+into a dwelling. In determining whether a product is a consumer product,
 302+doubtful cases shall be resolved in favor of coverage. For a particular
 303+product received by a particular user, "normally used" refers to a
 304+typical or common use of that class of product, regardless of the status
 305+of the particular user or of the way in which the particular user
 306+actually uses, or expects or is expected to use, the product. A product
 307+is a consumer product regardless of whether the product has substantial
 308+commercial, industrial or non-consumer uses, unless such uses represent
 309+the only significant mode of use of the product.
 310+
 311+ "Installation Information" for a User Product means any methods,
 312+procedures, authorization keys, or other information required to install
 313+and execute modified versions of a covered work in that User Product from
 314+a modified version of its Corresponding Source. The information must
 315+suffice to ensure that the continued functioning of the modified object
 316+code is in no case prevented or interfered with solely because
 317+modification has been made.
 318+
 319+ If you convey an object code work under this section in, or with, or
 320+specifically for use in, a User Product, and the conveying occurs as
 321+part of a transaction in which the right of possession and use of the
 322+User Product is transferred to the recipient in perpetuity or for a
 323+fixed term (regardless of how the transaction is characterized), the
 324+Corresponding Source conveyed under this section must be accompanied
 325+by the Installation Information. But this requirement does not apply
 326+if neither you nor any third party retains the ability to install
 327+modified object code on the User Product (for example, the work has
 328+been installed in ROM).
 329+
 330+ The requirement to provide Installation Information does not include a
 331+requirement to continue to provide support service, warranty, or updates
 332+for a work that has been modified or installed by the recipient, or for
 333+the User Product in which it has been modified or installed. Access to a
 334+network may be denied when the modification itself materially and
 335+adversely affects the operation of the network or violates the rules and
 336+protocols for communication across the network.
 337+
 338+ Corresponding Source conveyed, and Installation Information provided,
 339+in accord with this section must be in a format that is publicly
 340+documented (and with an implementation available to the public in
 341+source code form), and must require no special password or key for
 342+unpacking, reading or copying.
 343+
 344+ 7. Additional Terms.
 345+
 346+ "Additional permissions" are terms that supplement the terms of this
 347+License by making exceptions from one or more of its conditions.
 348+Additional permissions that are applicable to the entire Program shall
 349+be treated as though they were included in this License, to the extent
 350+that they are valid under applicable law. If additional permissions
 351+apply only to part of the Program, that part may be used separately
 352+under those permissions, but the entire Program remains governed by
 353+this License without regard to the additional permissions.
 354+
 355+ When you convey a copy of a covered work, you may at your option
 356+remove any additional permissions from that copy, or from any part of
 357+it. (Additional permissions may be written to require their own
 358+removal in certain cases when you modify the work.) You may place
 359+additional permissions on material, added by you to a covered work,
 360+for which you have or can give appropriate copyright permission.
 361+
 362+ Notwithstanding any other provision of this License, for material you
 363+add to a covered work, you may (if authorized by the copyright holders of
 364+that material) supplement the terms of this License with terms:
 365+
 366+ a) Disclaiming warranty or limiting liability differently from the
 367+ terms of sections 15 and 16 of this License; or
 368+
 369+ b) Requiring preservation of specified reasonable legal notices or
 370+ author attributions in that material or in the Appropriate Legal
 371+ Notices displayed by works containing it; or
 372+
 373+ c) Prohibiting misrepresentation of the origin of that material, or
 374+ requiring that modified versions of such material be marked in
 375+ reasonable ways as different from the original version; or
 376+
 377+ d) Limiting the use for publicity purposes of names of licensors or
 378+ authors of the material; or
 379+
 380+ e) Declining to grant rights under trademark law for use of some
 381+ trade names, trademarks, or service marks; or
 382+
 383+ f) Requiring indemnification of licensors and authors of that
 384+ material by anyone who conveys the material (or modified versions of
 385+ it) with contractual assumptions of liability to the recipient, for
 386+ any liability that these contractual assumptions directly impose on
 387+ those licensors and authors.
 388+
 389+ All other non-permissive additional terms are considered "further
 390+restrictions" within the meaning of section 10. If the Program as you
 391+received it, or any part of it, contains a notice stating that it is
 392+governed by this License along with a term that is a further
 393+restriction, you may remove that term. If a license document contains
 394+a further restriction but permits relicensing or conveying under this
 395+License, you may add to a covered work material governed by the terms
 396+of that license document, provided that the further restriction does
 397+not survive such relicensing or conveying.
 398+
 399+ If you add terms to a covered work in accord with this section, you
 400+must place, in the relevant source files, a statement of the
 401+additional terms that apply to those files, or a notice indicating
 402+where to find the applicable terms.
 403+
 404+ Additional terms, permissive or non-permissive, may be stated in the
 405+form of a separately written license, or stated as exceptions;
 406+the above requirements apply either way.
 407+
 408+ 8. Termination.
 409+
 410+ You may not propagate or modify a covered work except as expressly
 411+provided under this License. Any attempt otherwise to propagate or
 412+modify it is void, and will automatically terminate your rights under
 413+this License (including any patent licenses granted under the third
 414+paragraph of section 11).
 415+
 416+ However, if you cease all violation of this License, then your
 417+license from a particular copyright holder is reinstated (a)
 418+provisionally, unless and until the copyright holder explicitly and
 419+finally terminates your license, and (b) permanently, if the copyright
 420+holder fails to notify you of the violation by some reasonable means
 421+prior to 60 days after the cessation.
 422+
 423+ Moreover, your license from a particular copyright holder is
 424+reinstated permanently if the copyright holder notifies you of the
 425+violation by some reasonable means, this is the first time you have
 426+received notice of violation of this License (for any work) from that
 427+copyright holder, and you cure the violation prior to 30 days after
 428+your receipt of the notice.
 429+
 430+ Termination of your rights under this section does not terminate the
 431+licenses of parties who have received copies or rights from you under
 432+this License. If your rights have been terminated and not permanently
 433+reinstated, you do not qualify to receive new licenses for the same
 434+material under section 10.
 435+
 436+ 9. Acceptance Not Required for Having Copies.
 437+
 438+ You are not required to accept this License in order to receive or
 439+run a copy of the Program. Ancillary propagation of a covered work
 440+occurring solely as a consequence of using peer-to-peer transmission
 441+to receive a copy likewise does not require acceptance. However,
 442+nothing other than this License grants you permission to propagate or
 443+modify any covered work. These actions infringe copyright if you do
 444+not accept this License. Therefore, by modifying or propagating a
 445+covered work, you indicate your acceptance of this License to do so.
 446+
 447+ 10. Automatic Licensing of Downstream Recipients.
 448+
 449+ Each time you convey a covered work, the recipient automatically
 450+receives a license from the original licensors, to run, modify and
 451+propagate that work, subject to this License. You are not responsible
 452+for enforcing compliance by third parties with this License.
 453+
 454+ An "entity transaction" is a transaction transferring control of an
 455+organization, or substantially all assets of one, or subdividing an
 456+organization, or merging organizations. If propagation of a covered
 457+work results from an entity transaction, each party to that
 458+transaction who receives a copy of the work also receives whatever
 459+licenses to the work the party's predecessor in interest had or could
 460+give under the previous paragraph, plus a right to possession of the
 461+Corresponding Source of the work from the predecessor in interest, if
 462+the predecessor has it or can get it with reasonable efforts.
 463+
 464+ You may not impose any further restrictions on the exercise of the
 465+rights granted or affirmed under this License. For example, you may
 466+not impose a license fee, royalty, or other charge for exercise of
 467+rights granted under this License, and you may not initiate litigation
 468+(including a cross-claim or counterclaim in a lawsuit) alleging that
 469+any patent claim is infringed by making, using, selling, offering for
 470+sale, or importing the Program or any portion of it.
 471+
 472+ 11. Patents.
 473+
 474+ A "contributor" is a copyright holder who authorizes use under this
 475+License of the Program or a work on which the Program is based. The
 476+work thus licensed is called the contributor's "contributor version".
 477+
 478+ A contributor's "essential patent claims" are all patent claims
 479+owned or controlled by the contributor, whether already acquired or
 480+hereafter acquired, that would be infringed by some manner, permitted
 481+by this License, of making, using, or selling its contributor version,
 482+but do not include claims that would be infringed only as a
 483+consequence of further modification of the contributor version. For
 484+purposes of this definition, "control" includes the right to grant
 485+patent sublicenses in a manner consistent with the requirements of
 486+this License.
 487+
 488+ Each contributor grants you a non-exclusive, worldwide, royalty-free
 489+patent license under the contributor's essential patent claims, to
 490+make, use, sell, offer for sale, import and otherwise run, modify and
 491+propagate the contents of its contributor version.
 492+
 493+ In the following three paragraphs, a "patent license" is any express
 494+agreement or commitment, however denominated, not to enforce a patent
 495+(such as an express permission to practice a patent or covenant not to
 496+sue for patent infringement). To "grant" such a patent license to a
 497+party means to make such an agreement or commitment not to enforce a
 498+patent against the party.
 499+
 500+ If you convey a covered work, knowingly relying on a patent license,
 501+and the Corresponding Source of the work is not available for anyone
 502+to copy, free of charge and under the terms of this License, through a
 503+publicly available network server or other readily accessible means,
 504+then you must either (1) cause the Corresponding Source to be so
 505+available, or (2) arrange to deprive yourself of the benefit of the
 506+patent license for this particular work, or (3) arrange, in a manner
 507+consistent with the requirements of this License, to extend the patent
 508+license to downstream recipients. "Knowingly relying" means you have
 509+actual knowledge that, but for the patent license, your conveying the
 510+covered work in a country, or your recipient's use of the covered work
 511+in a country, would infringe one or more identifiable patents in that
 512+country that you have reason to believe are valid.
 513+
 514+ If, pursuant to or in connection with a single transaction or
 515+arrangement, you convey, or propagate by procuring conveyance of, a
 516+covered work, and grant a patent license to some of the parties
 517+receiving the covered work authorizing them to use, propagate, modify
 518+or convey a specific copy of the covered work, then the patent license
 519+you grant is automatically extended to all recipients of the covered
 520+work and works based on it.
 521+
 522+ A patent license is "discriminatory" if it does not include within
 523+the scope of its coverage, prohibits the exercise of, or is
 524+conditioned on the non-exercise of one or more of the rights that are
 525+specifically granted under this License. You may not convey a covered
 526+work if you are a party to an arrangement with a third party that is
 527+in the business of distributing software, under which you make payment
 528+to the third party based on the extent of your activity of conveying
 529+the work, and under which the third party grants, to any of the
 530+parties who would receive the covered work from you, a discriminatory
 531+patent license (a) in connection with copies of the covered work
 532+conveyed by you (or copies made from those copies), or (b) primarily
 533+for and in connection with specific products or compilations that
 534+contain the covered work, unless you entered into that arrangement,
 535+or that patent license was granted, prior to 28 March 2007.
 536+
 537+ Nothing in this License shall be construed as excluding or limiting
 538+any implied license or other defenses to infringement that may
 539+otherwise be available to you under applicable patent law.
 540+
 541+ 12. No Surrender of Others' Freedom.
 542+
 543+ If conditions are imposed on you (whether by court order, agreement or
 544+otherwise) that contradict the conditions of this License, they do not
 545+excuse you from the conditions of this License. If you cannot convey a
 546+covered work so as to satisfy simultaneously your obligations under this
 547+License and any other pertinent obligations, then as a consequence you may
 548+not convey it at all. For example, if you agree to terms that obligate you
 549+to collect a royalty for further conveying from those to whom you convey
 550+the Program, the only way you could satisfy both those terms and this
 551+License would be to refrain entirely from conveying the Program.
 552+
 553+ 13. Use with the GNU Affero General Public License.
 554+
 555+ Notwithstanding any other provision of this License, you have
 556+permission to link or combine any covered work with a work licensed
 557+under version 3 of the GNU Affero General Public License into a single
 558+combined work, and to convey the resulting work. The terms of this
 559+License will continue to apply to the part which is the covered work,
 560+but the special requirements of the GNU Affero General Public License,
 561+section 13, concerning interaction through a network will apply to the
 562+combination as such.
 563+
 564+ 14. Revised Versions of this License.
 565+
 566+ The Free Software Foundation may publish revised and/or new versions of
 567+the GNU General Public License from time to time. Such new versions will
 568+be similar in spirit to the present version, but may differ in detail to
 569+address new problems or concerns.
 570+
 571+ Each version is given a distinguishing version number. If the
 572+Program specifies that a certain numbered version of the GNU General
 573+Public License "or any later version" applies to it, you have the
 574+option of following the terms and conditions either of that numbered
 575+version or of any later version published by the Free Software
 576+Foundation. If the Program does not specify a version number of the
 577+GNU General Public License, you may choose any version ever published
 578+by the Free Software Foundation.
 579+
 580+ If the Program specifies that a proxy can decide which future
 581+versions of the GNU General Public License can be used, that proxy's
 582+public statement of acceptance of a version permanently authorizes you
 583+to choose that version for the Program.
 584+
 585+ Later license versions may give you additional or different
 586+permissions. However, no additional obligations are imposed on any
 587+author or copyright holder as a result of your choosing to follow a
 588+later version.
 589+
 590+ 15. Disclaimer of Warranty.
 591+
 592+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
 593+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
 594+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
 595+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
 596+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 597+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
 598+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
 599+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
 600+
 601+ 16. Limitation of Liability.
 602+
 603+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
 604+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
 605+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
 606+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
 607+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
 608+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
 609+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
 610+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
 611+SUCH DAMAGES.
 612+
 613+ 17. Interpretation of Sections 15 and 16.
 614+
 615+ If the disclaimer of warranty and limitation of liability provided
 616+above cannot be given local legal effect according to their terms,
 617+reviewing courts shall apply local law that most closely approximates
 618+an absolute waiver of all civil liability in connection with the
 619+Program, unless a warranty or assumption of liability accompanies a
 620+copy of the Program in return for a fee.
 621+
 622+ END OF TERMS AND CONDITIONS
 623+
 624+ How to Apply These Terms to Your New Programs
 625+
 626+ If you develop a new program, and you want it to be of the greatest
 627+possible use to the public, the best way to achieve this is to make it
 628+free software which everyone can redistribute and change under these terms.
 629+
 630+ To do so, attach the following notices to the program. It is safest
 631+to attach them to the start of each source file to most effectively
 632+state the exclusion of warranty; and each file should have at least
 633+the "copyright" line and a pointer to where the full notice is found.
 634+
 635+ <one line to give the program's name and a brief idea of what it does.>
 636+ Copyright (C) <year> <name of author>
 637+
 638+ This program is free software: you can redistribute it and/or modify
 639+ it under the terms of the GNU General Public License as published by
 640+ the Free Software Foundation, either version 3 of the License, or
 641+ (at your option) any later version.
 642+
 643+ This program is distributed in the hope that it will be useful,
 644+ but WITHOUT ANY WARRANTY; without even the implied warranty of
 645+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 646+ GNU General Public License for more details.
 647+
 648+ You should have received a copy of the GNU General Public License
 649+ along with this program. If not, see <http://www.gnu.org/licenses/>.
 650+
 651+Also add information on how to contact you by electronic and paper mail.
 652+
 653+ If the program does terminal interaction, make it output a short
 654+notice like this when it starts in an interactive mode:
 655+
 656+ <program> Copyright (C) <year> <name of author>
 657+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
 658+ This is free software, and you are welcome to redistribute it
 659+ under certain conditions; type `show c' for details.
 660+
 661+The hypothetical commands `show w' and `show c' should show the appropriate
 662+parts of the General Public License. Of course, your program's commands
 663+might be different; for a GUI interface, you would use an "about box".
 664+
 665+ You should also get your employer (if you work as a programmer) or school,
 666+if any, to sign a "copyright disclaimer" for the program, if necessary.
 667+For more information on this, and how to apply and follow the GNU GPL, see
 668+<http://www.gnu.org/licenses/>.
 669+
 670+ The GNU General Public License does not permit incorporating your program
 671+into proprietary programs. If your program is a subroutine library, you
 672+may consider it more useful to permit linking proprietary applications with
 673+the library. If this is what you want to do, use the GNU Lesser General
 674+Public License instead of this License. But first, please read
 675+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
\ No newline at end of file
Index: trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer/flowplayer-3.0.0-rc2.min.js
@@ -0,0 +1,15 @@
 2+/**
 3+ * flowplayer.js 3.0.0-rc2. The Flowplayer API.
 4+ *
 5+ * This file is part of Flowplayer, http://flowplayer.org
 6+ *
 7+ * Author: Tero Piirainen, <support@flowplayer.org>
 8+ * Copyright (c) 2008 Flowplayer Ltd
 9+ *
 10+ * Released under the MIT License:
 11+ * http://www.opensource.org/licenses/mit-license.php
 12+ *
 13+ * Version: 3.0.0-rc2 - Fri Nov 07 2008 16:50:52 GMT-0000 (GMT+00:00)
 14+ */
 15+(function(){function log(args){if(typeof opera=='object'){opera.postError("$f.fireEvent: "+args.join(" | "));}else if(typeof console=='object'){console.log("$f.fireEvent",[].slice.call(args));}}function clone(obj){if(!obj||typeof obj!='object'){return obj;}var temp=new obj.constructor();for(var key in obj){if(obj.hasOwnProperty(key)){temp[key]=clone(obj[key]);}}return temp;}function each(obj,fn){if(!obj){return;}var name,i=0,length=obj.length;if(length===undefined){for(name in obj){if(fn.call(obj[name],name,obj[name])===false){break;}}}else{for(var value=obj[0];i<length&&fn.call(value,i,value)!==false;value=obj[++i]){}}return obj;}function el(id){return document.getElementById(id);}function extend(to,from,skipFuncs){if(to&&from){each(from,function(name,value){if(!skipFuncs||typeof value!='function'){to[name]=value;}});}}function select(query){var index=query.indexOf(".");if(index!=-1){var tag=query.substring(0,index)||"*";var klass=query.substring(index+1,query.length);var els=[];each(document.getElementsByTagName(tag),function(){if(this.className&&this.className.indexOf(klass)!=-1){els.push(this);}});return els;}}function stopEvent(e){e=e||window.event;if(e.preventDefault){e.stopPropagation();e.preventDefault();}else{e.returnValue=false;e.cancelBubble=true;}return false;}function bind(to,evt,fn){to[evt]=to[evt]||[];to[evt].push(fn);}function makeId(){return"_"+(""+Math.random()).substring(2,10);}var Clip=function(json,index,player){var self=this;var cuepoints={};var listeners={};this.index=index;if(typeof json=='string'){json={url:json};}extend(this,json,true);each(("Start*,MetaData,Pause*,Resume*,Seek*,Stop*,Finish,LastSecond,Update,BufferFull,BufferEmpty").split(","),function(){var evt="on"+this;if(evt.indexOf("*")!=-1){evt=evt.substring(0,evt.length-1);var before="onBefore"+evt.substring(2);self[before]=function(fn){bind(listeners,before,fn);return self;};}self[evt]=function(fn){bind(listeners,evt,fn);return self;};if(index==-1){if(self[before]){player[before]=self[before];}if(self[evt]){player[evt]=self[evt];}}});extend(this,{onCuepoint:function(points,fn){if(arguments.length==1){cuepoints.embedded=[null,points];return self;}if(typeof points=='number'){points=[points];}var fnId=makeId();cuepoints[fnId]=[points,fn];if(player.isLoaded()){player._api().fp_addCuepoints(points,index,fnId);}return self;},update:function(json){extend(self,json);if(player.isLoaded()){player._api().fp_updateClip(json,index);}var conf=player._config();var clip=(index==-1)?conf.clip:conf.playlist[index];extend(clip,json,true);},_fireEvent:function(evt,arg1,arg2,target){if(evt=='onLoad'){each(cuepoints,function(key,val){player._api().fp_addCuepoints(val[0],index,key);});return false;}if(index!=-1){target=self;}if(evt=='onCuepoint'){var fn=cuepoints[arg1];if(fn){return fn[1].call(player,target,arg2);}}if(evt=='onMetaData'||evt=='onUpdate'){extend(target,arg1);if(!target.duration){target.duration=arg1.metaData.duration;}else{target.fullDuration=arg1.metaData.duration;}}var ret=true;each(listeners[evt],function(){ret=this.call(player,target,arg1);});return ret;}});if(json.onCuepoint){self.onCuepoint.apply(self,json.onCuepoint);delete json.onCuepoint;}each(json,function(key,val){if(typeof val=='function'){bind(listeners,key,val);delete json[key];}});if(index==-1){player.onCuepoint=this.onCuepoint;}};var Plugin=function(name,json,player,fn){var listeners={};var self=this;var hasMethods=false;if(fn){extend(listeners,fn);}each(json,function(key,val){if(typeof val=='function'){listeners[key]=val;delete json[key];}});extend(this,{animate:function(props,speed,fn){if(!props){return self;}if(typeof speed=='function'){fn=speed;speed=500;}if(typeof props=='string'){var key=props;props={};props[key]=speed;speed=500;}if(fn){var fnId=makeId();listeners[fnId]=fn;}if(speed===undefined){speed=500;}json=player._api().fp_animate(name,props,speed,fnId);return self;},css:function(props,val){if(val!==undefined){var css={};css[props]=val;props=css;}json=player._api().fp_css(name,props);extend(self,json);return self;},show:function(){this.display='block';player._api().fp_showPlugin(name);return self;},hide:function(){this.display='none';player._api().fp_hidePlugin(name);return self;},toggle:function(){this.display=player._api().fp_togglePlugin(name);return self;},fadeTo:function(o,speed,fn){if(typeof speed=='function'){fn=speed;speed=500;}if(fn){var fnId=makeId();listeners[fnId]=fn;}this.display=player._api().fp_fadeTo(name,o,speed,fnId);this.opacity=o;return self;},fadeIn:function(speed,fn){return self.fadeTo(1,speed,fn);},fadeOut:function(speed,fn){return self.fadeTo(0,speed,fn);},getName:function(){return name;},_fireEvent:function(evt,arg){if(evt=='onUpdate'){var json=arg||player._api().fp_getPlugin(name);if(!json){return;}extend(self,json);delete self.methods;if(!hasMethods){each(json.methods,function(){var method=""+this;self[method]=function(){var a=[].slice.call(arguments);var ret=player._api().fp_invoke(name,method,a);return ret=='undefined'?self:ret;};});hasMethods=true;}}var fn=listeners[evt];if(fn){fn.call(self,arg);if(evt.substring(0,1)=="_"){delete listeners[evt];}}}});};function Player(wrapper,params,conf){var
 16+self=this,api=null,html,commonClip,playlist=[],plugins={},listeners={},playerId,apiId,activeIndex,swfHeight;extend(self,{id:function(){return playerId;},isLoaded:function(){return(api!==null);},getParent:function(){return wrapper;},hide:function(){if(api){api.style.height="0px";}return self;},show:function(){if(api){api.style.height=swfHeight+"px";}return self;},isHidden:function(){return api&&parseInt(api.style.height,10)===0;},load:function(fn){if(!api&&self._fireEvent("onBeforeLoad")!==false){each(players,function(){this.unload();});html=wrapper.innerHTML;flashembed(wrapper,params,{config:conf});if(fn){fn.cached=true;bind(listeners,"onLoad",fn);}}return self;},unload:function(){if(api&&html.replace(/\s/g,'')!==''&&!api.fp_isFullscreen()&&self._fireEvent("onBeforeUnload")!==false){api.fp_close();wrapper.innerHTML=html;self._fireEvent("onUnload");api=null;}return self;},getClip:function(index){if(index===undefined){index=activeIndex;}return playlist[index];},getCommonClip:function(){return commonClip;},getPlaylist:function(){return playlist;},getPlugin:function(name){var plugin=plugins[name];if(!plugin&&self.isLoaded()){var json=self._api().fp_getPlugin(name);if(json){plugin=new Plugin(name,json,self);plugins[name]=plugin;}}return plugin;},getScreen:function(){return self.getPlugin("screen");},getControls:function(){return self.getPlugin("controls");},getConfig:function(){return clone(conf);},getFlashParams:function(){return params;},loadPlugin:function(name,url,props,fn){if(typeof props=='function'){fn=props;props={};}var fnId=fn?makeId():"_";self._api().fp_loadPlugin(name,url,props,fnId);var arg={};arg[fnId]=fn;var p=new Plugin(name,null,self,arg);plugins[name]=p;return p;},getState:function(){return api?api.fp_getState():-1;},play:function(clip){function play(){if(clip!==undefined){self._api().fp_play(clip);}else{self._api().fp_play();}}if(api){play();}else{self.load(function(){play();});}return self;},getVersion:function(){var js="flowplayer.js 3.0.0-rc2";if(api){var ver=api.fp_getVersion();ver.push(js);return ver;}return js;},_api:function(){if(!api){throw"Flowplayer "+self.id()+" not loaded. Try moving your call to player's onLoad event";}return api;},_config:function(){return conf;}});each(("Click*,Load*,Unload*,Keypress*,Volume*,Mute*,Unmute*,PlaylistReplace,Fullscreen*,FullscreenExit,Error").split(","),function(){var name="on"+this;if(name.indexOf("*")!=-1){name=name.substring(0,name.length-1);var name2="onBefore"+name.substring(2);self[name2]=function(fn){bind(listeners,name2,fn);return self;};}self[name]=function(fn){bind(listeners,name,fn);return self;};});each(("pause,resume,mute,unmute,stop,toggle,seek,getStatus,getVolume,setVolume,getTime,isPaused,isPlaying,startBuffering,stopBuffering,isFullscreen,reset").split(","),function(){var name=this;self[name]=function(arg){if(!api){return self;}var ret=(arg===undefined)?api["fp_"+name]():api["fp_"+name](arg);return ret=='undefined'?self:ret;};});self._fireEvent=function(evt,arg0,arg1,arg2){if(conf.debug){log(arguments);}if(evt=='onLoad'&&!api){api=api||el(apiId);swfHeight=api.clientHeight;each(playlist,function(){this._fireEvent("onLoad");});each(plugins,function(name,p){p._fireEvent("onUpdate");});commonClip._fireEvent("onLoad");}if(evt=='onContextMenu'){each(conf.contextMenu[arg0],function(key,fn){fn.call(self);});return;}if(evt=='onPluginEvent'){var name=arg0.name||arg0;var p=plugins[name];if(p){if(arg0.name){p._fireEvent("onUpdate",arg0);}p._fireEvent(arg1);}return;}if(evt=='onPlaylistReplace'){playlist=[];var index=0;each(arg0,function(){playlist.push(new Clip(this,index++));});}var ret=true;if(arg0===0||(arg0&&arg0>=0)){activeIndex=arg0;var clip=playlist[arg0];if(!clip||clip._fireEvent(evt,arg1,arg2)!==false){ret=commonClip._fireEvent(evt,arg1,arg2,clip);}}var i=0;each(listeners[evt],function(){ret=this.call(self,arg0);if(this.cached){listeners[evt].splice(i,1);}if(ret===false){return false;}i++;});return ret;};function init(){if($f(wrapper)){return null;}players.push(self);if(typeof params=='string'){params={src:params};}playerId=wrapper.id||"fp"+makeId();apiId=params.id||playerId+"_api";params.id=apiId;conf.playerId=playerId;if(typeof conf=='string'){conf={clip:{url:conf}};}conf.clip=conf.clip||{};commonClip=new Clip(conf.clip,-1,self);if(wrapper.getAttribute("href")){conf.playlist=[{url:wrapper.getAttribute("href",2)}];}conf.playlist=conf.playlist||[conf.clip];var index=0;each(conf.playlist,function(){var clip=this;if(typeof clip=='object'&&clip.length){clip=""+clip;}if(!clip.url&&typeof clip=='string'){clip={url:clip};}extend(clip,conf.clip,true);conf.playlist[index]=clip;clip=new Clip(clip,index,self);playlist.push(clip);index++;});each(conf,function(key,val){if(typeof val=='function'){bind(listeners,key,val);delete conf[key];}});each(conf.plugins,function(name,val){if(val){plugins[name]=new Plugin(name,val,self);}});if(!conf.plugins||conf.plugins.controls===undefined){plugins.controls=new Plugin("controls",null,self);}params.bgcolor=params.bgcolor||"#000000";params.version=params.version||[9,0];params.expressInstall='http://www.flowplayer.org/swf/expressinstall.swf';function doClick(e){if(self._fireEvent("onBeforeClick")!==false){self.load();}return stopEvent(e);}html=wrapper.innerHTML;if(html.replace(/\s/g,'')!==''){if(wrapper.addEventListener){wrapper.addEventListener("click",doClick,false);}else if(wrapper.attachEvent){wrapper.attachEvent("onclick",doClick);}}else{if(wrapper.addEventListener){wrapper.addEventListener("click",stopEvent,false);}self.load();}}if(typeof wrapper=='string'){flashembed.domReady(function(){var node=el(wrapper);if(!node){throw"Flowplayer cannot access element: "+wrapper;}else{wrapper=node;init();}});}else{init();}}var players=[];function Iterator(arr){this.length=arr.length;this.each=function(fn){each(arr,fn);};this.size=function(){return arr.length;};}window.flowplayer=window.$f=function(){var instance=null;var arg=arguments[0];if(!arguments.length){each(players,function(){if(this.isLoaded()){instance=this;return false;}});return instance||players[0];}if(arguments.length==1){if(typeof arg=='number'){return players[arg];}else{if(arg=='*'){return new Iterator(players);}each(players,function(){if(this.id()==arg.id||this.id()==arg||this.getParent()==arg){instance=this;return false;}});return instance;}}if(arguments.length>1){var swf=arguments[1];var conf=(arguments.length==3)?arguments[2]:{};if(typeof arg=='string'){if(arg.indexOf(".")!=-1){var instances=[];each(select(arg),function(){instances.push(new Player(this,clone(swf),clone(conf)));});return new Iterator(instances);}else{var node=el(arg);return new Player(node!==null?node:arg,swf,conf);}}else if(arg){return new Player(arg,swf,conf);}}return null;};extend(window.$f,{fireEvent:function(id,evt,a0,a1,a2){var p=$f(id);return p?p._fireEvent(evt,a0,a1,a2):null;},addPlugin:function(name,fn){Player.prototype[name]=fn;return $f;},each:each,extend:extend});if(typeof jQuery=='function'){jQuery.prototype.flowplayer=function(params,conf){if(!arguments.length||typeof arguments[0]=='number'){var arr=[];this.each(function(){var p=$f(this);if(p){arr.push(p);}});return arguments.length?arr[arguments[0]]:new Iterator(arr);}return this.each(function(){$f(this,clone(params),conf?clone(conf):{});});};}})();(function(){var jQ=typeof jQuery=='function';function isDomReady(){if(domReady.done){return false;}var d=document;if(d&&d.getElementsByTagName&&d.getElementById&&d.body){clearInterval(domReady.timer);domReady.timer=null;for(var i=0;i<domReady.ready.length;i++){domReady.ready[i].call();}domReady.ready=null;domReady.done=true;}}var domReady=jQ?jQuery:function(f){if(domReady.done){return f();}if(domReady.timer){domReady.ready.push(f);}else{domReady.ready=[f];domReady.timer=setInterval(isDomReady,13);}};function extend(to,from){if(from){for(key in from){if(from.hasOwnProperty(key)){to[key]=from[key];}}}}function concatVars(vars){var out="";for(var key in vars){if(vars[key]){out+=[key]+'='+toString(vars[key])+'&';}}return out.substring(0,out.length-1);}function toString(obj){switch(typeOf(obj)){case'string':obj=obj.replace(new RegExp('(["\\\\])','g'),'\\$1');obj=obj.replace(/^\s?(\d+)%/,"$1pct");return'"'+obj+'"';case'array':return'['+map(obj,function(el){return toString(el);}).join(',')+']';case'function':return'"function()"';case'object':var str=[];for(var prop in obj){if(obj.hasOwnProperty(prop)){str.push('"'+prop+'":'+toString(obj[prop]));}}return'{'+str.join(',')+'}';}return String(obj).replace(/\s/g," ").replace(/\'/g,"\"");}function typeOf(obj){if(obj===null||obj===undefined){return false;}var type=typeof obj;return(type=='object'&&obj.push)?'array':type;}if(window.attachEvent){window.attachEvent("onbeforeunload",function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){};});}function map(arr,func){var newArr=[];for(var i in arr){if(arr.hasOwnProperty(i)){newArr[i]=func(arr[i]);}}return newArr;}window.flashembed=function(root,userParams,flashvars){function getHTML(){var html="";if(typeof flashvars=='function'){flashvars=flashvars();}params.src+=((params.src.indexOf("?")!=-1?"&":"?")+Math.random());if(navigator.plugins&&navigator.mimeTypes&&navigator.mimeTypes.length){html='<embed type="application/x-shockwave-flash" ';if(params.id){extend(params,{name:params.id});}for(var key in params){if(params[key]!==null){html+=[key]+'="'+params[key]+'"\n\t';}}if(flashvars){html+='flashvars=\''+concatVars(flashvars)+'\'';}html+='/>';}else{html='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" ';html+='width="'+params.width+'" height="'+params.height+'"';if(!params.id&&document.all){params.id="_"+(""+Math.random()).substring(5);}if(params.id){html+=' id="'+params.id+'"';}html+='>';html+='\n\t<param name="movie" value="'+params.src+'" />';params.id=params.src=params.width=params.height=null;for(var k in params){if(params[k]!==null){html+='\n\t<param name="'+k+'" value="'+params[k]+'" />';}}if(flashvars){html+='\n\t<param name="flashvars" value=\''+concatVars(flashvars)+'\' />';}html+="</object>";if(debug){alert(html);}}return html;}var params={src:'#',width:'100%',height:'100%',version:null,onFail:null,expressInstall:null,debug:false,allowfullscreen:true,allowscriptaccess:'always',quality:'high',type:'application/x-shockwave-flash',pluginspage:'http://www.adobe.com/go/getflashplayer'};if(typeof userParams=='string'){userParams={src:userParams};}extend(params,userParams);var version=flashembed.getVersion();var required=params.version;var express=params.expressInstall;var debug=params.debug;if(typeof root=='string'){var el=document.getElementById(root);if(el){root=el;}else{domReady(function(){flashembed(root,userParams,flashvars);});return;}}if(!root){return;}if(!required||flashembed.isSupported(required)){params.onFail=params.version=params.expressInstall=params.debug=null;root.innerHTML=getHTML();return root.firstChild;}else if(params.onFail){var ret=params.onFail.call(params,flashembed.getVersion(),flashvars);if(ret===true){root.innerHTML=ret;}}else if(required&&express&&flashembed.isSupported([6,65])){extend(params,{src:express});flashvars={MMredirectURL:location.href,MMplayerType:'PlugIn',MMdoctitle:document.title};root.innerHTML=getHTML();}else{if(root.innerHTML.replace(/\s/g,'')!==''){}else{root.innerHTML="<h2>Flash version "+required+" or greater is required</h2>"+"<h3>"+(version[0]>0?"Your version is "+version:"You have no flash plugin installed")+"</h3>"+"<p>Download latest version from <a href='"+params.pluginspage+"'>here</a></p>";}}return root;};extend(window.flashembed,{getVersion:function(){var version=[0,0];if(navigator.plugins&&typeof navigator.plugins["Shockwave Flash"]=="object"){var _d=navigator.plugins["Shockwave Flash"].description;if(typeof _d!="undefined"){_d=_d.replace(/^.*\s+(\S+\s+\S+$)/,"$1");var _m=parseInt(_d.replace(/^(.*)\..*$/,"$1"),10);var _r=/r/.test(_d)?parseInt(_d.replace(/^.*r(.*)$/,"$1"),10):0;version=[_m,_r];}}else if(window.ActiveXObject){try{var _a=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");}catch(e){try{_a=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");version=[6,0];_a.AllowScriptAccess="always";}catch(ee){if(version[0]==6){return;}}try{_a=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");}catch(eee){}}if(typeof _a=="object"){_d=_a.GetVariable("$version");if(typeof _d!="undefined"){_d=_d.replace(/^\S+\s+(.*)$/,"$1").split(",");version=[parseInt(_d[0],10),parseInt(_d[2],10)];}}}return version;},isSupported:function(version){var now=flashembed.getVersion();var ret=(now[0]>version[0])||(now[0]==version[0]&&now[1]>=version[1]);return ret;},domReady:domReady,toString:toString});if(jQ){jQuery.prototype.flashembed=function(params,flashvars){return this.each(function(){flashembed(this,params,flashvars);});};}})();
\ No newline at end of file
Index: trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer/flowplayer-3.0.0-rc2.swf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: trunk/extensions/MetavidWiki/skins/mv_embed/flowplayer/flowplayer-3.0.0-rc2.swf
___________________________________________________________________
Added: svn:mime-type
117 + application/octet-stream
Index: trunk/extensions/MetavidWiki/skins/mv_embed/embedLibs/mv_flashEmbed.js
@@ -1,22 +1,1537 @@
22 /**
3 - * metavid: mv_flashEmbed builds off of:
4 - *
5 - * samples from: flashembed 0.25. Adobe Flash embedding script
 3+ * metavid: mv_flashEmbed builds off of flowplayer api (included first in this file)
 4+ */
 5+
 6+ /**
 7+ * flowplayer.js 3.0.0-rc2. The Flowplayer API.
 8+ *
 9+ * This file is part of Flowplayer, http://flowplayer.org
610 *
7 - * http://flowplayer.org/player/flash-embed.html
 11+ * Author: Tero Piirainen, <support@flowplayer.org>
 12+ * Copyright (c) 2008 Flowplayer Ltd
813 *
9 - * Copyright (c) 2008 Tero Piirainen (tero@flowplayer.org)
 14+ * Released under the MIT License:
 15+ * http://www.opensource.org/licenses/mit-license.php
 16+ *
 17+ * Version: 3.0.0-rc2 - Fri Nov 07 2008 16:50:59 GMT-0000 (GMT+00:00)
 18+ */
 19+(function() {
 20+
 21+/*
 22+ FEATURES
 23+ --------
 24+ - handling multiple instances
 25+ - Flowplayer programming API
 26+ - Flowplayer event model
 27+ - player loading / unloading
 28+ - $f() function
 29+ - jQuery support
 30+*/
 31+
 32+
 33+/*jslint glovar: true, browser: true */
 34+/*global flowplayer, $f */
 35+
 36+// {{{ private utility methods
 37+
 38+ function log(args) {
 39+
 40+ // write into opera console
 41+ if (typeof opera == 'object') {
 42+ opera.postError("$f.fireEvent: " + args.join(" | "));
 43+
 44+
 45+ } else if (typeof console == 'object') {
 46+ console.log("$f.fireEvent", [].slice.call(args));
 47+ }
 48+ }
 49+
 50+
 51+ // thanks: http://keithdevens.com/weblog/archive/2007/Jun/07/javascript.clone
 52+ function clone(obj) {
 53+ if (!obj || typeof obj != 'object') { return obj; }
 54+ var temp = new obj.constructor();
 55+ for (var key in obj) {
 56+ if (obj.hasOwnProperty(key)) {
 57+ temp[key] = clone(obj[key]);
 58+ }
 59+ }
 60+ return temp;
 61+ }
 62+
 63+ // stripped from jQuery, thanks John Resig
 64+ function each(obj, fn) {
 65+ if (!obj) { return; }
 66+
 67+ var name, i = 0, length = obj.length;
 68+
 69+ // object
 70+ if (length === undefined) {
 71+ for (name in obj) {
 72+ if (fn.call(obj[name], name, obj[name]) === false) { break; }
 73+ }
 74+
 75+ // array
 76+ } else {
 77+ for (var value = obj[0];
 78+ i < length && fn.call( value, i, value ) !== false; value = obj[++i]) {
 79+ }
 80+ }
 81+
 82+ return obj;
 83+ }
 84+
 85+
 86+ // convenience
 87+ function el(id) {
 88+ return document.getElementById(id);
 89+ }
 90+
 91+
 92+ // used extensively. a very simple implementation.
 93+ function extend(to, from, skipFuncs) {
 94+ if (to && from) {
 95+ each(from, function(name, value) {
 96+ if (!skipFuncs || typeof value != 'function') {
 97+ to[name] = value;
 98+ }
 99+ });
 100+ }
 101+ }
 102+
 103+ // var arr = select("elem.className");
 104+ function select(query) {
 105+ var index = query.indexOf(".");
 106+ if (index != -1) {
 107+ var tag = query.substring(0, index) || "*";
 108+ var klass = query.substring(index + 1, query.length);
 109+ var els = [];
 110+ each(document.getElementsByTagName(tag), function() {
 111+ if (this.className && this.className.indexOf(klass) != -1) {
 112+ els.push(this);
 113+ }
 114+ });
 115+ return els;
 116+ }
 117+ }
 118+
 119+ // fix event inconsistencies across browsers
 120+ function stopEvent(e) {
 121+ e = e || window.event;
 122+
 123+ if (e.preventDefault) {
 124+ e.stopPropagation();
 125+ e.preventDefault();
 126+
 127+ } else {
 128+ e.returnValue = false;
 129+ e.cancelBubble = true;
 130+ }
 131+ return false;
 132+ }
 133+
 134+ // push an event listener into existing array of listeners
 135+ function bind(to, evt, fn) {
 136+ to[evt] = to[evt] || [];
 137+ to[evt].push(fn);
 138+ }
 139+
 140+
 141+ // generates an unique id
 142+ function makeId() {
 143+ return "_" + ("" + Math.random()).substring(2, 10);
 144+ }
 145+
 146+//}}}
 147+
 148+
 149+// {{{ Clip
 150+
 151+ var Clip = function(json, index, player) {
 152+
 153+ // private variables
 154+ var self = this;
 155+ var cuepoints = {};
 156+ var listeners = {};
 157+ this.index = index;
 158+
 159+ // instance variables
 160+ if (typeof json == 'string') {
 161+ json = {url:json};
 162+ }
 163+
 164+ extend(this, json, true);
 165+
 166+ // event handling
 167+ each(("Start*,MetaData,Pause*,Resume*,Seek*,Stop*,Finish,LastSecond,Update,BufferFull,BufferEmpty").split(","),
 168+ function() {
 169+
 170+ var evt = "on" + this;
 171+
 172+ // before event
 173+ if (evt.indexOf("*") != -1) {
 174+ evt = evt.substring(0, evt.length -1);
 175+ var before = "onBefore" + evt.substring(2);
 176+
 177+ self[before] = function(fn) {
 178+ bind(listeners, before, fn);
 179+ return self;
 180+ };
 181+ }
 182+
 183+ self[evt] = function(fn) {
 184+ bind(listeners, evt, fn);
 185+ return self;
 186+ };
 187+
 188+
 189+ // set common clip event listeners to player level
 190+ if (index == -1) {
 191+ if (self[before]) {
 192+ player[before] = self[before];
 193+ }
 194+ if (self[evt]) {
 195+ player[evt] = self[evt];
 196+ }
 197+ }
 198+
 199+ });
 200+
 201+ extend(this, {
 202+
 203+
 204+ onCuepoint: function(points, fn) {
 205+
 206+ // embedded cuepoints
 207+ if (arguments.length == 1) {
 208+ cuepoints.embedded = [null, points];
 209+ return self;
 210+ }
 211+
 212+ if (typeof points == 'number') {
 213+ points = [points];
 214+ }
 215+
 216+ var fnId = makeId();
 217+ cuepoints[fnId] = [points, fn];
 218+
 219+ if (player.isLoaded()) {
 220+ player._api().fp_addCuepoints(points, index, fnId);
 221+ }
 222+
 223+ return self;
 224+ },
 225+
 226+ update: function(json) {
 227+ extend(self, json);
 228+
 229+ if (player.isLoaded()) {
 230+ player._api().fp_updateClip(json, index);
 231+ }
 232+ var conf = player._config();
 233+ var clip = (index == -1) ? conf.clip : conf.playlist[index];
 234+ extend(clip, json, true);
 235+ },
 236+
 237+
 238+ // internal event for performing clip tasks. should be made private someday
 239+ _fireEvent: function(evt, arg1, arg2, target) {
 240+
 241+ if (evt == 'onLoad') {
 242+ each(cuepoints, function(key, val) {
 243+ player._api().fp_addCuepoints(val[0], index, key);
 244+ });
 245+ return false;
 246+ }
 247+
 248+ // target clip we are working against
 249+ if (index != -1) {
 250+ target = self;
 251+ }
 252+
 253+ if (evt == 'onCuepoint') {
 254+ var fn = cuepoints[arg1];
 255+ if (fn) {
 256+ return fn[1].call(player, target, arg2);
 257+ }
 258+ }
 259+
 260+ if (evt == 'onMetaData' || evt == 'onUpdate') {
 261+
 262+ extend(target, arg1);
 263+
 264+ if (!target.duration) {
 265+ target.duration = arg1.metaData.duration;
 266+ } else {
 267+ target.fullDuration = arg1.metaData.duration;
 268+ }
 269+ }
 270+
 271+ var ret = true;
 272+ each(listeners[evt], function() {
 273+ ret = this.call(player, target, arg1);
 274+ });
 275+ return ret;
 276+ }
 277+
 278+ });
 279+
 280+
 281+ // get cuepoints from config
 282+ if (json.onCuepoint) {
 283+ self.onCuepoint.apply(self, json.onCuepoint);
 284+ delete json.onCuepoint;
 285+ }
 286+
 287+ // get other events
 288+ each(json, function(key, val) {
 289+ if (typeof val == 'function') {
 290+ bind(listeners, key, val);
 291+ delete json[key];
 292+ }
 293+ });
 294+
 295+
 296+ // setup common clip event callbacks for Player object too (shortcuts)
 297+ if (index == -1) {
 298+ player.onCuepoint = this.onCuepoint;
 299+ }
 300+
 301+ };
 302+
 303+//}}}
 304+
 305+
 306+// {{{ Plugin
 307+
 308+ var Plugin = function(name, json, player, fn) {
 309+
 310+ var listeners = {};
 311+ var self = this;
 312+ var hasMethods = false;
 313+
 314+ if (fn) {
 315+ extend(listeners, fn);
 316+ }
 317+
 318+ // custom callback functions in configuration
 319+ each(json, function(key, val) {
 320+ if (typeof val == 'function') {
 321+ listeners[key] = val;
 322+ delete json[key];
 323+ }
 324+ });
 325+
 326+ // core plugin methods
 327+ extend(this, {
 328+
 329+ animate: function(props, speed, fn) {
 330+ if (!props) {
 331+ return self;
 332+ }
 333+
 334+ if (typeof speed == 'function') {
 335+ fn = speed;
 336+ speed = 500;
 337+ }
 338+
 339+ if (typeof props == 'string') {
 340+ var key = props;
 341+ props = {};
 342+ props[key] = speed;
 343+ speed = 500;
 344+ }
 345+
 346+ if (fn) {
 347+ var fnId = makeId();
 348+ listeners[fnId] = fn;
 349+ }
 350+
 351+ if (speed === undefined) { speed = 500; }
 352+ json = player._api().fp_animate(name, props, speed, fnId);
 353+ return self;
 354+ },
 355+
 356+ css: function(props, val) {
 357+ if (val !== undefined) {
 358+ var css = {};
 359+ css[props] = val;
 360+ props = css;
 361+ }
 362+ json = player._api().fp_css(name, props);
 363+ extend(self, json);
 364+ return self;
 365+ },
 366+
 367+ show: function() {
 368+ this.display = 'block';
 369+ player._api().fp_showPlugin(name);
 370+ return self;
 371+ },
 372+
 373+ hide: function() {
 374+ this.display = 'none';
 375+ player._api().fp_hidePlugin(name);
 376+ return self;
 377+ },
 378+
 379+ toggle: function() {
 380+ this.display = player._api().fp_togglePlugin(name);
 381+ return self;
 382+ },
 383+
 384+ fadeTo: function(o, speed, fn) {
 385+
 386+ if (typeof speed == 'function') {
 387+ fn = speed;
 388+ speed = 500;
 389+ }
 390+
 391+ if (fn) {
 392+ var fnId = makeId();
 393+ listeners[fnId] = fn;
 394+ }
 395+ this.display = player._api().fp_fadeTo(name, o, speed, fnId);
 396+ this.opacity = o;
 397+ return self;
 398+ },
 399+
 400+ fadeIn: function(speed, fn) {
 401+ return self.fadeTo(1, speed, fn);
 402+ },
 403+
 404+ fadeOut: function(speed, fn) {
 405+ return self.fadeTo(0, speed, fn);
 406+ },
 407+
 408+ getName: function() {
 409+ return name;
 410+ },
 411+
 412+
 413+ // internal method not meant to be used by clients
 414+ _fireEvent: function(evt, arg) {
 415+
 416+
 417+ // update plugins properties & methods
 418+ if (evt == 'onUpdate') {
 419+ var json = arg || player._api().fp_getPlugin(name);
 420+ if (!json) { return; }
 421+
 422+ extend(self, json);
 423+ delete self.methods;
 424+
 425+ if (!hasMethods) {
 426+ each(json.methods, function() {
 427+ var method = "" + this;
 428+
 429+ self[method] = function() {
 430+ var a = [].slice.call(arguments);
 431+ var ret = player._api().fp_invoke(name, method, a);
 432+ return ret == 'undefined' ? self : ret;
 433+ };
 434+ });
 435+ hasMethods = true;
 436+ }
 437+ }
 438+
 439+ // plugin callbacks
 440+ var fn = listeners[evt];
 441+
 442+ if (fn) {
 443+
 444+ fn.call(self, arg);
 445+
 446+ // "one-shot" callback
 447+ if (evt.substring(0, 1) == "_") {
 448+ delete listeners[evt];
 449+ }
 450+ }
 451+ }
 452+
 453+ });
 454+
 455+ };
 456+
 457+
 458+//}}}
 459+
 460+
 461+function Player(wrapper, params, conf) {
 462+
 463+ // private variables (+ arguments)
 464+ var
 465+ self = this,
 466+ api = null,
 467+ html,
 468+ commonClip,
 469+ playlist = [],
 470+ plugins = {},
 471+ listeners = {},
 472+ playerId,
 473+ apiId,
 474+ activeIndex,
 475+ swfHeight;
 476+
 477+
 478+// {{{ public methods
 479+
 480+ extend(self, {
 481+
 482+ id: function() {
 483+ return playerId;
 484+ },
 485+
 486+ isLoaded: function() {
 487+ return (api !== null);
 488+ },
 489+
 490+ getParent: function() {
 491+ return wrapper;
 492+ },
 493+
 494+ hide: function() {
 495+ if (api) { api.style.height = "0px"; }
 496+ return self;
 497+ },
 498+
 499+ show: function() {
 500+ if (api) { api.style.height = swfHeight + "px"; }
 501+ return self;
 502+ },
 503+
 504+ isHidden: function() {
 505+ return api && parseInt(api.style.height, 10) === 0;
 506+ },
 507+
 508+
 509+ load: function(fn) {
 510+
 511+ if (!api && self._fireEvent("onBeforeLoad") !== false) {
 512+
 513+ // unload all instances
 514+ each(players, function() {
 515+ this.unload();
 516+ });
 517+
 518+ html = wrapper.innerHTML;
 519+ flashembed(wrapper, params, {config: conf});
 520+
 521+ // function argument
 522+ if (fn) {
 523+ fn.cached = true;
 524+ bind(listeners, "onLoad", fn);
 525+ }
 526+ }
 527+
 528+ return self;
 529+ },
 530+
 531+ unload: function() {
 532+
 533+ if (api && html.replace(/\s/g, '') !== '' && !api.fp_isFullscreen() &&
 534+ self._fireEvent("onBeforeUnload") !== false) {
 535+ api.fp_close();
 536+ wrapper.innerHTML = html;
 537+ self._fireEvent("onUnload");
 538+ api = null;
 539+ }
 540+
 541+ return self;
 542+ },
 543+
 544+ getClip: function(index) {
 545+ if (index === undefined) {
 546+ index = activeIndex;
 547+ }
 548+ return playlist[index];
 549+ },
 550+
 551+
 552+ getCommonClip: function() {
 553+ return commonClip;
 554+ },
 555+
 556+ getPlaylist: function() {
 557+ return playlist;
 558+ },
 559+
 560+ getPlugin: function(name) {
 561+ var plugin = plugins[name];
 562+
 563+ // create plugin if nessessary
 564+ if (!plugin && self.isLoaded()) {
 565+ var json = self._api().fp_getPlugin(name);
 566+ if (json) {
 567+ plugin = new Plugin(name, json, self);
 568+ plugins[name] = plugin;
 569+ }
 570+ }
 571+ return plugin;
 572+ },
 573+
 574+ getScreen: function() {
 575+ return self.getPlugin("screen");
 576+ },
 577+
 578+ getControls: function() {
 579+ return self.getPlugin("controls");
 580+ },
 581+
 582+ getConfig: function() {
 583+ return clone(conf);
 584+ },
 585+
 586+ getFlashParams: function() {
 587+ return params;
 588+ },
 589+
 590+ loadPlugin: function(name, url, props, fn) {
 591+
 592+ // properties not supplied
 593+ if (typeof props == 'function') {
 594+ fn = props;
 595+ props = {};
 596+ }
 597+
 598+ // if fn not given, make a fake id so that plugin's onUpdate get's fired
 599+ var fnId = fn ? makeId() : "_";
 600+ self._api().fp_loadPlugin(name, url, props, fnId);
 601+
 602+ // create new plugin
 603+ var arg = {};
 604+ arg[fnId] = fn;
 605+ var p = new Plugin(name, null, self, arg);
 606+ plugins[name] = p;
 607+ return p;
 608+ },
 609+
 610+
 611+ getState: function() {
 612+ return api ? api.fp_getState() : -1;
 613+ },
 614+
 615+ // "lazy" play
 616+ play: function(clip) {
 617+
 618+ function play() {
 619+ if (clip !== undefined) {
 620+ self._api().fp_play(clip);
 621+ } else {
 622+ if(typeof self._api().fp_play == 'function')
 623+ self._api().fp_play();
 624+ }
 625+ }
 626+
 627+ if (api) {
 628+ play();
 629+
 630+ } else {
 631+ self.load(function() {
 632+ play();
 633+ });
 634+ }
 635+
 636+ return self;
 637+ },
 638+
 639+ getVersion: function() {
 640+ var js = "flowplayer.js 3.0.0-rc2";
 641+ if (api) {
 642+ var ver = api.fp_getVersion();
 643+ ver.push(js);
 644+ return ver;
 645+ }
 646+ return js;
 647+ },
 648+
 649+ _api: function() {
 650+ if (!api) {
 651+ throw "Flowplayer " +self.id()+ " not loaded. Try moving your call to player's onLoad event";
 652+ }
 653+ return api;
 654+ },
 655+
 656+ _config: function() {
 657+ return conf;
 658+ }
 659+
 660+ });
 661+
 662+
 663+ // event handlers
 664+ each(("Click*,Load*,Unload*,Keypress*,Volume*,Mute*,Unmute*,PlaylistReplace,Fullscreen*,FullscreenExit,Error").split(","),
 665+ function() {
 666+ var name = "on" + this;
 667+
 668+ // before event
 669+ if (name.indexOf("*") != -1) {
 670+ name = name.substring(0, name.length -1);
 671+ var name2 = "onBefore" + name.substring(2);
 672+ self[name2] = function(fn) {
 673+ bind(listeners, name2, fn);
 674+ return self;
 675+ };
 676+ }
 677+
 678+ // normal event
 679+ self[name] = function(fn) {
 680+ bind(listeners, name, fn);
 681+ return self;
 682+ };
 683+ }
 684+ );
 685+
 686+
 687+ // core API methods
 688+ each(("pause,resume,mute,unmute,stop,toggle,seek,getStatus,getVolume,setVolume,getTime,isPaused,isPlaying,startBuffering,stopBuffering,isFullscreen,reset").split(","),
 689+ function() {
 690+ var name = this;
 691+
 692+ self[name] = function(arg) {
 693+ if (!api) { return self; }
 694+ var ret = (arg === undefined) ? api["fp_" + name]() : api["fp_" + name](arg);
 695+ return ret == 'undefined' ? self : ret;
 696+ };
 697+ }
 698+ );
 699+
 700+//}}}
 701+
 702+
 703+// {{{ public method: _fireEvent
 704+
 705+ self._fireEvent = function(evt, arg0, arg1, arg2) {
 706+
 707+ if (conf.debug) {
 708+ log(arguments);
 709+ }
 710+
 711+ // internal onLoad
 712+ if (evt == 'onLoad' && !api) {
 713+
 714+ api = api || el(apiId);
 715+ swfHeight = api.clientHeight;
 716+
 717+ each(playlist, function() {
 718+ this._fireEvent("onLoad");
 719+ });
 720+
 721+ each(plugins, function(name, p) {
 722+ p._fireEvent("onUpdate");
 723+ });
 724+
 725+
 726+ commonClip._fireEvent("onLoad");
 727+ }
 728+
 729+ if (evt == 'onContextMenu') {
 730+ each(conf.contextMenu[arg0], function(key, fn) {
 731+ fn.call(self);
 732+ });
 733+ return;
 734+ }
 735+
 736+ if (evt == 'onPluginEvent') {
 737+ var name = arg0.name || arg0;
 738+ var p = plugins[name];
 739+ if (p) {
 740+ if (arg0.name) {
 741+ p._fireEvent("onUpdate", arg0);
 742+ }
 743+ p._fireEvent(arg1);
 744+ }
 745+ return;
 746+ }
 747+
 748+ // onPlaylistReplace
 749+ if (evt == 'onPlaylistReplace') {
 750+ playlist = [];
 751+ var index = 0;
 752+ each(arg0, function() {
 753+ playlist.push(new Clip(this, index++));
 754+ });
 755+ }
 756+
 757+ var ret = true;
 758+
 759+ // clip event
 760+ if (arg0 === 0 || (arg0 && arg0 >= 0)) {
 761+
 762+ activeIndex = arg0;
 763+ var clip = playlist[arg0];
 764+
 765+ if (!clip || clip._fireEvent(evt, arg1, arg2) !== false) {
 766+
 767+ // clip argument is given for common clip, because it behaves as the target
 768+ ret = commonClip._fireEvent(evt, arg1, arg2, clip);
 769+ }
 770+ }
 771+
 772+ // player event
 773+ var i = 0;
 774+ each(listeners[evt], function() {
 775+ ret = this.call(self, arg0);
 776+
 777+ // remove cached entry
 778+ if (this.cached) {
 779+ listeners[evt].splice(i, 1);
 780+ }
 781+
 782+ // break loop
 783+ if (ret === false) { return false; }
 784+ i++;
 785+
 786+ });
 787+
 788+ return ret;
 789+ };
 790+
 791+//}}}
 792+
 793+
 794+// {{{ init
 795+
 796+ function init() {
 797+
 798+ if ($f(wrapper)) {
 799+ return null;
 800+ }
 801+
 802+ // register this player into global array of instances
 803+ players.push(self);
 804+
 805+
 806+ // flashembed parameters
 807+ if (typeof params == 'string') {
 808+ params = {src: params};
 809+ }
 810+
 811+ // playerId
 812+ playerId = wrapper.id || "fp" + makeId();
 813+ apiId = params.id || playerId + "_api";
 814+ params.id = apiId;
 815+ conf.playerId = playerId;
 816+
 817+
 818+ // plain url is given as config
 819+ if (typeof conf == 'string') {
 820+ conf = {clip:{url:conf}};
 821+ }
 822+
 823+ // common clip is always there
 824+ conf.clip = conf.clip || {};
 825+ commonClip = new Clip(conf.clip, -1, self);
 826+
 827+
 828+ // wrapper href as playlist
 829+ if (wrapper.getAttribute("href")) {
 830+ conf.playlist = [{url:wrapper.getAttribute("href", 2)}];
 831+ }
 832+
 833+ // playlist
 834+ conf.playlist = conf.playlist || [conf.clip];
 835+
 836+ var index = 0;
 837+ each(conf.playlist, function() {
 838+
 839+ var clip = this;
 840+
 841+ // clip is an array, we don't allow that
 842+ if (typeof clip == 'object' && clip.length) {
 843+ clip = "" + clip;
 844+ }
 845+
 846+ if (!clip.url && typeof clip == 'string') {
 847+ clip = {url: clip};
 848+ }
 849+
 850+ // populate common clip properties to each clip
 851+ extend(clip, conf.clip, true);
 852+
 853+ // modify configuration playlist
 854+ conf.playlist[index] = clip;
 855+
 856+ // populate playlist array
 857+ clip = new Clip(clip, index, self);
 858+ playlist.push(clip);
 859+ index++;
 860+ });
 861+
 862+
 863+ // event listeners
 864+ each(conf, function(key, val) {
 865+ if (typeof val == 'function') {
 866+ bind(listeners, key, val);
 867+ delete conf[key];
 868+ }
 869+ });
 870+
 871+
 872+ // plugins
 873+ each(conf.plugins, function(name, val) {
 874+ if (val) {
 875+ plugins[name] = new Plugin(name, val, self);
 876+ }
 877+ });
 878+
 879+
 880+ // setup controlbar plugin if not explicitly defined
 881+ if (!conf.plugins || conf.plugins.controls === undefined) {
 882+ plugins.controls = new Plugin("controls", null, self);
 883+ }
 884+
 885+ // Flowplayer uses black background by default
 886+ params.bgcolor = params.bgcolor || "#000000";
 887+
 888+
 889+ // setup default settings for express install
 890+ params.version = params.version || [9,0];
 891+ params.expressInstall = 'http://www.flowplayer.org/swf/expressinstall.swf';
 892+
 893+
 894+ // click function
 895+ function doClick(e) {
 896+ if (self._fireEvent("onBeforeClick") !== false) {
 897+ self.load();
 898+ }
 899+ return stopEvent(e);
 900+ }
 901+
 902+ // defer loading upon click
 903+ html = wrapper.innerHTML;
 904+ if (html.replace(/\s/g, '') !== '') {
 905+
 906+ if (wrapper.addEventListener) {
 907+ wrapper.addEventListener("click", doClick, false);
 908+
 909+ } else if (wrapper.attachEvent) {
 910+ wrapper.attachEvent("onclick", doClick);
 911+ }
 912+
 913+ // player is loaded upon page load
 914+ } else {
 915+
 916+ // prevent default action from wrapper (safari problem) loaded
 917+ if (wrapper.addEventListener) {
 918+ wrapper.addEventListener("click", stopEvent, false);
 919+ }
 920+
 921+ // load player
 922+ self.load();
 923+ }
 924+
 925+ }
 926+
 927+ // possibly defer initialization until DOM get's loaded
 928+ if (typeof wrapper == 'string') {
 929+ flashembed.domReady(function() {
 930+ var node = el(wrapper);
 931+
 932+ if (!node) {
 933+ throw "Flowplayer cannot access element: " + wrapper;
 934+ } else {
 935+ wrapper = node;
 936+ init();
 937+ }
 938+ });
 939+
 940+ // we have a DOM element so page is already loaded
 941+ } else {
 942+ init();
 943+ }
 944+
 945+
 946+//}}}
 947+
 948+
 949+}
 950+
 951+
 952+// {{{ flowplayer() & statics
 953+
 954+// container for player instances
 955+var players = [];
 956+
 957+
 958+// this object is returned when multiple player's are requested
 959+function Iterator(arr) {
 960+
 961+ this.length = arr.length;
 962+
 963+ this.each = function(fn) {
 964+ each(arr, fn);
 965+ };
 966+
 967+ this.size = function() {
 968+ return arr.length;
 969+ };
 970+}
 971+
 972+// these two variables are the only global variables
 973+window.flowplayer = window.$f = function() {
 974+
 975+ var instance = null;
 976+ var arg = arguments[0];
 977+
 978+
 979+ // $f()
 980+ if (!arguments.length) {
 981+ each(players, function() {
 982+ if (this.isLoaded()) {
 983+ instance = this;
 984+ return false;
 985+ }
 986+ });
 987+
 988+ return instance || players[0];
 989+ }
 990+
 991+ if (arguments.length == 1) {
 992+
 993+ // $f(index);
 994+ if (typeof arg == 'number') {
 995+ return players[arg];
 996+
 997+
 998+ // $f(wrapper || 'containerId' || '*');
 999+ } else {
 1000+
 1001+ // $f("*");
 1002+ if (arg == '*') {
 1003+ return new Iterator(players);
 1004+ }
 1005+
 1006+ // $f(wrapper || 'containerId');
 1007+ each(players, function() {
 1008+ if (this.id() == arg.id || this.id() == arg || this.getParent() == arg) {
 1009+ instance = this;
 1010+ return false;
 1011+ }
 1012+ });
 1013+
 1014+ return instance;
 1015+ }
 1016+ }
 1017+
 1018+ // instance builder
 1019+ if (arguments.length > 1) {
 1020+
 1021+ var swf = arguments[1];
 1022+ var conf = (arguments.length == 3) ? arguments[2] : {};
 1023+
 1024+ if (typeof arg == 'string') {
 1025+
 1026+ // select arg by classname
 1027+ if (arg.indexOf(".") != -1) {
 1028+ var instances = [];
 1029+
 1030+ each(select(arg), function() {
 1031+ instances.push(new Player(this, clone(swf), clone(conf)));
 1032+ });
 1033+
 1034+ return new Iterator(instances);
 1035+
 1036+ // select node by id
 1037+ } else {
 1038+ var node = el(arg);
 1039+ return new Player(node !== null ? node : arg, swf, conf);
 1040+ }
 1041+
 1042+
 1043+ // arg is a DOM element
 1044+ } else if (arg) {
 1045+ return new Player(arg, swf, conf);
 1046+ }
 1047+
 1048+ }
 1049+
 1050+ return null;
 1051+};
 1052+
 1053+extend(window.$f, {
 1054+
 1055+ // called by Flash External Interface
 1056+ fireEvent: function(id, evt, a0, a1, a2) {
 1057+ var p = $f(id);
 1058+ return p ? p._fireEvent(evt, a0, a1, a2) : null;
 1059+ },
 1060+
 1061+
 1062+ // create plugins by modifying Player's prototype
 1063+ addPlugin: function(name, fn) {
 1064+ Player.prototype[name] = fn;
 1065+ return $f;
 1066+ },
 1067+
 1068+ // utility methods for plugin developers
 1069+ each: each,
 1070+
 1071+ extend: extend
 1072+
 1073+});
 1074+
 1075+//}}}
 1076+
 1077+
 1078+//{{{ jQuery support
 1079+
 1080+if (typeof jQuery == 'function') {
 1081+
 1082+ jQuery.prototype.flowplayer = function(params, conf) {
 1083+
 1084+ // select instances
 1085+ if (!arguments.length || typeof arguments[0] == 'number') {
 1086+ var arr = [];
 1087+ this.each(function() {
 1088+ var p = $f(this);
 1089+ if (p) {
 1090+ arr.push(p);
 1091+ }
 1092+ });
 1093+ return arguments.length ? arr[arguments[0]] : new Iterator(arr);
 1094+ }
 1095+
 1096+ // create flowplayer instances
 1097+ return this.each(function() {
 1098+ $f(this, clone(params), conf ? clone(conf) : {});
 1099+ });
 1100+
 1101+ };
 1102+
 1103+}
 1104+
 1105+//}}}
 1106+
 1107+
 1108+})();
 1109+/**
 1110+ * flashembed 0.33. Adobe Flash embedding script
 1111+ *
 1112+ * http://flowplayer.org/tools/flash-embed.html
101113 *
 1114+ * Copyright (c) 2008 Tero Piirainen (support@flowplayer.org)
 1115+ *
111116 * Released under the MIT License:
121117 * http://www.opensource.org/licenses/mit-license.php
 1118+ *
 1119+ * >> Basically you can do anything you want but leave this header as is <<
131120 *
14 - * = Basically you can do anything but leave this header as is
15 - *
16 - */
 1121+ * first version 0.01 - 03/11/2008
 1122+ * version 0.33 - Mon Nov 03 2008 15:37:15 GMT-0000 (GMT+00:00)
 1123+ */
 1124+(function() {
 1125+
 1126+//{{{ utility functions
 1127+
 1128+var jQ = typeof jQuery == 'function';
 1129+
 1130+
 1131+// from "Pro JavaScript techniques" by John Resig
 1132+function isDomReady() {
 1133+ if (domReady.done) { return false; }
 1134+
 1135+ var d = document;
 1136+ if (d && d.getElementsByTagName && d.getElementById && d.body) {
 1137+ clearInterval(domReady.timer);
 1138+ domReady.timer = null;
 1139+
 1140+ for (var i = 0; i < domReady.ready.length; i++) {
 1141+ domReady.ready[i].call();
 1142+ }
 1143+
 1144+ domReady.ready = null;
 1145+ domReady.done = true;
 1146+ }
 1147+}
 1148+
 1149+// if jQuery is present, use it's more effective domReady method
 1150+var domReady = jQ ? jQuery : function(f) {
 1151+
 1152+ if (domReady.done) {
 1153+ return f();
 1154+ }
 1155+
 1156+ if (domReady.timer) {
 1157+ domReady.ready.push(f);
 1158+
 1159+ } else {
 1160+ domReady.ready = [f];
 1161+ domReady.timer = setInterval(isDomReady, 13);
 1162+ }
 1163+};
 1164+
 1165+
 1166+// override extend params function
 1167+function extend(to, from) {
 1168+ if (from) {
 1169+ for (key in from) {
 1170+ if (from.hasOwnProperty(key)) {
 1171+ to[key] = from[key];
 1172+ }
 1173+ }
 1174+ }
 1175+}
 1176+
 1177+
 1178+function concatVars(vars) {
 1179+ var out = "";
 1180+
 1181+ for (var key in vars) {
 1182+ if (vars[key]) {
 1183+ out += [key] + '=' + toString(vars[key]) + '&';
 1184+ }
 1185+ }
 1186+ return out.substring(0, out.length -1);
 1187+}
 1188+
 1189+
 1190+
 1191+// JSON.toString() function
 1192+function toString(obj) {
 1193+
 1194+ switch (typeOf(obj)){
 1195+ case 'string':
 1196+ obj = obj.replace(new RegExp('(["\\\\])', 'g'), '\\$1');
 1197+
 1198+ // flash does not handle %- characters well. transforms "50%" to "50pct" (a dirty hack, I admit)
 1199+ obj = obj.replace(/^\s?(\d+)%/, "$1pct");
 1200+ return '"' +obj+ '"';
 1201+
 1202+ case 'array':
 1203+ return '['+ map(obj, function(el) {
 1204+ return toString(el);
 1205+ }).join(',') +']';
 1206+
 1207+ case 'function':
 1208+ return '"function()"';
 1209+
 1210+ case 'object':
 1211+ var str = [];
 1212+ for (var prop in obj) {
 1213+ if (obj.hasOwnProperty(prop)) {
 1214+ str.push('"'+prop+'":'+ toString(obj[prop]));
 1215+ }
 1216+ }
 1217+ return '{'+str.join(',')+'}';
 1218+ }
 1219+
 1220+ // replace ' --> " and remove spaces
 1221+ return String(obj).replace(/\s/g, " ").replace(/\'/g, "\"");
 1222+}
 1223+
 1224+
 1225+// private functions
 1226+function typeOf(obj) {
 1227+ if (obj === null || obj === undefined) { return false; }
 1228+ var type = typeof obj;
 1229+ return (type == 'object' && obj.push) ? 'array' : type;
 1230+}
 1231+
 1232+
 1233+// version 9 bugfix: (http://blog.deconcept.com/2006/07/28/swfobject-143-released/)
 1234+if (window.attachEvent) {
 1235+ window.attachEvent("onbeforeunload", function() {
 1236+ __flash_unloadHandler = function() {};
 1237+ __flash_savedUnloadHandler = function() {};
 1238+ });
 1239+}
 1240+
 1241+function map(arr, func) {
 1242+ var newArr = [];
 1243+ for (var i in arr) {
 1244+ if (arr.hasOwnProperty(i)) {
 1245+ newArr[i] = func(arr[i]);
 1246+ }
 1247+ }
 1248+ return newArr;
 1249+}
 1250+
 1251+//}}}
 1252+
 1253+
 1254+window.flashembed = function(root, userParams, flashvars) {
 1255+
 1256+
 1257+//{{{ getHTML
 1258+
 1259+ function getHTML() {
 1260+
 1261+ var html = "";
 1262+ if (typeof flashvars == 'function') { flashvars = flashvars(); }
 1263+
 1264+
 1265+ // sometimes ie fails to load flash if it's on cache
 1266+ params.src += ((params.src.indexOf("?") != -1 ? "&" : "?") + Math.random());
 1267+
 1268+
 1269+ // mozilla
 1270+ if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) {
 1271+
 1272+ html = '<embed type="application/x-shockwave-flash" ';
 1273+
 1274+ if (params.id) {
 1275+ extend(params, {name:params.id});
 1276+ }
 1277+
 1278+ for (var key in params) {
 1279+ if (params[key] !== null) {
 1280+ html += [key] + '="' +params[key]+ '"\n\t';
 1281+ }
 1282+ }
 1283+
 1284+ if (flashvars) {
 1285+ html += 'flashvars=\'' + concatVars(flashvars) + '\'';
 1286+ }
 1287+
 1288+ // thanks Tom Price (07/17/2008)
 1289+ html += '/>';
 1290+
 1291+ // ie
 1292+ } else {
 1293+
 1294+ html = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" ';
 1295+ html += 'width="' + params.width + '" height="' + params.height + '"';
 1296+
 1297+ // force id for IE. otherwise embedded Flash object cannot be returned
 1298+ if (!params.id && document.all) {
 1299+ params.id = "_" + ("" + Math.random()).substring(5);
 1300+ }
 1301+
 1302+ if (params.id) {
 1303+ html += ' id="' + params.id + '"';
 1304+ }
 1305+
 1306+ html += '>';
 1307+ html += '\n\t<param name="movie" value="'+ params.src +'" />';
 1308+
 1309+ params.id = params.src = params.width = params.height = null;
 1310+
 1311+ for (var k in params) {
 1312+ if (params[k] !== null) {
 1313+ html += '\n\t<param name="'+ k +'" value="'+ params[k] +'" />';
 1314+ }
 1315+ }
 1316+
 1317+ if (flashvars) {
 1318+ html += '\n\t<param name="flashvars" value=\'' + concatVars(flashvars) + '\' />';
 1319+ }
 1320+
 1321+ html += "</object>";
 1322+ if (debug) {
 1323+ alert(html);
 1324+ }
 1325+
 1326+ }
 1327+
 1328+ return html;
 1329+ }
 1330+
 1331+ //}}}
 1332+
 1333+
 1334+//{{{ construction
 1335+
 1336+ // setup params
 1337+ var params = {
 1338+
 1339+ // very common params
 1340+ src: '#',
 1341+ width: '100%',
 1342+ height: '100%',
 1343+
 1344+ // flashembed specific options
 1345+ version:null,
 1346+ onFail:null,
 1347+ expressInstall:null,
 1348+ debug: false,
 1349+
 1350+ // flashembed defaults
 1351+ // bgcolor: 'transparent',
 1352+ allowfullscreen: true,
 1353+ allowscriptaccess: 'always',
 1354+ quality: 'high',
 1355+ type: 'application/x-shockwave-flash',
 1356+ pluginspage: 'http://www.adobe.com/go/getflashplayer'
 1357+ };
 1358+
 1359+
 1360+ if (typeof userParams == 'string') {
 1361+ userParams = {src: userParams};
 1362+ }
 1363+
 1364+ extend(params, userParams);
 1365+
 1366+ var version = flashembed.getVersion();
 1367+ var required = params.version;
 1368+ var express = params.expressInstall;
 1369+ var debug = params.debug;
 1370+
 1371+
 1372+ if (typeof root == 'string') {
 1373+ var el = document.getElementById(root);
 1374+ if (el) {
 1375+ root = el;
 1376+ } else {
 1377+ domReady(function() {
 1378+ flashembed(root, userParams, flashvars);
 1379+ });
 1380+ return;
 1381+ }
 1382+ }
 1383+
 1384+ if (!root) { return; }
 1385+
 1386+
 1387+ // is supported
 1388+ if (!required || flashembed.isSupported(required)) {
 1389+ params.onFail = params.version = params.expressInstall = params.debug = null;
 1390+
 1391+ // root.innerHTML may cause broplems: http://domscripting.com/blog/display/99
 1392+ // thanks to: Ryan Rud
 1393+ // var tmp = document.createElement("extradiv");
 1394+ // tmp.innerHTML = getHTML();
 1395+ // root.appendChild(tmp);
 1396+
 1397+ root.innerHTML = getHTML();
 1398+
 1399+ // return our API
 1400+ return root.firstChild;
 1401+
 1402+ // custom fail event
 1403+ } else if (params.onFail) {
 1404+ var ret = params.onFail.call(params, flashembed.getVersion(), flashvars);
 1405+ if (ret === true) { root.innerHTML = ret; }
 1406+
 1407+
 1408+ // express install
 1409+ } else if (required && express && flashembed.isSupported([6,65])) {
 1410+
 1411+ extend(params, {src: express});
 1412+
 1413+ flashvars = {
 1414+ MMredirectURL: location.href,
 1415+ MMplayerType: 'PlugIn',
 1416+ MMdoctitle: document.title
 1417+ };
 1418+
 1419+ root.innerHTML = getHTML();
 1420+
 1421+ // not supported
 1422+ } else {
 1423+
 1424+ // minor bug fixed here 08.04.2008 (thanks JRodman)
 1425+
 1426+ if (root.innerHTML.replace(/\s/g, '') !== '') {
 1427+ // custom content was supplied
 1428+
 1429+ } else {
 1430+ root.innerHTML =
 1431+ "<h2>Flash version " + required + " or greater is required</h2>" +
 1432+ "<h3>" +
 1433+ (version[0] > 0 ? "Your version is " + version : "You have no flash plugin installed") +
 1434+ "</h3>" +
 1435+ "<p>Download latest version from <a href='" + params.pluginspage + "'>here</a></p>";
 1436+ }
 1437+ }
 1438+
 1439+ return root;
 1440+
 1441+//}}}
 1442+
 1443+
 1444+};
 1445+
 1446+
 1447+//{{{ static methods
 1448+
 1449+extend(window.flashembed, {
 1450+
 1451+ // arr[major, minor, fix]
 1452+ getVersion: function() {
 1453+
 1454+ var version = [0, 0];
 1455+
 1456+ if (navigator.plugins && typeof navigator.plugins["Shockwave Flash"] == "object") {
 1457+ var _d = navigator.plugins["Shockwave Flash"].description;
 1458+ if (typeof _d != "undefined") {
 1459+ _d = _d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
 1460+ var _m = parseInt(_d.replace(/^(.*)\..*$/, "$1"), 10);
 1461+ var _r = /r/.test(_d) ? parseInt(_d.replace(/^.*r(.*)$/, "$1"), 10) : 0;
 1462+ version = [_m, _r];
 1463+ }
 1464+
 1465+ } else if (window.ActiveXObject) {
 1466+
 1467+ try { // avoid fp 6 crashes
 1468+ var _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
 1469+
 1470+ } catch(e) {
 1471+ try {
 1472+ _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
 1473+ version = [6, 0];
 1474+ _a.AllowScriptAccess = "always"; // throws if fp < 6.47
 1475+
 1476+ } catch(ee) {
 1477+ if (version[0] == 6) { return; }
 1478+ }
 1479+ try {
 1480+ _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
 1481+ } catch(eee) {
 1482+
 1483+ }
 1484+
 1485+ }
 1486+
 1487+ if (typeof _a == "object") {
 1488+ _d = _a.GetVariable("$version"); // bugs in fp 6.21 / 6.23
 1489+ if (typeof _d != "undefined") {
 1490+ _d = _d.replace(/^\S+\s+(.*)$/, "$1").split(",");
 1491+ version = [parseInt(_d[0], 10), parseInt(_d[2], 10)];
 1492+ }
 1493+ }
 1494+ }
 1495+
 1496+ return version;
 1497+ },
 1498+
 1499+ isSupported: function(version) {
 1500+ var now = flashembed.getVersion();
 1501+ var ret = (now[0] > version[0]) || (now[0] == version[0] && now[1] >= version[1]);
 1502+ return ret;
 1503+ },
 1504+
 1505+ domReady: domReady,
 1506+
 1507+ // returns a String representation from JSON object
 1508+ toString: toString
 1509+
 1510+});
 1511+
 1512+//}}}
 1513+
 1514+
 1515+// setup jquery support
 1516+if (jQ) {
 1517+
 1518+ jQuery.prototype.flashembed = function(params, flashvars) {
 1519+ return this.each(function() {
 1520+ flashembed(this, params, flashvars);
 1521+ });
 1522+ };
 1523+
 1524+}
 1525+
 1526+})();
 1527+
 1528+/************************************************
 1529+********* mv_embed extension to flowplayer.js ***
 1530+************************************************/
171531 var flashEmbed = {
181532 instanceOf:'flashEmbed',
191533 monitorTimerId : 0,
20 - startedTimedPlayback:false,
 1534+ old_pid:0,
 1535+ startedTimedPlayback:false,
211536 supports: {
221537 'play_head':true,
231538 'play_or_pause':true,
@@ -24,125 +1539,69 @@
251540 //'fullscreen':true,
261541 'time_display':true,
271542 //'volume_control':true,
28 - 'overlay':false
29 - },
30 - flashParams : {
31 - // very common params
32 - src: '#',
33 - width: 400,
34 - height:300,
35 -
36 - // flashembed defaults
37 - allowfullscreen: true,
38 - allowscriptaccess: 'always',
39 - quality: 'high',
40 - bgcolor: '#ffffff',
41 - type: 'application/x-shockwave-flash',
42 - pluginspage: 'http://www.adobe.com/go/getflashplayer'
43 - },
44 - flashVars :{
45 - config: { autoPlay: true,
46 - hideControls: true,
47 - initialScale:'fit',
48 - bufferLength:60,
49 - startingBufferLength:5,
50 - loop:false
51 - }
52 - },
 1543+ 'overlay':false,
 1544+ 'fullscreen':false
 1545+ },
531546 getEmbedHTML: function (){
541547 setTimeout('document.getElementById(\''+this.id+'\').postEmbedJS()', 150);
551548 return this.wrapEmebedContainer( this.getEmbedObj() );
561549 },
571550 getEmbedObj:function(){
58 - if(!this.duration)this.duration=30;
59 - var html = "";
60 - //set up custom params/config
61 - /*
62 - <embed id="player_api" height="100%" width="100%"
63 - flashvars="config={"playerId":"player","clip":{},
64 - "playlist":[{"url":"http://www.archive.org/download/mv_senate_proceeding_10-23-08/senate_proceeding_10-23-08_512kb.mp4?start=10"}]}"
65 - name="player_api" bgcolor="#000000" pluginspage="http://www.adobe.com/go/getflashplayer"
66 - type="application/x-shockwave-flash" quality="high" allowscriptaccess="always"
67 - allowfullscreen="true" src="../flowplayer-3.0.0-rc2.swf?0.5720695237577815"/>
68 - */
69 - this.flashParams.src = mv_embed_path + 'flowplayer-3.0.0-rc2.swf';
70 - this.flashParams.width = this.width;
71 - this.flashParams.height = this.height;
72 - this.flashParams.id = this.pid;
73 -
74 - //set the id:
75 - this.flashVars.config.playerId = this.pid;
76 -
77 - js_log('set flash videoFile: '+ this.media_element.selected_source.getURI(this.seek_time_sec) );
78 - this.flashVars.config.playlist = new Array({"url":this.media_element.selected_source.getURI(this.seek_time_sec)});
79 -
80 - if(this.muted)
81 - this.flashVars.config.initialVolumePercentage=0;
82 -
83 - // mozilla
84 - if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) {
85 - html = '<embed ' +
86 - 'id="'+this.pid+'" ';
87 - for(var key in this.flashParams) {
88 - if (this.flashParams[key] != null)
89 - html += [key] + '="' +this.flashParams[key]+ '"\n\t';
90 - }
91 - if (this.flashVars) {
92 - html += 'flashvars=\'';
93 - var and = '';
94 - for(var key in this.flashVars) {
95 - html +=and+ [key] + '=' + asString(this.flashVars[key]);
96 - and = '&';
97 - }
98 - html += '\'';
99 - }
100 - html += '/>';
101 - // ie
102 - } else {
103 - html = '<object id="'+this.pid+'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" ';
104 - html += 'width="' + this.flashParams.width + '" height="' + this.flashParams.height + '"';
105 - if ( this.flashParams.id) html += ' id="' + this.pid + '"';
106 - html += '>';
107 - html += '\n\t<param name="movie" value="'+ this.flashParams.src +'" />';
108 - this.flashParams.id = this.flashParams.src = this.flashParams.width = this.flashParams.height = null;
109 - for (var key in this.flashParams) {
110 - if (this.flashParams[key] != null)
111 - html += '\n\t<param name="'+ key +'" value="'+ this.flashParams[key] +'" />';
112 - }
113 - if (this.flashVars) {
114 - html += '\n\t<param name="flashvars" value=\'';
115 - var and = '';
116 - for(var key in this.flashVars) {
117 - html += and + [key] + '=' + asString(this.flashVars[key]) ;
118 - and = '&';
119 - }
120 - html += '\' />';
121 - }
122 - html += "</object>";
123 - }
124 - js_log('embed code:'+ html);
125 - return html;
 1551+ /*return '<a href="' + this.media_element.selected_source.getURI(this.seek_time_sec) +'" '+
 1552+ 'style="display:block;width:' + this.width + 'px;height:' + this.height + 'px" '+
 1553+ 'id="' + this.pid + '"> rewrite me'+
 1554+ '</a>';*/
 1555+ //give the embed element a unique pid (work around for flowplayer persistence)
 1556+ if( this.old_pid!=0 ){
 1557+ this.pid = this.pid +'_'+ this.old_pid;
 1558+ }
 1559+ return '<a '+
 1560+ 'href="'+this.media_element.selected_source.getURI(this.seek_time_sec)+'" '+
 1561+ 'style="display:block;width:400px;height:300px" '+
 1562+ 'id="'+this.pid+'">'+
 1563+ '</a>';
1261564 },
1271565 postEmbedJS: function()
1281566 {
129 - this.getFLA();
130 - if(this.fla){
131 - setTimeout('$j(\'#'+this.id+'\').get(0).monitor()', 250);
132 - }else{
133 - js_log('flash not ready');
134 - setTimeout('$j(\'#'+this.id+'\').get(0).postEmbedJS()',250);
135 - }
136 - },
 1567+ var _this = this;
 1568+ //js_log('postEmbedJS: ' + mv_embed_path + 'flowplayer/flowplayer-3.0.0-rc2.swf' ) ;
 1569+ $f(this.pid, "/flowplayer/flowplayer-3.0.0-rc2.swf", {
 1570+ clip: {
 1571+ url: _this.media_element.selected_source.getURI(this.seek_time_sec),
 1572+
 1573+ // when this is false playback does not start until play button is pressed
 1574+ autoPlay: true
 1575+ },
 1576+ plugins: {
 1577+ controls: null
 1578+ }
 1579+ });
 1580+ //get the this.fla value:
 1581+ this.getFLA();
 1582+ //set up bindings (for when interacting with the swf causes action:
 1583+ this.fla.onPause(function(){
 1584+ js_log('flash:onPause');
 1585+ if(!_this.paused){
 1586+ _this.pause();
 1587+ }
 1588+ })
 1589+ this.fla.onResume(function(){
 1590+ js_log('flash;onResume');
 1591+ if(_this.paused){
 1592+ _this.play();
 1593+ }
 1594+ });
 1595+ //start monitor:
 1596+ this.monitor();
 1597+ this.old_pid++;
 1598+ },
1371599 /* js hooks/controls */
1381600 play: function(){
139 - this.getFLA();
140 - if(!this.fla || this.thumbnail_disp)
141 - {
142 - //call the parent
143 - this.parent_play();
144 - }else{
145 - this.fla.DoPlay();
146 - this.paused=false;
 1601+ this.getFLA();
 1602+ //update play/pause button etc
 1603+ this.parent_play();
 1604+ if( this.fla ){
 1605+ this.fla.play();
1471606 setTimeout('$j(\'#'+this.id+'\').get(0).monitor()', 250);
1481607 }
1491608 },
@@ -157,11 +1616,19 @@
1581617 }
1591618 }
1601619 },
 1620+ fullscreen:function(){
 1621+ if(this.fla){
 1622+ this.fla.fullscreen();
 1623+ }else{
 1624+ js_log('must be playing before you can go fullscreen');
 1625+ }
 1626+ },
1611627 pause : function()
1621628 {
1631629 this.getFLA();
164 - if(this.fla['Pause'])
165 - this.fla.Pause();
 1630+ this.parent_pause();
 1631+ if(this.fla['pause'])
 1632+ this.fla.pause();
1661633 //stop updates:
1671634 if( this.monitorTimerId != 0 )
1681635 {
@@ -178,14 +1645,26 @@
1791646 }
1801647 }
1811648 this.getFLA();
182 - if(!this.fla['getTime'])
183 - return js_log('can not monitor without time');
184 -
 1649+
1851650 var flash_state = this.fla.getStatus();
186 - js_log('flash state: '+flash_state);
187 -
188 - this.currentTime = this.fla.getTime();
1891651
 1652+ //simplification of buffer state ... should move to support returning time rages like:
 1653+ //http://www.whatwg.org/specs/web-apps/current-work/#normalized-timeranges-object
 1654+ this.bufferedPercent = flash_state.bufferEnd / this.getDuration();
 1655+
 1656+ //set the current Time (based on timeFormat)
 1657+ if( this.media_element.selected_source.timeFormat =='anx' ){
 1658+ this.currentTime = flash_state.time;
 1659+ //js_log('set buffer: ' + flash_state.bufferEnd + ' at time: ' + flash_state.time +' of total dur: ' + this.getDuration());
 1660+ }else{
 1661+ this.currentTime = flash_state.time + this.media_element.selected_source.start_offset;
 1662+ //stop buffering if greater than the duration:
 1663+ if( flash_state.bufferEnd > this.getDuration() + 5 ){
 1664+ js_log('should stop buffering (does not seem to work)' + flash_state.bufferEnd + ' > dur: ' + this.getDuration() );
 1665+ this.fla.stopBuffering();
 1666+ }
 1667+ }
 1668+
1901669 var end_ntp = (this.media_element.selected_source.end_ntp)?
1911670 this.media_element.selected_source.end_ntp : seconds2ntp(0);
1921671 var start_ntp = this.media_element.selected_source.start_ntp;
@@ -198,7 +1677,7 @@
1991678 if(this.currentTime > 1 && this.seek_time_sec != 0 && !this.media_element.selected_source.supports_url_time_encoding)
2001679 {
2011680 js_log('flashEmbed: _local_ Seeking to ' + this.seek_time_sec);
202 - this.fla.Seek(this.seek_time_sec);
 1681+ this.fla.seek( this.seek_time_sec );
2031682 this.seek_time_sec = 0;
2041683 }
2051684
@@ -214,28 +1693,34 @@
2151694 this.setSliderValue((this.currentTime - ntp2seconds(start_ntp)) / (ntp2seconds(end_ntp)-ntp2seconds(start_ntp)) );
2161695 }
2171696 }
218 -
219 - //super hackery to see if we have "probably" reached the end of playback:
220 - if(this.startedTimedPlayback && this.prevTime==this.currentTime && (this.currentTime > (ntp2seconds(end_ntp)-1)) ){
221 - js_log('probablly reached end of stream: '+this.currentTime);
 1697+
 1698+ //checks to see if we reached the end of playback:
 1699+ if(this.startedTimedPlayback &&
 1700+ ( this.currentTime > (ntp2seconds(end_ntp)+1)
 1701+ ||
 1702+ ( this.currentTime > (ntp2seconds(end_ntp)-1)
 1703+ && this.prevTime == this.currentTime) )
 1704+ ){
 1705+ js_log('probbaly reached end of stream: '+this.currentTime);
2221706 this.onClipDone();
223 - }
224 - this.prevTime = this.currentTime;
225 -
 1707+ }
 1708+ this.prevTime = this.currentTime;
2261709 //js_log('cur perc loaded: ' + this.fla.getPercentLoaded() +' cur time : ' + (this.currentTime - ntp2seconds(start_ntp)) +' / ' +(ntp2seconds(end_ntp)-ntp2seconds(start_ntp)));
2271710 },
2281711 // get the embed fla object
2291712 getFLA : function (){
230 - this.fla = this.getPluginEmbed();
 1713+ this.fla = $f(this.pid);
2311714 },
2321715 stop : function(){
233 - js_log('f:flashEmbed:stop');
 1716+ js_log('f:flashEmbed:stop');
2341717 this.startedTimedPlayback=false;
2351718 if (this.monitorTimerId != 0 )
2361719 {
2371720 clearInterval(this.monitorTimerId);
2381721 this.monitorTimerId = 0;
2391722 }
 1723+ if(this.fla)
 1724+ this.fla.unload();
2401725 this.parent_stop();
2411726 },
2421727 onStop: function(){
@@ -256,7 +1741,7 @@
2571742 this.monitor();
2581743 }else{
2591744 js_log('clip done and '+ this.startedTimedPlayback);
260 - //stop the clip if its not stoped already:
 1745+ //stop the clip if its not stopped already:
2611746 this.stop();
2621747 this.setStatus("Clip Done...");
2631748 //run the onClip done action:
@@ -264,108 +1749,3 @@
2651750 }
2661751 }
2671752 }
268 -function asString(obj) {
269 - switch (typeOf(obj)){
270 - case 'string':
271 - return '"'+obj.replace(new RegExp('(["\\\\])', 'g'), '\\$1')+'"';
272 - case 'array':
273 - return '['+ map(obj, function(el) {
274 - return asString(el);
275 - }).join(',') +']';
276 - case 'object':
277 - var str = [];
278 - for (var property in obj) {
279 - str.push('"'+property+'":'+ asString(obj[property]));
280 - }
281 - return '{'+str.join(',')+'}';
282 - }
283 - // replace ' --> " and remove spaces
284 - return String(obj)
285 - .replace(/\s/g, " ")
286 - .replace(/\'/g, "\""); //'
287 -}
288 -function map(arr,func){
289 - var newArr=[];
290 - for(var i in arr){
291 - if(arr.hasOwnProperty(i)){
292 - newArr[i]=func(arr[i]);
293 - }
294 - }
295 - return newArr;
296 -}
297 -
298 -// private functions
299 -function typeOf(obj){
300 - if (obj === null || obj === undefined) return false;
301 - var type = typeof obj;
302 - return (type == 'object' && obj.push) ? 'array' : type;
303 -}
304 -
305 -function locateFlashEmbed(clip)
306 -{
307 - for(var i in global_player_list)
308 - {
309 - var embed = document.getElementById(global_player_list[i]);
310 - if(embed.media_element.selected_source.src.match(clip.fileName))
311 - {
312 - //js_log('found flash embed');
313 - return embed;
314 - }
315 - }
316 -}
317 -
318 -/* flowplayer callbacks */
319 -function onFlowPlayerReady()
320 -{
321 - js_log('f:flash_CB:onFlowPlayerReady');
322 -}
323 -
324 -function onClipDone(clip)
325 -{
326 - js_log('f:flash_CB:onClipDone');
327 - var embed = locateFlashEmbed(clip);
328 - embed.onClipDone();
329 -}
330 -
331 -function onLoadBegin(clip)
332 -{
333 - var embed = locateFlashEmbed(clip);
334 - js_log('f:flash_CB:onLoadBegin');
335 - embed.setStatus("Loading Begun...");
336 -}
337 -
338 -function onPlay(clip)
339 -{
340 - var embed = locateFlashEmbed(clip);
341 - js_log('f:flash_CB:onPlay');
342 - embed.setStatus("Playing...");
343 -}
344 -
345 -function onStop(clip)
346 -{
347 - var embed = locateFlashEmbed(clip);
348 - js_log('f:flash_CB:onStop');
349 - embed.setStatus("Stopped...");
350 -}
351 -
352 -function onPause(clip)
353 -{
354 -// var embed = locateFlashEmbed(clip);
355 - js_log('f:flash_CB:onPause');
356 -// embed.pause();
357 - embed.setStatus("Paused...");
358 -}
359 -
360 -function onResume(clip)
361 -{
362 - var embed = locateFlashEmbed(clip);
363 - js_log('f:flash_CB:onResume');
364 - embed.setStatus("Resumed...");
365 -}
366 -
367 -function onStartBuffering(clip)
368 -{
369 - var embed = locateFlashEmbed(clip);
370 - js_log('f:flash_CB:onStartBuffering');
371 - embed.setStatus("Buffering Started...");
372 -}
Index: trunk/extensions/MetavidWiki/skins/mv_embed/embedLibs/mv_vlcEmbed.js
@@ -83,13 +83,13 @@
8484 }
8585 },
8686 doSeek : function(value){
87 - //if( ! this.inputTrackerIgnoreChange ){
 87+ if( this.vlc ) {
8888 if( (this.vlc.input.state == 3) && (this.vlc.input.position != value) )
8989 {
9090 this.vlc.input.position = value;
91 - document.getElementById("info_" + this.id ).innerHTML = 'seeking'
 91+ this.setStatus( 'seeking...' );
9292 }
93 - //}
 93+ }
9494 },
9595 playMovieAt : function (order){
9696 //@@todo add clips to playlist after (order) and then play
Index: trunk/extensions/MetavidWiki/skins/mv_embed/skins/mvpcf/styles.css
@@ -245,26 +245,40 @@
246246 width: 100%;
247247 height: 12px;
248248 position: relative;
249 - z-index: 1;
 249+ z-index: 4;
250250 background: url(images/player_seek_left.png) 0 0 no-repeat;
251251 }
252252 .videoPlayer .seeker .seeker_bar_close {
253253 width: 5px;
254254 height: 12px;
255255 position: relative;
256 - z-index: 1;
 256+ z-index: 4;
257257 float: right;
258258 display: inline;
259259 margin: -13px 0 0 0;
260260 background: url(images/player_seek_right.png) 0 0 no-repeat;
261261 }
262 -
 262+.videoPlayer .seeker .mv_progress{
 263+ width: 0%;
 264+ height: 12px;
 265+ left:0px;
 266+ top:0px;
 267+ position: absolute;
 268+}
 269+.videoPlayer .seeker .mv_playback {
 270+ z-index: 3;
 271+ background: #CCC;
 272+}
 273+.videoPlayer .seeker .mv_buffer {
 274+ z-index: 2;
 275+ background: #99C;
 276+}
263277 .videoPlayer .seeker .seeker_slider {
264278 background: url(images/player_slider.png) 0 0 no-repeat;
265279 width: 14px;
266280 height: 14px;
267281 position: relative;
268 - z-index: 2;
 282+ z-index: 5;
269283 margin: -13px 0 0 0px;
270284 cursor: pointer;
271285 }
Index: trunk/extensions/MetavidWiki/skins/mv_embed/mv_embed.js
@@ -15,9 +15,9 @@
1616 *
1717 */
1818
19 -//fix multiple instances of mv_embed (ie include twice from two diffrent servers)
 19+//fix multiple instances of mv_embed (ie include twice from two different servers)
2020 var MV_DO_INIT=true;
21 -if(MV_EMBED_VERSION){
 21+if( MV_EMBED_VERSION ){
2222 js_log('mv_embed already included do nothing');
2323 MV_DO_INIT=false;
2424 }
@@ -496,7 +496,7 @@
497497 {
498498 var cookieVal = '';
499499 for(var i in this.preference)
500 - cookieVal = cookieVal + i + '='+ this.preference[i] + '&';
 500+ cookieVal+= i + '='+ this.preference[i] + '&';
501501 cookieVal=cookieVal.substr(0, cookieVal.length-1);
502502 js_log('setting preference cookie to ' + cookieVal);
503503 var week = 7*86400*1000;
@@ -506,20 +506,21 @@
507507
508508 var getCookie = function ( cookieName ) {
509509 var m = document.cookie.match( cookieName + '=(.*?)(;|$)' );
 510+ js_log('getCookie:' + (m ? unescape( m[1] ) : false));
510511 return m ? unescape( m[1] ) : false;
511 - }
 512+}
512513
513 -var setCookie = function ( name, value, expiry, path, domain, secure ) {
514 - var expiryDate = false;
515 - if ( expiry ) {
516 - expiryDate = new Date();
517 - expiryDate.setTime( expiryDate.getTime() + expiry );
518 - }
519 - document.cookie = name + "=" + escape(value) +
520 - (expiryDate ? ("; expires=" + expiryDate.toGMTString()) : "") +
521 - (path ? ("; path=" + path) : "") +
522 - (domain ? ("; domain=" + domain) : "") +
523 - (secure ? "; secure" : "");
 514+function setCookie(name, value, expiry, path, domain, secure) {
 515+ var expiryDate = false;
 516+ if ( expiry ) {
 517+ expiryDate = new Date();
 518+ expiryDate.setTime( expiryDate.getTime() + expiry );
 519+ }
 520+ document.cookie = name + "=" + escape(value) +
 521+ (expiryDate ? ("; expires=" + expiryDate.toGMTString()) : "") +
 522+ (path ? ("; path=" + path) : "") +
 523+ (domain ? ("; domain=" + domain) : "") +
 524+ (secure ? "; secure" : "");
524525 }
525526
526527 /*
@@ -549,13 +550,12 @@
550551 $j('body').append( this.components['mv_embedded_options'].o() );
551552
552553 var o='';
553 - for(var i in this.components){
554 - if(this.supports[i]){
555 - if(this.avaliable_width > this.components[i].w ){
 554+ for( var i in this.components ){
 555+ if( this.supports[i] ){
 556+ if( this.avaliable_width > this.components[i].w ){
556557 //special case with playhead don't add unless we have 60px
557558 if( i=='play_head' && ctrlBuilder.avaliable_width < 60 )
558 - continue;
559 -
 559+ continue;
560560 o+=this.components[i].o();
561561 this.avaliable_width -= this.components[i].w;
562562 }else{
@@ -591,7 +591,7 @@
592592 $j('#big_play_link_'+id).fadeOut('fast');
593593 //if playlist always start at 0
594594 embedObj.start_time_sec = (embedObj.instanceOf == 'mvPlayList')?0:
595 - _this.start_time_sec = ntp2seconds(embedObj.getTimeReq().split('/')[0]);
 595+ ntp2seconds(embedObj.getTimeReq().split('/')[0]);
596596 },
597597 drag:function(e, ui){
598598 //@@todo get the -14 number from the skin somehow
@@ -689,6 +689,8 @@
690690 ' <div id="seeker_bar_'+ctrlBuilder.id+'" class="seeker_bar">'+
691691 ' <div class="seeker_bar_outer"></div>'+
692692 ' <div id="mv_seeker_slider_'+ctrlBuilder.id+'" class="seeker_slider"></div>'+
 693+ ' <div class="mv_progress mv_playback"></div>'+
 694+ ' <div class="mv_progress mv_buffer"></div>'+
693695 ' <div class="seeker_bar_close"></div>'+
694696 ' </div>'+
695697 ' </div><!--seeker-->'
@@ -926,7 +928,7 @@
927929 * $j(document).ready( function(){ */
928930 function init_mv_embed(force){
929931 js_log('f:init_mv_embed');
930 - if(!force && mv_init_done){
 932+ if(!force && ( mv_init_done || !MV_DO_INIT ) ){
931933 js_log("mv_init_done do nothing...");
932934 return false;
933935 }
@@ -1539,14 +1541,14 @@
15401542 getURI : function(seek_time_sec)
15411543 {
15421544 if( !seek_time_sec || !this.supports_url_time_encoding )
1543 - return this.src;
1544 - if( this.timeFormat == 'anx' ){
 1545+ return this.src;
 1546+ if( this.timeFormat == 'anx' ){
15451547 var new_url = getUpdateTimeURL(this.src, seconds2ntp(seek_time_sec)+'/'+ this.end_ntp);
15461548 }else if(this.timeFormat=='mp4'){
15471549 var mp4URL = parseUri( this.src );
15481550 var new_url = mp4URL.protocol+'://'+mp4URL.authority + mp4URL.path + '?start='
15491551 + ( seek_time_sec + parseInt(mp4URL.queryKey['start']) );
1550 - }
 1552+ }
15511553 return new_url;
15521554 },
15531555 /** Title accessor function.
@@ -1571,7 +1573,7 @@
15721574 * supports media_url?t=ntp_start/ntp_end url request format
15731575 */
15741576 parseURLDuration : function(){
1575 - js_log('f:parseURLDuration() for:' + this.src);
 1577+ //js_log('f:parseURLDuration() for:' + this.src);
15761578 //check if we have a timeFormat:
15771579 if( this.timeFormat ){
15781580 if( this.timeFormat == 'anx' ){
@@ -1579,8 +1581,7 @@
15801582 if( annoURL.queryKey['t'] ){
15811583 var times = annoURL.queryKey['t'].split('/');
15821584 this.start_ntp = times[0];
1583 - this.end_ntp = times[1];
1584 -
 1585+ this.end_ntp = times[1];
15851586 }
15861587 }
15871588 if( this.timeFormat == 'mp4' ){
@@ -1893,8 +1894,9 @@
18941895 supports:{},
18951896 //for seek thumb updates:
18961897 cur_thumb_seek_time:0,
1897 - thumb_seek_interval:null,
1898 -
 1898+ thumb_seek_interval:null,
 1899+ //set the buffered percent:
 1900+ bufferedPercent:0,
18991901 //utility functions for property values:
19001902 hx : function ( s ) {
19011903 if ( typeof s != 'String' ) {
@@ -2222,7 +2224,7 @@
22232225 var annoURL = parseUri(anno_track_url);
22242226 var times = annoURL.queryKey['t'].split('/');
22252227 var stime_parts = times[0].split(':');
2226 - var etime_parts = times[0].split(':');
 2228+ var etime_parts = times[1].split(':');
22272229 //zero out the hour:
22282230 var new_start = stime_parts[0]+':'+'0:0';
22292231 //zero out the end sec
@@ -2388,10 +2390,10 @@
23892391 html_code = '<div id="videoPlayer_'+this.id+'" style="width:'+this.width+'px;" class="videoPlayer">';
23902392 html_code += '<div style="width:'+parseInt(this.width)+'px;height:'+parseInt(this.height)+'px;" id="mv_embedded_player_'+this.id+'">' +
23912393 this.getThumbnailHTML() +
2392 - '</div>';
2393 -
 2394+ '</div>';
 2395+
23942396 js_log("mvEmbed:controls "+ typeof this.controls);
2395 -
 2397+
23962398 if(this.controls)
23972399 {
23982400 js_log("f:getHTML:AddControls");
@@ -2823,47 +2825,35 @@
28242826 }else{
28252827 this.doEmbedHTML();
28262828 this.onClipDone_disp=false;
2827 - this.paused=false;
 2829+ this.paused=false;
28282830 }
28292831 }else{
28302832 //the plugin is already being displayed
28312833 js_log("we are already playing..." );
28322834 this.paused=false; //make sure we are not "paused"
28332835 }
2834 - //update "paused state"
2835 - js_log("SHOULD UPDATE play BUTTON");
2836 - $j("#mv_play_pause_button_"+this_id).attr('class', 'pause_button');
 2836+ $j("#mv_play_pause_button_"+this_id).attr('class', 'pause_button');
28372837 },
2838 - toggleMute:function(){
2839 - var this_id = (this.pc!=null)?this.pc.pp.id:this.id;
2840 - js_log('f:toggleMute');
2841 - if(this.muted){
2842 - this.muted=false;
2843 - $j('#volume_icon_'+this_id).removeClass('volume_off').addClass('volume_on');
2844 - }else{
2845 - this.muted=true;
2846 - $j('#volume_icon_'+this_id).removeClass('volume_on').addClass('volume_off');
2847 - }
2848 - },
 2838+ /*
 2839+ * base embed pause
 2840+ * there is no general way to pause the video
 2841+ * must be overwritten by embed object to support this functionality.
 2842+ */
 2843+ pause : function(){
 2844+ js_log('mv_embed:do pause');
 2845+ var this_id = (this.pc!=null)?this.pc.pp.id:this.id;
 2846+ //(playing) do pause
 2847+ this.paused=true;
 2848+ //update "paused state"
 2849+ $j("#mv_play_pause_button_"+this_id).attr('class', 'play_button');
 2850+ },
28492851 play_or_pause : function(){
28502852 js_log('embed:f:play_or_pause');
2851 - var this_id = (this.pc!=null)?this.pc.pp.id:this.id;
2852 -
28532853 //check state and set play or pause
28542854 if(this.paused){
2855 - js_log('mv_embed:do play');
2856 - //(paused) do play
2857 - this.play();
2858 - this.paused=false;
2859 - //update "paused state" onPlay
2860 - $j("#mv_play_pause_button_"+this_id).attr('class', 'pause_button');
2861 - }else{
2862 - js_log('mv_embed:do pause');
2863 - //(playing) do pause
 2855+ this.play();
 2856+ }else{
28642857 this.pause();
2865 - this.paused=true;
2866 - //update "paused state"
2867 - $j("#mv_play_pause_button_"+this_id).attr('class', 'play_button');
28682858 }
28692859 },
28702860 //called when we play to the end of a stream (load the thumbnail)
@@ -2874,18 +2864,10 @@
28752865 }
28762866 },
28772867 /*
2878 - * base embed pause
2879 - * there is no general way to pause the video
2880 - * must be overwritten by embed object to support this functionality.
2881 - */
2882 - pause : function(){
2883 - return null
2884 - },
2885 - /*
28862868 * base embed stop (can be overwritten by the plugin)
28872869 */
28882870 stop: function(){
2889 - js_log('mvEmbed:stop:'+this.id);
 2871+ js_log('mvEmbed:stop:'+this.id);
28902872 //check if thumbnail is being displayed in which case do nothing
28912873 if(this.thumbnail_disp){
28922874 //already in stooped state
@@ -2893,8 +2875,9 @@
28942876 }else{
28952877 //rewrite the html to thumbnail disp
28962878 this.doThumbnailHTML();
 2879+ this.bufferedPercent=0; //reset buffer state
28972880 this.setSliderValue(0);
2898 - this.setStatus(this.getTimeReq());
 2881+ this.setStatus( this.getTimeReq() );
28992882 }
29002883 if(this.update_interval)
29012884 {
@@ -2902,6 +2885,17 @@
29032886 this.update_interval = null;
29042887 }
29052888 },
 2889+ toggleMute:function(){
 2890+ var this_id = (this.pc!=null)?this.pc.pp.id:this.id;
 2891+ js_log('f:toggleMute');
 2892+ if(this.muted){
 2893+ this.muted=false;
 2894+ $j('#volume_icon_'+this_id).removeClass('volume_off').addClass('volume_on');
 2895+ }else{
 2896+ this.muted=true;
 2897+ $j('#volume_icon_'+this_id).removeClass('volume_on').addClass('volume_off');
 2898+ }
 2899+ },
29062900 fullscreen:function(){
29072901 js_log('fullscreen not supported for this plugin type');
29082902 },
@@ -2911,6 +2905,9 @@
29122906 if(this.thumbnail_disp){
29132907 //in stoped state
29142908 return false;
 2909+ }else if( this.paused ){
 2910+ //paused state
 2911+ return false;
29152912 }else{
29162913 return true;
29172914 }
@@ -2918,6 +2915,9 @@
29192916 isPaused : function(){
29202917 return this.isPlaying() && this.paused;
29212918 },
 2919+ isStoped : function(){
 2920+ return this.thumbnail_disp;
 2921+ },
29222922 playlistSupport:function(){
29232923 //by default not supported (implemented in js)
29242924 return false;
@@ -2948,6 +2948,20 @@
29492949 if(val > ($j('#mv_seeker_'+this_id).width() -this.mv_seeker_width) )
29502950 val = $j('#mv_seeker_'+this_id).width() -this.mv_seeker_width ;
29512951 $j('#mv_seeker_slider_'+this_id).css('left', (val)+'px' );
 2952+
 2953+ //update the playback progress bar
 2954+ $j('#mv_seeker_' + this_id + ' .mv_playback').css("width", Math.round( val + (this.mv_seeker_width*.5) ) + 'px' );
 2955+
 2956+ //update the buffer progress bar (if available )
 2957+ if( this.bufferedPercent!=0 ){
 2958+ //js_log('bufferedPercent: ' + this.bufferedPercent);
 2959+ if(this.bufferedPercent > 1)
 2960+ this.bufferedPercent=1;
 2961+ $j('#mv_seeker_' + this_id + ' .mv_buffer').css("width", (this.bufferedPercent*100) +'%' );
 2962+ }else{
 2963+ $j('#mv_seeker_' + this_id + ' .mv_buffer').css("width", '0px' );
 2964+ }
 2965+
29522966 //js_log('set#mv_seeker_slider_'+this_id + ' perc in: ' + perc + ' * ' + $j('#mv_seeker_'+this_id).width() + ' = set to: '+ val + ' - '+ Math.round(this.mv_seeker_width*perc) );
29532967 //js_log('op:' + offset_perc + ' *('+perc+' * ' + $j('#slider_'+id).width() + ')');
29542968 },
@@ -2958,21 +2972,6 @@
29592973 }
29602974 }
29612975
2962 -/* returns html for a transparent png (for ie<7)
2963 - * not currently used:
2964 -function getTransparentPng(image){
2965 - if(!image.style)image.style='';
2966 - if( embedTypes.msie ){
2967 - return '<span id="'+image.id+'" style="display:inline-block;width:'+image.width+'px;height:'+image.height+'px;' +
2968 - 'filter:progid:DXImageTransform.Microsoft.AlphaImageLoader' +
2969 - '(src=\''+image.src+'\', sizingMethod=\'scale\');"></span>';
2970 - }else{
2971 - return '<img id="'+image.id+'" style="'+image.style+'" width="'+image.width+'" height="'+image.height+'" border="0" src="'+
2972 - image.src + '">';
2973 - }
2974 -}
2975 -*/
2976 -
29772976 /*
29782977 * utility functions:
29792978 */
@@ -2997,6 +2996,9 @@
29982997
29992998 function seconds2ntp(sec){
30002999 var sec = parseInt(sec);
 3000+ if( isNaN( sec ) ){
 3001+ return '0:0:0';
 3002+ }
30013003 var hours = Math.floor(sec/ 3600);
30023004 var minutes = Math.floor((sec/60) % 60);
30033005 var seconds = sec % 60;
Index: trunk/extensions/MetavidWiki/skins/mv_embed/mv_remote_media_search.js
@@ -12,7 +12,7 @@
1313 num_req:0,
1414
1515 result_display_mode:'box', //box or list
16 - api_mode:'metavid', //api mode (mediawiki api or metavid enhanced wiki api)
 16+ api_mode:'mediawiki', //api mode (mediawiki api or metavid enhanced wiki api)
1717 resultsObj:{},
1818 //init the object:
1919 init:function( initObj ){

Status & tagging log