+++ /dev/null
-===============================
-TimeSide - Web Audio Components
-===============================
-
-TimeSide UI Dependencies
-========================
-
-* SoundManager 2 >= 2.91 : http://www.schillmania.com/projects/soundmanager2
-* jQuery => 1.2.6 : http://www.jquery.com
-* jsGraphics => 3.03 http://www.walterzorn.com/jsgraphics/jsgraphics_e.htm
-
-Licensing
-=========
-
-Copyright (c) 2008-2009 Samalyse
-Author: Olivier Guilyardi <olivier samalyse com>
-
-TimeSide is released under the terms of the GNU General Public License
-version 2. Please see the LICENSE file for details.
-
+++ /dev/null
-/*!
- * jQuery JavaScript Library v1.6
- * http://jquery.com/
- *
- * Copyright 2011, John Resig
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * Includes Sizzle.js
- * http://sizzlejs.com/
- * Copyright 2011, The Dojo Foundation
- * Released under the MIT, BSD, and GPL Licenses.
- *
- * Date: Mon May 2 13:50:00 2011 -0400
- */
-(function(a,b){function cw(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function ct(a){if(!ch[a]){var b=f("<"+a+">").appendTo("body"),d=b.css("display");b.remove();if(d==="none"||d===""){ci||(ci=c.createElement("iframe"),ci.frameBorder=ci.width=ci.height=0),c.body.appendChild(ci);if(!cj||!ci.createElement)cj=(ci.contentWindow||ci.contentDocument).document,cj.write("<!doctype><html><body></body></html>");b=cj.createElement(a),cj.body.appendChild(b),d=f.css(b,"display"),c.body.removeChild(ci)}ch[a]=d}return ch[a]}function cs(a,b){var c={};f.each(cn.concat.apply([],cn.slice(0,b)),function(){c[this]=a});return c}function cr(){co=b}function cq(){setTimeout(cr,0);return co=f.now()}function cg(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function cf(){try{return new a.XMLHttpRequest}catch(b){}}function b_(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function b$(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function bZ(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bD.test(a)?d(a,e):bZ(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)bZ(a+"["+e+"]",b[e],c,d);else d(a,b)}function bY(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bS,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=bY(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bY(a,c,d,e,"*",g));return l}function bX(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bO),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bB(a,b,c){var d=b==="width"?bv:bw,e=b==="width"?a.offsetWidth:a.offsetHeight;if(c==="border")return e;f.each(d,function(){c||(e-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?e+=parseFloat(f.css(a,"margin"+this))||0:e-=parseFloat(f.css(a,"border"+this+"Width"))||0});return e}function bl(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval(b.text||b.textContent||b.innerHTML||""),b.parentNode&&b.parentNode.removeChild(b)}function bk(a){f.nodeName(a,"input")?bj(a):a.getElementsByTagName&&f.grep(a.getElementsByTagName("input"),bj)}function bj(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bi(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function bh(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bg(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c=f.expando,d=f.data(a),e=f.data(b,d);if(d=d[c]){var g=d.events;e=e[c]=f.extend({},d);if(g){delete e.handle,e.events={};for(var h in g)for(var i=0,j=g[h].length;i<j;i++)f.event.add(b,h+(g[h][i].namespace?".":"")+g[h][i].namespace,g[h][i],g[h][i].data)}}}}function bf(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function W(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(R.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function V(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function N(a,b){return(a&&a!=="*"?a+".":"")+b.replace(z,"`").replace(A,"&")}function M(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;i<s.length;i++)g=s[i],g.origType.replace(x,"")===a.type?q.push(g.selector):s.splice(i--,1);e=f(a.target).closest(q,a.currentTarget);for(j=0,k=e.length;j<k;j++){m=e[j];for(i=0;i<s.length;i++){g=s[i];if(m.selector===g.selector&&(!n||n.test(g.namespace))&&!m.elem.disabled){h=m.elem,d=null;if(g.preType==="mouseenter"||g.preType==="mouseleave")a.type=g.preType,d=f(a.relatedTarget).closest(g.selector)[0],d&&f.contains(h,d)&&(d=h);(!d||d!==h)&&p.push({elem:h,handleObj:g,level:m.level})}}}for(j=0,k=p.length;j<k;j++){e=p[j];if(c&&e.level>c)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function K(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function E(){return!0}function D(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){name="data-"+c.replace(j,"$1-$2").toLowerCase(),d=a.getAttribute(name);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(e){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function H(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(H,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=d.userAgent,x,y,z,A=Object.prototype.toString,B=Object.prototype.hasOwnProperty,C=Array.prototype.push,D=Array.prototype.slice,E=String.prototype.trim,F=Array.prototype.indexOf,G={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)==="<"&&a.charAt(a.length-1)===">"&&a.length>=3?g=[null,a,null]:g=i.exec(a);if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6",length:0,size:function(){return this.length},toArray:function(){return D.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?C.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),y.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(D.apply(this,arguments),"slice",D.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:C,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;y.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!y){y=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",z,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",z),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&H()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):G[A.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;if(a.constructor&&!B.call(a,"constructor")&&!B.call(a.constructor.prototype,"isPrototypeOf"))return!1;var c;for(c in a);return c===b||B.call(a,c)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(b,c,d){a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b)),d=c.documentElement,(!d||!d.nodeName||d.nodeName==="parsererror")&&e.error("Invalid XML: "+b);return c},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:E?function(a){return a==null?"":E.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?C.call(c,a):e.merge(c,a)}return c},inArray:function(a,b){if(F)return F.call(b,a);for(var c=0,d=b.length;c<d;c++)if(b[c]===a)return c;return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=D.call(arguments,2),g=function(){return a.apply(c,f.concat(D.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=s.exec(a)||t.exec(a)||u.exec(a)||a.indexOf("compatible")<0&&v.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(c,d){d&&d instanceof e&&!(d instanceof a)&&(d=a(d));return e.fn.init.call(this,c,d,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){G["[object "+b+"]"]=b.toLowerCase()}),x=e.uaMatch(w),x.browser&&(e.browser[x.browser]=!0,e.browser.version=x.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?z=function(){c.removeEventListener("DOMContentLoaded",z,!1),e.ready()}:c.attachEvent&&(z=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",z),e.ready())});return e}(),g="done fail isResolved isRejected promise then always pipe".split(" "),h=[].slice;f.extend({_Deferred:function(){var a=[],b,c,d,e={done:function(){if(!d){var c=arguments,g,h,i,j,k;b&&(k=b,b=0);for(g=0,h=c.length;g<h;g++)i=c[g],j=f.type(i),j==="array"?e.done.apply(e,i):j==="function"&&a.push(i);k&&e.resolveWith(k[0],k[1])}return this},resolveWith:function(e,f){if(!d&&!b&&!c){f=f||[],c=1;try{while(a[0])a.shift().apply(e,f)}finally{b=[e,f],c=0}}return this},resolve:function(){e.resolveWith(this,arguments);return this},isResolved:function(){return!!c||!!b},cancel:function(){d=1,a=[];return this}};return e},Deferred:function(a){var b=f._Deferred(),c=f._Deferred(),d;f.extend(b,{then:function(a,c){b.done(a).fail(c);return this},always:function(){return b.done.apply(b,arguments).fail.apply(this,arguments)},fail:c.done,rejectWith:c.resolveWith,reject:c.resolve,isRejected:c.isResolved,pipe:function(a,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[c,"reject"]},function(a,c){var e=c[0],g=c[1],h;f.isFunction(e)?b[a](function(){h=e.apply(this,arguments),f.isFunction(h.promise)?h.promise().then(d.resolve,d.reject):d[g](h)}):b[a](d[g])})}).promise()},promise:function(a){if(a==null){if(d)return d;d=a={}}var c=g.length;while(c--)a[g[c]]=b[g[c]];return a}}),b.done(c.cancel).fail(b.cancel),delete b.cancel,a&&a.call(b,b);return b},when:function(a){function i(a){return function(c){b[a]=arguments.length>1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c<d;c++)b[c]&&f.isFunction(b[c].promise)?b[c].promise().then(i(c),g.reject):--e;e||g.resolveWith(g,b)}else g!==a&&g.resolveWith(g,d?[a]:[]);return g.promise()}}),f.support=function(){var a=c.createElement("div"),b,d,e,f,g,h,i,j,k,l,m,n,o,p,q;a.setAttribute("className","t"),a.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",b=a.getElementsByTagName("*"),d=a.getElementsByTagName("a")[0];if(!b||!b.length||!d)return{};e=c.createElement("select"),f=e.appendChild(c.createElement("option")),g=a.getElementsByTagName("input")[0],i={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(d.getAttribute("style")),hrefNormalized:d.getAttribute("href")==="/a",opacity:/^0.55$/.test(d.style.opacity),cssFloat:!!d.style.cssFloat,checkOn:g.value==="on",optSelected:f.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},g.checked=!0,i.noCloneChecked=g.cloneNode(!0).checked,e.disabled=!0,i.optDisabled=!f.disabled;try{delete a.test}catch(r){i.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function click(){i.noCloneEvent=!1,a.detachEvent("onclick",click)}),a.cloneNode(!0).fireEvent("onclick")),g=c.createElement("input"),g.value="t",g.setAttribute("type","radio"),i.radioValue=g.value==="t",g.setAttribute("checked","checked"),a.appendChild(g),j=c.createDocumentFragment(),j.appendChild(a.firstChild),i.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",k=c.createElement("body"),l={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"};for(p in l)k.style[p]=l[p];k.appendChild(a),c.documentElement.appendChild(k),i.appendChecked=g.checked,i.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,i.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="<div style='width:4px;'></div>",i.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",m=a.getElementsByTagName("td"),q=m[0].offsetHeight===0,m[0].style.display="",m[1].style.display="none",i.reliableHiddenOffsets=q&&m[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(h=c.createElement("div"),h.style.width="0",h.style.marginRight="0",a.appendChild(h),i.reliableMarginRight=(parseInt(c.defaultView.getComputedStyle(h,null).marginRight,10)||0)===0),k.innerHTML="",c.documentElement.removeChild(k);if(a.attachEvent)for(p in{submit:1,change:1,focusin:1})o="on"+p,q=o in a,q||(a.setAttribute(o,"return;"),q=typeof a[o]=="function"),i[p+"Bubbles"]=q;return i}(),f.boxModel=f.support.boxModel;var i=/^(?:\{.*\}|\[.*\])$/,j=/([a-z])([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!l(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g=f.expando,h=typeof c=="string",i,j=a.nodeType,k=j?f.cache:a,l=j?a[f.expando]:a[f.expando]&&f.expando;if((!l||e&&l&&!k[l][g])&&h&&d===b)return;l||(j?a[f.expando]=l=++f.uuid:l=f.expando),k[l]||(k[l]={},j||(k[l].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?k[l][g]=f.extend(k[l][g],c):k[l]=f.extend(k[l],c);i=k[l],e&&(i[g]||(i[g]={}),i=i[g]),d!==b&&(i[c]=d);if(c==="events"&&!i[c])return i[g]&&i[g].events;return h?i[c]:i}},removeData:function(b,c,d){if(!!f.acceptData(b)){var e=f.expando,g=b.nodeType,h=g?f.cache:b,i=g?b[f.expando]:f.expando;if(!h[i])return;if(c){var j=d?h[i][e]:h[i];if(j){delete j[c];if(!l(j))return}}if(d){delete h[i][e];if(!l(h[i]))return}var k=h[i][e];f.support.deleteExpando||h!=a?delete h[i]:h[i]=null,k?(h[i]={},g||(h[i].toJSON=f.noop),h[i][e]=k):g&&(f.support.deleteExpando?delete b[f.expando]:b.removeAttribute?b.removeAttribute(f.expando):b[f.expando]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d=null;if(typeof a=="undefined"){if(this.length){d=f.data(this[0]);if(this[0].nodeType===1){var e=this[0].attributes,g;for(var h=0,i=e.length;h<i;h++)g=e[h].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),k(this[0],g,d[g]))}}return d}if(typeof a=="object")return this.each(function(){f.data(this,a)});var j=a.split(".");j[1]=j[1]?"."+j[1]:"";if(c===b){d=this.triggerHandler("getData"+j[1]+"!",[j[0]]),d===b&&this.length&&(d=f.data(this[0],a),d=k(this[0],a,d));return d===b&&j[1]?this.data(j[0]):d}return this.each(function(){var b=f(this),d=[j[0],c];b.triggerHandler("setData"+j[1]+"!",d),f.data(this,a,c),b.triggerHandler("changeData"+j[1]+"!",d)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,c){a&&(c=(c||"fx")+"mark",f.data(a,c,(f.data(a,c,b,!0)||0)+1,!0))},_unmark:function(a,c,d){a!==!0&&(d=c,c=a,a=!1);if(c){d=d||"fx";var e=d+"mark",g=a?0:(f.data(c,e,b,!0)||1)-1;g?f.data(c,e,g,!0):(f.removeData(c,e,!0),m(c,d,"mark"))}},queue:function(a,c,d){if(a){c=(c||"fx")+"queue";var e=f.data(a,c,b,!0);d&&(!e||f.isArray(d)?e=f.data(a,c,f.makeArray(d),!0):e.push(d));return e||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e;d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),d.call(a,function(){f.dequeue(a,b)})),c.length||(f.removeData(a,b+"queue",!0),m(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(){var c=this;setTimeout(function(){f.dequeue(c,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function l(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark";while(g--)if(tmp=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f._Deferred(),!0))h++,tmp.done(l);l();return d.promise()}});var n=/[\n\t\r]/g,o=/\s+/,p=/\r/g,q=/^(?:button|input)$/i,r=/^(?:button|input|object|select|textarea)$/i,s=/^a(?:rea)?$/i,t=/^(?:data-|aria-)/,u=/\:/,v;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.addClass(a.call(this,b,c.attr("class")||""))});if(a&&typeof a=="string"){var b=(a||"").split(o);for(var c=0,d=this.length;c<d;c++){var e=this[c];if(e.nodeType===1)if(!e.className)e.className=a;else{var g=" "+e.className+" ",h=e.className;for(var i=0,j=b.length;i<j;i++)g.indexOf(" "+b[i]+" ")<0&&(h+=" "+b[i]);e.className=f.trim(h)}}}return this},removeClass:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.removeClass(a.call(this,b,c.attr("class")))});if(a&&typeof a=="string"||a===b){var c=(a||"").split(o);for(var d=0,e=this.length;d<e;d++){var g=this[d];if(g.nodeType===1&&g.className)if(a){var h=(" "+g.className+" ").replace(n," ");for(var i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){var d=f(this);d.toggleClass(a.call(this,c,d.attr("class"),b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(o);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ";for(var c=0,d=this.length;c<d;c++)if((" "+this[c].className+" ").replace(n," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e=this[0];if(!arguments.length){if(e){c=f.valHooks[e.nodeName.toLowerCase()]||f.valHooks[e.type];if(c&&"get"in c&&(d=c.get(e,"value"))!==b)return d;return(e.value||"").replace(p,"")}return b}var g=f.isFunction(a);return this.each(function(d){var e=f(this),h;if(this.nodeType===1){g?h=a.call(this,d,e.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||"set"in c&&c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b=a.selectedIndex,c=[],d=a.options,e=a.type==="select-one";if(b<0)return null;for(var g=e?b:0,h=e?b+1:d.length;g<h;g++){var i=d[g];if(i.selected&&(f.support.optDisabled?!i.disabled:i.getAttribute("disabled")===null)&&(!i.parentNode.disabled||!f.nodeName(i.parentNode,"optgroup"))){value=f(i).val();if(e)return value;c.push(value)}}if(e&&!c.length&&d.length)return f(d[b]).val();return c},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attrFix:{tabindex:"tabIndex",readonly:"readOnly"},attr:function(a,c,d,e){var g=a.nodeType;if(!a||g===3||g===8||g===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);var h,i,j=g!==1||!f.isXMLDoc(a);c=j&&f.attrFix[c]||c,i=f.attrHooks[c]||(v&&(f.nodeName(a,"form")||u.test(c))?v:b);if(d!==b){if(d===null||d===!1&&!t.test(c)){f.removeAttr(a,c);return b}if(i&&"set"in i&&j&&(h=i.set(a,d,c))!==b)return h;d===!0&&!t.test(c)&&(d=c),a.setAttribute(c,""+d);return d}if(i&&"get"in i&&j)return i.get(a,c);h=a.getAttribute(c);return h===null?b:h},removeAttr:function(a,b){a.nodeType===1&&(b=f.attrFix[b]||b,f.support.getSetAttribute?a.removeAttribute(b):(f.attr(a,b,""),a.removeAttributeNode(a.getAttributeNode(b))))},attrHooks:{type:{set:function(a,b){if(q.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.getAttribute("value");a.setAttribute("type",b),c&&(a.value=c);return b}}},tabIndex:{get:function(a){var c=a.getAttributeNode("tabIndex");return c&&c.specified?parseInt(c.value,10):r.test(a.nodeName)||s.test(a.nodeName)&&a.href?0:b}}},propFix:{},prop:function(a,c,d){var e=a.nodeType;if(!a||e===3||e===8||e===2)return b;var g,h,i=e!==1||!f.isXMLDoc(a);c=i&&f.propFix[c]||c,h=f.propHooks[c];return d!==b?h&&"set"in h&&(g=h.set(a,d,c))!==b?g:a[c]=d:h&&"get"in h&&(g=h.get(a,c))!==b?g:a[c]},propHooks:{}}),f.support.getSetAttribute||(f.attrFix=f.extend(f.attrFix,{"for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder"}),v=f.attrHooks.name=f.attrHooks.value=f.valHooks.button={get:function(a,c){var d;if(c==="value"&&!f.nodeName(a,"button"))return a.getAttribute(c);d=a.getAttributeNode(c);return d&&d.specified?d.nodeValue:b},set:function(a,b,c){var d=a.getAttributeNode(c);if(d){d.nodeValue=b;return b}}},f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})})),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}})),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var w=Object.prototype.hasOwnProperty,x=/\.(.*)$/,y=/^(?:textarea|input|select)$/i,z=/\./g,A=/ /g,B=/[^\w\s.|`]/g,C=function(a){return a.replace(B,"\\$&")};f.event={add:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){if(d===!1)d=D;else if(!d)return;var g,h;d.handler&&(g=d,d=g.handler),d.guid||(d.guid=f.guid++);var i=f._data(a);if(!i)return;var j=i.events,k=i.handle;j||(i.events=j={}),k||(i.handle=k=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.handle.apply(k.elem,arguments):b}),k.elem=a,c=c.split(" ");var l,m=0,n;while(l=c[m++]){h=g?f.extend({},g):{handler:d,data:e},l.indexOf(".")>-1?(n=l.split("."),l=n.shift(),h.namespace=n.slice(0).sort().join(".")):(n=[],h.namespace=""),h.type=l,h.guid||(h.guid=d.guid);var o=j[l],p=f.event.special[l]||{};if(!o){o=j[l]=[];if(!p.setup||p.setup.call(a,e,n,k)===!1)a.addEventListener?a.addEventListener(l,k,!1):a.attachEvent&&a.attachEvent("on"+l,k)}p.add&&(p.add.call(a,h),h.handler.guid||(h.handler.guid=d.guid)),o.push(h),f.event.global[l]=!0}a=null}},global:{},remove:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){d===!1&&(d=D);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=f.hasData(a)&&f._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(d=c.handler,c=c.type);if(!c||typeof c=="string"&&c.charAt(0)==="."){c=c||"";for(h in t)f.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+f.map(m.slice(0).sort(),C).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!d){for(j=0;j<p.length;j++){q=p[j];if(l||n.test(q.namespace))f.event.remove(a,r,q.handler,j),p.splice(j--,1)}continue}o=f.event.special[h]||{};for(j=e||0;j<p.length;j++){q=p[j];if(d.guid===q.guid){if(l||n.test(q.namespace))e==null&&p.splice(j--,1),o.remove&&o.remove.call(a,q);if(e!=null)break}}if(p.length===0||e!=null&&p.length===1)(!o.teardown||o.teardown.call(a,m)===!1)&&f.removeEvent(a,h,s.handle),g=null,delete t[h]}if(f.isEmptyObject(t)){var u=s.handle;u&&(u.elem=null),delete s.events,delete s.handle,f.isEmptyObject(s)&&f.removeData(a,b,!0)}}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){var h=c.type||c,i=[],j;h.indexOf("!")>=0&&(h=h.slice(0,-1),j=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if(!!e&&!f.event.customEvent[h]||!!f.event.global[h]){c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.exclusive=j,c.namespace=i.join("."),c.namespace_re=new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)");if(g||!e)c.preventDefault(),c.stopPropagation();if(!e){f.each(f.cache,function(){var a=f.expando,b=this[a];b&&b.events&&b.events[h]&&f.event.trigger(c,d,b.handle.elem)});return}if(e.nodeType===3||e.nodeType===8)return;c.result=b,c.target=e,d=d?f.makeArray(d):[],d.unshift(c);var k=e,l=h.indexOf(":")<0?"on"+h:"";do{var m=f._data(k,"handle");c.currentTarget=k,m&&m.apply(k,d),l&&f.acceptData(k)&&k[l]&&k[l].apply(k,d)===!1&&(c.result=!1,c.preventDefault()),k=k.parentNode||k.ownerDocument||k===c.target.ownerDocument&&a}while(k&&!c.isPropagationStopped());if(!c.isDefaultPrevented()){var n,o=f.event.special[h]||{};if((!o._default||o._default.call(e.ownerDocument,c)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)){try{l&&e[h]&&(n=e[l],n&&(e[l]=null),f.event.triggered=h,e[h]())}catch(p){}n&&(e[l]=n),f.event.triggered=b}}return c.result}},handle:function(c){c=f.event.fix(c||a.event);var d=((f._data(this,"events")||{})[c.type]||[]).slice(0),e=!c.exclusive&&!c.namespace,g=Array.prototype.slice.call(arguments,0);g[0]=c,c.currentTarget=this;for(var h=0,i=d.length;h<i;h++){var j=d[h];if(e||c.namespace_re.test(j.namespace)){c.handler=j.handler,c.data=j.data,c.handleObj=j;var k=j.handler.apply(this,g);k!==b&&(c.result=k,k===!1&&(c.preventDefault(),c.stopPropagation()));if(c.isImmediatePropagationStopped())break}}return c.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(a){if(a[f.expando])return a;var d=a;a=f.Event(d);for(var e=this.props.length,g;e;)g=this.props[--e],a[g]=d[g];a.target||(a.target=a.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),!a.relatedTarget&&a.fromElement&&(a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement);if(a.pageX==null&&a.clientX!=null){var h=a.target.ownerDocument||c,i=h.documentElement,j=h.body;a.pageX=a.clientX+(i&&i.scrollLeft||j&&j.scrollLeft||0)-(i&&i.clientLeft||j&&j.clientLeft||0),a.pageY=a.clientY+(i&&i.scrollTop||j&&j.scrollTop||0)-(i&&i.clientTop||j&&j.clientTop||0)}a.which==null&&(a.charCode!=null||a.keyCode!=null)&&(a.which=a.charCode!=null?a.charCode:a.keyCode),!a.metaKey&&a.ctrlKey&&(a.metaKey=a.ctrlKey),!a.which&&a.button!==b&&(a.which=a.button&1?1:a.button&2?3:a.button&4?2:0);return a},guid:1e8,proxy:f.proxy,special:{ready:{setup:f.bindReady,teardown:f.noop},live:{add:function(a){f.event.add(this,N(a.origType,a.selector),f.extend({},a,{handler:M,guid:a.handler.guid}))},remove:function(a){f.event.remove(this,N(a.origType,a.selector),a)}},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}}},f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!this.preventDefault)return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?E:D):this.type=a,b&&f.extend(this,b),this.timeStamp=f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=E;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=E;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=E,this.stopPropagation()},isDefaultPrevented:D,isPropagationStopped:D,isImmediatePropagationStopped:D};var F=function(a){var b=a.relatedTarget;try{if(b&&b!==c&&!b.parentNode)return;while(b&&b!==this)b=b.parentNode;b!==this&&(a.type=a.data,f.event.handle.apply(this,arguments))}catch(d){}},G=function(a){a.type=a.data,f.event.handle.apply(this,arguments)};f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={setup:function(c){f.event.add(this,b,c&&c.selector?G:F,a)},teardown:function(a){f.event.remove(this,b,a&&a.selector?G:F)}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(a,b){if(!f.nodeName(this,"form"))f.event.add(this,"click.specialSubmit",function(a){var b=a.target,c=b.type;(c==="submit"||c==="image")&&f(b).closest("form").length&&K("submit",this,arguments)}),f.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,c=b.type;(c==="text"||c==="password")&&f(b).closest("form").length&&a.keyCode===13&&K("submit",this,arguments)});else return!1},teardown:function(a){f.event.remove(this,".specialSubmit")}});if(!f.support.changeBubbles){var H,I=function(a){var b=a.type,c=a.value;b==="radio"||b==="checkbox"?c=a.checked:b==="select-multiple"?c=a.selectedIndex>-1?f.map(a.options,function(a){return a.selected}).join("-"):"":f.nodeName(a,"select")&&(c=a.selectedIndex);return c},J=function J(a){var c=a.target,d,e;if(!!y.test(c.nodeName)&&!c.readOnly){d=f._data(c,"_change_data"),e=I(c),(a.type!=="focusout"||c.type!=="radio")&&f._data(c,"_change_data",e);if(d===b||e===d)return;if(d!=null||e)a.type="change",a.liveFired=b,f.event.trigger(a,arguments[1],c)}};f.event.special.change={filters:{focusout:J,beforedeactivate:J,click:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(c==="radio"||c==="checkbox"||f.nodeName(b,"select"))&&J.call(this,a)},keydown:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(a.keyCode===13&&!f.nodeName(b,"textarea")||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&J.call(this,a)},beforeactivate:function(a){var b=a.target;f._data(b,"_change_data",I(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in H)f.event.add(this,c+".specialChange",H[c]);return y.test(this.nodeName)},teardown:function(a){f.event.remove(this,".specialChange");return y.test(this.nodeName)}},H=f.event.special.change.filters,H.focus=H.beforeactivate}f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){function e(a){var c=f.event.fix(a);c.type=b,c.originalEvent={},f.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var d=0;f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.each(["bind","one"],function(a,c){f.fn[c]=function(a,d,e){var g;if(typeof a=="object"){for(var h in a)this[c](h,d,a[h],e);return this}if(arguments.length===2||d===!1)e=d,d=b;c==="one"?(g=function(a){f(this).unbind(a,g);return e.apply(this,arguments)},g.guid=e.guid||f.guid++):g=e;if(a==="unload"&&c!=="one")this.one(a,d,e);else for(var i=0,j=this.length;i<j;i++)f.event.add(this[i],a,g,d);return this}}),f.fn.extend({unbind:function(a,b){if(typeof a=="object"&&!a.preventDefault)for(var c in a)this.unbind(c,a[c]);else for(var d=0,e=this.length;d<e;d++)f.event.remove(this[d],a,b);return this},delegate:function(a,b,c,d){return this.live(b,c,d,a)},undelegate:function(a,b,c){return arguments.length===0?this.unbind("live"):this.die(b,null,c,a)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f.data(this,"lastToggle"+a.guid)||0)%d;f.data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var L={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};f.each(["live","die"],function(a,c){f.fn[c]=function(a,d,e,g){var h,i=0,j,k,l,m=g||this.selector,n=g?this:f(this.context);if(typeof a=="object"&&!a.preventDefault){for(var o in a)n[c](o,d,a[o],m);return this}if(c==="die"&&!a&&g&&g.charAt(0)==="."){n.unbind(g);return this}if(d===!1||f.isFunction(d))e=d||D,d=b;a=(a||"").split(" ");while((h=a[i++])!=null){j=x.exec(h),k="",j&&(k=j[0],h=h.replace(x,""));if(h==="hover"){a.push("mouseenter"+k,"mouseleave"+k);continue}l=h,L[h]?(a.push(L[h]+k),h=h+k):h=(L[h]||h)+k;if(c==="live")for(var p=0,q=n.length;p<q;p++)f.event.add(n[p],"live."+N(h,m),{data:d,selector:m,handler:e,origType:h,origHandler:e,preType:l});else n.unbind("live."+N(h,m),e)}return this}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}if(i.nodeType===1){f||(i.sizcache=c,i.sizset=g);if(typeof b!="string"){if(i===b){j=!0;break}}else if(k.filter(b,[i]).length>0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}i.nodeType===1&&!f&&(i.sizcache=c,i.sizset=g);if(i.nodeName.toLowerCase()===b){j=i;break}i=i[a]}d[g]=j}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d=0,e=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,f,g){f=f||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return f;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(e.call(n)==="[object Array]")if(!u)f.push.apply(f,n);else if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&f.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&f.push(j[t]);else p(n,f);o&&(k(o,h,f,g),k.uniqueSort(f));return f};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},k.matches=function(a,b){return k(a,null,null,b)},k.matchesSelector=function(a,b){return k(b,null,null,[a]).length>0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e<f;e++){var g,h=l.order[e];if(g=l.leftMatch[h].exec(a)){var j=g[1];g.splice(1,1);if(j.substr(j.length-1)!=="\\"){g[1]=(g[1]||"").replace(i,""),d=l.find[h](g,b,c);if(d!=null){a=a.replace(l.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},k.filter=function(a,c,d,e){var f,g,h=a,i=[],j=c,m=c&&c[0]&&k.isXML(c[0]);while(a&&c.length){for(var n in l.filter)if((f=l.leftMatch[n].exec(a))!=null&&f[2]){var o,p,q=l.filter[n],r=f[1];g=!1,f.splice(1,1);if(r.substr(r.length-1)==="\\")continue;j===i&&(i=[]);if(l.preFilter[n]){f=l.preFilter[n](f,j,d,i,e,m);if(!f)g=o=!0;else if(f===!0)continue}if(f)for(var s=0;(p=j[s])!=null;s++)if(p){o=q(p,f,s,j);var t=e^!!o;d&&o!=null?t?g=!0:j[s]=!1:t&&(i.push(p),g=!0)}if(o!==b){d||(j=i),a=a.replace(l.match[n],"");if(!g)return[];break}}if(a===h)if(g==null)k.error(a);else break;h=a}return j},k.error=function(a){throw"Syntax error, unrecognized expression: "+a};var l=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!j.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&k.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&k.filter(b,a,!0)}},"":function(a,b,c){var e,f=d++,g=u;typeof b=="string"&&!j.test(b)&&(b=b.toLowerCase(),e=b,g=t),g("parentNode",b,f,a,e,c)},"~":function(a,b,c){var e,f=d++,g=u;typeof b=="string"&&!j.test(b)&&(b=b.toLowerCase(),e=b,g=t),g("previousSibling",b,f,a,e,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(i,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);a[0]=d++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){return a.nodeName.toLowerCase()==="input"&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}k.error(e)},CHILD:function(a,b){var c=b[1],d=a;switch(c){case"only":case"first":while(d=d.previousSibling)if(d.nodeType===1)return!1;if(c==="first")return!0;d=a;case"last":while(d=d.nextSibling)if(d.nodeType===1)return!1;return!0;case"nth":var e=b[2],f=b[3];if(e===1&&f===0)return!0;var g=b[0],h=a.parentNode;if(h&&(h.sizcache!==g||!a.nodeIndex)){var i=0;for(d=h.firstChild;d;d=d.nextSibling)d.nodeType===1&&(d.nodeIndex=++i);h.sizcache=g}var j=a.nodeIndex-f;return e===0?j===0:j%e===0&&j/e>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(e.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var f=a.length;c<f;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var r,s;c.documentElement.compareDocumentPosition?r=function(a,b){if(a===b){g=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(r=function(a,b){var c,d,e=[],f=[],h=a.parentNode,i=b.parentNode,j=h;if(a===b){g=!0;return 0}if(h===i)return s(a,b);if(!h)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return s(e[k],f[k]);return k===c?s(a,f[k],-1):s(e[k],b,1)},s=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),k.getText=function(a){var b="",c;for(var d=0;a[d];d++)c=a[d],c.nodeType===3||c.nodeType===4?b+=c.nodeValue:c.nodeType!==8&&(b+=k.getText(c.childNodes));return b},function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g<h;g++)k(a,f[g],d);return k.filter(e,d)};f.find=k,f.expr=k.selectors,f.expr[":"]=f.expr.filters,f.unique=k.uniqueSort,f.text=k.getText,f.isXMLDoc=k.isXML,f.contains=k.contains}();var O=/Until$/,P=/^(?:parents|prevUntil|prevAll)/,Q=/,/,R=/^.[^:#\[\.,]*$/,S=Array.prototype.slice,T=f.expr.match.POS,U={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(W(this,a,!1),"not",a)},filter:function(a){return this.pushStack(W(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(d=0,e=a.length;d<e;d++)i=a[d],j[i]||(j[i]=T.test(i)?f(i,b||this.context):i);while(g&&g.ownerDocument&&g!==b){for(i in j)h=j[i],(h.jquery?h.index(g)>-1:f(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=T.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(l?l.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a||typeof a=="string")return f.inArray(this[0],a?f(a):this.parent().children());return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(V(c[0])||V(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=S.call(arguments);O.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!U[a]?f.unique(e):e,(this.length>1||Q.test(d))&&P.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var X=/ jQuery\d+="(?:\d+|null)"/g,Y=/^\s+/,Z=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,$=/<([\w:]+)/,_=/<tbody/i,ba=/<|&#?\w+;/,bb=/<(?:script|object|embed|option|style)/i,bc=/checked\s*(?:[^=]|=\s*.checked.)/i,bd=/\/(java|ecma)script/i,be={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};be.optgroup=be.option,be.tbody=be.tfoot=be.colgroup=be.caption=be.thead,be.th=be.td,f.support.htmlSerialize||(be._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(X,""):null;if(typeof a=="string"&&!bb.test(a)&&(f.support.leadingWhitespace||!Y.test(a))&&!be[($.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Z,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bc.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bf(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bl)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i=b&&b[0]?b[0].ownerDocument||b[0]:c;a.length===1&&typeof a[0]=="string"&&a[0].length<512&&i===c&&a[0].charAt(0)==="<"&&!bb.test(a[0])&&(f.support.checkClone||!bc.test(a[0]))&&(g=!0,h=f.fragments[a[0]],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[a[0]]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bh(a,d),e=bi(a),g=bi(d);for(h=0;e[h];++h)bh(e[h],g[h])}if(b){bg(a,d);if(c){e=bi(a),g=bi(d);for(h=0;e[h];++h)bg(e[h],g[h])}}return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[];for(var i=0,j;(j=a[i])!=null;i++){typeof j=="number"&&(j+="");if(!j)continue;if(typeof j=="string")if(!ba.test(j))j=b.createTextNode(j);else{j=j.replace(Z,"<$1></$2>");var k=($.exec(j)||["",""])[1].toLowerCase(),l=be[k]||be._default,m=l[0],n=b.createElement("div");n.innerHTML=l[1]+j+l[2];while(m--)n=n.lastChild;if(!f.support.tbody){var o=_.test(j),p=k==="table"&&!o?n.firstChild&&n.firstChild.childNodes:l[1]==="<table>"&&!o?n.childNodes:[];for(var q=p.length-1;q>=0;--q)f.nodeName(p[q],"tbody")&&!p[q].childNodes.length&&p[q].parentNode.removeChild(p[q])}!f.support.leadingWhitespace&&Y.test(j)&&n.insertBefore(b.createTextNode(Y.exec(j)[0]),n.firstChild),j=n.childNodes}var r;if(!f.support.appendChecked)if(j[0]&&typeof (r=j.length)=="number")for(i=0;i<r;i++)bk(j[i]);else bk(j);j.nodeType?h.push(j):h=f.merge(h,j)}if(d){g=function(a){return!a.type||bd.test(a.type)};for(i=0;h[i];i++)if(e&&f.nodeName(h[i],"script")&&(!h[i].type||h[i].type.toLowerCase()==="text/javascript"))e.push(h[i].parentNode?h[i].parentNode.removeChild(h[i]):h[i]);else{if(h[i].nodeType===1){var s=f.grep(h[i].getElementsByTagName("script"),g);h.splice.apply(h,[i+1,0].concat(s))}d.appendChild(h[i])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.expando,g=f.event.special,h=f.support.deleteExpando;for(var i=0,j;(j=a[i])!=null;i++){if(j.nodeName&&f.noData[j.nodeName.toLowerCase()])continue;c=j[f.expando];if(c){b=d[c]&&d[c][e];if(b&&b.events){for(var k in b.events)g[k]?f.event.remove(j,k):f.removeEvent(j,k,b.handle);b.handle&&(b.handle.elem=null)}h?delete j[f.expando]:j.removeAttribute&&j.removeAttribute(f.expando),delete d[c]}}}});var bm=/alpha\([^)]*\)/i,bn=/opacity=([^)]*)/,bo=/-([a-z])/ig,bp=/([A-Z]|^ms)/g,bq=/^-?\d+(?:px)?$/i,br=/^-?\d/,bs=/^[+\-]=/,bt=/[^+\-\.\de]+/g,bu={position:"absolute",visibility:"hidden",display:"block"},bv=["Left","Right"],bw=["Top","Bottom"],bx,by,bz,bA=function(a,b){return b.toUpperCase()};f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bx(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{zIndex:!0,fontWeight:!0,opacity:!0,zoom:!0,lineHeight:!0,widows:!0,orphans:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d;if(h==="number"&&isNaN(d)||d==null)return;h==="string"&&bs.test(d)&&(d=+d.replace(bt,"")+parseFloat(f.css(a,c))),h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bx)return bx(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]},camelCase:function(a){return a.replace(bo,bA)}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){a.offsetWidth!==0?e=bB(a,b,d):f.swap(a,bu,function(){e=bB(a,b,d)});if(e<=0){e=bx(a,b,b),e==="0px"&&bz&&(e=bz(a,b,b));if(e!=null)return e===""||e==="auto"?"0px":e}if(e<0||e==null){e=a.style[b];return e===""||e==="auto"?"0px":e}return typeof e=="string"?e:e+"px"}},set:function(a,b){if(!bq.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bn.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle;c.zoom=1;var e=f.isNaN(b)?"":"alpha(opacity="+b*100+")",g=d&&d.filter||c.filter||"";c.filter=bm.test(g)?g.replace(bm,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bx(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(by=function(a,c){var d,e,g;c=c.replace(bp,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bz=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bq.test(d)&&br.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bx=by||bz,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bC=/%20/g,bD=/\[\]$/,bE=/\r?\n/g,bF=/#.*$/,bG=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bH=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bI=/^(?:about|app|app\-storage|.+\-extension|file|widget):$/,bJ=/^(?:GET|HEAD)$/,bK=/^\/\//,bL=/\?/,bM=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bN=/^(?:select|textarea)/i,bO=/\s+/,bP=/([?&])_=[^&]*/,bQ=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bR=f.fn.load,bS={},bT={},bU,bV;try{bU=e.href}catch(bW){bU=c.createElement("a"),bU.href="",bU=bU.href}bV=bQ.exec(bU.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bR)return bR.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bM,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bN.test(this.nodeName)||bH.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bE,"\r\n")}}):{name:b.name,value:c.replace(bE,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?f.extend(!0,a,f.ajaxSettings,b):(b=a,a=f.extend(!0,f.ajaxSettings,b));for(var c in{context:1,url:1})c in b?a[c]=b[c]:c in f.ajaxSettings&&(a[c]=f.ajaxSettings[c]);return a},ajaxSettings:{url:bU,isLocal:bI.test(bV[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":"*/*"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML}},ajaxPrefilter:bX(bS),ajaxTransport:bX(bT),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a?4:0;var o,r,u,w=l?b$(d,v,l):b,x,y;if(a>=200&&a<300||a===304){if(d.ifModified){if(x=v.getResponseHeader("Last-Modified"))f.lastModified[k]=x;if(y=v.getResponseHeader("Etag"))f.etag[k]=y}if(a===304)c="notmodified",o=!0;else try{r=b_(d,w),c="success",o=!0}catch(z){c="parsererror",u=z}}else{u=c;if(!c||a)c="error",a<0&&(a=0)}v.status=a,v.statusText=c,o?h.resolveWith(e,[r,c,v]):h.rejectWith(e,[v,c,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.resolveWith(e,[v,c]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f._Deferred(),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.done,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bF,"").replace(bK,bV[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bO),d.crossDomain==null&&(r=bQ.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bV[1]&&r[2]==bV[2]&&(r[3]||(r[1]==="http:"?80:443))==(bV[3]||(bV[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bY(bS,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bJ.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bL.test(d.url)?"&":"?")+d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bP,"$1_="+x);d.url=y+(y===d.url?(bL.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", */*; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bY(bT,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){status<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)bZ(g,a[g],c,e);return d.join("&").replace(bC,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var ca=f.now(),cb=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+ca++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cb.test(b.url)||e&&cb.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cb,l),b.url===j&&(e&&(k=k.replace(cb,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cc=a.ActiveXObject?function(){for(var a in ce)ce[a](0,1)}:!1,cd=0,ce;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&cf()||cg()}:cf,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cc&&delete ce[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cd,cc&&(ce||(ce={},f(a).unload(cc)),ce[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ch={},ci,cj,ck=/^(?:toggle|show|hide)$/,cl=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cm,cn=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],co,cp=a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cs("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",ct(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cs("hide",3),a,b,c);for(var d=0,e=this.length;d<e;d++)if(this[d].style){var g=f.css(this[d],"display");g!=="none"&&!f._data(this[d],"olddisplay")&&f._data(this[d],"olddisplay",g)}for(d=0;d<e;d++)this[d].style&&(this[d].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cs("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);return this[e.queue===!1?"each":"queue"](function(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g];if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(f.support.inlineBlockNeedsLayout?(j=ct(this.nodeName),j==="inline"?this.style.display="inline-block":(this.style.display="inline",this.style.zoom=1)):this.style.display="inline-block")),b.animatedProperties[g]=f.isArray(h)?h[1]:b.specialEasing&&b.specialEasing[g]||b.easing||"swing"}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)k=new f.fx(this,b,i),h=a[i],ck.test(h)?k[h==="toggle"?d?"show":"hide":h]():(l=cl.exec(h),m=k.cur(),l?(n=parseFloat(l[2]),o=l[3]||(f.cssNumber[g]?"":"px"),o!=="px"&&(f.style(this,i,(n||1)+o),m=(n||1)/k.cur()*m,f.style(this,i,m+o)),l[1]&&(n=(l[1]==="-="?-1:1)*n+m),k.custom(m,n,o)):k.custom(m,h,""));return!0})},stop:function(a,b){a&&this.queue([]),this.each(function(){var a=f.timers,c=a.length;b||f._unmark(!0,this);while(c--)a[c].elem===this&&(b&&a[c](!0),a.splice(c,1))}),b||this.dequeue();return this}}),f.each({slideDown:cs("show",1),slideUp:cs("hide",1),slideToggle:cs("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default,d.old=d.complete,d.complete=function(a){d.queue!==!1?f.dequeue(this):a!==!1&&f._unmark(this),f.isFunction(d.old)&&d.old.call(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,b,c){function h(a){return d.step(a)}var d=this,e=f.fx,g;this.startTime=co||cq(),this.start=a,this.end=b,this.unit=c||this.unit||(f.cssNumber[this.prop]?"":"px"),this.now=this.start,this.pos=this.state=0,h.elem=this.elem,h()&&f.timers.push(h)&&!cm&&(cp?(cm=1,g=function(){cm&&(cp(g),e.tick())},cp(g)):cm=setInterval(e.tick,e.interval))},show:function(){this.options.orig[this.prop]=f.style(this.elem,this.prop),this.options.show=!0,this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b=co||cq(),c=!0,d=this.elem,e=this.options,g,h;if(a||b>=e.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),e.animatedProperties[this.prop]=!0;for(g in e.animatedProperties)e.animatedProperties[g]!==!0&&(c=!1);if(c){e.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){d.style["overflow"+b]=e.overflow[a]}),e.hide&&f(d).hide();if(e.hide||e.show)for(var i in e.animatedProperties)f.style(d,i,e.orig[i]);e.complete.call(d)}return!1}e.duration==Infinity?this.now=b:(h=b-this.startTime,this.state=h/e.duration,this.pos=f.easing[e.animatedProperties[this.prop]](this.state,h,0,1,e.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a=f.timers,b=a.length;while(b--)a[b]()||a.splice(b,1);a.length||f.fx.stop()},interval:13,stop:function(){clearInterval(cm),cm=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit:a.elem[a.prop]=a.now}}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cu=/^t(?:able|d|h)$/i,cv=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cw(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);f.offset.initialize();var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.offset.supportsFixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.offset.doesNotAddBorder&&(!f.offset.doesAddBorderForTableAndCells||!cu.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.offset.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.offset.supportsFixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={initialize:function(){var a=c.body,b=c.createElement("div"),d,e,g,h,i=parseFloat(f.css(a,"marginTop"))||0,j="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";f.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),d=b.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,this.doesNotAddBorder=e.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,e.style.position="fixed",e.style.top="20px",this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),f.offset.initialize=f.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.offset.initialize(),f.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cv.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cv.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cw(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cw(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){return this[0]?parseFloat(f.css(this[0],d,"padding")):null},f.fn["outer"+c]=function(a){return this[0]?parseFloat(f.css(this[0],d,a?"margin":"border")):null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c];return e.document.compatMode==="CSS1Compat"&&g||e.document.body["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var h=f.css(e,d),i=parseFloat(h);return f.isNaN(i)?h:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window);
\ No newline at end of file
+++ /dev/null
-/*
- * Raphael 1.5.2 - JavaScript Vector Library
- *
- * Copyright (c) 2010 Dmitry Baranovskiy (http://raphaeljs.com)
- * Licensed under the MIT (http://raphaeljs.com/license.html) license.
- */
-(function(){function a(){if(a.is(arguments[0],G)){var b=arguments[0],d=bV[m](a,b.splice(0,3+a.is(b[0],E))),e=d.set();for(var g=0,h=b[w];g<h;g++){var i=b[g]||{};c[f](i.type)&&e[L](d[i.type]().attr(i))}return e}return bV[m](a,arguments)}a.version="1.5.2";var b=/[, ]+/,c={circle:1,rect:1,path:1,ellipse:1,text:1,image:1},d=/\{(\d+)\}/g,e="prototype",f="hasOwnProperty",g=document,h=window,i={was:Object[e][f].call(h,"Raphael"),is:h.Raphael},j=function(){this.customAttributes={}},k,l="appendChild",m="apply",n="concat",o="createTouch"in g,p="",q=" ",r=String,s="split",t="click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend orientationchange touchcancel gesturestart gesturechange gestureend"[s](q),u={mousedown:"touchstart",mousemove:"touchmove",mouseup:"touchend"},v="join",w="length",x=r[e].toLowerCase,y=Math,z=y.max,A=y.min,B=y.abs,C=y.pow,D=y.PI,E="number",F="string",G="array",H="toString",I="fill",J=Object[e][H],K={},L="push",M=/^url\(['"]?([^\)]+?)['"]?\)$/i,N=/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\))\s*$/i,O={"NaN":1,Infinity:1,"-Infinity":1},P=/^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,Q=y.round,R="setAttribute",S=parseFloat,T=parseInt,U=" progid:DXImageTransform.Microsoft",V=r[e].toUpperCase,W={blur:0,"clip-rect":"0 0 1e9 1e9",cursor:"default",cx:0,cy:0,fill:"#fff","fill-opacity":1,font:"10px \"Arial\"","font-family":"\"Arial\"","font-size":"10","font-style":"normal","font-weight":400,gradient:0,height:0,href:"http://raphaeljs.com/",opacity:1,path:"M0,0",r:0,rotation:0,rx:0,ry:0,scale:"1 1",src:"",stroke:"#000","stroke-dasharray":"","stroke-linecap":"butt","stroke-linejoin":"butt","stroke-miterlimit":0,"stroke-opacity":1,"stroke-width":1,target:"_blank","text-anchor":"middle",title:"Raphael",translation:"0 0",width:0,x:0,y:0},X={along:"along",blur:E,"clip-rect":"csv",cx:E,cy:E,fill:"colour","fill-opacity":E,"font-size":E,height:E,opacity:E,path:"path",r:E,rotation:"csv",rx:E,ry:E,scale:"csv",stroke:"colour","stroke-opacity":E,"stroke-width":E,translation:"csv",width:E,x:E,y:E},Y="replace",Z=/^(from|to|\d+%?)$/,$=/\s*,\s*/,_={hs:1,rg:1},ba=/,?([achlmqrstvxz]),?/gi,bb=/([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig,bc=/(-?\d*\.?\d*(?:e[-+]?\d+)?)\s*,?\s*/ig,bd=/^r(?:\(([^,]+?)\s*,\s*([^\)]+?)\))?/,be=function(a,b){return a.key-b.key};a.type=h.SVGAngle||g.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")?"SVG":"VML";if(a.type=="VML"){var bf=g.createElement("div"),bg;bf.innerHTML="<v:shape adj=\"1\"/>";bg=bf.firstChild;bg.style.behavior="url(#default#VML)";if(!(bg&&typeof bg.adj=="object"))return a.type=null;bf=null}a.svg=!(a.vml=a.type=="VML");j[e]=a[e];k=j[e];a._id=0;a._oid=0;a.fn={};a.is=function(a,b){b=x.call(b);if(b=="finite")return!O[f](+a);return b=="null"&&a===null||b==typeof a||b=="object"&&a===Object(a)||b=="array"&&Array.isArray&&Array.isArray(a)||J.call(a).slice(8,-1).toLowerCase()==b};a.angle=function(b,c,d,e,f,g){{if(f==null){var h=b-d,i=c-e;if(!h&&!i)return 0;return((h<0)*180+y.atan(-i/-h)*180/D+360)%360}return a.angle(b,c,f,g)-a.angle(d,e,f,g)}};a.rad=function(a){return a%360*D/180};a.deg=function(a){return a*180/D%360};a.snapTo=function(b,c,d){d=a.is(d,"finite")?d:10;if(a.is(b,G)){var e=b.length;while(e--)if(B(b[e]-c)<=d)return b[e]}else{b=+b;var f=c%b;if(f<d)return c-f;if(f>b-d)return c-f+b}return c};function bh(){var a=[],b=0;for(;b<32;b++)a[b]=(~(~(y.random()*16)))[H](16);a[12]=4;a[16]=(a[16]&3|8)[H](16);return"r-"+a[v]("")}a.setWindow=function(a){h=a;g=h.document};var bi=function(b){if(a.vml){var c=/^\s+|\s+$/g,d;try{var e=new ActiveXObject("htmlfile");e.write("<body>");e.close();d=e.body}catch(a){d=createPopup().document.body}var f=d.createTextRange();bi=bm(function(a){try{d.style.color=r(a)[Y](c,p);var b=f.queryCommandValue("ForeColor");b=(b&255)<<16|b&65280|(b&16711680)>>>16;return"#"+("000000"+b[H](16)).slice(-6)}catch(a){return"none"}})}else{var h=g.createElement("i");h.title="Raphaël Colour Picker";h.style.display="none";g.body[l](h);bi=bm(function(a){h.style.color=a;return g.defaultView.getComputedStyle(h,p).getPropertyValue("color")})}return bi(b)},bj=function(){return"hsb("+[this.h,this.s,this.b]+")"},bk=function(){return"hsl("+[this.h,this.s,this.l]+")"},bl=function(){return this.hex};a.hsb2rgb=function(b,c,d,e){if(a.is(b,"object")&&"h"in b&&"s"in b&&"b"in b){d=b.b;c=b.s;b=b.h;e=b.o}return a.hsl2rgb(b,c,d/2,e)};a.hsl2rgb=function(b,c,d,e){if(a.is(b,"object")&&"h"in b&&"s"in b&&"l"in b){d=b.l;c=b.s;b=b.h}if(b>1||c>1||d>1){b/=360;c/=100;d/=100}var f={},g=["r","g","b"],h,i,j,k,l,m;if(c){d<0.5?h=d*(1+c):h=d+c-d*c;i=2*d-h;for(var n=0;n<3;n++){j=b+1/3*-(n-1);j<0&&j++;j>1&&j--;j*6<1?f[g[n]]=i+(h-i)*6*j:j*2<1?f[g[n]]=h:j*3<2?f[g[n]]=i+(h-i)*(2/3-j)*6:f[g[n]]=i}}else f={r:d,g:d,b:d};f.r*=255;f.g*=255;f.b*=255;f.hex="#"+(16777216|f.b|f.g<<8|f.r<<16).toString(16).slice(1);a.is(e,"finite")&&(f.opacity=e);f.toString=bl;return f};a.rgb2hsb=function(b,c,d){if(c==null&&a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b){d=b.b;c=b.g;b=b.r}if(c==null&&a.is(b,F)){var e=a.getRGB(b);b=e.r;c=e.g;d=e.b}if(b>1||c>1||d>1){b/=255;c/=255;d/=255}var f=z(b,c,d),g=A(b,c,d),h,i,j=f;{if(g==f)return{h:0,s:0,b:f,toString:bj};var k=f-g;i=k/f;b==f?h=(c-d)/k:c==f?h=2+(d-b)/k:h=4+(b-c)/k;h/=6;h<0&&h++;h>1&&h--}return{h:h,s:i,b:j,toString:bj}};a.rgb2hsl=function(b,c,d){if(c==null&&a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b){d=b.b;c=b.g;b=b.r}if(c==null&&a.is(b,F)){var e=a.getRGB(b);b=e.r;c=e.g;d=e.b}if(b>1||c>1||d>1){b/=255;c/=255;d/=255}var f=z(b,c,d),g=A(b,c,d),h,i,j=(f+g)/2,k;if(g==f)k={h:0,s:0,l:j};else{var l=f-g;i=j<0.5?l/(f+g):l/(2-f-g);b==f?h=(c-d)/l:c==f?h=2+(d-b)/l:h=4+(b-c)/l;h/=6;h<0&&h++;h>1&&h--;k={h:h,s:i,l:j}}k.toString=bk;return k};a._path2string=function(){return this.join(",")[Y](ba,"$1")};function bm(a,b,c){function d(){var g=Array[e].slice.call(arguments,0),h=g[v]("►"),i=d.cache=d.cache||{},j=d.count=d.count||[];if(i[f](h))return c?c(i[h]):i[h];j[w]>=1000&&delete i[j.shift()];j[L](h);i[h]=a[m](b,g);return c?c(i[h]):i[h]}return d}a.getRGB=bm(function(b){if(!b||!(!((b=r(b)).indexOf("-")+1)))return{r:-1,g:-1,b:-1,hex:"none",error:1};if(b=="none")return{r:-1,g:-1,b:-1,hex:"none"};!(_[f](b.toLowerCase().substring(0,2))||b.charAt()=="#")&&(b=bi(b));var c,d,e,g,h,i,j,k=b.match(N);if(k){if(k[2]){g=T(k[2].substring(5),16);e=T(k[2].substring(3,5),16);d=T(k[2].substring(1,3),16)}if(k[3]){g=T((i=k[3].charAt(3))+i,16);e=T((i=k[3].charAt(2))+i,16);d=T((i=k[3].charAt(1))+i,16)}if(k[4]){j=k[4][s]($);d=S(j[0]);j[0].slice(-1)=="%"&&(d*=2.55);e=S(j[1]);j[1].slice(-1)=="%"&&(e*=2.55);g=S(j[2]);j[2].slice(-1)=="%"&&(g*=2.55);k[1].toLowerCase().slice(0,4)=="rgba"&&(h=S(j[3]));j[3]&&j[3].slice(-1)=="%"&&(h/=100)}if(k[5]){j=k[5][s]($);d=S(j[0]);j[0].slice(-1)=="%"&&(d*=2.55);e=S(j[1]);j[1].slice(-1)=="%"&&(e*=2.55);g=S(j[2]);j[2].slice(-1)=="%"&&(g*=2.55);(j[0].slice(-3)=="deg"||j[0].slice(-1)=="°")&&(d/=360);k[1].toLowerCase().slice(0,4)=="hsba"&&(h=S(j[3]));j[3]&&j[3].slice(-1)=="%"&&(h/=100);return a.hsb2rgb(d,e,g,h)}if(k[6]){j=k[6][s]($);d=S(j[0]);j[0].slice(-1)=="%"&&(d*=2.55);e=S(j[1]);j[1].slice(-1)=="%"&&(e*=2.55);g=S(j[2]);j[2].slice(-1)=="%"&&(g*=2.55);(j[0].slice(-3)=="deg"||j[0].slice(-1)=="°")&&(d/=360);k[1].toLowerCase().slice(0,4)=="hsla"&&(h=S(j[3]));j[3]&&j[3].slice(-1)=="%"&&(h/=100);return a.hsl2rgb(d,e,g,h)}k={r:d,g:e,b:g};k.hex="#"+(16777216|g|e<<8|d<<16).toString(16).slice(1);a.is(h,"finite")&&(k.opacity=h);return k}return{r:-1,g:-1,b:-1,hex:"none",error:1}},a);a.getColor=function(a){var b=this.getColor.start=this.getColor.start||{h:0,s:1,b:a||0.75},c=this.hsb2rgb(b.h,b.s,b.b);b.h+=0.075;if(b.h>1){b.h=0;b.s-=0.2;b.s<=0&&(this.getColor.start={h:0,s:1,b:b.b})}return c.hex};a.getColor.reset=function(){delete this.start};a.parsePathString=bm(function(b){if(!b)return null;var c={a:7,c:6,h:1,l:2,m:2,q:4,s:4,t:2,v:1,z:0},d=[];a.is(b,G)&&a.is(b[0],G)&&(d=bo(b));d[w]||r(b)[Y](bb,function(a,b,e){var f=[],g=x.call(b);e[Y](bc,function(a,b){b&&f[L](+b)});if(g=="m"&&f[w]>2){d[L]([b][n](f.splice(0,2)));g="l";b=b=="m"?"l":"L"}while(f[w]>=c[g]){d[L]([b][n](f.splice(0,c[g])));if(!c[g])break}});d[H]=a._path2string;return d});a.findDotsAtSegment=function(a,b,c,d,e,f,g,h,i){var j=1-i,k=C(j,3)*a+C(j,2)*3*i*c+j*3*i*i*e+C(i,3)*g,l=C(j,3)*b+C(j,2)*3*i*d+j*3*i*i*f+C(i,3)*h,m=a+2*i*(c-a)+i*i*(e-2*c+a),n=b+2*i*(d-b)+i*i*(f-2*d+b),o=c+2*i*(e-c)+i*i*(g-2*e+c),p=d+2*i*(f-d)+i*i*(h-2*f+d),q=(1-i)*a+i*c,r=(1-i)*b+i*d,s=(1-i)*e+i*g,t=(1-i)*f+i*h,u=90-y.atan((m-o)/(n-p))*180/D;(m>o||n<p)&&(u+=180);return{x:k,y:l,m:{x:m,y:n},n:{x:o,y:p},start:{x:q,y:r},end:{x:s,y:t},alpha:u}};var bn=bm(function(a){if(!a)return{x:0,y:0,width:0,height:0};a=bw(a);var b=0,c=0,d=[],e=[],f;for(var g=0,h=a[w];g<h;g++){f=a[g];if(f[0]=="M"){b=f[1];c=f[2];d[L](b);e[L](c)}else{var i=bv(b,c,f[1],f[2],f[3],f[4],f[5],f[6]);d=d[n](i.min.x,i.max.x);e=e[n](i.min.y,i.max.y);b=f[5];c=f[6]}}var j=A[m](0,d),k=A[m](0,e);return{x:j,y:k,width:z[m](0,d)-j,height:z[m](0,e)-k}}),bo=function(b){var c=[];if(!a.is(b,G)||!a.is(b&&b[0],G))b=a.parsePathString(b);for(var d=0,e=b[w];d<e;d++){c[d]=[];for(var f=0,g=b[d][w];f<g;f++)c[d][f]=b[d][f]}c[H]=a._path2string;return c},bp=bm(function(b){if(!a.is(b,G)||!a.is(b&&b[0],G))b=a.parsePathString(b);var c=[],d=0,e=0,f=0,g=0,h=0;if(b[0][0]=="M"){d=b[0][1];e=b[0][2];f=d;g=e;h++;c[L](["M",d,e])}for(var i=h,j=b[w];i<j;i++){var k=c[i]=[],l=b[i];if(l[0]!=x.call(l[0])){k[0]=x.call(l[0]);switch(k[0]){case"a":k[1]=l[1];k[2]=l[2];k[3]=l[3];k[4]=l[4];k[5]=l[5];k[6]=+(l[6]-d).toFixed(3);k[7]=+(l[7]-e).toFixed(3);break;case"v":k[1]=+(l[1]-e).toFixed(3);break;case"m":f=l[1];g=l[2];default:for(var m=1,n=l[w];m<n;m++)k[m]=+(l[m]-(m%2?d:e)).toFixed(3)}}else{k=c[i]=[];if(l[0]=="m"){f=l[1]+d;g=l[2]+e}for(var o=0,p=l[w];o<p;o++)c[i][o]=l[o]}var q=c[i][w];switch(c[i][0]){case"z":d=f;e=g;break;case"h":d+=+c[i][q-1];break;case"v":e+=+c[i][q-1];break;default:d+=+c[i][q-2];e+=+c[i][q-1]}}c[H]=a._path2string;return c},0,bo),bq=bm(function(b){if(!a.is(b,G)||!a.is(b&&b[0],G))b=a.parsePathString(b);var c=[],d=0,e=0,f=0,g=0,h=0;if(b[0][0]=="M"){d=+b[0][1];e=+b[0][2];f=d;g=e;h++;c[0]=["M",d,e]}for(var i=h,j=b[w];i<j;i++){var k=c[i]=[],l=b[i];if(l[0]!=V.call(l[0])){k[0]=V.call(l[0]);switch(k[0]){case"A":k[1]=l[1];k[2]=l[2];k[3]=l[3];k[4]=l[4];k[5]=l[5];k[6]=+(l[6]+d);k[7]=+(l[7]+e);break;case"V":k[1]=+l[1]+e;break;case"H":k[1]=+l[1]+d;break;case"M":f=+l[1]+d;g=+l[2]+e;default:for(var m=1,n=l[w];m<n;m++)k[m]=+l[m]+(m%2?d:e)}}else for(var o=0,p=l[w];o<p;o++)c[i][o]=l[o];switch(k[0]){case"Z":d=f;e=g;break;case"H":d=k[1];break;case"V":e=k[1];break;case"M":f=c[i][c[i][w]-2];g=c[i][c[i][w]-1];default:d=c[i][c[i][w]-2];e=c[i][c[i][w]-1]}}c[H]=a._path2string;return c},null,bo),br=function(a,b,c,d){return[a,b,c,d,c,d]},bs=function(a,b,c,d,e,f){var g=1/3,h=2/3;return[g*a+h*c,g*b+h*d,g*e+h*c,g*f+h*d,e,f]},bt=function(a,b,c,d,e,f,g,h,i,j){var k=D*120/180,l=D/180*(+e||0),m=[],o,p=bm(function(a,b,c){var d=a*y.cos(c)-b*y.sin(c),e=a*y.sin(c)+b*y.cos(c);return{x:d,y:e}});if(j){G=j[0];H=j[1];E=j[2];F=j[3]}else{o=p(a,b,-l);a=o.x;b=o.y;o=p(h,i,-l);h=o.x;i=o.y;var q=y.cos(D/180*e),r=y.sin(D/180*e),t=(a-h)/2,u=(b-i)/2,x=t*t/(c*c)+u*u/(d*d);if(x>1){x=y.sqrt(x);c=x*c;d=x*d}var z=c*c,A=d*d,C=(f==g?-1:1)*y.sqrt(B((z*A-z*u*u-A*t*t)/(z*u*u+A*t*t))),E=C*c*u/d+(a+h)/2,F=C*-d*t/c+(b+i)/2,G=y.asin(((b-F)/d).toFixed(9)),H=y.asin(((i-F)/d).toFixed(9));G=a<E?D-G:G;H=h<E?D-H:H;G<0&&(G=D*2+G);H<0&&(H=D*2+H);g&&G>H&&(G=G-D*2);!g&&H>G&&(H=H-D*2)}var I=H-G;if(B(I)>k){var J=H,K=h,L=i;H=G+k*(g&&H>G?1:-1);h=E+c*y.cos(H);i=F+d*y.sin(H);m=bt(h,i,c,d,e,0,g,K,L,[H,J,E,F])}I=H-G;var M=y.cos(G),N=y.sin(G),O=y.cos(H),P=y.sin(H),Q=y.tan(I/4),R=4/3*c*Q,S=4/3*d*Q,T=[a,b],U=[a+R*N,b-S*M],V=[h+R*P,i-S*O],W=[h,i];U[0]=2*T[0]-U[0];U[1]=2*T[1]-U[1];{if(j)return[U,V,W][n](m);m=[U,V,W][n](m)[v]()[s](",");var X=[];for(var Y=0,Z=m[w];Y<Z;Y++)X[Y]=Y%2?p(m[Y-1],m[Y],l).y:p(m[Y],m[Y+1],l).x;return X}},bu=function(a,b,c,d,e,f,g,h,i){var j=1-i;return{x:C(j,3)*a+C(j,2)*3*i*c+j*3*i*i*e+C(i,3)*g,y:C(j,3)*b+C(j,2)*3*i*d+j*3*i*i*f+C(i,3)*h}},bv=bm(function(a,b,c,d,e,f,g,h){var i=e-2*c+a-(g-2*e+c),j=2*(c-a)-2*(e-c),k=a-c,l=(-j+y.sqrt(j*j-4*i*k))/2/i,n=(-j-y.sqrt(j*j-4*i*k))/2/i,o=[b,h],p=[a,g],q;B(l)>"1e12"&&(l=0.5);B(n)>"1e12"&&(n=0.5);if(l>0&&l<1){q=bu(a,b,c,d,e,f,g,h,l);p[L](q.x);o[L](q.y)}if(n>0&&n<1){q=bu(a,b,c,d,e,f,g,h,n);p[L](q.x);o[L](q.y)}i=f-2*d+b-(h-2*f+d);j=2*(d-b)-2*(f-d);k=b-d;l=(-j+y.sqrt(j*j-4*i*k))/2/i;n=(-j-y.sqrt(j*j-4*i*k))/2/i;B(l)>"1e12"&&(l=0.5);B(n)>"1e12"&&(n=0.5);if(l>0&&l<1){q=bu(a,b,c,d,e,f,g,h,l);p[L](q.x);o[L](q.y)}if(n>0&&n<1){q=bu(a,b,c,d,e,f,g,h,n);p[L](q.x);o[L](q.y)}return{min:{x:A[m](0,p),y:A[m](0,o)},max:{x:z[m](0,p),y:z[m](0,o)}}}),bw=bm(function(a,b){var c=bq(a),d=b&&bq(b),e={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},f={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},g=function(a,b){var c,d;if(!a)return["C",b.x,b.y,b.x,b.y,b.x,b.y];!(a[0]in{T:1,Q:1})&&(b.qx=b.qy=null);switch(a[0]){case"M":b.X=a[1];b.Y=a[2];break;case"A":a=["C"][n](bt[m](0,[b.x,b.y][n](a.slice(1))));break;case"S":c=b.x+(b.x-(b.bx||b.x));d=b.y+(b.y-(b.by||b.y));a=["C",c,d][n](a.slice(1));break;case"T":b.qx=b.x+(b.x-(b.qx||b.x));b.qy=b.y+(b.y-(b.qy||b.y));a=["C"][n](bs(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1];b.qy=a[2];a=["C"][n](bs(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"][n](br(b.x,b.y,a[1],a[2]));break;case"H":a=["C"][n](br(b.x,b.y,a[1],b.y));break;case"V":a=["C"][n](br(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"][n](br(b.x,b.y,b.X,b.Y));break}return a},h=function(a,b){if(a[b][w]>7){a[b].shift();var e=a[b];while(e[w])a.splice(b++,0,["C"][n](e.splice(0,6)));a.splice(b,1);k=z(c[w],d&&d[w]||0)}},i=function(a,b,e,f,g){if(a&&b&&a[g][0]=="M"&&b[g][0]!="M"){b.splice(g,0,["M",f.x,f.y]);e.bx=0;e.by=0;e.x=a[g][1];e.y=a[g][2];k=z(c[w],d&&d[w]||0)}};for(var j=0,k=z(c[w],d&&d[w]||0);j<k;j++){c[j]=g(c[j],e);h(c,j);d&&(d[j]=g(d[j],f));d&&h(d,j);i(c,d,e,f,j);i(d,c,f,e,j);var l=c[j],o=d&&d[j],p=l[w],q=d&&o[w];e.x=l[p-2];e.y=l[p-1];e.bx=S(l[p-4])||e.x;e.by=S(l[p-3])||e.y;f.bx=d&&(S(o[q-4])||f.x);f.by=d&&(S(o[q-3])||f.y);f.x=d&&o[q-2];f.y=d&&o[q-1]}return d?[c,d]:c},null,bo),bx=bm(function(b){var c=[];for(var d=0,e=b[w];d<e;d++){var f={},g=b[d].match(/^([^:]*):?([\d\.]*)/);f.color=a.getRGB(g[1]);if(f.color.error)return null;f.color=f.color.hex;g[2]&&(f.offset=g[2]+"%");c[L](f)}for(d=1,e=c[w]-1;d<e;d++){if(!c[d].offset){var h=S(c[d-1].offset||0),i=0;for(var j=d+1;j<e;j++){if(c[j].offset){i=c[j].offset;break}}if(!i){i=100;j=e}i=S(i);var k=(i-h)/(j-d+1);for(;d<j;d++){h+=k;c[d].offset=h+"%"}}}return c}),by=function(b,c,d,e){var f;if(a.is(b,F)||a.is(b,"object")){f=a.is(b,F)?g.getElementById(b):b;if(f.tagName)return c==null?{container:f,width:f.style.pixelWidth||f.offsetWidth,height:f.style.pixelHeight||f.offsetHeight}:{container:f,width:c,height:d}}else return{container:1,x:b,y:c,width:d,height:e}},bz=function(a,b){var c=this;for(var d in b){if(b[f](d)&&!(d in a))switch(typeof b[d]){case"function":(function(b){a[d]=a===c?b:function(){return b[m](c,arguments)}})(b[d]);break;case"object":a[d]=a[d]||{};bz.call(this,a[d],b[d]);break;default:a[d]=b[d];break}}},bA=function(a,b){a==b.top&&(b.top=a.prev);a==b.bottom&&(b.bottom=a.next);a.next&&(a.next.prev=a.prev);a.prev&&(a.prev.next=a.next)},bB=function(a,b){if(b.top===a)return;bA(a,b);a.next=null;a.prev=b.top;b.top.next=a;b.top=a},bC=function(a,b){if(b.bottom===a)return;bA(a,b);a.next=b.bottom;a.prev=null;b.bottom.prev=a;b.bottom=a},bD=function(a,b,c){bA(a,c);b==c.top&&(c.top=a);b.next&&(b.next.prev=a);a.next=b.next;a.prev=b;b.next=a},bE=function(a,b,c){bA(a,c);b==c.bottom&&(c.bottom=a);b.prev&&(b.prev.next=a);a.prev=b.prev;b.prev=a;a.next=b},bF=function(a){return function(){throw new Error("Raphaël: you are calling to method “"+a+"” of removed object")}};a.pathToRelative=bp;if(a.svg){k.svgns="http://www.w3.org/2000/svg";k.xlink="http://www.w3.org/1999/xlink";Q=function(a){return+a+(~(~a)===a)*0.5};var bG=function(a,b){if(b)for(var c in b)b[f](c)&&a[R](c,r(b[c]));else{a=g.createElementNS(k.svgns,a);a.style.webkitTapHighlightColor="rgba(0,0,0,0)";return a}};a[H]=function(){return"Your browser supports SVG.\nYou are running Raphaël "+this.version};var bH=function(a,b){var c=bG("path");b.canvas&&b.canvas[l](c);var d=new bN(c,b);d.type="path";bK(d,{fill:"none",stroke:"#000",path:a});return d},bI=function(a,b,c){var d="linear",e=0.5,f=0.5,h=a.style;b=r(b)[Y](bd,function(a,b,c){d="radial";if(b&&c){e=S(b);f=S(c);var g=(f>0.5)*2-1;C(e-0.5,2)+C(f-0.5,2)>0.25&&(f=y.sqrt(0.25-C(e-0.5,2))*g+0.5)&&f!=0.5&&(f=f.toFixed(5)-0.00001*g)}return p});b=b[s](/\s*\-\s*/);if(d=="linear"){var i=b.shift();i=-S(i);if(isNaN(i))return null;var j=[0,0,y.cos(i*D/180),y.sin(i*D/180)],k=1/(z(B(j[2]),B(j[3]))||1);j[2]*=k;j[3]*=k;if(j[2]<0){j[0]=-j[2];j[2]=0}if(j[3]<0){j[1]=-j[3];j[3]=0}}var m=bx(b);if(!m)return null;var n=a.getAttribute(I);n=n.match(/^url\(#(.*)\)$/);n&&c.defs.removeChild(g.getElementById(n[1]));var o=bG(d+"Gradient");o.id=bh();bG(o,d=="radial"?{fx:e,fy:f}:{x1:j[0],y1:j[1],x2:j[2],y2:j[3]});c.defs[l](o);for(var q=0,t=m[w];q<t;q++){var u=bG("stop");bG(u,{offset:m[q].offset?m[q].offset:q?"100%":"0%","stop-color":m[q].color||"#fff"});o[l](u)}bG(a,{fill:"url(#"+o.id+")",opacity:1,"fill-opacity":1});h.fill=p;h.opacity=1;h.fillOpacity=1;return 1},bJ=function(b){var c=b.getBBox();bG(b.pattern,{patternTransform:a.format("translate({0},{1})",c.x,c.y)})},bK=function(c,d){var e={"":[0],none:[0],"-":[3,1],".":[1,1],"-.":[3,1,1,1],"-..":[3,1,1,1,1,1],". ":[1,3],"- ":[4,3],"--":[8,3],"- .":[4,3,1,3],"--.":[8,3,1,3],"--..":[8,3,1,3,1,3]},h=c.node,i=c.attrs,j=c.rotate(),k=function(a,b){b=e[x.call(b)];if(b){var c=a.attrs["stroke-width"]||"1",f=({round:c,square:c,butt:0})[a.attrs["stroke-linecap"]||d["stroke-linecap"]]||0,g=[],i=b[w];while(i--)g[i]=b[i]*c+(i%2?1:-1)*f;bG(h,{"stroke-dasharray":g[v](",")})}};d[f]("rotation")&&(j=d.rotation);var m=r(j)[s](b);if(m.length-1){m[1]=+m[1];m[2]=+m[2]}else m=null;S(j)&&c.rotate(0,true);for(var n in d){if(d[f](n)){if(!W[f](n))continue;var o=d[n];i[n]=o;switch(n){case"blur":c.blur(o);break;case"rotation":c.rotate(o,true);break;case"href":case"title":case"target":var t=h.parentNode;if(x.call(t.tagName)!="a"){var u=bG("a");t.insertBefore(u,h);u[l](h);t=u}n=="target"&&o=="blank"?t.setAttributeNS(c.paper.xlink,"show","new"):t.setAttributeNS(c.paper.xlink,n,o);break;case"cursor":h.style.cursor=o;break;case"clip-rect":var y=r(o)[s](b);if(y[w]==4){c.clip&&c.clip.parentNode.parentNode.removeChild(c.clip.parentNode);var z=bG("clipPath"),A=bG("rect");z.id=bh();bG(A,{x:y[0],y:y[1],width:y[2],height:y[3]});z[l](A);c.paper.defs[l](z);bG(h,{"clip-path":"url(#"+z.id+")"});c.clip=A}if(!o){var B=g.getElementById(h.getAttribute("clip-path")[Y](/(^url\(#|\)$)/g,p));B&&B.parentNode.removeChild(B);bG(h,{"clip-path":p});delete c.clip}break;case"path":c.type=="path"&&bG(h,{d:o?i.path=bq(o):"M0,0"});break;case"width":h[R](n,o);if(i.fx){n="x";o=i.x}else break;case"x":i.fx&&(o=-i.x-(i.width||0));case"rx":if(n=="rx"&&c.type=="rect")break;case"cx":m&&(n=="x"||n=="cx")&&(m[1]+=o-i[n]);h[R](n,o);c.pattern&&bJ(c);break;case"height":h[R](n,o);if(i.fy){n="y";o=i.y}else break;case"y":i.fy&&(o=-i.y-(i.height||0));case"ry":if(n=="ry"&&c.type=="rect")break;case"cy":m&&(n=="y"||n=="cy")&&(m[2]+=o-i[n]);h[R](n,o);c.pattern&&bJ(c);break;case"r":c.type=="rect"?bG(h,{rx:o,ry:o}):h[R](n,o);break;case"src":c.type=="image"&&h.setAttributeNS(c.paper.xlink,"href",o);break;case"stroke-width":h.style.strokeWidth=o;h[R](n,o);i["stroke-dasharray"]&&k(c,i["stroke-dasharray"]);break;case"stroke-dasharray":k(c,o);break;case"translation":var C=r(o)[s](b);C[0]=+C[0]||0;C[1]=+C[1]||0;if(m){m[1]+=C[0];m[2]+=C[1]}cz.call(c,C[0],C[1]);break;case"scale":C=r(o)[s](b);c.scale(+C[0]||1,+C[1]||+C[0]||1,isNaN(S(C[2]))?null:+C[2],isNaN(S(C[3]))?null:+C[3]);break;case I:var D=r(o).match(M);if(D){z=bG("pattern");var E=bG("image");z.id=bh();bG(z,{x:0,y:0,patternUnits:"userSpaceOnUse",height:1,width:1});bG(E,{x:0,y:0});E.setAttributeNS(c.paper.xlink,"href",D[1]);z[l](E);var F=g.createElement("img");F.style.cssText="position:absolute;left:-9999em;top-9999em";F.onload=function(){bG(z,{width:this.offsetWidth,height:this.offsetHeight});bG(E,{width:this.offsetWidth,height:this.offsetHeight});g.body.removeChild(this);c.paper.safari()};g.body[l](F);F.src=D[1];c.paper.defs[l](z);h.style.fill="url(#"+z.id+")";bG(h,{fill:"url(#"+z.id+")"});c.pattern=z;c.pattern&&bJ(c);break}var G=a.getRGB(o);if(G.error)if((({circle:1,ellipse:1})[f](c.type)||r(o).charAt()!="r")&&bI(h,o,c.paper)){i.gradient=o;i.fill="none";break}else{delete d.gradient;delete i.gradient;!a.is(i.opacity,"undefined")&&a.is(d.opacity,"undefined")&&bG(h,{opacity:i.opacity});!a.is(i["fill-opacity"],"undefined")&&a.is(d["fill-opacity"],"undefined")&&bG(h,{"fill-opacity":i["fill-opacity"]})}G[f]("opacity")&&bG(h,{"fill-opacity":G.opacity>1?G.opacity/100:G.opacity});case"stroke":G=a.getRGB(o);h[R](n,G.hex);n=="stroke"&&G[f]("opacity")&&bG(h,{"stroke-opacity":G.opacity>1?G.opacity/100:G.opacity});break;case"gradient":(({circle:1,ellipse:1})[f](c.type)||r(o).charAt()!="r")&&bI(h,o,c.paper);break;case"opacity":i.gradient&&!i[f]("stroke-opacity")&&bG(h,{"stroke-opacity":o>1?o/100:o});case"fill-opacity":if(i.gradient){var H=g.getElementById(h.getAttribute(I)[Y](/^url\(#|\)$/g,p));if(H){var J=H.getElementsByTagName("stop");J[J[w]-1][R]("stop-opacity",o)}break}default:n=="font-size"&&(o=T(o,10)+"px");var K=n[Y](/(\-.)/g,function(a){return V.call(a.substring(1))});h.style[K]=o;h[R](n,o);break}}}bM(c,d);m?c.rotate(m.join(q)):S(j)&&c.rotate(j,true)},bL=1.2,bM=function(b,c){if(b.type!="text"||!(c[f]("text")||c[f]("font")||c[f]("font-size")||c[f]("x")||c[f]("y")))return;var d=b.attrs,e=b.node,h=e.firstChild?T(g.defaultView.getComputedStyle(e.firstChild,p).getPropertyValue("font-size"),10):10;if(c[f]("text")){d.text=c.text;while(e.firstChild)e.removeChild(e.firstChild);var i=r(c.text)[s]("\n");for(var j=0,k=i[w];j<k;j++)if(i[j]){var m=bG("tspan");j&&bG(m,{dy:h*bL,x:d.x});m[l](g.createTextNode(i[j]));e[l](m)}}else{i=e.getElementsByTagName("tspan");for(j=0,k=i[w];j<k;j++)j&&bG(i[j],{dy:h*bL,x:d.x})}bG(e,{y:d.y});var n=b.getBBox(),o=d.y-(n.y+n.height/2);o&&a.is(o,"finite")&&bG(e,{y:d.y+o})},bN=function(b,c){var d=0,e=0;this[0]=b;this.id=a._oid++;this.node=b;b.raphael=this;this.paper=c;this.attrs=this.attrs||{};this.transformations=[];this._={tx:0,ty:0,rt:{deg:0,cx:0,cy:0},sx:1,sy:1};!c.bottom&&(c.bottom=this);this.prev=c.top;c.top&&(c.top.next=this);c.top=this;this.next=null},bO=bN[e];bN[e].rotate=function(c,d,e){if(this.removed)return this;if(c==null){if(this._.rt.cx)return[this._.rt.deg,this._.rt.cx,this._.rt.cy][v](q);return this._.rt.deg}var f=this.getBBox();c=r(c)[s](b);if(c[w]-1){d=S(c[1]);e=S(c[2])}c=S(c[0]);d!=null&&d!==false?this._.rt.deg=c:this._.rt.deg+=c;e==null&&(d=null);this._.rt.cx=d;this._.rt.cy=e;d=d==null?f.x+f.width/2:d;e=e==null?f.y+f.height/2:e;if(this._.rt.deg){this.transformations[0]=a.format("rotate({0} {1} {2})",this._.rt.deg,d,e);this.clip&&bG(this.clip,{transform:a.format("rotate({0} {1} {2})",-this._.rt.deg,d,e)})}else{this.transformations[0]=p;this.clip&&bG(this.clip,{transform:p})}bG(this.node,{transform:this.transformations[v](q)});return this};bN[e].hide=function(){!this.removed&&(this.node.style.display="none");return this};bN[e].show=function(){!this.removed&&(this.node.style.display="");return this};bN[e].remove=function(){if(this.removed)return;bA(this,this.paper);this.node.parentNode.removeChild(this.node);for(var a in this)delete this[a];this.removed=true};bN[e].getBBox=function(){if(this.removed)return this;if(this.type=="path")return bn(this.attrs.path);if(this.node.style.display=="none"){this.show();var a=true}var b={};try{b=this.node.getBBox()}catch(a){}finally{b=b||{}}if(this.type=="text"){b={x:b.x,y:Infinity,width:0,height:0};for(var c=0,d=this.node.getNumberOfChars();c<d;c++){var e=this.node.getExtentOfChar(c);e.y<b.y&&(b.y=e.y);e.y+e.height-b.y>b.height&&(b.height=e.y+e.height-b.y);e.x+e.width-b.x>b.width&&(b.width=e.x+e.width-b.x)}}a&&this.hide();return b};bN[e].attr=function(b,c){if(this.removed)return this;if(b==null){var d={};for(var e in this.attrs)this.attrs[f](e)&&(d[e]=this.attrs[e]);this._.rt.deg&&(d.rotation=this.rotate());(this._.sx!=1||this._.sy!=1)&&(d.scale=this.scale());d.gradient&&d.fill=="none"&&(d.fill=d.gradient)&&delete d.gradient;return d}if(c==null&&a.is(b,F)){if(b=="translation")return cz.call(this);if(b=="rotation")return this.rotate();if(b=="scale")return this.scale();if(b==I&&this.attrs.fill=="none"&&this.attrs.gradient)return this.attrs.gradient;return this.attrs[b]}if(c==null&&a.is(b,G)){var g={};for(var h=0,i=b.length;h<i;h++)g[b[h]]=this.attr(b[h]);return g}if(c!=null){var j={};j[b]=c}else b!=null&&a.is(b,"object")&&(j=b);for(var k in this.paper.customAttributes)if(this.paper.customAttributes[f](k)&&j[f](k)&&a.is(this.paper.customAttributes[k],"function")){var l=this.paper.customAttributes[k].apply(this,[][n](j[k]));this.attrs[k]=j[k];for(var m in l)l[f](m)&&(j[m]=l[m])}bK(this,j);return this};bN[e].toFront=function(){if(this.removed)return this;this.node.parentNode[l](this.node);var a=this.paper;a.top!=this&&bB(this,a);return this};bN[e].toBack=function(){if(this.removed)return this;if(this.node.parentNode.firstChild!=this.node){this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild);bC(this,this.paper);var a=this.paper}return this};bN[e].insertAfter=function(a){if(this.removed)return this;var b=a.node||a[a.length-1].node;b.nextSibling?b.parentNode.insertBefore(this.node,b.nextSibling):b.parentNode[l](this.node);bD(this,a,this.paper);return this};bN[e].insertBefore=function(a){if(this.removed)return this;var b=a.node||a[0].node;b.parentNode.insertBefore(this.node,b);bE(this,a,this.paper);return this};bN[e].blur=function(a){var b=this;if(+a!==0){var c=bG("filter"),d=bG("feGaussianBlur");b.attrs.blur=a;c.id=bh();bG(d,{stdDeviation:+a||1.5});c.appendChild(d);b.paper.defs.appendChild(c);b._blur=c;bG(b.node,{filter:"url(#"+c.id+")"})}else{if(b._blur){b._blur.parentNode.removeChild(b._blur);delete b._blur;delete b.attrs.blur}b.node.removeAttribute("filter")}};var bP=function(a,b,c,d){var e=bG("circle");a.canvas&&a.canvas[l](e);var f=new bN(e,a);f.attrs={cx:b,cy:c,r:d,fill:"none",stroke:"#000"};f.type="circle";bG(e,f.attrs);return f},bQ=function(a,b,c,d,e,f){var g=bG("rect");a.canvas&&a.canvas[l](g);var h=new bN(g,a);h.attrs={x:b,y:c,width:d,height:e,r:f||0,rx:f||0,ry:f||0,fill:"none",stroke:"#000"};h.type="rect";bG(g,h.attrs);return h},bR=function(a,b,c,d,e){var f=bG("ellipse");a.canvas&&a.canvas[l](f);var g=new bN(f,a);g.attrs={cx:b,cy:c,rx:d,ry:e,fill:"none",stroke:"#000"};g.type="ellipse";bG(f,g.attrs);return g},bS=function(a,b,c,d,e,f){var g=bG("image");bG(g,{x:c,y:d,width:e,height:f,preserveAspectRatio:"none"});g.setAttributeNS(a.xlink,"href",b);a.canvas&&a.canvas[l](g);var h=new bN(g,a);h.attrs={x:c,y:d,width:e,height:f,src:b};h.type="image";return h},bT=function(a,b,c,d){var e=bG("text");bG(e,{x:b,y:c,"text-anchor":"middle"});a.canvas&&a.canvas[l](e);var f=new bN(e,a);f.attrs={x:b,y:c,"text-anchor":"middle",text:d,font:W.font,stroke:"none",fill:"#000"};f.type="text";bK(f,f.attrs);return f},bU=function(a,b){this.width=a||this.width;this.height=b||this.height;this.canvas[R]("width",this.width);this.canvas[R]("height",this.height);return this},bV=function(){var b=by[m](0,arguments),c=b&&b.container,d=b.x,e=b.y,f=b.width,h=b.height;if(!c)throw new Error("SVG container not found.");var i=bG("svg");d=d||0;e=e||0;f=f||512;h=h||342;bG(i,{xmlns:"http://www.w3.org/2000/svg",version:1.1,width:f,height:h});if(c==1){i.style.cssText="position:absolute;left:"+d+"px;top:"+e+"px";g.body[l](i)}else c.firstChild?c.insertBefore(i,c.firstChild):c[l](i);c=new j;c.width=f;c.height=h;c.canvas=i;bz.call(c,c,a.fn);c.clear();return c};k.clear=function(){var a=this.canvas;while(a.firstChild)a.removeChild(a.firstChild);this.bottom=this.top=null;(this.desc=bG("desc"))[l](g.createTextNode("Created with Raphaël"));a[l](this.desc);a[l](this.defs=bG("defs"))};k.remove=function(){this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);for(var a in this)this[a]=bF(a)}}if(a.vml){var bW={M:"m",L:"l",C:"c",Z:"x",m:"t",l:"r",c:"v",z:"x"},bX=/([clmz]),?([^clmz]*)/gi,bY=/ progid:\S+Blur\([^\)]+\)/g,bZ=/-?[^,\s-]+/g,b$=1000+q+1000,b_=10,ca={path:1,rect:1},cb=function(a){var b=/[ahqstv]/ig,c=bq;r(a).match(b)&&(c=bw);b=/[clmz]/g;if(c==bq&&!r(a).match(b)){var d=r(a)[Y](bX,function(a,b,c){var d=[],e=x.call(b)=="m",f=bW[b];c[Y](bZ,function(a){if(e&&d[w]==2){f+=d+bW[b=="m"?"l":"L"];d=[]}d[L](Q(a*b_))});return f+d});return d}var e=c(a),f,g;d=[];for(var h=0,i=e[w];h<i;h++){f=e[h];g=x.call(e[h][0]);g=="z"&&(g="x");for(var j=1,k=f[w];j<k;j++)g+=Q(f[j]*b_)+(j!=k-1?",":p);d[L](g)}return d[v](q)};a[H]=function(){return"Your browser doesn’t support SVG. Falling down to VML.\nYou are running Raphaël "+this.version};bH=function(a,b){var c=cd("group");c.style.cssText="position:absolute;left:0;top:0;width:"+b.width+"px;height:"+b.height+"px";c.coordsize=b.coordsize;c.coordorigin=b.coordorigin;var d=cd("shape"),e=d.style;e.width=b.width+"px";e.height=b.height+"px";d.coordsize=b$;d.coordorigin=b.coordorigin;c[l](d);var f=new bN(d,c,b),g={fill:"none",stroke:"#000"};a&&(g.path=a);f.type="path";f.path=[];f.Path=p;bK(f,g);b.canvas[l](c);return f};bK=function(c,d){c.attrs=c.attrs||{};var e=c.node,h=c.attrs,i=e.style,j,k=(d.x!=h.x||d.y!=h.y||d.width!=h.width||d.height!=h.height||d.r!=h.r)&&c.type=="rect",m=c;for(var n in d)d[f](n)&&(h[n]=d[n]);if(k){h.path=cc(h.x,h.y,h.width,h.height,h.r);c.X=h.x;c.Y=h.y;c.W=h.width;c.H=h.height}d.href&&(e.href=d.href);d.title&&(e.title=d.title);d.target&&(e.target=d.target);d.cursor&&(i.cursor=d.cursor);"blur"in d&&c.blur(d.blur);if(d.path&&c.type=="path"||k)e.path=cb(h.path);d.rotation!=null&&c.rotate(d.rotation,true);if(d.translation){j=r(d.translation)[s](b);cz.call(c,j[0],j[1]);if(c._.rt.cx!=null){c._.rt.cx+=+j[0];c._.rt.cy+=+j[1];c.setBox(c.attrs,j[0],j[1])}}if(d.scale){j=r(d.scale)[s](b);c.scale(+j[0]||1,+j[1]||+j[0]||1,+j[2]||null,+j[3]||null)}if("clip-rect"in d){var o=r(d["clip-rect"])[s](b);if(o[w]==4){o[2]=+o[2]+ +o[0];o[3]=+o[3]+ +o[1];var q=e.clipRect||g.createElement("div"),t=q.style,u=e.parentNode;t.clip=a.format("rect({1}px {2}px {3}px {0}px)",o);if(!e.clipRect){t.position="absolute";t.top=0;t.left=0;t.width=c.paper.width+"px";t.height=c.paper.height+"px";u.parentNode.insertBefore(q,u);q[l](u);e.clipRect=q}}d["clip-rect"]||e.clipRect&&(e.clipRect.style.clip=p)}c.type=="image"&&d.src&&(e.src=d.src);if(c.type=="image"&&d.opacity){e.filterOpacity=U+".Alpha(opacity="+d.opacity*100+")";i.filter=(e.filterMatrix||p)+(e.filterOpacity||p)}d.font&&(i.font=d.font);d["font-family"]&&(i.fontFamily="\""+d["font-family"][s](",")[0][Y](/^['"]+|['"]+$/g,p)+"\"");d["font-size"]&&(i.fontSize=d["font-size"]);d["font-weight"]&&(i.fontWeight=d["font-weight"]);d["font-style"]&&(i.fontStyle=d["font-style"]);if(d.opacity!=null||d["stroke-width"]!=null||d.fill!=null||d.stroke!=null||d["stroke-width"]!=null||d["stroke-opacity"]!=null||d["fill-opacity"]!=null||d["stroke-dasharray"]!=null||d["stroke-miterlimit"]!=null||d["stroke-linejoin"]!=null||d["stroke-linecap"]!=null){e=c.shape||e;var v=e.getElementsByTagName(I)&&e.getElementsByTagName(I)[0],x=false;!v&&(x=v=cd(I));if("fill-opacity"in d||"opacity"in d){var y=((+h["fill-opacity"]+1||2)-1)*((+h.opacity+1||2)-1)*((+a.getRGB(d.fill).o+1||2)-1);y=A(z(y,0),1);v.opacity=y}d.fill&&(v.on=true);if(v.on==null||d.fill=="none")v.on=false;if(v.on&&d.fill){var B=d.fill.match(M);if(B){v.src=B[1];v.type="tile"}else{v.color=a.getRGB(d.fill).hex;v.src=p;v.type="solid";if(a.getRGB(d.fill).error&&(m.type in{circle:1,ellipse:1}||r(d.fill).charAt()!="r")&&bI(m,d.fill)){h.fill="none";h.gradient=d.fill}}}x&&e[l](v);var C=e.getElementsByTagName("stroke")&&e.getElementsByTagName("stroke")[0],D=false;!C&&(D=C=cd("stroke"));if(d.stroke&&d.stroke!="none"||d["stroke-width"]||d["stroke-opacity"]!=null||d["stroke-dasharray"]||d["stroke-miterlimit"]||d["stroke-linejoin"]||d["stroke-linecap"])C.on=true;(d.stroke=="none"||C.on==null||d.stroke==0||d["stroke-width"]==0)&&(C.on=false);var E=a.getRGB(d.stroke);C.on&&d.stroke&&(C.color=E.hex);y=((+h["stroke-opacity"]+1||2)-1)*((+h.opacity+1||2)-1)*((+E.o+1||2)-1);var F=(S(d["stroke-width"])||1)*0.75;y=A(z(y,0),1);d["stroke-width"]==null&&(F=h["stroke-width"]);d["stroke-width"]&&(C.weight=F);F&&F<1&&(y*=F)&&(C.weight=1);C.opacity=y;d["stroke-linejoin"]&&(C.joinstyle=d["stroke-linejoin"]||"miter");C.miterlimit=d["stroke-miterlimit"]||8;d["stroke-linecap"]&&(C.endcap=d["stroke-linecap"]=="butt"?"flat":d["stroke-linecap"]=="square"?"square":"round");if(d["stroke-dasharray"]){var G={"-":"shortdash",".":"shortdot","-.":"shortdashdot","-..":"shortdashdotdot",". ":"dot","- ":"dash","--":"longdash","- .":"dashdot","--.":"longdashdot","--..":"longdashdotdot"};C.dashstyle=G[f](d["stroke-dasharray"])?G[d["stroke-dasharray"]]:p}D&&e[l](C)}if(m.type=="text"){i=m.paper.span.style;h.font&&(i.font=h.font);h["font-family"]&&(i.fontFamily=h["font-family"]);h["font-size"]&&(i.fontSize=h["font-size"]);h["font-weight"]&&(i.fontWeight=h["font-weight"]);h["font-style"]&&(i.fontStyle=h["font-style"]);m.node.string&&(m.paper.span.innerHTML=r(m.node.string)[Y](/</g,"<")[Y](/&/g,"&")[Y](/\n/g,"<br>"));m.W=h.w=m.paper.span.offsetWidth;m.H=h.h=m.paper.span.offsetHeight;m.X=h.x;m.Y=h.y+Q(m.H/2);switch(h["text-anchor"]){case"start":m.node.style["v-text-align"]="left";m.bbx=Q(m.W/2);break;case"end":m.node.style["v-text-align"]="right";m.bbx=-Q(m.W/2);break;default:m.node.style["v-text-align"]="center";break}}};bI=function(a,b){a.attrs=a.attrs||{};var c=a.attrs,d,e="linear",f=".5 .5";a.attrs.gradient=b;b=r(b)[Y](bd,function(a,b,c){e="radial";if(b&&c){b=S(b);c=S(c);C(b-0.5,2)+C(c-0.5,2)>0.25&&(c=y.sqrt(0.25-C(b-0.5,2))*((c>0.5)*2-1)+0.5);f=b+q+c}return p});b=b[s](/\s*\-\s*/);if(e=="linear"){var g=b.shift();g=-S(g);if(isNaN(g))return null}var h=bx(b);if(!h)return null;a=a.shape||a.node;d=a.getElementsByTagName(I)[0]||cd(I);!d.parentNode&&a.appendChild(d);if(h[w]){d.on=true;d.method="none";d.color=h[0].color;d.color2=h[h[w]-1].color;var i=[];for(var j=0,k=h[w];j<k;j++)h[j].offset&&i[L](h[j].offset+q+h[j].color);d.colors&&(d.colors.value=i[w]?i[v]():"0% "+d.color);if(e=="radial"){d.type="gradientradial";d.focus="100%";d.focussize=f;d.focusposition=f}else{d.type="gradient";d.angle=(270-g)%360}}return 1};bN=function(b,c,d){var e=0,f=0,g=0,h=1;this[0]=b;this.id=a._oid++;this.node=b;b.raphael=this;this.X=0;this.Y=0;this.attrs={};this.Group=c;this.paper=d;this._={tx:0,ty:0,rt:{deg:0},sx:1,sy:1};!d.bottom&&(d.bottom=this);this.prev=d.top;d.top&&(d.top.next=this);d.top=this;this.next=null};bO=bN[e];bO.rotate=function(a,c,d){if(this.removed)return this;if(a==null){if(this._.rt.cx)return[this._.rt.deg,this._.rt.cx,this._.rt.cy][v](q);return this._.rt.deg}a=r(a)[s](b);if(a[w]-1){c=S(a[1]);d=S(a[2])}a=S(a[0]);c!=null?this._.rt.deg=a:this._.rt.deg+=a;d==null&&(c=null);this._.rt.cx=c;this._.rt.cy=d;this.setBox(this.attrs,c,d);this.Group.style.rotation=this._.rt.deg;return this};bO.setBox=function(a,b,c){if(this.removed)return this;var d=this.Group.style,e=this.shape&&this.shape.style||this.node.style;a=a||{};for(var g in a)a[f](g)&&(this.attrs[g]=a[g]);b=b||this._.rt.cx;c=c||this._.rt.cy;var h=this.attrs,i,j,k,l;switch(this.type){case"circle":i=h.cx-h.r;j=h.cy-h.r;k=l=h.r*2;break;case"ellipse":i=h.cx-h.rx;j=h.cy-h.ry;k=h.rx*2;l=h.ry*2;break;case"image":i=+h.x;j=+h.y;k=h.width||0;l=h.height||0;break;case"text":this.textpath.v=["m",Q(h.x),", ",Q(h.y-2),"l",Q(h.x)+1,", ",Q(h.y-2)][v](p);i=h.x-Q(this.W/2);j=h.y-this.H/2;k=this.W;l=this.H;break;case"rect":case"path":if(this.attrs.path){var m=bn(this.attrs.path);i=m.x;j=m.y;k=m.width;l=m.height}else{i=0;j=0;k=this.paper.width;l=this.paper.height}break;default:i=0;j=0;k=this.paper.width;l=this.paper.height;break}b=b==null?i+k/2:b;c=c==null?j+l/2:c;var n=b-this.paper.width/2,o=c-this.paper.height/2,q;d.left!=(q=n+"px")&&(d.left=q);d.top!=(q=o+"px")&&(d.top=q);this.X=ca[f](this.type)?-n:i;this.Y=ca[f](this.type)?-o:j;this.W=k;this.H=l;if(ca[f](this.type)){e.left!=(q=-n*b_+"px")&&(e.left=q);e.top!=(q=-o*b_+"px")&&(e.top=q)}else if(this.type=="text"){e.left!=(q=-n+"px")&&(e.left=q);e.top!=(q=-o+"px")&&(e.top=q)}else{d.width!=(q=this.paper.width+"px")&&(d.width=q);d.height!=(q=this.paper.height+"px")&&(d.height=q);e.left!=(q=i-n+"px")&&(e.left=q);e.top!=(q=j-o+"px")&&(e.top=q);e.width!=(q=k+"px")&&(e.width=q);e.height!=(q=l+"px")&&(e.height=q)}};bO.hide=function(){!this.removed&&(this.Group.style.display="none");return this};bO.show=function(){!this.removed&&(this.Group.style.display="block");return this};bO.getBBox=function(){if(this.removed)return this;if(ca[f](this.type))return bn(this.attrs.path);return{x:this.X+(this.bbx||0),y:this.Y,width:this.W,height:this.H}};bO.remove=function(){if(this.removed)return;bA(this,this.paper);this.node.parentNode.removeChild(this.node);this.Group.parentNode.removeChild(this.Group);this.shape&&this.shape.parentNode.removeChild(this.shape);for(var a in this)delete this[a];this.removed=true};bO.attr=function(b,c){if(this.removed)return this;if(b==null){var d={};for(var e in this.attrs)this.attrs[f](e)&&(d[e]=this.attrs[e]);this._.rt.deg&&(d.rotation=this.rotate());(this._.sx!=1||this._.sy!=1)&&(d.scale=this.scale());d.gradient&&d.fill=="none"&&(d.fill=d.gradient)&&delete d.gradient;return d}if(c==null&&a.is(b,"string")){if(b=="translation")return cz.call(this);if(b=="rotation")return this.rotate();if(b=="scale")return this.scale();if(b==I&&this.attrs.fill=="none"&&this.attrs.gradient)return this.attrs.gradient;return this.attrs[b]}if(this.attrs&&c==null&&a.is(b,G)){var g,h={};for(e=0,g=b[w];e<g;e++)h[b[e]]=this.attr(b[e]);return h}var i;if(c!=null){i={};i[b]=c}c==null&&a.is(b,"object")&&(i=b);if(i){for(var j in this.paper.customAttributes)if(this.paper.customAttributes[f](j)&&i[f](j)&&a.is(this.paper.customAttributes[j],"function")){var k=this.paper.customAttributes[j].apply(this,[][n](i[j]));this.attrs[j]=i[j];for(var l in k)k[f](l)&&(i[l]=k[l])}i.text&&this.type=="text"&&(this.node.string=i.text);bK(this,i);i.gradient&&(({circle:1,ellipse:1})[f](this.type)||r(i.gradient).charAt()!="r")&&bI(this,i.gradient);(!ca[f](this.type)||this._.rt.deg)&&this.setBox(this.attrs)}return this};bO.toFront=function(){!this.removed&&this.Group.parentNode[l](this.Group);this.paper.top!=this&&bB(this,this.paper);return this};bO.toBack=function(){if(this.removed)return this;if(this.Group.parentNode.firstChild!=this.Group){this.Group.parentNode.insertBefore(this.Group,this.Group.parentNode.firstChild);bC(this,this.paper)}return this};bO.insertAfter=function(a){if(this.removed)return this;a.constructor==cC&&(a=a[a.length-1]);a.Group.nextSibling?a.Group.parentNode.insertBefore(this.Group,a.Group.nextSibling):a.Group.parentNode[l](this.Group);bD(this,a,this.paper);return this};bO.insertBefore=function(a){if(this.removed)return this;a.constructor==cC&&(a=a[0]);a.Group.parentNode.insertBefore(this.Group,a.Group);bE(this,a,this.paper);return this};bO.blur=function(b){var c=this.node.runtimeStyle,d=c.filter;d=d.replace(bY,p);if(+b!==0){this.attrs.blur=b;c.filter=d+q+U+".Blur(pixelradius="+(+b||1.5)+")";c.margin=a.format("-{0}px 0 0 -{0}px",Q(+b||1.5))}else{c.filter=d;c.margin=0;delete this.attrs.blur}};bP=function(a,b,c,d){var e=cd("group"),f=cd("oval"),g=f.style;e.style.cssText="position:absolute;left:0;top:0;width:"+a.width+"px;height:"+a.height+"px";e.coordsize=b$;e.coordorigin=a.coordorigin;e[l](f);var h=new bN(f,e,a);h.type="circle";bK(h,{stroke:"#000",fill:"none"});h.attrs.cx=b;h.attrs.cy=c;h.attrs.r=d;h.setBox({x:b-d,y:c-d,width:d*2,height:d*2});a.canvas[l](e);return h};function cc(b,c,d,e,f){return f?a.format("M{0},{1}l{2},0a{3},{3},0,0,1,{3},{3}l0,{5}a{3},{3},0,0,1,{4},{3}l{6},0a{3},{3},0,0,1,{4},{4}l0,{7}a{3},{3},0,0,1,{3},{4}z",b+f,c,d-f*2,f,-f,e-f*2,f*2-d,f*2-e):a.format("M{0},{1}l{2},0,0,{3},{4},0z",b,c,d,e,-d)}bQ=function(a,b,c,d,e,f){var g=cc(b,c,d,e,f),h=a.path(g),i=h.attrs;h.X=i.x=b;h.Y=i.y=c;h.W=i.width=d;h.H=i.height=e;i.r=f;i.path=g;h.type="rect";return h};bR=function(a,b,c,d,e){var f=cd("group"),g=cd("oval"),h=g.style;f.style.cssText="position:absolute;left:0;top:0;width:"+a.width+"px;height:"+a.height+"px";f.coordsize=b$;f.coordorigin=a.coordorigin;f[l](g);var i=new bN(g,f,a);i.type="ellipse";bK(i,{stroke:"#000"});i.attrs.cx=b;i.attrs.cy=c;i.attrs.rx=d;i.attrs.ry=e;i.setBox({x:b-d,y:c-e,width:d*2,height:e*2});a.canvas[l](f);return i};bS=function(a,b,c,d,e,f){var g=cd("group"),h=cd("image");g.style.cssText="position:absolute;left:0;top:0;width:"+a.width+"px;height:"+a.height+"px";g.coordsize=b$;g.coordorigin=a.coordorigin;h.src=b;g[l](h);var i=new bN(h,g,a);i.type="image";i.attrs.src=b;i.attrs.x=c;i.attrs.y=d;i.attrs.w=e;i.attrs.h=f;i.setBox({x:c,y:d,width:e,height:f});a.canvas[l](g);return i};bT=function(b,c,d,e){var f=cd("group"),g=cd("shape"),h=g.style,i=cd("path"),j=i.style,k=cd("textpath");f.style.cssText="position:absolute;left:0;top:0;width:"+b.width+"px;height:"+b.height+"px";f.coordsize=b$;f.coordorigin=b.coordorigin;i.v=a.format("m{0},{1}l{2},{1}",Q(c*10),Q(d*10),Q(c*10)+1);i.textpathok=true;h.width=b.width;h.height=b.height;k.string=r(e);k.on=true;g[l](k);g[l](i);f[l](g);var m=new bN(k,f,b);m.shape=g;m.textpath=i;m.type="text";m.attrs.text=e;m.attrs.x=c;m.attrs.y=d;m.attrs.w=1;m.attrs.h=1;bK(m,{font:W.font,stroke:"none",fill:"#000"});m.setBox();b.canvas[l](f);return m};bU=function(a,b){var c=this.canvas.style;a==+a&&(a+="px");b==+b&&(b+="px");c.width=a;c.height=b;c.clip="rect(0 "+a+" "+b+" 0)";return this};var cd;g.createStyleSheet().addRule(".rvml","behavior:url(#default#VML)");try{!g.namespaces.rvml&&g.namespaces.add("rvml","urn:schemas-microsoft-com:vml");cd=function(a){return g.createElement("<rvml:"+a+" class=\"rvml\">")}}catch(a){cd=function(a){return g.createElement("<"+a+" xmlns=\"urn:schemas-microsoft.com:vml\" class=\"rvml\">")}}bV=function(){var b=by[m](0,arguments),c=b.container,d=b.height,e,f=b.width,h=b.x,i=b.y;if(!c)throw new Error("VML container not found.");var k=new j,n=k.canvas=g.createElement("div"),o=n.style;h=h||0;i=i||0;f=f||512;d=d||342;f==+f&&(f+="px");d==+d&&(d+="px");k.width=1000;k.height=1000;k.coordsize=b_*1000+q+b_*1000;k.coordorigin="0 0";k.span=g.createElement("span");k.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";n[l](k.span);o.cssText=a.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",f,d);if(c==1){g.body[l](n);o.left=h+"px";o.top=i+"px";o.position="absolute"}else c.firstChild?c.insertBefore(n,c.firstChild):c[l](n);bz.call(k,k,a.fn);return k};k.clear=function(){this.canvas.innerHTML=p;this.span=g.createElement("span");this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";this.canvas[l](this.span);this.bottom=this.top=null};k.remove=function(){this.canvas.parentNode.removeChild(this.canvas);for(var a in this)this[a]=bF(a);return true}}var ce=navigator.userAgent.match(/Version\\x2f(.*?)\s/);navigator.vendor=="Apple Computer, Inc."&&(ce&&ce[1]<4||navigator.platform.slice(0,2)=="iP")?k.safari=function(){var a=this.rect(-99,-99,this.width+99,this.height+99).attr({stroke:"none"});h.setTimeout(function(){a.remove()})}:k.safari=function(){};var cf=function(){this.returnValue=false},cg=function(){return this.originalEvent.preventDefault()},ch=function(){this.cancelBubble=true},ci=function(){return this.originalEvent.stopPropagation()},cj=(function(){{if(g.addEventListener)return function(a,b,c,d){var e=o&&u[b]?u[b]:b,g=function(e){if(o&&u[f](b))for(var g=0,h=e.targetTouches&&e.targetTouches.length;g<h;g++){if(e.targetTouches[g].target==a){var i=e;e=e.targetTouches[g];e.originalEvent=i;e.preventDefault=cg;e.stopPropagation=ci;break}}return c.call(d,e)};a.addEventListener(e,g,false);return function(){a.removeEventListener(e,g,false);return true}};if(g.attachEvent)return function(a,b,c,d){var e=function(a){a=a||h.event;a.preventDefault=a.preventDefault||cf;a.stopPropagation=a.stopPropagation||ch;return c.call(d,a)};a.attachEvent("on"+b,e);var f=function(){a.detachEvent("on"+b,e);return true};return f}}})(),ck=[],cl=function(a){var b=a.clientX,c=a.clientY,d=g.documentElement.scrollTop||g.body.scrollTop,e=g.documentElement.scrollLeft||g.body.scrollLeft,f,h=ck.length;while(h--){f=ck[h];if(o){var i=a.touches.length,j;while(i--){j=a.touches[i];if(j.identifier==f.el._drag.id){b=j.clientX;c=j.clientY;(a.originalEvent?a.originalEvent:a).preventDefault();break}}}else a.preventDefault();b+=e;c+=d;f.move&&f.move.call(f.move_scope||f.el,b-f.el._drag.x,c-f.el._drag.y,b,c,a)}},cm=function(b){a.unmousemove(cl).unmouseup(cm);var c=ck.length,d;while(c--){d=ck[c];d.el._drag={};d.end&&d.end.call(d.end_scope||d.start_scope||d.move_scope||d.el,b)}ck=[]};for(var cn=t[w];cn--;)(function(b){a[b]=bN[e][b]=function(c,d){if(a.is(c,"function")){this.events=this.events||[];this.events.push({name:b,f:c,unbind:cj(this.shape||this.node||g,b,c,d||this)})}return this};a["un"+b]=bN[e]["un"+b]=function(a){var c=this.events,d=c[w];while(d--)if(c[d].name==b&&c[d].f==a){c[d].unbind();c.splice(d,1);!c.length&&delete this.events;return this}return this}})(t[cn]);bO.hover=function(a,b,c,d){return this.mouseover(a,c).mouseout(b,d||c)};bO.unhover=function(a,b){return this.unmouseover(a).unmouseout(b)};bO.drag=function(b,c,d,e,f,h){this._drag={};this.mousedown(function(i){(i.originalEvent||i).preventDefault();var j=g.documentElement.scrollTop||g.body.scrollTop,k=g.documentElement.scrollLeft||g.body.scrollLeft;this._drag.x=i.clientX+k;this._drag.y=i.clientY+j;this._drag.id=i.identifier;c&&c.call(f||e||this,i.clientX+k,i.clientY+j,i);!ck.length&&a.mousemove(cl).mouseup(cm);ck.push({el:this,move:b,end:d,move_scope:e,start_scope:f,end_scope:h})});return this};bO.undrag=function(b,c,d){var e=ck.length;while(e--)ck[e].el==this&&(ck[e].move==b&&ck[e].end==d)&&ck.splice(e++,1);!ck.length&&a.unmousemove(cl).unmouseup(cm)};k.circle=function(a,b,c){return bP(this,a||0,b||0,c||0)};k.rect=function(a,b,c,d,e){return bQ(this,a||0,b||0,c||0,d||0,e||0)};k.ellipse=function(a,b,c,d){return bR(this,a||0,b||0,c||0,d||0)};k.path=function(b){b&&!a.is(b,F)&&!a.is(b[0],G)&&(b+=p);return bH(a.format[m](a,arguments),this)};k.image=function(a,b,c,d,e){return bS(this,a||"about:blank",b||0,c||0,d||0,e||0)};k.text=function(a,b,c){return bT(this,a||0,b||0,r(c))};k.set=function(a){arguments[w]>1&&(a=Array[e].splice.call(arguments,0,arguments[w]));return new cC(a)};k.setSize=bU;k.top=k.bottom=null;k.raphael=a;function co(){return this.x+q+this.y}bO.resetScale=function(){if(this.removed)return this;this._.sx=1;this._.sy=1;this.attrs.scale="1 1"};bO.scale=function(a,b,c,d){if(this.removed)return this;if(a==null&&b==null)return{x:this._.sx,y:this._.sy,toString:co};b=b||a;!(+b)&&(b=a);var e,f,g,h,i=this.attrs;if(a!=0){var j=this.getBBox(),k=j.x+j.width/2,l=j.y+j.height/2,m=B(a/this._.sx),o=B(b/this._.sy);c=+c||c==0?c:k;d=+d||d==0?d:l;var r=this._.sx>0,s=this._.sy>0,t=~(~(a/B(a))),u=~(~(b/B(b))),x=m*t,y=o*u,z=this.node.style,A=c+B(k-c)*x*(k>c==r?1:-1),C=d+B(l-d)*y*(l>d==s?1:-1),D=a*t>b*u?o:m;switch(this.type){case"rect":case"image":var E=i.width*m,F=i.height*o;this.attr({height:F,r:i.r*D,width:E,x:A-E/2,y:C-F/2});break;case"circle":case"ellipse":this.attr({rx:i.rx*m,ry:i.ry*o,r:i.r*D,cx:A,cy:C});break;case"text":this.attr({x:A,y:C});break;case"path":var G=bp(i.path),H=true,I=r?x:m,J=s?y:o;for(var K=0,L=G[w];K<L;K++){var M=G[K],N=V.call(M[0]);{if(N=="M"&&H)continue;H=false}if(N=="A"){M[G[K][w]-2]*=I;M[G[K][w]-1]*=J;M[1]*=m;M[2]*=o;M[5]=+(t+u?!(!(+M[5])):!(+M[5]))}else if(N=="H")for(var O=1,P=M[w];O<P;O++)M[O]*=I;else if(N=="V")for(O=1,P=M[w];O<P;O++)M[O]*=J;else for(O=1,P=M[w];O<P;O++)M[O]*=O%2?I:J}var Q=bn(G);e=A-Q.x-Q.width/2;f=C-Q.y-Q.height/2;G[0][1]+=e;G[0][2]+=f;this.attr({path:G});break}if(this.type in{text:1,image:1}&&(t!=1||u!=1))if(this.transformations){this.transformations[2]="scale("[n](t,",",u,")");this.node[R]("transform",this.transformations[v](q));e=t==-1?-i.x-(E||0):i.x;f=u==-1?-i.y-(F||0):i.y;this.attr({x:e,y:f});i.fx=t-1;i.fy=u-1}else{this.node.filterMatrix=U+".Matrix(M11="[n](t,", M12=0, M21=0, M22=",u,", Dx=0, Dy=0, sizingmethod='auto expand', filtertype='bilinear')");z.filter=(this.node.filterMatrix||p)+(this.node.filterOpacity||p)}else if(this.transformations){this.transformations[2]=p;this.node[R]("transform",this.transformations[v](q));i.fx=0;i.fy=0}else{this.node.filterMatrix=p;z.filter=(this.node.filterMatrix||p)+(this.node.filterOpacity||p)}i.scale=[a,b,c,d][v](q);this._.sx=a;this._.sy=b}return this};bO.clone=function(){if(this.removed)return null;var a=this.attr();delete a.scale;delete a.translation;return this.paper[this.type]().attr(a)};var cp={},cq=function(b,c,d,e,f,g,h,i,j){var k=0,l=100,m=[b,c,d,e,f,g,h,i].join(),n=cp[m],o,p;!n&&(cp[m]=n={data:[]});n.timer&&clearTimeout(n.timer);n.timer=setTimeout(function(){delete cp[m]},2000);if(j!=null){var q=cq(b,c,d,e,f,g,h,i);l=~(~q)*10}for(var r=0;r<l+1;r++){if(n.data[j]>r)p=n.data[r*l];else{p=a.findDotsAtSegment(b,c,d,e,f,g,h,i,r/l);n.data[r]=p}r&&(k+=C(C(o.x-p.x,2)+C(o.y-p.y,2),0.5));if(j!=null&&k>=j)return p;o=p}if(j==null)return k},cr=function(b,c){return function(d,e,f){d=bw(d);var g,h,i,j,k="",l={},m,n=0;for(var o=0,p=d.length;o<p;o++){i=d[o];if(i[0]=="M"){g=+i[1];h=+i[2]}else{j=cq(g,h,i[1],i[2],i[3],i[4],i[5],i[6]);if(n+j>e){if(c&&!l.start){m=cq(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n);k+=["C",m.start.x,m.start.y,m.m.x,m.m.y,m.x,m.y];if(f)return k;l.start=k;k=["M",m.x,m.y+"C",m.n.x,m.n.y,m.end.x,m.end.y,i[5],i[6]][v]();n+=j;g=+i[5];h=+i[6];continue}if(!b&&!c){m=cq(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n);return{x:m.x,y:m.y,alpha:m.alpha}}}n+=j;g=+i[5];h=+i[6]}k+=i}l.end=k;m=b?n:c?l:a.findDotsAtSegment(g,h,i[1],i[2],i[3],i[4],i[5],i[6],1);m.alpha&&(m={x:m.x,y:m.y,alpha:m.alpha});return m}},cs=cr(1),ct=cr(),cu=cr(0,1);bO.getTotalLength=function(){if(this.type!="path")return;if(this.node.getTotalLength)return this.node.getTotalLength();return cs(this.attrs.path)};bO.getPointAtLength=function(a){if(this.type!="path")return;return ct(this.attrs.path,a)};bO.getSubpath=function(a,b){if(this.type!="path")return;if(B(this.getTotalLength()-b)<"1e-6")return cu(this.attrs.path,a).end;var c=cu(this.attrs.path,b,1);return a?cu(c,a).end:c};a.easing_formulas={linear:function(a){return a},"<":function(a){return C(a,3)},">":function(a){return C(a-1,3)+1},"<>":function(a){a=a*2;if(a<1)return C(a,3)/2;a-=2;return(C(a,3)+2)/2},backIn:function(a){var b=1.70158;return a*a*((b+1)*a-b)},backOut:function(a){a=a-1;var b=1.70158;return a*a*((b+1)*a+b)+1},elastic:function(a){if(a==0||a==1)return a;var b=0.3,c=b/4;return C(2,-10*a)*y.sin((a-c)*(2*D)/b)+1},bounce:function(a){var b=7.5625,c=2.75,d;if(a<1/c)d=b*a*a;else if(a<2/c){a-=1.5/c;d=b*a*a+0.75}else if(a<2.5/c){a-=2.25/c;d=b*a*a+0.9375}else{a-=2.625/c;d=b*a*a+0.984375}return d}};var cv=[],cw=function(){var b=+(new Date);for(var c=0;c<cv[w];c++){var d=cv[c];if(d.stop||d.el.removed)continue;var e=b-d.start,g=d.ms,h=d.easing,i=d.from,j=d.diff,k=d.to,l=d.t,m=d.el,n={},o;if(e<g){var r=h(e/g);for(var s in i)if(i[f](s)){switch(X[s]){case"along":o=r*g*j[s];k.back&&(o=k.len-o);var t=ct(k[s],o);m.translate(j.sx-j.x||0,j.sy-j.y||0);j.x=t.x;j.y=t.y;m.translate(t.x-j.sx,t.y-j.sy);k.rot&&m.rotate(j.r+t.alpha,t.x,t.y);break;case E:o=+i[s]+r*g*j[s];break;case"colour":o="rgb("+[cy(Q(i[s].r+r*g*j[s].r)),cy(Q(i[s].g+r*g*j[s].g)),cy(Q(i[s].b+r*g*j[s].b))][v](",")+")";break;case"path":o=[];for(var u=0,x=i[s][w];u<x;u++){o[u]=[i[s][u][0]];for(var y=1,z=i[s][u][w];y<z;y++)o[u][y]=+i[s][u][y]+r*g*j[s][u][y];o[u]=o[u][v](q)}o=o[v](q);break;case"csv":switch(s){case"translation":var A=r*g*j[s][0]-l.x,B=r*g*j[s][1]-l.y;l.x+=A;l.y+=B;o=A+q+B;break;case"rotation":o=+i[s][0]+r*g*j[s][0];i[s][1]&&(o+=","+i[s][1]+","+i[s][2]);break;case"scale":o=[+i[s][0]+r*g*j[s][0],+i[s][1]+r*g*j[s][1],2 in k[s]?k[s][2]:p,3 in k[s]?k[s][3]:p][v](q);break;case"clip-rect":o=[];u=4;while(u--)o[u]=+i[s][u]+r*g*j[s][u];break}break;default:var C=[].concat(i[s]);o=[];u=m.paper.customAttributes[s].length;while(u--)o[u]=+C[u]+r*g*j[s][u];break}n[s]=o}m.attr(n);m._run&&m._run.call(m)}else{if(k.along){t=ct(k.along,k.len*!k.back);m.translate(j.sx-(j.x||0)+t.x-j.sx,j.sy-(j.y||0)+t.y-j.sy);k.rot&&m.rotate(j.r+t.alpha,t.x,t.y)}(l.x||l.y)&&m.translate(-l.x,-l.y);k.scale&&(k.scale+=p);m.attr(k);cv.splice(c--,1)}}a.svg&&m&&m.paper&&m.paper.safari();cv[w]&&setTimeout(cw)},cx=function(b,c,d,e,f){var g=d-e;c.timeouts.push(setTimeout(function(){a.is(f,"function")&&f.call(c);c.animate(b,g,b.easing)},e))},cy=function(a){return z(A(a,255),0)},cz=function(a,b){if(a==null)return{x:this._.tx,y:this._.ty,toString:co};this._.tx+=+a;this._.ty+=+b;switch(this.type){case"circle":case"ellipse":this.attr({cx:+a+this.attrs.cx,cy:+b+this.attrs.cy});break;case"rect":case"image":case"text":this.attr({x:+a+this.attrs.x,y:+b+this.attrs.y});break;case"path":var c=bp(this.attrs.path);c[0][1]+=+a;c[0][2]+=+b;this.attr({path:c});break}return this};bO.animateWith=function(a,b,c,d,e){for(var f=0,g=cv.length;f<g;f++)cv[f].el.id==a.id&&(b.start=cv[f].start);return this.animate(b,c,d,e)};bO.animateAlong=cA();bO.animateAlongBack=cA(1);function cA(b){return function(c,d,e,f){var g={back:b};a.is(e,"function")?f=e:g.rot=e;c&&c.constructor==bN&&(c=c.attrs.path);c&&(g.along=c);return this.animate(g,d,f)}}function cB(a,b,c,d,e,f){var g=3*b,h=3*(d-b)-g,i=1-g-h,j=3*c,k=3*(e-c)-j,l=1-j-k;function m(a){return((i*a+h)*a+g)*a}function n(a,b){var c=o(a,b);return((l*c+k)*c+j)*c}function o(a,b){var c,d,e,f,j,k;for(e=a,k=0;k<8;k++){f=m(e)-a;if(B(f)<b)return e;j=(3*i*e+2*h)*e+g;if(B(j)<0.000001)break;e=e-f/j}c=0;d=1;e=a;if(e<c)return c;if(e>d)return d;while(c<d){f=m(e);if(B(f-a)<b)return e;a>f?c=e:d=e;e=(d-c)/2+c}return e}return n(a,1/(200*f))}bO.onAnimation=function(a){this._run=a||0;return this};bO.animate=function(c,d,e,g){var h=this;h.timeouts=h.timeouts||[];if(a.is(e,"function")||!e)g=e||null;if(h.removed){g&&g.call(h);return h}var i={},j={},k=false,l={};for(var m in c)if(c[f](m)){if(X[f](m)||h.paper.customAttributes[f](m)){k=true;i[m]=h.attr(m);i[m]==null&&(i[m]=W[m]);j[m]=c[m];switch(X[m]){case"along":var n=cs(c[m]),o=ct(c[m],n*!(!c.back)),p=h.getBBox();l[m]=n/d;l.tx=p.x;l.ty=p.y;l.sx=o.x;l.sy=o.y;j.rot=c.rot;j.back=c.back;j.len=n;c.rot&&(l.r=S(h.rotate())||0);break;case E:l[m]=(j[m]-i[m])/d;break;case"colour":i[m]=a.getRGB(i[m]);var q=a.getRGB(j[m]);l[m]={r:(q.r-i[m].r)/d,g:(q.g-i[m].g)/d,b:(q.b-i[m].b)/d};break;case"path":var t=bw(i[m],j[m]);i[m]=t[0];var u=t[1];l[m]=[];for(var v=0,x=i[m][w];v<x;v++){l[m][v]=[0];for(var y=1,z=i[m][v][w];y<z;y++)l[m][v][y]=(u[v][y]-i[m][v][y])/d}break;case"csv":var A=r(c[m])[s](b),B=r(i[m])[s](b);switch(m){case"translation":i[m]=[0,0];l[m]=[A[0]/d,A[1]/d];break;case"rotation":i[m]=B[1]==A[1]&&B[2]==A[2]?B:[0,A[1],A[2]];l[m]=[(A[0]-i[m][0])/d,0,0];break;case"scale":c[m]=A;i[m]=r(i[m])[s](b);l[m]=[(A[0]-i[m][0])/d,(A[1]-i[m][1])/d,0,0];break;case"clip-rect":i[m]=r(i[m])[s](b);l[m]=[];v=4;while(v--)l[m][v]=(A[v]-i[m][v])/d;break}j[m]=A;break;default:A=[].concat(c[m]);B=[].concat(i[m]);l[m]=[];v=h.paper.customAttributes[m][w];while(v--)l[m][v]=((A[v]||0)-(B[v]||0))/d;break}}}if(k){var G=a.easing_formulas[e];if(!G){G=r(e).match(P);if(G&&G[w]==5){var H=G;G=function(a){return cB(a,+H[1],+H[2],+H[3],+H[4],d)}}else G=function(a){return a}}cv.push({start:c.start||+(new Date),ms:d,easing:G,from:i,diff:l,to:j,el:h,t:{x:0,y:0}});a.is(g,"function")&&(h._ac=setTimeout(function(){g.call(h)},d));cv[w]==1&&setTimeout(cw)}else{var C=[],D;for(var F in c)if(c[f](F)&&Z.test(F)){m={value:c[F]};F=="from"&&(F=0);F=="to"&&(F=100);m.key=T(F,10);C.push(m)}C.sort(be);C[0].key&&C.unshift({key:0,value:h.attrs});for(v=0,x=C[w];v<x;v++)cx(C[v].value,h,d/100*C[v].key,d/100*(C[v-1]&&C[v-1].key||0),C[v-1]&&C[v-1].value.callback);D=C[C[w]-1].value.callback;D&&h.timeouts.push(setTimeout(function(){D.call(h)},d))}return this};bO.stop=function(){for(var a=0;a<cv.length;a++)cv[a].el.id==this.id&&cv.splice(a--,1);for(a=0,ii=this.timeouts&&this.timeouts.length;a<ii;a++)clearTimeout(this.timeouts[a]);this.timeouts=[];clearTimeout(this._ac);delete this._ac;return this};bO.translate=function(a,b){return this.attr({translation:a+" "+b})};bO[H]=function(){return"Raphaël’s object"};a.ae=cv;var cC=function(a){this.items=[];this[w]=0;this.type="set";if(a)for(var b=0,c=a[w];b<c;b++){if(a[b]&&(a[b].constructor==bN||a[b].constructor==cC)){this[this.items[w]]=this.items[this.items[w]]=a[b];this[w]++}}};cC[e][L]=function(){var a,b;for(var c=0,d=arguments[w];c<d;c++){a=arguments[c];if(a&&(a.constructor==bN||a.constructor==cC)){b=this.items[w];this[b]=this.items[b]=a;this[w]++}}return this};cC[e].pop=function(){delete this[this[w]--];return this.items.pop()};for(var cD in bO)bO[f](cD)&&(cC[e][cD]=(function(a){return function(){for(var b=0,c=this.items[w];b<c;b++)this.items[b][a][m](this.items[b],arguments);return this}})(cD));cC[e].attr=function(b,c){if(b&&a.is(b,G)&&a.is(b[0],"object"))for(var d=0,e=b[w];d<e;d++)this.items[d].attr(b[d]);else for(var f=0,g=this.items[w];f<g;f++)this.items[f].attr(b,c);return this};cC[e].animate=function(b,c,d,e){(a.is(d,"function")||!d)&&(e=d||null);var f=this.items[w],g=f,h,i=this,j;e&&(j=function(){!(--f)&&e.call(i)});d=a.is(d,F)?d:j;h=this.items[--g].animate(b,c,d,j);while(g--)this.items[g]&&!this.items[g].removed&&this.items[g].animateWith(h,b,c,d,j);return this};cC[e].insertAfter=function(a){var b=this.items[w];while(b--)this.items[b].insertAfter(a);return this};cC[e].getBBox=function(){var a=[],b=[],c=[],d=[];for(var e=this.items[w];e--;){var f=this.items[e].getBBox();a[L](f.x);b[L](f.y);c[L](f.x+f.width);d[L](f.y+f.height)}a=A[m](0,a);b=A[m](0,b);return{x:a,y:b,width:z[m](0,c)-a,height:z[m](0,d)-b}};cC[e].clone=function(a){a=new cC;for(var b=0,c=this.items[w];b<c;b++)a[L](this.items[b].clone());return a};a.registerFont=function(a){if(!a.face)return a;this.fonts=this.fonts||{};var b={w:a.w,face:{},glyphs:{}},c=a.face["font-family"];for(var d in a.face)a.face[f](d)&&(b.face[d]=a.face[d]);this.fonts[c]?this.fonts[c][L](b):this.fonts[c]=[b];if(!a.svg){b.face["units-per-em"]=T(a.face["units-per-em"],10);for(var e in a.glyphs)if(a.glyphs[f](e)){var g=a.glyphs[e];b.glyphs[e]={w:g.w,k:{},d:g.d&&"M"+g.d[Y](/[mlcxtrv]/g,function(a){return({l:"L",c:"C",x:"z",t:"m",r:"l",v:"c"})[a]||"M"})+"z"};if(g.k)for(var h in g.k)g[f](h)&&(b.glyphs[e].k[h]=g.k[h])}}return a};k.getFont=function(b,c,d,e){e=e||"normal";d=d||"normal";c=+c||({normal:400,bold:700,lighter:300,bolder:800})[c]||400;if(!a.fonts)return;var g=a.fonts[b];if(!g){var h=new RegExp("(^|\\s)"+b[Y](/[^\w\d\s+!~.:_-]/g,p)+"(\\s|$)","i");for(var i in a.fonts)if(a.fonts[f](i)){if(h.test(i)){g=a.fonts[i];break}}}var j;if(g)for(var k=0,l=g[w];k<l;k++){j=g[k];if(j.face["font-weight"]==c&&(j.face["font-style"]==d||!j.face["font-style"])&&j.face["font-stretch"]==e)break}return j};k.print=function(c,d,e,f,g,h,i){h=h||"middle";i=z(A(i||0,1),-1);var j=this.set(),k=r(e)[s](p),l=0,m=p,n;a.is(f,e)&&(f=this.getFont(f));if(f){n=(g||16)/f.face["units-per-em"];var o=f.face.bbox.split(b),q=+o[0],t=+o[1]+(h=="baseline"?o[3]-o[1]+ +f.face.descent:(o[3]-o[1])/2);for(var u=0,v=k[w];u<v;u++){var x=u&&f.glyphs[k[u-1]]||{},y=f.glyphs[k[u]];l+=u?(x.w||f.w)+(x.k&&x.k[k[u]]||0)+f.w*i:0;y&&y.d&&j[L](this.path(y.d).attr({fill:"#000",stroke:"none",translation:[l,0]}))}j.scale(n,n,q,t).translate(c-q,d-t)}return j};a.format=function(b,c){var e=a.is(c,G)?[0][n](c):arguments;b&&a.is(b,F)&&e[w]-1&&(b=b[Y](d,function(a,b){return e[++b]==null?p:e[b]}));return b||p};a.ninja=function(){i.was?h.Raphael=i.is:delete Raphael;return a};a.el=bO;a.st=cC[e];i.was?h.Raphael=a:Raphael=a})()
\ No newline at end of file
+++ /dev/null
-/** @license
-
-
- SoundManager 2: JavaScript Sound for the Web
- ----------------------------------------------
- http://schillmania.com/projects/soundmanager2/
-
- Copyright (c) 2007, Scott Schiller. All rights reserved.
- Code provided under the BSD License:
- http://schillmania.com/projects/soundmanager2/license.txt
-
- V2.97a.20111030
-*/
-(function(S){function T(T,fa){function k(b){return function(a){return!this._t||!this._t._a?(this._t&&this._t.sID?c._wD(h+"ignoring "+a.type+": "+this._t.sID):c._wD(h+"ignoring "+a.type),null):b.call(this,a)}}this.flashVersion=8;this.debugMode=true;this.debugFlash=false;this.useConsole=true;this.waitForWindowLoad=this.consoleOnly=false;this.bgColor="#ffffff";this.useHighPerformance=false;this.flashPollingInterval=null;this.flashLoadTimeout=1E3;this.wmode=null;this.allowScriptAccess="always";this.useFlashBlock=
-false;this.useHTML5Audio=true;this.html5Test=/^(probably|maybe)$/i;this.preferFlash=true;this.noSWFCache=false;this.audioFormats={mp3:{type:['audio/mpeg; codecs="mp3"',"audio/mpeg","audio/mp3","audio/MPA","audio/mpa-robust"],required:true},mp4:{related:["aac","m4a"],type:['audio/mp4; codecs="mp4a.40.2"',"audio/aac","audio/x-m4a","audio/MP4A-LATM","audio/mpeg4-generic"],required:false},ogg:{type:["audio/ogg; codecs=vorbis"],required:false},wav:{type:['audio/wav; codecs="1"',"audio/wav","audio/wave",
-"audio/x-wav"],required:false}};this.defaultOptions={autoLoad:false,stream:true,autoPlay:false,loops:1,onid3:null,onload:null,whileloading:null,onplay:null,onpause:null,onresume:null,whileplaying:null,onstop:null,onfailure:null,onfinish:null,multiShot:true,multiShotEvents:false,position:null,pan:0,type:null,usePolicyFile:false,volume:100};this.flash9Options={isMovieStar:null,usePeakData:false,useWaveformData:false,useEQData:false,onbufferchange:null,ondataerror:null};this.movieStarOptions={bufferTime:3,
-serverURL:null,onconnect:null,duration:null};this.movieID="sm2-container";this.id=fa||"sm2movie";this.swfCSS={swfBox:"sm2-object-box",swfDefault:"movieContainer",swfError:"swf_error",swfTimedout:"swf_timedout",swfLoaded:"swf_loaded",swfUnblocked:"swf_unblocked",sm2Debug:"sm2_debug",highPerf:"high_performance",flashDebug:"flash_debug"};this.debugID="soundmanager-debug";this.debugURLParam=/([#?&])debug=1/i;this.versionNumber="V2.97a.20111030";this.movieURL=this.version=null;this.url=T||null;this.altURL=
-null;this.enabled=this.swfLoaded=false;this.oMC=this.o=null;this.sounds={};this.soundIDs=[];this.didFlashBlock=this.specialWmodeCase=this.muted=false;this.filePattern=null;this.filePatterns={flash8:/\.mp3(\?.*)?$/i,flash9:/\.mp3(\?.*)?$/i};this.features={buffering:false,peakData:false,waveformData:false,eqData:false,movieStar:false};this.sandbox={type:null,types:{remote:"remote (domain-based) rules",localWithFile:"local with file access (no internet access)",localWithNetwork:"local with network (internet access only, no local access)",
-localTrusted:"local, trusted (local+internet access)"},description:null,noRemote:null,noLocal:null};var J;try{J=typeof Audio!=="undefined"&&typeof(new Audio).canPlayType!=="undefined"}catch(Xa){J=false}this.hasHTML5=J;this.html5={usingFlash:null};this.flash={};this.ignoreFlash=this.html5Only=false;var ya,c=this,h="HTML5::",u,q=navigator.userAgent,i=S,K=i.location.href.toString(),g=document,ga,U,j,y=[],ha=true,r,L=false,M=false,m=false,v=false,ia=false,l,Qa=0,N,s,ja,C,D,V,za,ka,B,W,X,E,la,Y,Z,F,Aa,
-ma,Ra=["log","info","warn","error"],Ba,$,Ca,O=null,na=null,n,oa,G,Da,aa,ba,pa,o,ca=false,qa=false,Ea,Fa,w=null,Ga,da,P,z,ra,sa,Ha,p,Ia=Array.prototype.slice,Q=false,t,ea,Ja,x,Ka,ta=q.match(/(ipad|iphone|ipod)/i),Sa=q.match(/firefox/i),Ta=q.match(/droid/i),A=q.match(/msie/i),Ua=q.match(/webkit/i),R=q.match(/safari/i)&&!q.match(/chrome/i),Va=q.match(/opera/i);J=q.match(/(mobile|pre\/|xoom)/i)||ta;var ua=!K.match(/usehtml5audio/i)&&!K.match(/sm2\-ignorebadua/i)&&R&&q.match(/OS X 10_6_([3-7])/i),va=typeof console!==
-"undefined"&&typeof console.log!=="undefined",wa=typeof g.hasFocus!=="undefined"?g.hasFocus():null,H=R&&typeof g.hasFocus==="undefined",La=!H,Ma=/(mp3|mp4|mpa)/i,I=g.location?g.location.protocol.match(/http/i):null,Na=!I?"http://":"",Oa=/^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|mp4v|3gp|3g2)\s*(?:$|;)/i,Pa="mpeg4,aac,flv,mov,mp4,m4v,f4v,m4a,mp4v,3gp,3g2".split(","),Wa=RegExp("\\.("+Pa.join("|")+")(\\?.*)?$","i");this.mimePattern=/^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i;this.useAltURL=
-!I;this._global_a=null;if(J&&(c.useHTML5Audio=true,c.preferFlash=false,ta))Q=c.ignoreFlash=true;this.supported=this.ok=function(){return w?m&&!v:c.useHTML5Audio&&c.hasHTML5};this.getMovie=function(c){return u(c)||g[c]||i[c]};this.createSound=function(b){function a(){e=aa(e);c.sounds[d.id]=new ya(d);c.soundIDs.push(d.id);return c.sounds[d.id]}var e=null,f=null,d=null;if(!m||!c.ok())return pa("soundManager.createSound(): "+n(!m?"notReady":"notOK")),false;arguments.length===2&&(b={id:arguments[0],url:arguments[1]});
-d=e=s(b);d.id.toString().charAt(0).match(/^[0-9]$/)&&c._wD("soundManager.createSound(): "+n("badID",d.id),2);c._wD("soundManager.createSound(): "+d.id+" ("+d.url+")",1);if(o(d.id,true))return c._wD("soundManager.createSound(): "+d.id+" exists",1),c.sounds[d.id];if(da(d))f=a(),c._wD("Loading sound "+d.id+" via HTML5"),f._setup_html5(d);else{if(j>8){if(d.isMovieStar===null)d.isMovieStar=d.serverURL||(d.type?d.type.match(Oa):false)||d.url.match(Wa);d.isMovieStar&&c._wD("soundManager.createSound(): using MovieStar handling");
-if(d.isMovieStar){if(d.usePeakData)l("noPeak"),d.usePeakData=false;d.loops>1&&l("noNSLoop")}}d=ba(d,"soundManager.createSound(): ");f=a();if(j===8)c.o._createSound(d.id,d.loops||1,d.usePolicyFile);else if(c.o._createSound(d.id,d.url,d.usePeakData,d.useWaveformData,d.useEQData,d.isMovieStar,d.isMovieStar?d.bufferTime:false,d.loops||1,d.serverURL,d.duration||null,d.autoPlay,true,d.autoLoad,d.usePolicyFile),!d.serverURL)f.connected=true,d.onconnect&&d.onconnect.apply(f);!d.serverURL&&(d.autoLoad||d.autoPlay)&&
-f.load(d)}!d.serverURL&&d.autoPlay&&f.play();return f};this.destroySound=function(b,a){if(!o(b))return false;var e=c.sounds[b],f;e._iO={};e.stop();e.unload();for(f=0;f<c.soundIDs.length;f++)if(c.soundIDs[f]===b){c.soundIDs.splice(f,1);break}a||e.destruct(true);delete c.sounds[b];return true};this.load=function(b,a){return!o(b)?false:c.sounds[b].load(a)};this.unload=function(b){return!o(b)?false:c.sounds[b].unload()};this.onposition=function(b,a,e,f){return!o(b)?false:c.sounds[b].onposition(a,e,f)};
-this.start=this.play=function(b,a){if(!m||!c.ok())return pa("soundManager.play(): "+n(!m?"notReady":"notOK")),false;return!o(b)?(a instanceof Object||(a={url:a}),a&&a.url?(c._wD('soundManager.play(): attempting to create "'+b+'"',1),a.id=b,c.createSound(a).play()):false):c.sounds[b].play(a)};this.setPosition=function(b,a){return!o(b)?false:c.sounds[b].setPosition(a)};this.stop=function(b){if(!o(b))return false;c._wD("soundManager.stop("+b+")",1);return c.sounds[b].stop()};this.stopAll=function(){var b;
-c._wD("soundManager.stopAll()",1);for(b in c.sounds)c.sounds.hasOwnProperty(b)&&c.sounds[b].stop()};this.pause=function(b){return!o(b)?false:c.sounds[b].pause()};this.pauseAll=function(){var b;for(b=c.soundIDs.length;b--;)c.sounds[c.soundIDs[b]].pause()};this.resume=function(b){return!o(b)?false:c.sounds[b].resume()};this.resumeAll=function(){var b;for(b=c.soundIDs.length;b--;)c.sounds[c.soundIDs[b]].resume()};this.togglePause=function(b){return!o(b)?false:c.sounds[b].togglePause()};this.setPan=function(b,
-a){return!o(b)?false:c.sounds[b].setPan(a)};this.setVolume=function(b,a){return!o(b)?false:c.sounds[b].setVolume(a)};this.mute=function(b){var a=0;typeof b!=="string"&&(b=null);if(b){if(!o(b))return false;c._wD('soundManager.mute(): Muting "'+b+'"');return c.sounds[b].mute()}else{c._wD("soundManager.mute(): Muting all sounds");for(a=c.soundIDs.length;a--;)c.sounds[c.soundIDs[a]].mute();c.muted=true}return true};this.muteAll=function(){c.mute()};this.unmute=function(b){typeof b!=="string"&&(b=null);
-if(b){if(!o(b))return false;c._wD('soundManager.unmute(): Unmuting "'+b+'"');return c.sounds[b].unmute()}else{c._wD("soundManager.unmute(): Unmuting all sounds");for(b=c.soundIDs.length;b--;)c.sounds[c.soundIDs[b]].unmute();c.muted=false}return true};this.unmuteAll=function(){c.unmute()};this.toggleMute=function(b){return!o(b)?false:c.sounds[b].toggleMute()};this.getMemoryUse=function(){var b=0;c.o&&j!==8&&(b=parseInt(c.o._getMemoryUse(),10));return b};this.disable=function(b){var a;typeof b==="undefined"&&
-(b=false);if(v)return false;v=true;l("shutdown",1);for(a=c.soundIDs.length;a--;)Ba(c.sounds[c.soundIDs[a]]);N(b);p.remove(i,"load",D);return true};this.canPlayMIME=function(b){var a;c.hasHTML5&&(a=P({type:b}));return!w||a?a:b?!!(j>8&&b.match(Oa)||b.match(c.mimePattern)):null};this.canPlayURL=function(b){var a;c.hasHTML5&&(a=P({url:b}));return!w||a?a:b?!!b.match(c.filePattern):null};this.canPlayLink=function(b){return typeof b.type!=="undefined"&&b.type&&c.canPlayMIME(b.type)?true:c.canPlayURL(b.href)};
-this.getSoundById=function(b,a){if(!b)throw Error("soundManager.getSoundById(): sID is null/undefined");var e=c.sounds[b];!e&&!a&&c._wD('"'+b+'" is an invalid sound ID.',2);return e};this.onready=function(b,a){if(b&&b instanceof Function)return m&&c._wD(n("queue","onready")),a||(a=i),ja("onready",b,a),C(),true;else throw n("needFunction","onready");};this.ontimeout=function(b,a){if(b&&b instanceof Function)return m&&c._wD(n("queue","ontimeout")),a||(a=i),ja("ontimeout",b,a),C({type:"ontimeout"}),
-true;else throw n("needFunction","ontimeout");};this._wD=this._writeDebug=function(b,a,e){var f,d;if(!c.debugMode)return false;typeof e!=="undefined"&&e&&(b=b+" | "+(new Date).getTime());if(va&&c.useConsole){e=Ra[a];if(typeof console[e]!=="undefined")console[e](b);else console.log(b);if(c.useConsoleOnly)return true}try{f=u("soundmanager-debug");if(!f)return false;d=g.createElement("div");if(++Qa%2===0)d.className="sm2-alt";a=typeof a==="undefined"?0:parseInt(a,10);d.appendChild(g.createTextNode(b));
-if(a){if(a>=2)d.style.fontWeight="bold";if(a===3)d.style.color="#ff3333"}f.insertBefore(d,f.firstChild)}catch(Ya){}return true};this._debug=function(){var b,a;l("currentObj",1);for(b=0,a=c.soundIDs.length;b<a;b++)c.sounds[c.soundIDs[b]]._debug()};this.reboot=function(){c._wD("soundManager.reboot()");c.soundIDs.length&&c._wD("Destroying "+c.soundIDs.length+" SMSound objects...");var b,a;for(b=c.soundIDs.length;b--;)c.sounds[c.soundIDs[b]].destruct();try{if(A)na=c.o.innerHTML;O=c.o.parentNode.removeChild(c.o);
-c._wD("Flash movie removed.")}catch(e){l("badRemove",2)}na=O=w=null;c.enabled=la=m=ca=qa=L=M=v=c.swfLoaded=false;c.soundIDs=c.sounds=[];c.o=null;for(b in y)if(y.hasOwnProperty(b))for(a=y[b].length;a--;)y[b][a].fired=false;c._wD("soundManager: Rebooting...");i.setTimeout(c.beginDelayedInit,20)};this.getMoviePercent=function(){return c.o&&typeof c.o.PercentLoaded!=="undefined"?c.o.PercentLoaded():null};this.beginDelayedInit=function(){ia=true;E();setTimeout(function(){if(qa)return false;Z();X();return qa=
-true},20);V()};this.destruct=function(){c._wD("soundManager.destruct()");c.disable(true)};ya=function(b){var a=this,e,f,d;this.sID=b.id;this.url=b.url;this._iO=this.instanceOptions=this.options=s(b);this.pan=this.options.pan;this.volume=this.options.volume;this._lastURL=null;this.isHTML5=false;this._a=null;this.id3={};this._debug=function(){if(c.debugMode){var b=null,d=[],e,f;for(b in a.options)a.options[b]!==null&&(a.options[b]instanceof Function?(e=a.options[b].toString(),e=e.replace(/\s\s+/g," "),
-f=e.indexOf("{"),d.push(" "+b+": {"+e.substr(f+1,Math.min(Math.max(e.indexOf("\n")-1,64),64)).replace(/\n/g,"")+"... }")):d.push(" "+b+": "+a.options[b]));c._wD("SMSound() merged options: {\n"+d.join(", \n")+"\n}")}};this._debug();this.load=function(b){var d=null;if(typeof b!=="undefined")a._iO=s(b,a.options),a.instanceOptions=a._iO;else if(b=a.options,a._iO=b,a.instanceOptions=a._iO,a._lastURL&&a._lastURL!==a.url)l("manURL"),a._iO.url=a.url,a.url=null;if(!a._iO.url)a._iO.url=a.url;c._wD("SMSound.load(): "+
-a._iO.url,1);if(a._iO.url===a.url&&a.readyState!==0&&a.readyState!==2)return l("onURL",1),a;a._lastURL=a.url;a.loaded=false;a.readyState=1;a.playState=0;if(da(a._iO))d=a._setup_html5(a._iO),d._called_load?c._wD(h+"ignoring request to load again: "+a.sID):(c._wD(h+"load: "+a.sID),a._html5_canplay=false,d.load(),d._called_load=true,a._iO.autoPlay&&a.play());else try{a.isHTML5=false,a._iO=ba(aa(a._iO)),j===8?c.o._load(a.sID,a._iO.url,a._iO.stream,a._iO.autoPlay,a._iO.whileloading?1:0,a._iO.loops||1,
-a._iO.usePolicyFile):c.o._load(a.sID,a._iO.url,!!a._iO.stream,!!a._iO.autoPlay,a._iO.loops||1,!!a._iO.autoLoad,a._iO.usePolicyFile)}catch(e){l("smError",2),r("onload",false),F({type:"SMSOUND_LOAD_JS_EXCEPTION",fatal:true})}return a};this.unload=function(){a.readyState!==0&&(c._wD('SMSound.unload(): "'+a.sID+'"'),a.isHTML5?(f(),a._a&&(a._a.pause(),ra(a._a))):j===8?c.o._unload(a.sID,"about:blank"):c.o._unload(a.sID),e());return a};this.destruct=function(b){c._wD('SMSound.destruct(): "'+a.sID+'"');if(a.isHTML5){if(f(),
-a._a)a._a.pause(),ra(a._a),Q||a._remove_html5_events(),a._a._t=null,a._a=null}else a._iO.onfailure=null,c.o._destroySound(a.sID);b||c.destroySound(a.sID,true)};this.start=this.play=function(b,e){var f,e=e===void 0?true:e;b||(b={});a._iO=s(b,a._iO);a._iO=s(a._iO,a.options);a.instanceOptions=a._iO;if(a._iO.serverURL&&!a.connected)return a.getAutoPlay()||(c._wD("SMSound.play(): Netstream not connected yet - setting autoPlay"),a.setAutoPlay(true)),a;da(a._iO)&&(a._setup_html5(a._iO),d());if(a.playState===
-1&&!a.paused)if(f=a._iO.multiShot)c._wD('SMSound.play(): "'+a.sID+'" already playing (multi-shot)',1);else return c._wD('SMSound.play(): "'+a.sID+'" already playing (one-shot)',1),a;if(a.loaded)c._wD('SMSound.play(): "'+a.sID+'"');else if(a.readyState===0){c._wD('SMSound.play(): Attempting to load "'+a.sID+'"',1);if(!a.isHTML5)a._iO.autoPlay=true;a.load(a._iO)}else if(a.readyState===2)return c._wD('SMSound.play(): Could not load "'+a.sID+'" - exiting',2),a;else c._wD('SMSound.play(): "'+a.sID+'" is loading - attempting to play..',
-1);if(!a.isHTML5&&j===9&&a.position>0&&a.position===a.duration)c._wD('SMSound.play(): "'+a.sID+'": Sound at end, resetting to position:0'),a._iO.position=0;if(a.paused&&a.position&&a.position>0)c._wD('SMSound.play(): "'+a.sID+'" is resuming from paused state',1),a.resume();else{c._wD('SMSound.play(): "'+a.sID+'" is starting to play');a.playState=1;a.paused=false;(!a.instanceCount||a._iO.multiShotEvents||!a.isHTML5&&j>8&&!a.getAutoPlay())&&a.instanceCount++;a.position=typeof a._iO.position!=="undefined"&&
-!isNaN(a._iO.position)?a._iO.position:0;if(!a.isHTML5)a._iO=ba(aa(a._iO));if(a._iO.onplay&&e)a._iO.onplay.apply(a),a._onplay_called=true;a.setVolume(a._iO.volume,true);a.setPan(a._iO.pan,true);a.isHTML5?(d(),f=a._setup_html5(),a.setPosition(a._iO.position),f.play()):c.o._start(a.sID,a._iO.loops||1,j===9?a._iO.position:a._iO.position/1E3)}return a};this.stop=function(b){if(a.playState===1){a._onbufferchange(0);a.resetOnPosition(0);a.paused=false;if(!a.isHTML5)a.playState=0;a._iO.onstop&&a._iO.onstop.apply(a);
-if(a.isHTML5){if(a._a)a.setPosition(0),a._a.pause(),a.playState=0,a._onTimer(),f()}else c.o._stop(a.sID,b),a._iO.serverURL&&a.unload();a.instanceCount=0;a._iO={}}return a};this.setAutoPlay=function(b){c._wD("sound "+a.sID+" turned autoplay "+(b?"on":"off"));a._iO.autoPlay=b;a.isHTML5||(c.o._setAutoPlay(a.sID,b),b&&!a.instanceCount&&a.readyState===1&&(a.instanceCount++,c._wD("sound "+a.sID+" incremented instance count to "+a.instanceCount)))};this.getAutoPlay=function(){return a._iO.autoPlay};this.setPosition=
-function(b){b===void 0&&(b=0);var d=a.isHTML5?Math.max(b,0):Math.min(a.duration||a._iO.duration,Math.max(b,0));a.position=d;b=a.position/1E3;a.resetOnPosition(a.position);a._iO.position=d;if(a.isHTML5){if(a._a)if(a._html5_canplay){if(a._a.currentTime!==b){c._wD("setPosition("+b+"): setting position");try{a._a.currentTime=b,(a.playState===0||a.paused)&&a._a.pause()}catch(e){c._wD("setPosition("+b+"): setting position failed: "+e.message,2)}}}else c._wD("setPosition("+b+"): delaying, sound not ready")}else b=
-j===9?a.position:b,a.readyState&&a.readyState!==2&&c.o._setPosition(a.sID,b,a.paused||!a.playState);a.isHTML5&&a.paused&&a._onTimer(true);return a};this.pause=function(b){if(a.paused||a.playState===0&&a.readyState!==1)return a;c._wD("SMSound.pause()");a.paused=true;a.isHTML5?(a._setup_html5().pause(),f()):(b||b===void 0)&&c.o._pause(a.sID);a._iO.onpause&&a._iO.onpause.apply(a);return a};this.resume=function(){if(!a.paused)return a;c._wD("SMSound.resume()");a.paused=false;a.playState=1;a.isHTML5?(a._setup_html5().play(),
-d()):(a._iO.isMovieStar&&a.setPosition(a.position),c.o._pause(a.sID));!a._onplay_called&&a._iO.onplay?(a._iO.onplay.apply(a),a._onplay_called=true):a._iO.onresume&&a._iO.onresume.apply(a);return a};this.togglePause=function(){c._wD("SMSound.togglePause()");if(a.playState===0)return a.play({position:j===9&&!a.isHTML5?a.position:a.position/1E3}),a;a.paused?a.resume():a.pause();return a};this.setPan=function(b,d){typeof b==="undefined"&&(b=0);typeof d==="undefined"&&(d=false);a.isHTML5||c.o._setPan(a.sID,
-b);a._iO.pan=b;if(!d)a.pan=b,a.options.pan=b;return a};this.setVolume=function(b,d){typeof b==="undefined"&&(b=100);typeof d==="undefined"&&(d=false);if(a.isHTML5){if(a._a)a._a.volume=Math.max(0,Math.min(1,b/100))}else c.o._setVolume(a.sID,c.muted&&!a.muted||a.muted?0:b);a._iO.volume=b;if(!d)a.volume=b,a.options.volume=b;return a};this.mute=function(){a.muted=true;if(a.isHTML5){if(a._a)a._a.muted=true}else c.o._setVolume(a.sID,0);return a};this.unmute=function(){a.muted=false;var b=typeof a._iO.volume!==
-"undefined";if(a.isHTML5){if(a._a)a._a.muted=false}else c.o._setVolume(a.sID,b?a._iO.volume:a.options.volume);return a};this.toggleMute=function(){return a.muted?a.unmute():a.mute()};this.onposition=function(c,b,d){a._onPositionItems.push({position:c,method:b,scope:typeof d!=="undefined"?d:a,fired:false});return a};this.processOnPosition=function(){var b,d;b=a._onPositionItems.length;if(!b||!a.playState||a._onPositionFired>=b)return false;for(;b--;)if(d=a._onPositionItems[b],!d.fired&&a.position>=
-d.position)d.fired=true,c._onPositionFired++,d.method.apply(d.scope,[d.position]);return true};this.resetOnPosition=function(b){var d,e;d=a._onPositionItems.length;if(!d)return false;for(;d--;)if(e=a._onPositionItems[d],e.fired&&b<=e.position)e.fired=false,c._onPositionFired--;return true};d=function(){a.isHTML5&&Ea(a)};f=function(){a.isHTML5&&Fa(a)};e=function(){a._onPositionItems=[];a._onPositionFired=0;a._hasTimer=null;a._onplay_called=false;a._a=null;a._html5_canplay=false;a.bytesLoaded=null;
-a.bytesTotal=null;a.position=null;a.duration=a._iO&&a._iO.duration?a._iO.duration:null;a.durationEstimate=null;a.failures=0;a.loaded=false;a.playState=0;a.paused=false;a.readyState=0;a.muted=false;a.isBuffering=false;a.instanceOptions={};a.instanceCount=0;a.peakData={left:0,right:0};a.waveformData={left:[],right:[]};a.eqData=[];a.eqData.left=[];a.eqData.right=[]};e();this._onTimer=function(b){var d={};if(a._hasTimer||b)return a._a&&(b||(a.playState>0||a.readyState===1)&&!a.paused)?(a.duration=a._get_html5_duration(),
-a.durationEstimate=a.duration,b=a._a.currentTime?a._a.currentTime*1E3:0,a._whileplaying(b,d,d,d,d),true):(c._wD('_onTimer: Warn for "'+a.sID+'": '+(!a._a?"Could not find element. ":"")+(a.playState===0?"playState bad, 0?":"playState = "+a.playState+", OK")),false)};this._get_html5_duration=function(){var c=a._a?a._a.duration*1E3:a._iO?a._iO.duration:void 0;return c&&!isNaN(c)&&c!==Infinity?c:a._iO?a._iO.duration:null};this._setup_html5=function(b){var b=s(a._iO,b),d=Q?c._global_a:a._a,f=decodeURI(b.url),
-g=d&&d._t?d._t.instanceOptions:null;if(d){if(d._t&&g.url===b.url&&(!a._lastURL||a._lastURL===g.url))return d;c._wD("setting new URL on existing object: "+f+(a._lastURL?", old URL: "+a._lastURL:""));Q&&d._t&&d._t.playState&&b.url!==g.url&&d._t.stop();e();d.src=b.url;a.url=b.url;a._lastURL=b.url;d._called_load=false}else{c._wD("creating HTML5 Audio() element with URL: "+f);d=new Audio(b.url);d._called_load=false;if(Ta)d._called_load=true;if(Q)c._global_a=d}a.isHTML5=true;a._a=d;d._t=a;a._add_html5_events();
-d.loop=b.loops>1?"loop":"";b.autoLoad||b.autoPlay?(d.autobuffer="auto",d.preload="auto",a.load(),d._called_load=true):(d.autobuffer=false,d.preload="none");d.loop=b.loops>1?"loop":"";return d};this._add_html5_events=function(){if(a._a._added_events)return false;var b;c._wD(h+"adding event listeners: "+a.sID);a._a._added_events=true;for(b in x)x.hasOwnProperty(b)&&a._a&&a._a.addEventListener(b,x[b],false);return true};this._remove_html5_events=function(){var b;c._wD(h+"removing event listeners: "+
-a.sID);a._a._added_events=false;for(b in x)x.hasOwnProperty(b)&&a._a&&a._a.removeEventListener(b,x[b],false)};this._onload=function(b){b=!!b;c._wD('SMSound._onload(): "'+a.sID+'"'+(b?" loaded.":" failed to load? - "+a.url),b?1:2);!b&&!a.isHTML5&&(c.sandbox.noRemote===true&&c._wD("SMSound._onload(): "+n("noNet"),1),c.sandbox.noLocal===true&&c._wD("SMSound._onload(): "+n("noLocal"),1));a.loaded=b;a.readyState=b?3:2;a._onbufferchange(0);a._iO.onload&&a._iO.onload.apply(a,[b]);return true};this._onbufferchange=
-function(b){if(a.playState===0)return false;if(b&&a.isBuffering||!b&&!a.isBuffering)return false;a.isBuffering=b===1;a._iO.onbufferchange&&(c._wD("SMSound._onbufferchange(): "+b),a._iO.onbufferchange.apply(a));return true};this._onsuspend=function(){a._iO.onsuspend&&(c._wD("SMSound._onsuspend()"),a._iO.onsuspend.apply(a));return true};this._onfailure=function(b,d,e){a.failures++;c._wD('SMSound._onfailure(): "'+a.sID+'" count '+a.failures);if(a._iO.onfailure&&a.failures===1)a._iO.onfailure(a,b,d,e);
-else c._wD("SMSound._onfailure(): ignoring")};this._onfinish=function(){var b=a._iO.onfinish;a._onbufferchange(0);a.resetOnPosition(0);if(a.instanceCount){a.instanceCount--;if(!a.instanceCount)a.playState=0,a.paused=false,a.instanceCount=0,a.instanceOptions={},a._iO={},f();if((!a.instanceCount||a._iO.multiShotEvents)&&b)c._wD('SMSound._onfinish(): "'+a.sID+'"'),b.apply(a)}};this._whileloading=function(c,b,d,e){a.bytesLoaded=c;a.bytesTotal=b;a.duration=Math.floor(d);a.bufferLength=e;if(a._iO.isMovieStar)a.durationEstimate=
-a.duration;else if(a.durationEstimate=a._iO.duration?a.duration>a._iO.duration?a.duration:a._iO.duration:parseInt(a.bytesTotal/a.bytesLoaded*a.duration,10),a.durationEstimate===void 0)a.durationEstimate=a.duration;a.readyState!==3&&a._iO.whileloading&&a._iO.whileloading.apply(a)};this._whileplaying=function(c,b,d,e,f){if(isNaN(c)||c===null)return false;a.position=c;a.processOnPosition();if(!a.isHTML5&&j>8){if(a._iO.usePeakData&&typeof b!=="undefined"&&b)a.peakData={left:b.leftPeak,right:b.rightPeak};
-if(a._iO.useWaveformData&&typeof d!=="undefined"&&d)a.waveformData={left:d.split(","),right:e.split(",")};if(a._iO.useEQData&&typeof f!=="undefined"&&f&&f.leftEQ&&(c=f.leftEQ.split(","),a.eqData=c,a.eqData.left=c,typeof f.rightEQ!=="undefined"&&f.rightEQ))a.eqData.right=f.rightEQ.split(",")}a.playState===1&&(!a.isHTML5&&j===8&&!a.position&&a.isBuffering&&a._onbufferchange(0),a._iO.whileplaying&&a._iO.whileplaying.apply(a));return true};this._onid3=function(b,d){c._wD('SMSound._onid3(): "'+this.sID+
-'" ID3 data received.');var e=[],f,g;for(f=0,g=b.length;f<g;f++)e[b[f]]=d[f];a.id3=s(a.id3,e);a._iO.onid3&&a._iO.onid3.apply(a)};this._onconnect=function(b){b=b===1;c._wD('SMSound._onconnect(): "'+a.sID+'"'+(b?" connected.":" failed to connect? - "+a.url),b?1:2);if(a.connected=b)a.failures=0,o(a.sID)&&(a.getAutoPlay()?a.play(void 0,a.getAutoPlay()):a._iO.autoLoad&&a.load()),a._iO.onconnect&&a._iO.onconnect.apply(a,[b])};this._ondataerror=function(b){a.playState>0&&(c._wD("SMSound._ondataerror(): "+
-b),a._iO.ondataerror&&a._iO.ondataerror.apply(a))}};Y=function(){return g.body||g._docElement||g.getElementsByTagName("div")[0]};u=function(b){return g.getElementById(b)};s=function(b,a){var e={},f,d;for(f in b)b.hasOwnProperty(f)&&(e[f]=b[f]);f=typeof a==="undefined"?c.defaultOptions:a;for(d in f)f.hasOwnProperty(d)&&typeof e[d]==="undefined"&&(e[d]=f[d]);return e};p=function(){function b(a){var a=Ia.call(a),b=a.length;c?(a[1]="on"+a[1],b>3&&a.pop()):b===3&&a.push(false);return a}function a(a,b){var g=
-a.shift(),j=[f[b]];if(c)g[j](a[0],a[1]);else g[j].apply(g,a)}var c=i.attachEvent,f={add:c?"attachEvent":"addEventListener",remove:c?"detachEvent":"removeEventListener"};return{add:function(){a(b(arguments),"add")},remove:function(){a(b(arguments),"remove")}}}();x={abort:k(function(){c._wD(h+"abort: "+this._t.sID)}),canplay:k(function(){if(this._t._html5_canplay)return true;this._t._html5_canplay=true;c._wD(h+"canplay: "+this._t.sID+", "+this._t.url);this._t._onbufferchange(0);var b=!isNaN(this._t.position)?
-this._t.position/1E3:null;if(this._t.position&&this.currentTime!==b){c._wD(h+"canplay: setting position to "+b);try{this.currentTime=b}catch(a){c._wD(h+"setting position failed: "+a.message,2)}}}),load:k(function(){this._t.loaded||(this._t._onbufferchange(0),this._t._whileloading(this._t.bytesTotal,this._t.bytesTotal,this._t._get_html5_duration()),this._t._onload(true))}),emptied:k(function(){c._wD(h+"emptied: "+this._t.sID)}),ended:k(function(){c._wD(h+"ended: "+this._t.sID);this._t._onfinish()}),
-error:k(function(){c._wD(h+"error: "+this.error.code);this._t._onload(false)}),loadeddata:k(function(){var b=this._t,a=b.bytesTotal||1;c._wD(h+"loadeddata: "+this._t.sID);if(!b._loaded&&!R)b.duration=b._get_html5_duration(),b._whileloading(a,a,b._get_html5_duration()),b._onload(true)}),loadedmetadata:k(function(){c._wD(h+"loadedmetadata: "+this._t.sID)}),loadstart:k(function(){c._wD(h+"loadstart: "+this._t.sID);this._t._onbufferchange(1)}),play:k(function(){c._wD(h+"play: "+this._t.sID+", "+this._t.url);
-this._t._onbufferchange(0)}),playing:k(function(){c._wD(h+"playing: "+this._t.sID+", "+this._t.url);this._t._onbufferchange(0)}),progress:k(function(b){if(this._t.loaded)return false;var a,e,f;f=0;var d=b.type==="progress";e=b.target.buffered;var g=b.loaded||0,xa=b.total||1;if(e&&e.length){for(a=e.length;a--;)f=e.end(a)-e.start(a);g=f/b.target.duration;if(d&&e.length>1){f=[];e=e.length;for(a=0;a<e;a++)f.push(b.target.buffered.start(a)+"-"+b.target.buffered.end(a));c._wD(h+"progress: timeRanges: "+
-f.join(", "))}d&&!isNaN(g)&&c._wD(h+"progress: "+this._t.sID+": "+Math.floor(g*100)+"% loaded")}isNaN(g)||(this._t._onbufferchange(0),this._t._whileloading(g,xa,this._t._get_html5_duration()),g&&xa&&g===xa&&x.load.call(this,b))}),ratechange:k(function(){c._wD(h+"ratechange: "+this._t.sID)}),suspend:k(function(b){c._wD(h+"suspend: "+this._t.sID);x.progress.call(this,b);this._t._onsuspend()}),stalled:k(function(){c._wD(h+"stalled: "+this._t.sID)}),timeupdate:k(function(){this._t._onTimer()}),waiting:k(function(){c._wD(h+
-"waiting: "+this._t.sID);this._t._onbufferchange(1)})};da=function(b){return!b.serverURL&&(b.type?P({type:b.type}):P({url:b.url})||c.html5Only)};ra=function(b){if(b)b.src=Sa?"":"about:blank"};P=function(b){function a(a){return c.preferFlash&&t&&!c.ignoreFlash&&typeof c.flash[a]!=="undefined"&&c.flash[a]}if(!c.useHTML5Audio||!c.hasHTML5)return false;var e=b.url||null,b=b.type||null,f=c.audioFormats,d;if(b&&c.html5[b]!=="undefined")return c.html5[b]&&!a(b);if(!z){z=[];for(d in f)f.hasOwnProperty(d)&&
-(z.push(d),f[d].related&&(z=z.concat(f[d].related)));z=RegExp("\\.("+z.join("|")+")(\\?.*)?$","i")}d=e?e.toLowerCase().match(z):null;if(!d||!d.length)if(b)e=b.indexOf(";"),d=(e!==-1?b.substr(0,e):b).substr(6);else return false;else d=d[1];return d&&typeof c.html5[d]!=="undefined"?c.html5[d]&&!a(d):(b="audio/"+d,e=c.html5.canPlayType({type:b}),(c.html5[d]=e)&&c.html5[b]&&!a(b))};Ha=function(){function b(b){var d,e,f=false;if(!a||typeof a.canPlayType!=="function")return false;if(b instanceof Array){for(d=
-0,e=b.length;d<e&&!f;d++)if(c.html5[b[d]]||a.canPlayType(b[d]).match(c.html5Test))f=true,c.html5[b[d]]=true,c.flash[b[d]]=!(!c.preferFlash||!t||!b[d].match(Ma));return f}else return b=a&&typeof a.canPlayType==="function"?a.canPlayType(b):false,!(!b||!b.match(c.html5Test))}if(!c.useHTML5Audio||typeof Audio==="undefined")return false;var a=typeof Audio!=="undefined"?Va?new Audio(null):new Audio:null,e,f={},d,g;d=c.audioFormats;for(e in d)if(d.hasOwnProperty(e)&&(f[e]=b(d[e].type),f["audio/"+e]=f[e],
-c.flash[e]=c.preferFlash&&!c.ignoreFlash&&e.match(Ma)?true:false,d[e]&&d[e].related))for(g=d[e].related.length;g--;)f["audio/"+d[e].related[g]]=f[e],c.html5[d[e].related[g]]=f[e],c.flash[d[e].related[g]]=f[e];f.canPlayType=a?b:null;c.html5=s(c.html5,f);return true};W={notReady:"Not loaded yet - wait for soundManager.onload()/onready()",notOK:"Audio support is not available.",domError:"soundManager::createMovie(): appendChild/innerHTML call failed. DOM not ready or other error.",spcWmode:"soundManager::createMovie(): Removing wmode, preventing known SWF loading issue(s)",
-swf404:"soundManager: Verify that %s is a valid path.",tryDebug:"Try soundManager.debugFlash = true for more security details (output goes to SWF.)",checkSWF:"See SWF output for more debug info.",localFail:"soundManager: Non-HTTP page ("+g.location.protocol+" URL?) Review Flash player security settings for this special case:\nhttp://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html\nMay need to add/allow path, eg. c:/sm2/ or /users/me/sm2/",waitFocus:"soundManager: Special case: Waiting for focus-related event..",
-waitImpatient:"soundManager: Getting impatient, still waiting for Flash%s...",waitForever:"soundManager: Waiting indefinitely for Flash (will recover if unblocked)...",needFunction:"soundManager: Function object expected for %s",badID:'Warning: Sound ID "%s" should be a string, starting with a non-numeric character',currentObj:"--- soundManager._debug(): Current sound objects ---",waitEI:"soundManager::initMovie(): Waiting for ExternalInterface call from Flash..",waitOnload:"soundManager: Waiting for window.onload()",
-docLoaded:"soundManager: Document already loaded",onload:"soundManager::initComplete(): calling soundManager.onload()",onloadOK:"soundManager.onload() complete",init:"soundManager::init()",didInit:"soundManager::init(): Already called?",flashJS:"soundManager: Attempting to call Flash from JS..",secNote:"Flash security note: Network/internet URLs will not load due to security restrictions. Access can be configured via Flash Player Global Security Settings Page: http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html",
-badRemove:"Warning: Failed to remove flash movie.",noPeak:"Warning: peakData features unsupported for movieStar formats",shutdown:"soundManager.disable(): Shutting down",queue:"soundManager: Queueing %s handler",smFail:"soundManager: Failed to initialise.",smError:"SMSound.load(): Exception: JS-Flash communication failed, or JS error.",fbTimeout:"No flash response, applying ."+c.swfCSS.swfTimedout+" CSS..",fbLoaded:"Flash loaded",fbHandler:"soundManager::flashBlockHandler()",manURL:"SMSound.load(): Using manually-assigned URL",
-onURL:"soundManager.load(): current URL already assigned.",badFV:'soundManager.flashVersion must be 8 or 9. "%s" is invalid. Reverting to %s.',as2loop:"Note: Setting stream:false so looping can work (flash 8 limitation)",noNSLoop:"Note: Looping not implemented for MovieStar formats",needfl9:"Note: Switching to flash 9, required for MP4 formats.",mfTimeout:"Setting flashLoadTimeout = 0 (infinite) for off-screen, mobile flash case",mfOn:"mobileFlash::enabling on-screen flash repositioning",policy:"Enabling usePolicyFile for data access"};
-n=function(){var b=Ia.call(arguments),a=b.shift(),a=W&&W[a]?W[a]:"",c,f;if(a&&b&&b.length)for(c=0,f=b.length;c<f;c++)a=a.replace("%s",b[c]);return a};aa=function(b){if(j===8&&b.loops>1&&b.stream)l("as2loop"),b.stream=false;return b};ba=function(b,a){if(b&&!b.usePolicyFile&&(b.onid3||b.usePeakData||b.useWaveformData||b.useEQData))c._wD((a||"")+n("policy")),b.usePolicyFile=true;return b};pa=function(b){typeof console!=="undefined"&&typeof console.warn!=="undefined"?console.warn(b):c._wD(b)};ga=function(){return false};
-Ba=function(b){for(var a in b)b.hasOwnProperty(a)&&typeof b[a]==="function"&&(b[a]=ga)};$=function(b){typeof b==="undefined"&&(b=false);if(v||b)l("smFail",2),c.disable(b)};Ca=function(b){var a=null;if(b)if(b.match(/\.swf(\?.*)?$/i)){if(a=b.substr(b.toLowerCase().lastIndexOf(".swf?")+4))return b}else b.lastIndexOf("/")!==b.length-1&&(b+="/");b=(b&&b.lastIndexOf("/")!==-1?b.substr(0,b.lastIndexOf("/")+1):"./")+c.movieURL;c.noSWFCache&&(b+="?ts="+(new Date).getTime());return b};ka=function(){j=parseInt(c.flashVersion,
-10);if(j!==8&&j!==9)c._wD(n("badFV",j,8)),c.flashVersion=j=8;var b=c.debugMode||c.debugFlash?"_debug.swf":".swf";if(c.useHTML5Audio&&!c.html5Only&&c.audioFormats.mp4.required&&j<9)c._wD(n("needfl9")),c.flashVersion=j=9;c.version=c.versionNumber+(c.html5Only?" (HTML5-only mode)":j===9?" (AS3/Flash 9)":" (AS2/Flash 8)");j>8?(c.defaultOptions=s(c.defaultOptions,c.flash9Options),c.features.buffering=true,c.defaultOptions=s(c.defaultOptions,c.movieStarOptions),c.filePatterns.flash9=RegExp("\\.(mp3|"+Pa.join("|")+
-")(\\?.*)?$","i"),c.features.movieStar=true):c.features.movieStar=false;c.filePattern=c.filePatterns[j!==8?"flash9":"flash8"];c.movieURL=(j===8?"soundmanager2.swf":"soundmanager2_flash9.swf").replace(".swf",b);c.features.peakData=c.features.waveformData=c.features.eqData=j>8};Aa=function(b,a){if(!c.o)return false;c.o._setPolling(b,a)};ma=function(){if(c.debugURLParam.test(K))c.debugMode=true;if(u(c.debugID))return false;var b,a,e,f;if(c.debugMode&&!u(c.debugID)&&(!va||!c.useConsole||c.useConsole&&
-va&&!c.consoleOnly)){b=g.createElement("div");b.id=c.debugID+"-toggle";a={position:"fixed",bottom:"0px",right:"0px",width:"1.2em",height:"1.2em",lineHeight:"1.2em",margin:"2px",textAlign:"center",border:"1px solid #999",cursor:"pointer",background:"#fff",color:"#333",zIndex:10001};b.appendChild(g.createTextNode("-"));b.onclick=Da;b.title="Toggle SM2 debug console";if(q.match(/msie 6/i))b.style.position="absolute",b.style.cursor="hand";for(f in a)a.hasOwnProperty(f)&&(b.style[f]=a[f]);a=g.createElement("div");
-a.id=c.debugID;a.style.display=c.debugMode?"block":"none";if(c.debugMode&&!u(b.id)){try{e=Y(),e.appendChild(b)}catch(d){throw Error(n("domError")+" \n"+d.toString());}e.appendChild(a)}}};o=this.getSoundById;l=function(b,a){return b?c._wD(n(b),a):""};if(K.indexOf("sm2-debug=alert")+1&&c.debugMode)c._wD=function(b){S.alert(b)};Da=function(){var b=u(c.debugID),a=u(c.debugID+"-toggle");if(!b)return false;ha?(a.innerHTML="+",b.style.display="none"):(a.innerHTML="-",b.style.display="block");ha=!ha};r=function(b,
-a,c){if(typeof sm2Debugger!=="undefined")try{sm2Debugger.handleEvent(b,a,c)}catch(f){}return true};G=function(){var b=[];c.debugMode&&b.push(c.swfCSS.sm2Debug);c.debugFlash&&b.push(c.swfCSS.flashDebug);c.useHighPerformance&&b.push(c.swfCSS.highPerf);return b.join(" ")};oa=function(){var b=n("fbHandler"),a=c.getMoviePercent(),e=c.swfCSS,f={type:"FLASHBLOCK"};if(c.html5Only)return false;if(c.ok()){if(c.didFlashBlock&&c._wD(b+": Unblocked"),c.oMC)c.oMC.className=[G(),e.swfDefault,e.swfLoaded+(c.didFlashBlock?
-" "+e.swfUnblocked:"")].join(" ")}else{if(w)c.oMC.className=G()+" "+e.swfDefault+" "+(a===null?e.swfTimedout:e.swfError),c._wD(b+": "+n("fbTimeout")+(a?" ("+n("fbLoaded")+")":""));c.didFlashBlock=true;C({type:"ontimeout",ignoreInit:true,error:f});F(f)}};ja=function(b,a,c){typeof y[b]==="undefined"&&(y[b]=[]);y[b].push({method:a,scope:c||null,fired:false})};C=function(b){b||(b={type:"onready"});if(!m&&b&&!b.ignoreInit)return false;if(b.type==="ontimeout"&&c.ok())return false;var a={success:b&&b.ignoreInit?
-c.ok():!v},e=b&&b.type?y[b.type]||[]:[],f=[],d,g=[a],j=w&&c.useFlashBlock&&!c.ok();if(b.error)g[0].error=b.error;for(a=0,d=e.length;a<d;a++)e[a].fired!==true&&f.push(e[a]);if(f.length){c._wD("soundManager: Firing "+f.length+" "+b.type+"() item"+(f.length===1?"":"s"));for(a=0,d=f.length;a<d;a++)if(f[a].scope?f[a].method.apply(f[a].scope,g):f[a].method.apply(this,g),!j)f[a].fired=true}return true};D=function(){i.setTimeout(function(){c.useFlashBlock&&oa();C();c.onload instanceof Function&&(l("onload",
-1),c.onload.apply(i),l("onloadOK",1));c.waitForWindowLoad&&p.add(i,"load",D)},1)};ea=function(){if(t!==void 0)return t;var b=false,a=navigator,c=a.plugins,f,d=i.ActiveXObject;if(c&&c.length)(a=a.mimeTypes)&&a["application/x-shockwave-flash"]&&a["application/x-shockwave-flash"].enabledPlugin&&a["application/x-shockwave-flash"].enabledPlugin.description&&(b=true);else if(typeof d!=="undefined"){try{f=new d("ShockwaveFlash.ShockwaveFlash")}catch(g){}b=!!f}return t=b};Ga=function(){var b,a;if(ta&&q.match(/os (1|2|3_0|3_1)/i)){c.hasHTML5=
-false;c.html5Only=true;if(c.oMC)c.oMC.style.display="none";return false}if(c.useHTML5Audio){if(!c.html5||!c.html5.canPlayType)return c._wD("SoundManager: No HTML5 Audio() support detected."),c.hasHTML5=false,true;else c.hasHTML5=true;if(ua&&(c._wD("soundManager::Note: Buggy HTML5 Audio in Safari on this OS X release, see https://bugs.webkit.org/show_bug.cgi?id=32159 - "+(!t?" would use flash fallback for MP3/MP4, but none detected.":"will use flash fallback for MP3/MP4, if available"),1),ea()))return true}else return true;
-for(a in c.audioFormats)if(c.audioFormats.hasOwnProperty(a)&&(c.audioFormats[a].required&&!c.html5.canPlayType(c.audioFormats[a].type)||c.flash[a]||c.flash[c.audioFormats[a].type]))b=true;c.ignoreFlash&&(b=false);c.html5Only=c.hasHTML5&&c.useHTML5Audio&&!b;return!c.html5Only};Ea=function(b){if(!b._hasTimer)b._hasTimer=true};Fa=function(b){if(b._hasTimer)b._hasTimer=false};F=function(b){b=typeof b!=="undefined"?b:{};c.onerror instanceof Function&&c.onerror.apply(i,[{type:typeof b.type!=="undefined"?
-b.type:null}]);typeof b.fatal!=="undefined"&&b.fatal&&c.disable()};Ja=function(){if(!ua||!ea())return false;var b=c.audioFormats,a,e;for(e in b)if(b.hasOwnProperty(e)&&(e==="mp3"||e==="mp4"))if(c._wD("soundManager: Using flash fallback for "+e+" format"),c.html5[e]=false,b[e]&&b[e].related)for(a=b[e].related.length;a--;)c.html5[b[e].related[a]]=false};this._setSandboxType=function(b){var a=c.sandbox;a.type=b;a.description=a.types[typeof a.types[b]!=="undefined"?b:"unknown"];c._wD("Flash security sandbox type: "+
-a.type);if(a.type==="localWithFile")a.noRemote=true,a.noLocal=false,l("secNote",2);else if(a.type==="localWithNetwork")a.noRemote=false,a.noLocal=true;else if(a.type==="localTrusted")a.noRemote=false,a.noLocal=false};this._externalInterfaceOK=function(b){if(c.swfLoaded)return false;var a=(new Date).getTime();c._wD("soundManager::externalInterfaceOK()"+(b?" (~"+(a-b)+" ms)":""));r("swf",true);r("flashtojs",true);c.swfLoaded=true;H=false;ua&&Ja();A?setTimeout(U,100):U()};Z=function(b,a){function e(){c._wD("-- SoundManager 2 "+
-c.version+(!c.html5Only&&c.useHTML5Audio?c.hasHTML5?" + HTML5 audio":", no HTML5 audio support":"")+(!c.html5Only?(c.useHighPerformance?", high performance mode, ":", ")+((c.flashPollingInterval?"custom ("+c.flashPollingInterval+"ms)":"normal")+" polling")+(c.wmode?", wmode: "+c.wmode:"")+(c.debugFlash?", flash debug mode":"")+(c.useFlashBlock?", flashBlock mode":""):"")+" --",1)}function f(a,b){return'<param name="'+a+'" value="'+b+'" />'}if(L&&M)return false;if(c.html5Only)return ka(),e(),c.oMC=
-u(c.movieID),U(),M=L=true,false;var d=a||c.url,j=c.altURL||d,h;h=Y();var i,o,k=G(),m,p=null,p=(p=g.getElementsByTagName("html")[0])&&p.dir&&p.dir.match(/rtl/i),b=typeof b==="undefined"?c.id:b;ka();c.url=Ca(I?d:j);a=c.url;c.wmode=!c.wmode&&c.useHighPerformance?"transparent":c.wmode;if(c.wmode!==null&&(q.match(/msie 8/i)||!A&&!c.useHighPerformance)&&navigator.platform.match(/win32|win64/i))c.specialWmodeCase=true,l("spcWmode"),c.wmode=null;h={name:b,id:b,src:a,width:"auto",height:"auto",quality:"high",
-allowScriptAccess:c.allowScriptAccess,bgcolor:c.bgColor,pluginspage:Na+"www.macromedia.com/go/getflashplayer",title:"JS/Flash audio component (SoundManager 2)",type:"application/x-shockwave-flash",wmode:c.wmode,hasPriority:"true"};if(c.debugFlash)h.FlashVars="debug=1";c.wmode||delete h.wmode;if(A)d=g.createElement("div"),o=['<object id="'+b+'" data="'+a+'" type="'+h.type+'" title="'+h.title+'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="'+Na+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" width="'+
-h.width+'" height="'+h.height+'">',f("movie",a),f("AllowScriptAccess",c.allowScriptAccess),f("quality",h.quality),c.wmode?f("wmode",c.wmode):"",f("bgcolor",c.bgColor),f("hasPriority","true"),c.debugFlash?f("FlashVars",h.FlashVars):"","</object>"].join("");else for(i in d=g.createElement("embed"),h)h.hasOwnProperty(i)&&d.setAttribute(i,h[i]);ma();k=G();if(h=Y())if(c.oMC=u(c.movieID)||g.createElement("div"),c.oMC.id){m=c.oMC.className;c.oMC.className=(m?m+" ":c.swfCSS.swfDefault)+(k?" "+k:"");c.oMC.appendChild(d);
-if(A)i=c.oMC.appendChild(g.createElement("div")),i.className=c.swfCSS.swfBox,i.innerHTML=o;M=true}else{c.oMC.id=c.movieID;c.oMC.className=c.swfCSS.swfDefault+" "+k;i=k=null;if(!c.useFlashBlock)if(c.useHighPerformance)k={position:"fixed",width:"8px",height:"8px",bottom:"0px",left:"0px",overflow:"hidden"};else if(k={position:"absolute",width:"6px",height:"6px",top:"-9999px",left:"-9999px"},p)k.left=Math.abs(parseInt(k.left,10))+"px";if(Ua)c.oMC.style.zIndex=1E4;if(!c.debugFlash)for(m in k)k.hasOwnProperty(m)&&
-(c.oMC.style[m]=k[m]);try{A||c.oMC.appendChild(d);h.appendChild(c.oMC);if(A)i=c.oMC.appendChild(g.createElement("div")),i.className=c.swfCSS.swfBox,i.innerHTML=o;M=true}catch(r){throw Error(n("domError")+" \n"+r.toString());}}L=true;e();c._wD("soundManager::createMovie(): Trying to load "+a+(!I&&c.altURL?" (alternate URL)":""),1);return true};X=function(){if(c.html5Only)return Z(),false;if(c.o)return false;c.o=c.getMovie(c.id);if(!c.o)O?(A?c.oMC.innerHTML=na:c.oMC.appendChild(O),O=null,L=true):Z(c.id,
-c.url),c.o=c.getMovie(c.id);c.o&&l("waitEI");c.oninitmovie instanceof Function&&setTimeout(c.oninitmovie,1);return true};V=function(){setTimeout(za,1E3)};za=function(){if(ca)return false;ca=true;p.remove(i,"load",V);if(H&&!wa)return l("waitFocus"),false;var b;m||(b=c.getMoviePercent(),c._wD(n("waitImpatient",b===100?" (SWF loaded)":b>0?" (SWF "+b+"% loaded)":"")));setTimeout(function(){b=c.getMoviePercent();m||(c._wD("soundManager: No Flash response within expected time.\nLikely causes: "+(b===0?
-"Loading "+c.movieURL+" may have failed (and/or Flash "+j+"+ not present?), ":"")+"Flash blocked or JS-Flash security error."+(c.debugFlash?" "+n("checkSWF"):""),2),!I&&b&&(l("localFail",2),c.debugFlash||l("tryDebug",2)),b===0&&c._wD(n("swf404",c.url)),r("flashtojs",false,": Timed out"+I?" (Check flash security or flash blockers)":" (No plugin/missing SWF?)"));!m&&La&&(b===null?c.useFlashBlock||c.flashLoadTimeout===0?(c.useFlashBlock&&oa(),l("waitForever")):$(true):c.flashLoadTimeout===0?l("waitForever"):
-$(true))},c.flashLoadTimeout)};B=function(){function b(){p.remove(i,"focus",B);p.remove(i,"load",B)}if(wa||!H)return b(),true;wa=La=true;c._wD("soundManager::handleFocus()");R&&H&&p.remove(i,"mousemove",B);ca=false;b();return true};Ka=function(){var b,a=[];if(c.useHTML5Audio&&c.hasHTML5){for(b in c.audioFormats)c.audioFormats.hasOwnProperty(b)&&a.push(b+": "+c.html5[b]+(!c.html5[b]&&t&&c.flash[b]?" (using flash)":c.preferFlash&&c.flash[b]&&t?" (preferring flash)":!c.html5[b]?" ("+(c.audioFormats[b].required?
-"required, ":"")+"and no flash support)":""));c._wD("-- SoundManager 2: HTML5 support tests ("+c.html5Test+"): "+a.join(", ")+" --",1)}};N=function(b){if(m)return false;if(c.html5Only)return c._wD("-- SoundManager 2: loaded --"),m=true,D(),r("onload",true),true;var a;if(!c.useFlashBlock||!c.flashLoadTimeout||c.getMoviePercent())m=true,v&&(a={type:!t&&w?"NO_FLASH":"INIT_TIMEOUT"});c._wD("-- SoundManager 2 "+(v?"failed to load":"loaded")+" ("+(v?"security/load error":"OK")+") --",1);if(v||b){if(c.useFlashBlock&&
-c.oMC)c.oMC.className=G()+" "+(c.getMoviePercent()===null?c.swfCSS.swfTimedout:c.swfCSS.swfError);C({type:"ontimeout",error:a});r("onload",false);F(a);return false}else r("onload",true);if(c.waitForWindowLoad&&!ia)return l("waitOnload"),p.add(i,"load",D),false;else c.waitForWindowLoad&&ia&&l("docLoaded"),D();return true};U=function(){l("init");if(m)return l("didInit"),false;if(c.html5Only){if(!m)p.remove(i,"load",c.beginDelayedInit),c.enabled=true,N();return true}X();try{l("flashJS"),c.o._externalInterfaceTest(false),
-Aa(true,c.flashPollingInterval||(c.useHighPerformance?10:50)),c.debugMode||c.o._disableDebug(),c.enabled=true,r("jstoflash",true),c.html5Only||p.add(i,"unload",ga)}catch(b){return c._wD("js/flash exception: "+b.toString()),r("jstoflash",false),F({type:"JS_TO_FLASH_EXCEPTION",fatal:true}),$(true),N(),false}N();p.remove(i,"load",c.beginDelayedInit);return true};E=function(){if(la)return false;la=true;ma();var b=K.toLowerCase(),a=null,a=null,e=typeof console!=="undefined"&&typeof console.log!=="undefined";
-if(b.indexOf("sm2-usehtml5audio=")!==-1)a=b.charAt(b.indexOf("sm2-usehtml5audio=")+18)==="1",e&&console.log((a?"Enabling ":"Disabling ")+"useHTML5Audio via URL parameter"),c.useHTML5Audio=a;if(b.indexOf("sm2-preferflash=")!==-1)a=b.charAt(b.indexOf("sm2-preferflash=")+16)==="1",e&&console.log((a?"Enabling ":"Disabling ")+"preferFlash via URL parameter"),c.preferFlash=a;if(!t&&c.hasHTML5)c._wD("SoundManager: No Flash detected"+(!c.useHTML5Audio?", enabling HTML5.":". Trying HTML5-only mode.")),c.useHTML5Audio=
-true,c.preferFlash=false;Ha();c.html5.usingFlash=Ga();w=c.html5.usingFlash;Ka();if(!t&&w)c._wD("SoundManager: Fatal error: Flash is needed to play some required formats, but is not available."),c.flashLoadTimeout=1;g.removeEventListener&&g.removeEventListener("DOMContentLoaded",E,false);X();return true};sa=function(){g.readyState==="complete"&&(E(),g.detachEvent("onreadystatechange",sa));return true};ea();p.add(i,"focus",B);p.add(i,"load",B);p.add(i,"load",V);R&&H&&p.add(i,"mousemove",B);g.addEventListener?
-g.addEventListener("DOMContentLoaded",E,false):g.attachEvent?g.attachEvent("onreadystatechange",sa):(r("onload",false),F({type:"NO_DOM2_EVENTS",fatal:true}));g.readyState==="complete"&&setTimeout(E,100)}var fa=null;if(typeof SM2_DEFER==="undefined"||!SM2_DEFER)fa=new T;S.SoundManager=T;S.soundManager=fa})(window);
\ No newline at end of file
+++ /dev/null
-/** @license\r
- *\r
- * SoundManager 2: JavaScript Sound for the Web\r
- * ----------------------------------------------\r
- * http://schillmania.com/projects/soundmanager2/\r
- *\r
- * Copyright (c) 2007, Scott Schiller. All rights reserved.\r
- * Code provided under the BSD License:\r
- * http://schillmania.com/projects/soundmanager2/license.txt\r
- *\r
- * V2.97a.20111030\r
- */\r
-(function($){function N(N,Z){function j(c){return function(a){return!this._t||!this._t._a?null:c.call(this,a)}}this.flashVersion=8;this.debugFlash=this.debugMode=false;this.useConsole=true;this.waitForWindowLoad=this.consoleOnly=false;this.bgColor="#ffffff";this.useHighPerformance=false;this.flashPollingInterval=null;this.flashLoadTimeout=1E3;this.wmode=null;this.allowScriptAccess="always";this.useFlashBlock=false;this.useHTML5Audio=true;this.html5Test=/^(probably|maybe)$/i;this.preferFlash=true;
-this.noSWFCache=false;this.audioFormats={mp3:{type:['audio/mpeg; codecs="mp3"',"audio/mpeg","audio/mp3","audio/MPA","audio/mpa-robust"],required:true},mp4:{related:["aac","m4a"],type:['audio/mp4; codecs="mp4a.40.2"',"audio/aac","audio/x-m4a","audio/MP4A-LATM","audio/mpeg4-generic"],required:false},ogg:{type:["audio/ogg; codecs=vorbis"],required:false},wav:{type:['audio/wav; codecs="1"',"audio/wav","audio/wave","audio/x-wav"],required:false}};this.defaultOptions={autoLoad:false,stream:true,autoPlay:false,
-loops:1,onid3:null,onload:null,whileloading:null,onplay:null,onpause:null,onresume:null,whileplaying:null,onstop:null,onfailure:null,onfinish:null,multiShot:true,multiShotEvents:false,position:null,pan:0,type:null,usePolicyFile:false,volume:100};this.flash9Options={isMovieStar:null,usePeakData:false,useWaveformData:false,useEQData:false,onbufferchange:null,ondataerror:null};this.movieStarOptions={bufferTime:3,serverURL:null,onconnect:null,duration:null};this.movieID="sm2-container";this.id=Z||"sm2movie";
-this.swfCSS={swfBox:"sm2-object-box",swfDefault:"movieContainer",swfError:"swf_error",swfTimedout:"swf_timedout",swfLoaded:"swf_loaded",swfUnblocked:"swf_unblocked",sm2Debug:"sm2_debug",highPerf:"high_performance",flashDebug:"flash_debug"};this.debugID="soundmanager-debug";this.debugURLParam=/([#?&])debug=1/i;this.versionNumber="V2.97a.20111030";this.movieURL=this.version=null;this.url=N||null;this.altURL=null;this.enabled=this.swfLoaded=false;this.oMC=this.o=null;this.sounds={};this.soundIDs=[];
-this.didFlashBlock=this.specialWmodeCase=this.muted=false;this.filePattern=null;this.filePatterns={flash8:/\.mp3(\?.*)?$/i,flash9:/\.mp3(\?.*)?$/i};this.features={buffering:false,peakData:false,waveformData:false,eqData:false,movieStar:false};this.sandbox={};var F;try{F=typeof Audio!=="undefined"&&typeof(new Audio).canPlayType!=="undefined"}catch(Oa){F=false}this.hasHTML5=F;this.html5={usingFlash:null};this.flash={};this.ignoreFlash=this.html5Only=false;var ra,c=this,O,o=navigator.userAgent,i=$,aa=
-i.location.href.toString(),h=document,ba,P,g,s=[],G=false,H=false,m=false,t=false,sa=false,I,n,ca,z,A,Q,ta,da,x,R,B,ea,fa,S,C,ua,ga,va,T,wa,J=null,ha=null,y,ia,D,U,V,ja,l,W=false,ka=false,xa,ya,q=null,za,X,K,u,la,ma,Aa,k,Ia=Array.prototype.slice,L=false,p,Y,Ba,r,Ca,na=o.match(/(ipad|iphone|ipod)/i),Ja=o.match(/firefox/i),Ka=o.match(/droid/i),v=o.match(/msie/i),La=o.match(/webkit/i),M=o.match(/safari/i)&&!o.match(/chrome/i),Ma=o.match(/opera/i);F=o.match(/(mobile|pre\/|xoom)/i)||na;var oa=!aa.match(/usehtml5audio/i)&&
-!aa.match(/sm2\-ignorebadua/i)&&M&&o.match(/OS X 10_6_([3-7])/i),pa=typeof h.hasFocus!=="undefined"?h.hasFocus():null,E=M&&typeof h.hasFocus==="undefined",Da=!E,Ea=/(mp3|mp4|mpa)/i,qa=h.location?h.location.protocol.match(/http/i):null,Fa=!qa?"http://":"",Ga=/^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|mp4v|3gp|3g2)\s*(?:$|;)/i,Ha="mpeg4,aac,flv,mov,mp4,m4v,f4v,m4a,mp4v,3gp,3g2".split(","),Na=RegExp("\\.("+Ha.join("|")+")(\\?.*)?$","i");this.mimePattern=/^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i;
-this.useAltURL=!qa;this._global_a=null;if(F&&(c.useHTML5Audio=true,c.preferFlash=false,na))L=c.ignoreFlash=true;this.supported=this.ok=function(){return q?m&&!t:c.useHTML5Audio&&c.hasHTML5};this.getMovie=function(c){return O(c)||h[c]||i[c]};this.createSound=function(b){function a(){e=U(e);c.sounds[d.id]=new ra(d);c.soundIDs.push(d.id);return c.sounds[d.id]}var e=null,f=null,d=null;if(!m||!c.ok())return ja("soundManager.createSound(): "+y(!m?"notReady":"notOK")),false;arguments.length===2&&(b={id:arguments[0],
-url:arguments[1]});d=e=n(b);if(l(d.id,true))return c.sounds[d.id];if(X(d))f=a(),f._setup_html5(d);else{if(g>8){if(d.isMovieStar===null)d.isMovieStar=d.serverURL||(d.type?d.type.match(Ga):false)||d.url.match(Na);if(d.isMovieStar&&d.usePeakData)d.usePeakData=false}d=V(d,"soundManager.createSound(): ");f=a();if(g===8)c.o._createSound(d.id,d.loops||1,d.usePolicyFile);else if(c.o._createSound(d.id,d.url,d.usePeakData,d.useWaveformData,d.useEQData,d.isMovieStar,d.isMovieStar?d.bufferTime:false,d.loops||
-1,d.serverURL,d.duration||null,d.autoPlay,true,d.autoLoad,d.usePolicyFile),!d.serverURL)f.connected=true,d.onconnect&&d.onconnect.apply(f);!d.serverURL&&(d.autoLoad||d.autoPlay)&&f.load(d)}!d.serverURL&&d.autoPlay&&f.play();return f};this.destroySound=function(b,a){if(!l(b))return false;var e=c.sounds[b],f;e._iO={};e.stop();e.unload();for(f=0;f<c.soundIDs.length;f++)if(c.soundIDs[f]===b){c.soundIDs.splice(f,1);break}a||e.destruct(true);delete c.sounds[b];return true};this.load=function(b,a){return!l(b)?
-false:c.sounds[b].load(a)};this.unload=function(b){return!l(b)?false:c.sounds[b].unload()};this.onposition=function(b,a,e,f){return!l(b)?false:c.sounds[b].onposition(a,e,f)};this.start=this.play=function(b,a){if(!m||!c.ok())return ja("soundManager.play(): "+y(!m?"notReady":"notOK")),false;return!l(b)?(a instanceof Object||(a={url:a}),a&&a.url?(a.id=b,c.createSound(a).play()):false):c.sounds[b].play(a)};this.setPosition=function(b,a){return!l(b)?false:c.sounds[b].setPosition(a)};this.stop=function(b){return!l(b)?
-false:c.sounds[b].stop()};this.stopAll=function(){for(var b in c.sounds)c.sounds.hasOwnProperty(b)&&c.sounds[b].stop()};this.pause=function(b){return!l(b)?false:c.sounds[b].pause()};this.pauseAll=function(){var b;for(b=c.soundIDs.length;b--;)c.sounds[c.soundIDs[b]].pause()};this.resume=function(b){return!l(b)?false:c.sounds[b].resume()};this.resumeAll=function(){var b;for(b=c.soundIDs.length;b--;)c.sounds[c.soundIDs[b]].resume()};this.togglePause=function(b){return!l(b)?false:c.sounds[b].togglePause()};
-this.setPan=function(b,a){return!l(b)?false:c.sounds[b].setPan(a)};this.setVolume=function(b,a){return!l(b)?false:c.sounds[b].setVolume(a)};this.mute=function(b){var a=0;typeof b!=="string"&&(b=null);if(b)return!l(b)?false:c.sounds[b].mute();else{for(a=c.soundIDs.length;a--;)c.sounds[c.soundIDs[a]].mute();c.muted=true}return true};this.muteAll=function(){c.mute()};this.unmute=function(b){typeof b!=="string"&&(b=null);if(b)return!l(b)?false:c.sounds[b].unmute();else{for(b=c.soundIDs.length;b--;)c.sounds[c.soundIDs[b]].unmute();
-c.muted=false}return true};this.unmuteAll=function(){c.unmute()};this.toggleMute=function(b){return!l(b)?false:c.sounds[b].toggleMute()};this.getMemoryUse=function(){var b=0;c.o&&g!==8&&(b=parseInt(c.o._getMemoryUse(),10));return b};this.disable=function(b){var a;typeof b==="undefined"&&(b=false);if(t)return false;t=true;for(a=c.soundIDs.length;a--;)va(c.sounds[c.soundIDs[a]]);I(b);k.remove(i,"load",A);return true};this.canPlayMIME=function(b){var a;c.hasHTML5&&(a=K({type:b}));return!q||a?a:b?!!(g>
-8&&b.match(Ga)||b.match(c.mimePattern)):null};this.canPlayURL=function(b){var a;c.hasHTML5&&(a=K({url:b}));return!q||a?a:b?!!b.match(c.filePattern):null};this.canPlayLink=function(b){return typeof b.type!=="undefined"&&b.type&&c.canPlayMIME(b.type)?true:c.canPlayURL(b.href)};this.getSoundById=function(b){if(!b)throw Error("soundManager.getSoundById(): sID is null/undefined");return c.sounds[b]};this.onready=function(c,a){if(c&&c instanceof Function)return a||(a=i),ca("onready",c,a),z(),true;else throw y("needFunction",
-"onready");};this.ontimeout=function(c,a){if(c&&c instanceof Function)return a||(a=i),ca("ontimeout",c,a),z({type:"ontimeout"}),true;else throw y("needFunction","ontimeout");};this._wD=this._writeDebug=function(){return true};this._debug=function(){};this.reboot=function(){var b,a;for(b=c.soundIDs.length;b--;)c.sounds[c.soundIDs[b]].destruct();try{if(v)ha=c.o.innerHTML;J=c.o.parentNode.removeChild(c.o)}catch(e){}ha=J=q=null;c.enabled=ea=m=W=ka=G=H=t=c.swfLoaded=false;c.soundIDs=c.sounds=[];c.o=null;
-for(b in s)if(s.hasOwnProperty(b))for(a=s[b].length;a--;)s[b][a].fired=false;i.setTimeout(c.beginDelayedInit,20)};this.getMoviePercent=function(){return c.o&&typeof c.o.PercentLoaded!=="undefined"?c.o.PercentLoaded():null};this.beginDelayedInit=function(){sa=true;B();setTimeout(function(){if(ka)return false;S();R();return ka=true},20);Q()};this.destruct=function(){c.disable(true)};ra=function(b){var a=this,e,f,d;this.sID=b.id;this.url=b.url;this._iO=this.instanceOptions=this.options=n(b);this.pan=
-this.options.pan;this.volume=this.options.volume;this._lastURL=null;this.isHTML5=false;this._a=null;this.id3={};this._debug=function(){};this.load=function(b){var d=null;if(typeof b!=="undefined")a._iO=n(b,a.options),a.instanceOptions=a._iO;else if(b=a.options,a._iO=b,a.instanceOptions=a._iO,a._lastURL&&a._lastURL!==a.url)a._iO.url=a.url,a.url=null;if(!a._iO.url)a._iO.url=a.url;if(a._iO.url===a.url&&a.readyState!==0&&a.readyState!==2)return a;a._lastURL=a.url;a.loaded=false;a.readyState=1;a.playState=
-0;if(X(a._iO)){if(d=a._setup_html5(a._iO),!d._called_load)a._html5_canplay=false,d.load(),d._called_load=true,a._iO.autoPlay&&a.play()}else try{a.isHTML5=false,a._iO=V(U(a._iO)),g===8?c.o._load(a.sID,a._iO.url,a._iO.stream,a._iO.autoPlay,a._iO.whileloading?1:0,a._iO.loops||1,a._iO.usePolicyFile):c.o._load(a.sID,a._iO.url,!!a._iO.stream,!!a._iO.autoPlay,a._iO.loops||1,!!a._iO.autoLoad,a._iO.usePolicyFile)}catch(e){C({type:"SMSOUND_LOAD_JS_EXCEPTION",fatal:true})}return a};this.unload=function(){a.readyState!==
-0&&(a.isHTML5?(f(),a._a&&(a._a.pause(),la(a._a))):g===8?c.o._unload(a.sID,"about:blank"):c.o._unload(a.sID),e());return a};this.destruct=function(b){if(a.isHTML5){if(f(),a._a)a._a.pause(),la(a._a),L||a._remove_html5_events(),a._a._t=null,a._a=null}else a._iO.onfailure=null,c.o._destroySound(a.sID);b||c.destroySound(a.sID,true)};this.start=this.play=function(b,w){var e,w=w===void 0?true:w;b||(b={});a._iO=n(b,a._iO);a._iO=n(a._iO,a.options);a.instanceOptions=a._iO;if(a._iO.serverURL&&!a.connected)return a.getAutoPlay()||
-a.setAutoPlay(true),a;X(a._iO)&&(a._setup_html5(a._iO),d());if(a.playState===1&&!a.paused&&(e=a._iO.multiShot,!e))return a;if(!a.loaded)if(a.readyState===0){if(!a.isHTML5)a._iO.autoPlay=true;a.load(a._iO)}else if(a.readyState===2)return a;if(!a.isHTML5&&g===9&&a.position>0&&a.position===a.duration)a._iO.position=0;if(a.paused&&a.position&&a.position>0)a.resume();else{a.playState=1;a.paused=false;(!a.instanceCount||a._iO.multiShotEvents||!a.isHTML5&&g>8&&!a.getAutoPlay())&&a.instanceCount++;a.position=
-typeof a._iO.position!=="undefined"&&!isNaN(a._iO.position)?a._iO.position:0;if(!a.isHTML5)a._iO=V(U(a._iO));if(a._iO.onplay&&w)a._iO.onplay.apply(a),a._onplay_called=true;a.setVolume(a._iO.volume,true);a.setPan(a._iO.pan,true);a.isHTML5?(d(),e=a._setup_html5(),a.setPosition(a._iO.position),e.play()):c.o._start(a.sID,a._iO.loops||1,g===9?a._iO.position:a._iO.position/1E3)}return a};this.stop=function(b){if(a.playState===1){a._onbufferchange(0);a.resetOnPosition(0);a.paused=false;if(!a.isHTML5)a.playState=
-0;a._iO.onstop&&a._iO.onstop.apply(a);if(a.isHTML5){if(a._a)a.setPosition(0),a._a.pause(),a.playState=0,a._onTimer(),f()}else c.o._stop(a.sID,b),a._iO.serverURL&&a.unload();a.instanceCount=0;a._iO={}}return a};this.setAutoPlay=function(b){a._iO.autoPlay=b;a.isHTML5||(c.o._setAutoPlay(a.sID,b),b&&!a.instanceCount&&a.readyState===1&&a.instanceCount++)};this.getAutoPlay=function(){return a._iO.autoPlay};this.setPosition=function(b){b===void 0&&(b=0);var d=a.isHTML5?Math.max(b,0):Math.min(a.duration||
-a._iO.duration,Math.max(b,0));a.position=d;b=a.position/1E3;a.resetOnPosition(a.position);a._iO.position=d;if(a.isHTML5){if(a._a&&a._html5_canplay&&a._a.currentTime!==b)try{a._a.currentTime=b,(a.playState===0||a.paused)&&a._a.pause()}catch(e){}}else b=g===9?a.position:b,a.readyState&&a.readyState!==2&&c.o._setPosition(a.sID,b,a.paused||!a.playState);a.isHTML5&&a.paused&&a._onTimer(true);return a};this.pause=function(b){if(a.paused||a.playState===0&&a.readyState!==1)return a;a.paused=true;a.isHTML5?
-(a._setup_html5().pause(),f()):(b||b===void 0)&&c.o._pause(a.sID);a._iO.onpause&&a._iO.onpause.apply(a);return a};this.resume=function(){if(!a.paused)return a;a.paused=false;a.playState=1;a.isHTML5?(a._setup_html5().play(),d()):(a._iO.isMovieStar&&a.setPosition(a.position),c.o._pause(a.sID));!a._onplay_called&&a._iO.onplay?(a._iO.onplay.apply(a),a._onplay_called=true):a._iO.onresume&&a._iO.onresume.apply(a);return a};this.togglePause=function(){if(a.playState===0)return a.play({position:g===9&&!a.isHTML5?
-a.position:a.position/1E3}),a;a.paused?a.resume():a.pause();return a};this.setPan=function(b,d){typeof b==="undefined"&&(b=0);typeof d==="undefined"&&(d=false);a.isHTML5||c.o._setPan(a.sID,b);a._iO.pan=b;if(!d)a.pan=b,a.options.pan=b;return a};this.setVolume=function(b,d){typeof b==="undefined"&&(b=100);typeof d==="undefined"&&(d=false);if(a.isHTML5){if(a._a)a._a.volume=Math.max(0,Math.min(1,b/100))}else c.o._setVolume(a.sID,c.muted&&!a.muted||a.muted?0:b);a._iO.volume=b;if(!d)a.volume=b,a.options.volume=
-b;return a};this.mute=function(){a.muted=true;if(a.isHTML5){if(a._a)a._a.muted=true}else c.o._setVolume(a.sID,0);return a};this.unmute=function(){a.muted=false;var b=typeof a._iO.volume!=="undefined";if(a.isHTML5){if(a._a)a._a.muted=false}else c.o._setVolume(a.sID,b?a._iO.volume:a.options.volume);return a};this.toggleMute=function(){return a.muted?a.unmute():a.mute()};this.onposition=function(b,c,d){a._onPositionItems.push({position:b,method:c,scope:typeof d!=="undefined"?d:a,fired:false});return a};
-this.processOnPosition=function(){var b,d;b=a._onPositionItems.length;if(!b||!a.playState||a._onPositionFired>=b)return false;for(;b--;)if(d=a._onPositionItems[b],!d.fired&&a.position>=d.position)d.fired=true,c._onPositionFired++,d.method.apply(d.scope,[d.position]);return true};this.resetOnPosition=function(b){var d,e;d=a._onPositionItems.length;if(!d)return false;for(;d--;)if(e=a._onPositionItems[d],e.fired&&b<=e.position)e.fired=false,c._onPositionFired--;return true};d=function(){a.isHTML5&&xa(a)};
-f=function(){a.isHTML5&&ya(a)};e=function(){a._onPositionItems=[];a._onPositionFired=0;a._hasTimer=null;a._onplay_called=false;a._a=null;a._html5_canplay=false;a.bytesLoaded=null;a.bytesTotal=null;a.position=null;a.duration=a._iO&&a._iO.duration?a._iO.duration:null;a.durationEstimate=null;a.failures=0;a.loaded=false;a.playState=0;a.paused=false;a.readyState=0;a.muted=false;a.isBuffering=false;a.instanceOptions={};a.instanceCount=0;a.peakData={left:0,right:0};a.waveformData={left:[],right:[]};a.eqData=
-[];a.eqData.left=[];a.eqData.right=[]};e();this._onTimer=function(b){var c={};if(a._hasTimer||b)return a._a&&(b||(a.playState>0||a.readyState===1)&&!a.paused)?(a.duration=a._get_html5_duration(),a.durationEstimate=a.duration,b=a._a.currentTime?a._a.currentTime*1E3:0,a._whileplaying(b,c,c,c,c),true):false};this._get_html5_duration=function(){var b=a._a?a._a.duration*1E3:a._iO?a._iO.duration:void 0;return b&&!isNaN(b)&&b!==Infinity?b:a._iO?a._iO.duration:null};this._setup_html5=function(b){var b=n(a._iO,
-b),d=L?c._global_a:a._a;decodeURI(b.url);var f=d&&d._t?d._t.instanceOptions:null;if(d){if(d._t&&f.url===b.url&&(!a._lastURL||a._lastURL===f.url))return d;L&&d._t&&d._t.playState&&b.url!==f.url&&d._t.stop();e();d.src=b.url;a.url=b.url;a._lastURL=b.url;d._called_load=false}else{d=new Audio(b.url);d._called_load=false;if(Ka)d._called_load=true;if(L)c._global_a=d}a.isHTML5=true;a._a=d;d._t=a;a._add_html5_events();d.loop=b.loops>1?"loop":"";b.autoLoad||b.autoPlay?(d.autobuffer="auto",d.preload="auto",
-a.load(),d._called_load=true):(d.autobuffer=false,d.preload="none");d.loop=b.loops>1?"loop":"";return d};this._add_html5_events=function(){if(a._a._added_events)return false;var b;a._a._added_events=true;for(b in r)r.hasOwnProperty(b)&&a._a&&a._a.addEventListener(b,r[b],false);return true};this._remove_html5_events=function(){var b;a._a._added_events=false;for(b in r)r.hasOwnProperty(b)&&a._a&&a._a.removeEventListener(b,r[b],false)};this._onload=function(b){b=!!b;a.loaded=b;a.readyState=b?3:2;a._onbufferchange(0);
-a._iO.onload&&a._iO.onload.apply(a,[b]);return true};this._onbufferchange=function(b){if(a.playState===0)return false;if(b&&a.isBuffering||!b&&!a.isBuffering)return false;a.isBuffering=b===1;a._iO.onbufferchange&&a._iO.onbufferchange.apply(a);return true};this._onsuspend=function(){a._iO.onsuspend&&a._iO.onsuspend.apply(a);return true};this._onfailure=function(b,c,d){a.failures++;if(a._iO.onfailure&&a.failures===1)a._iO.onfailure(a,b,c,d)};this._onfinish=function(){var b=a._iO.onfinish;a._onbufferchange(0);
-a.resetOnPosition(0);if(a.instanceCount){a.instanceCount--;if(!a.instanceCount)a.playState=0,a.paused=false,a.instanceCount=0,a.instanceOptions={},a._iO={},f();(!a.instanceCount||a._iO.multiShotEvents)&&b&&b.apply(a)}};this._whileloading=function(b,c,d,e){a.bytesLoaded=b;a.bytesTotal=c;a.duration=Math.floor(d);a.bufferLength=e;if(a._iO.isMovieStar)a.durationEstimate=a.duration;else if(a.durationEstimate=a._iO.duration?a.duration>a._iO.duration?a.duration:a._iO.duration:parseInt(a.bytesTotal/a.bytesLoaded*
-a.duration,10),a.durationEstimate===void 0)a.durationEstimate=a.duration;a.readyState!==3&&a._iO.whileloading&&a._iO.whileloading.apply(a)};this._whileplaying=function(b,c,d,e,f){if(isNaN(b)||b===null)return false;a.position=b;a.processOnPosition();if(!a.isHTML5&&g>8){if(a._iO.usePeakData&&typeof c!=="undefined"&&c)a.peakData={left:c.leftPeak,right:c.rightPeak};if(a._iO.useWaveformData&&typeof d!=="undefined"&&d)a.waveformData={left:d.split(","),right:e.split(",")};if(a._iO.useEQData&&typeof f!==
-"undefined"&&f&&f.leftEQ&&(b=f.leftEQ.split(","),a.eqData=b,a.eqData.left=b,typeof f.rightEQ!=="undefined"&&f.rightEQ))a.eqData.right=f.rightEQ.split(",")}a.playState===1&&(!a.isHTML5&&g===8&&!a.position&&a.isBuffering&&a._onbufferchange(0),a._iO.whileplaying&&a._iO.whileplaying.apply(a));return true};this._onid3=function(b,c){var d=[],e,f;for(e=0,f=b.length;e<f;e++)d[b[e]]=c[e];a.id3=n(a.id3,d);a._iO.onid3&&a._iO.onid3.apply(a)};this._onconnect=function(b){b=b===1;if(a.connected=b)a.failures=0,l(a.sID)&&
-(a.getAutoPlay()?a.play(void 0,a.getAutoPlay()):a._iO.autoLoad&&a.load()),a._iO.onconnect&&a._iO.onconnect.apply(a,[b])};this._ondataerror=function(){a.playState>0&&a._iO.ondataerror&&a._iO.ondataerror.apply(a)}};fa=function(){return h.body||h._docElement||h.getElementsByTagName("div")[0]};O=function(b){return h.getElementById(b)};n=function(b,a){var e={},f,d;for(f in b)b.hasOwnProperty(f)&&(e[f]=b[f]);f=typeof a==="undefined"?c.defaultOptions:a;for(d in f)f.hasOwnProperty(d)&&typeof e[d]==="undefined"&&
-(e[d]=f[d]);return e};k=function(){function b(a){var a=Ia.call(a),b=a.length;c?(a[1]="on"+a[1],b>3&&a.pop()):b===3&&a.push(false);return a}function a(a,b){var w=a.shift(),h=[f[b]];if(c)w[h](a[0],a[1]);else w[h].apply(w,a)}var c=i.attachEvent,f={add:c?"attachEvent":"addEventListener",remove:c?"detachEvent":"removeEventListener"};return{add:function(){a(b(arguments),"add")},remove:function(){a(b(arguments),"remove")}}}();r={abort:j(function(){}),canplay:j(function(){if(this._t._html5_canplay)return true;
-this._t._html5_canplay=true;this._t._onbufferchange(0);var b=!isNaN(this._t.position)?this._t.position/1E3:null;if(this._t.position&&this.currentTime!==b)try{this.currentTime=b}catch(a){}}),load:j(function(){this._t.loaded||(this._t._onbufferchange(0),this._t._whileloading(this._t.bytesTotal,this._t.bytesTotal,this._t._get_html5_duration()),this._t._onload(true))}),emptied:j(function(){}),ended:j(function(){this._t._onfinish()}),error:j(function(){this._t._onload(false)}),loadeddata:j(function(){var b=
-this._t,a=b.bytesTotal||1;if(!b._loaded&&!M)b.duration=b._get_html5_duration(),b._whileloading(a,a,b._get_html5_duration()),b._onload(true)}),loadedmetadata:j(function(){}),loadstart:j(function(){this._t._onbufferchange(1)}),play:j(function(){this._t._onbufferchange(0)}),playing:j(function(){this._t._onbufferchange(0)}),progress:j(function(b){if(this._t.loaded)return false;var a,c=0,f=b.target.buffered;a=b.loaded||0;var d=b.total||1;if(f&&f.length){for(a=f.length;a--;)c=f.end(a)-f.start(a);a=c/b.target.duration}isNaN(a)||
-(this._t._onbufferchange(0),this._t._whileloading(a,d,this._t._get_html5_duration()),a&&d&&a===d&&r.load.call(this,b))}),ratechange:j(function(){}),suspend:j(function(b){r.progress.call(this,b);this._t._onsuspend()}),stalled:j(function(){}),timeupdate:j(function(){this._t._onTimer()}),waiting:j(function(){this._t._onbufferchange(1)})};X=function(b){return!b.serverURL&&(b.type?K({type:b.type}):K({url:b.url})||c.html5Only)};la=function(b){if(b)b.src=Ja?"":"about:blank"};K=function(b){function a(a){return c.preferFlash&&
-p&&!c.ignoreFlash&&typeof c.flash[a]!=="undefined"&&c.flash[a]}if(!c.useHTML5Audio||!c.hasHTML5)return false;var e=b.url||null,b=b.type||null,f=c.audioFormats,d;if(b&&c.html5[b]!=="undefined")return c.html5[b]&&!a(b);if(!u){u=[];for(d in f)f.hasOwnProperty(d)&&(u.push(d),f[d].related&&(u=u.concat(f[d].related)));u=RegExp("\\.("+u.join("|")+")(\\?.*)?$","i")}d=e?e.toLowerCase().match(u):null;if(!d||!d.length)if(b)e=b.indexOf(";"),d=(e!==-1?b.substr(0,e):b).substr(6);else return false;else d=d[1];return d&&
-typeof c.html5[d]!=="undefined"?c.html5[d]&&!a(d):(b="audio/"+d,e=c.html5.canPlayType({type:b}),(c.html5[d]=e)&&c.html5[b]&&!a(b))};Aa=function(){function b(b){var d,e,f=false;if(!a||typeof a.canPlayType!=="function")return false;if(b instanceof Array){for(d=0,e=b.length;d<e&&!f;d++)if(c.html5[b[d]]||a.canPlayType(b[d]).match(c.html5Test))f=true,c.html5[b[d]]=true,c.flash[b[d]]=!(!c.preferFlash||!p||!b[d].match(Ea));return f}else return b=a&&typeof a.canPlayType==="function"?a.canPlayType(b):false,
-!(!b||!b.match(c.html5Test))}if(!c.useHTML5Audio||typeof Audio==="undefined")return false;var a=typeof Audio!=="undefined"?Ma?new Audio(null):new Audio:null,e,f={},d,h;d=c.audioFormats;for(e in d)if(d.hasOwnProperty(e)&&(f[e]=b(d[e].type),f["audio/"+e]=f[e],c.flash[e]=c.preferFlash&&!c.ignoreFlash&&e.match(Ea)?true:false,d[e]&&d[e].related))for(h=d[e].related.length;h--;)f["audio/"+d[e].related[h]]=f[e],c.html5[d[e].related[h]]=f[e],c.flash[d[e].related[h]]=f[e];f.canPlayType=a?b:null;c.html5=n(c.html5,
-f);return true};y=function(){};U=function(b){if(g===8&&b.loops>1&&b.stream)b.stream=false;return b};V=function(b){if(b&&!b.usePolicyFile&&(b.onid3||b.usePeakData||b.useWaveformData||b.useEQData))b.usePolicyFile=true;return b};ja=function(){};ba=function(){return false};va=function(b){for(var a in b)b.hasOwnProperty(a)&&typeof b[a]==="function"&&(b[a]=ba)};T=function(b){typeof b==="undefined"&&(b=false);(t||b)&&c.disable(b)};wa=function(b){var a=null;if(b)if(b.match(/\.swf(\?.*)?$/i)){if(a=b.substr(b.toLowerCase().lastIndexOf(".swf?")+
-4))return b}else b.lastIndexOf("/")!==b.length-1&&(b+="/");b=(b&&b.lastIndexOf("/")!==-1?b.substr(0,b.lastIndexOf("/")+1):"./")+c.movieURL;c.noSWFCache&&(b+="?ts="+(new Date).getTime());return b};da=function(){g=parseInt(c.flashVersion,10);if(g!==8&&g!==9)c.flashVersion=g=8;var b=c.debugMode||c.debugFlash?"_debug.swf":".swf";if(c.useHTML5Audio&&!c.html5Only&&c.audioFormats.mp4.required&&g<9)c.flashVersion=g=9;c.version=c.versionNumber+(c.html5Only?" (HTML5-only mode)":g===9?" (AS3/Flash 9)":" (AS2/Flash 8)");
-g>8?(c.defaultOptions=n(c.defaultOptions,c.flash9Options),c.features.buffering=true,c.defaultOptions=n(c.defaultOptions,c.movieStarOptions),c.filePatterns.flash9=RegExp("\\.(mp3|"+Ha.join("|")+")(\\?.*)?$","i"),c.features.movieStar=true):c.features.movieStar=false;c.filePattern=c.filePatterns[g!==8?"flash9":"flash8"];c.movieURL=(g===8?"soundmanager2.swf":"soundmanager2_flash9.swf").replace(".swf",b);c.features.peakData=c.features.waveformData=c.features.eqData=g>8};ua=function(b,a){if(!c.o)return false;
-c.o._setPolling(b,a)};ga=function(){if(c.debugURLParam.test(aa))c.debugMode=true};l=this.getSoundById;D=function(){var b=[];c.debugMode&&b.push(c.swfCSS.sm2Debug);c.debugFlash&&b.push(c.swfCSS.flashDebug);c.useHighPerformance&&b.push(c.swfCSS.highPerf);return b.join(" ")};ia=function(){y("fbHandler");var b=c.getMoviePercent(),a=c.swfCSS,e={type:"FLASHBLOCK"};if(c.html5Only)return false;if(c.ok()){if(c.oMC)c.oMC.className=[D(),a.swfDefault,a.swfLoaded+(c.didFlashBlock?" "+a.swfUnblocked:"")].join(" ")}else{if(q)c.oMC.className=
-D()+" "+a.swfDefault+" "+(b===null?a.swfTimedout:a.swfError);c.didFlashBlock=true;z({type:"ontimeout",ignoreInit:true,error:e});C(e)}};ca=function(b,a,c){typeof s[b]==="undefined"&&(s[b]=[]);s[b].push({method:a,scope:c||null,fired:false})};z=function(b){b||(b={type:"onready"});if(!m&&b&&!b.ignoreInit)return false;if(b.type==="ontimeout"&&c.ok())return false;var a={success:b&&b.ignoreInit?c.ok():!t},e=b&&b.type?s[b.type]||[]:[],f=[],d,a=[a],h=q&&c.useFlashBlock&&!c.ok();if(b.error)a[0].error=b.error;
-for(b=0,d=e.length;b<d;b++)e[b].fired!==true&&f.push(e[b]);if(f.length)for(b=0,d=f.length;b<d;b++)if(f[b].scope?f[b].method.apply(f[b].scope,a):f[b].method.apply(this,a),!h)f[b].fired=true;return true};A=function(){i.setTimeout(function(){c.useFlashBlock&&ia();z();c.onload instanceof Function&&c.onload.apply(i);c.waitForWindowLoad&&k.add(i,"load",A)},1)};Y=function(){if(p!==void 0)return p;var b=false,a=navigator,c=a.plugins,f,d=i.ActiveXObject;if(c&&c.length)(a=a.mimeTypes)&&a["application/x-shockwave-flash"]&&
-a["application/x-shockwave-flash"].enabledPlugin&&a["application/x-shockwave-flash"].enabledPlugin.description&&(b=true);else if(typeof d!=="undefined"){try{f=new d("ShockwaveFlash.ShockwaveFlash")}catch(h){}b=!!f}return p=b};za=function(){var b,a;if(na&&o.match(/os (1|2|3_0|3_1)/i)){c.hasHTML5=false;c.html5Only=true;if(c.oMC)c.oMC.style.display="none";return false}if(c.useHTML5Audio){if(!c.html5||!c.html5.canPlayType)return c.hasHTML5=false,true;else c.hasHTML5=true;if(oa&&Y())return true}else return true;
-for(a in c.audioFormats)if(c.audioFormats.hasOwnProperty(a)&&(c.audioFormats[a].required&&!c.html5.canPlayType(c.audioFormats[a].type)||c.flash[a]||c.flash[c.audioFormats[a].type]))b=true;c.ignoreFlash&&(b=false);c.html5Only=c.hasHTML5&&c.useHTML5Audio&&!b;return!c.html5Only};xa=function(b){if(!b._hasTimer)b._hasTimer=true};ya=function(b){if(b._hasTimer)b._hasTimer=false};C=function(b){b=typeof b!=="undefined"?b:{};c.onerror instanceof Function&&c.onerror.apply(i,[{type:typeof b.type!=="undefined"?
-b.type:null}]);typeof b.fatal!=="undefined"&&b.fatal&&c.disable()};Ba=function(){if(!oa||!Y())return false;var b=c.audioFormats,a,e;for(e in b)if(b.hasOwnProperty(e)&&(e==="mp3"||e==="mp4"))if(c.html5[e]=false,b[e]&&b[e].related)for(a=b[e].related.length;a--;)c.html5[b[e].related[a]]=false};this._setSandboxType=function(){};this._externalInterfaceOK=function(){if(c.swfLoaded)return false;(new Date).getTime();c.swfLoaded=true;E=false;oa&&Ba();v?setTimeout(P,100):P()};S=function(b,a){function e(a,b){return'<param name="'+
-a+'" value="'+b+'" />'}if(G&&H)return false;if(c.html5Only)return da(),c.oMC=O(c.movieID),P(),H=G=true,false;var f=a||c.url,d=c.altURL||f,g;g=fa();var i,l,j=D(),k,m=null,m=(m=h.getElementsByTagName("html")[0])&&m.dir&&m.dir.match(/rtl/i),b=typeof b==="undefined"?c.id:b;da();c.url=wa(qa?f:d);a=c.url;c.wmode=!c.wmode&&c.useHighPerformance?"transparent":c.wmode;if(c.wmode!==null&&(o.match(/msie 8/i)||!v&&!c.useHighPerformance)&&navigator.platform.match(/win32|win64/i))c.specialWmodeCase=true,c.wmode=
-null;g={name:b,id:b,src:a,width:"auto",height:"auto",quality:"high",allowScriptAccess:c.allowScriptAccess,bgcolor:c.bgColor,pluginspage:Fa+"www.macromedia.com/go/getflashplayer",title:"JS/Flash audio component (SoundManager 2)",type:"application/x-shockwave-flash",wmode:c.wmode,hasPriority:"true"};if(c.debugFlash)g.FlashVars="debug=1";c.wmode||delete g.wmode;if(v)f=h.createElement("div"),l=['<object id="'+b+'" data="'+a+'" type="'+g.type+'" title="'+g.title+'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="'+
-Fa+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" width="'+g.width+'" height="'+g.height+'">',e("movie",a),e("AllowScriptAccess",c.allowScriptAccess),e("quality",g.quality),c.wmode?e("wmode",c.wmode):"",e("bgcolor",c.bgColor),e("hasPriority","true"),c.debugFlash?e("FlashVars",g.FlashVars):"","</object>"].join("");else for(i in f=h.createElement("embed"),g)g.hasOwnProperty(i)&&f.setAttribute(i,g[i]);ga();j=D();if(g=fa())if(c.oMC=O(c.movieID)||h.createElement("div"),
-c.oMC.id){k=c.oMC.className;c.oMC.className=(k?k+" ":c.swfCSS.swfDefault)+(j?" "+j:"");c.oMC.appendChild(f);if(v)i=c.oMC.appendChild(h.createElement("div")),i.className=c.swfCSS.swfBox,i.innerHTML=l;H=true}else{c.oMC.id=c.movieID;c.oMC.className=c.swfCSS.swfDefault+" "+j;i=j=null;if(!c.useFlashBlock)if(c.useHighPerformance)j={position:"fixed",width:"8px",height:"8px",bottom:"0px",left:"0px",overflow:"hidden"};else if(j={position:"absolute",width:"6px",height:"6px",top:"-9999px",left:"-9999px"},m)j.left=
-Math.abs(parseInt(j.left,10))+"px";if(La)c.oMC.style.zIndex=1E4;if(!c.debugFlash)for(k in j)j.hasOwnProperty(k)&&(c.oMC.style[k]=j[k]);try{v||c.oMC.appendChild(f);g.appendChild(c.oMC);if(v)i=c.oMC.appendChild(h.createElement("div")),i.className=c.swfCSS.swfBox,i.innerHTML=l;H=true}catch(n){throw Error(y("domError")+" \n"+n.toString());}}return G=true};R=function(){if(c.html5Only)return S(),false;if(c.o)return false;c.o=c.getMovie(c.id);if(!c.o)J?(v?c.oMC.innerHTML=ha:c.oMC.appendChild(J),J=null,G=
-true):S(c.id,c.url),c.o=c.getMovie(c.id);c.oninitmovie instanceof Function&&setTimeout(c.oninitmovie,1);return true};Q=function(){setTimeout(ta,1E3)};ta=function(){if(W)return false;W=true;k.remove(i,"load",Q);if(E&&!pa)return false;var b;m||(b=c.getMoviePercent());setTimeout(function(){b=c.getMoviePercent();!m&&Da&&(b===null?c.useFlashBlock||c.flashLoadTimeout===0?c.useFlashBlock&&ia():T(true):c.flashLoadTimeout!==0&&T(true))},c.flashLoadTimeout)};x=function(){function b(){k.remove(i,"focus",x);
-k.remove(i,"load",x)}if(pa||!E)return b(),true;pa=Da=true;M&&E&&k.remove(i,"mousemove",x);W=false;b();return true};Ca=function(){var b,a=[];if(c.useHTML5Audio&&c.hasHTML5)for(b in c.audioFormats)c.audioFormats.hasOwnProperty(b)&&a.push(b+": "+c.html5[b]+(!c.html5[b]&&p&&c.flash[b]?" (using flash)":c.preferFlash&&c.flash[b]&&p?" (preferring flash)":!c.html5[b]?" ("+(c.audioFormats[b].required?"required, ":"")+"and no flash support)":""))};I=function(b){if(m)return false;if(c.html5Only)return m=true,
-A(),true;var a;if(!c.useFlashBlock||!c.flashLoadTimeout||c.getMoviePercent())m=true,t&&(a={type:!p&&q?"NO_FLASH":"INIT_TIMEOUT"});if(t||b){if(c.useFlashBlock&&c.oMC)c.oMC.className=D()+" "+(c.getMoviePercent()===null?c.swfCSS.swfTimedout:c.swfCSS.swfError);z({type:"ontimeout",error:a});C(a);return false}if(c.waitForWindowLoad&&!sa)return k.add(i,"load",A),false;else A();return true};P=function(){if(m)return false;if(c.html5Only){if(!m)k.remove(i,"load",c.beginDelayedInit),c.enabled=true,I();return true}R();
-try{c.o._externalInterfaceTest(false),ua(true,c.flashPollingInterval||(c.useHighPerformance?10:50)),c.debugMode||c.o._disableDebug(),c.enabled=true,c.html5Only||k.add(i,"unload",ba)}catch(b){return C({type:"JS_TO_FLASH_EXCEPTION",fatal:true}),T(true),I(),false}I();k.remove(i,"load",c.beginDelayedInit);return true};B=function(){if(ea)return false;ea=true;ga();if(!p&&c.hasHTML5)c.useHTML5Audio=true,c.preferFlash=false;Aa();c.html5.usingFlash=za();q=c.html5.usingFlash;Ca();if(!p&&q)c.flashLoadTimeout=
-1;h.removeEventListener&&h.removeEventListener("DOMContentLoaded",B,false);R();return true};ma=function(){h.readyState==="complete"&&(B(),h.detachEvent("onreadystatechange",ma));return true};Y();k.add(i,"focus",x);k.add(i,"load",x);k.add(i,"load",Q);M&&E&&k.add(i,"mousemove",x);h.addEventListener?h.addEventListener("DOMContentLoaded",B,false):h.attachEvent?h.attachEvent("onreadystatechange",ma):C({type:"NO_DOM2_EVENTS",fatal:true});h.readyState==="complete"&&setTimeout(B,100)}var Z=null;if(typeof SM2_DEFER===
-"undefined"||!SM2_DEFER)Z=new N;$.SoundManager=N;$.soundManager=Z})(window);
\ No newline at end of file
+++ /dev/null
-/** @license\r
- *\r
- * SoundManager 2: JavaScript Sound for the Web\r
- * ----------------------------------------------\r
- * http://schillmania.com/projects/soundmanager2/\r
- *\r
- * Copyright (c) 2007, Scott Schiller. All rights reserved.\r
- * Code provided under the BSD License:\r
- * http://schillmania.com/projects/soundmanager2/license.txt\r
- *\r
- * V2.97a.20111030\r
- */\r
-\r
-/*global window, SM2_DEFER, sm2Debugger, console, document, navigator, setTimeout, setInterval, clearInterval, Audio */\r
-/* jslint regexp: true, sloppy: true, white: true, nomen: true, plusplus: true */\r
-\r
-(function(window) {\r
-var soundManager = null;\r
-function SoundManager(smURL, smID) {\r
- this.flashVersion = 8;\r
- this.debugMode = false;\r
- this.debugFlash = false;\r
- this.useConsole = true;\r
- this.consoleOnly = false;\r
- this.waitForWindowLoad = false;\r
- this.bgColor = '#ffffff';\r
- this.useHighPerformance = false;\r
- this.flashPollingInterval = null;\r
- this.flashLoadTimeout = 1000;\r
- this.wmode = null;\r
- this.allowScriptAccess = 'always';\r
- this.useFlashBlock = false;\r
- this.useHTML5Audio = true;\r
- this.html5Test = /^(probably|maybe)$/i;\r
- this.preferFlash = true;\r
- this.noSWFCache = false;\r
- this.audioFormats = {\r
- 'mp3': {\r
- 'type': ['audio/mpeg; codecs="mp3"', 'audio/mpeg', 'audio/mp3', 'audio/MPA', 'audio/mpa-robust'],\r
- 'required': true\r
- },\r
- 'mp4': {\r
- 'related': ['aac','m4a'],\r
- 'type': ['audio/mp4; codecs="mp4a.40.2"', 'audio/aac', 'audio/x-m4a', 'audio/MP4A-LATM', 'audio/mpeg4-generic'],\r
- 'required': false\r
- },\r
- 'ogg': {\r
- 'type': ['audio/ogg; codecs=vorbis'],\r
- 'required': false\r
- },\r
- 'wav': {\r
- 'type': ['audio/wav; codecs="1"', 'audio/wav', 'audio/wave', 'audio/x-wav'],\r
- 'required': false\r
- }\r
- };\r
- this.defaultOptions = {\r
- 'autoLoad': false,\r
- 'stream': true,\r
- 'autoPlay': false,\r
- 'loops': 1,\r
- 'onid3': null,\r
- 'onload': null,\r
- 'whileloading': null,\r
- 'onplay': null,\r
- 'onpause': null,\r
- 'onresume': null,\r
- 'whileplaying': null,\r
- 'onstop': null,\r
- 'onfailure': null,\r
- 'onfinish': null,\r
- 'multiShot': true,\r
- 'multiShotEvents': false,\r
- 'position': null,\r
- 'pan': 0,\r
- 'type': null,\r
- 'usePolicyFile': false,\r
- 'volume': 100\r
- };\r
- this.flash9Options = {\r
- 'isMovieStar': null,\r
- 'usePeakData': false,\r
- 'useWaveformData': false,\r
- 'useEQData': false,\r
- 'onbufferchange': null,\r
- 'ondataerror': null\r
- };\r
- this.movieStarOptions = {\r
- 'bufferTime': 3,\r
- 'serverURL': null,\r
- 'onconnect': null,\r
- 'duration': null\r
- };\r
- this.movieID = 'sm2-container';\r
- this.id = (smID || 'sm2movie');\r
- this.swfCSS = {\r
- 'swfBox': 'sm2-object-box',\r
- 'swfDefault': 'movieContainer',\r
- 'swfError': 'swf_error',\r
- 'swfTimedout': 'swf_timedout',\r
- 'swfLoaded': 'swf_loaded',\r
- 'swfUnblocked': 'swf_unblocked',\r
- 'sm2Debug': 'sm2_debug',\r
- 'highPerf': 'high_performance',\r
- 'flashDebug': 'flash_debug'\r
- };\r
- this.debugID = 'soundmanager-debug';\r
- this.debugURLParam = /([#?&])debug=1/i;\r
- this.versionNumber = 'V2.97a.20111030';\r
- this.version = null;\r
- this.movieURL = null;\r
- this.url = (smURL || null);\r
- this.altURL = null;\r
- this.swfLoaded = false;\r
- this.enabled = false;\r
- this.o = null;\r
- this.oMC = null;\r
- this.sounds = {};\r
- this.soundIDs = [];\r
- this.muted = false;\r
- this.specialWmodeCase = false;\r
- this.didFlashBlock = false;\r
- this.filePattern = null;\r
- this.filePatterns = {\r
- 'flash8': /\.mp3(\?.*)?$/i,\r
- 'flash9': /\.mp3(\?.*)?$/i\r
- };\r
- this.features = {\r
- 'buffering': false,\r
- 'peakData': false,\r
- 'waveformData': false,\r
- 'eqData': false,\r
- 'movieStar': false\r
- };\r
- this.sandbox = {\r
- };\r
- this.hasHTML5 = (function() {\r
- try {\r
- return (typeof Audio !== 'undefined' && typeof new Audio().canPlayType !== 'undefined');\r
- } catch(e) {\r
- return false;\r
- }\r
- }());\r
- this.html5 = {\r
- 'usingFlash': null\r
- };\r
- this.flash = {};\r
- this.html5Only = false;\r
- this.ignoreFlash = false;\r
- var SMSound,\r
- _s = this, _sm = 'soundManager', _smc = _sm+'::', _h5 = 'HTML5::', _id, _ua = navigator.userAgent, _win = window, _wl = _win.location.href.toString(), _doc = document, _doNothing, _init, _fV, _on_queue = [], _debugOpen = true, _debugTS, _didAppend = false, _appendSuccess = false, _didInit = false, _disabled = false, _windowLoaded = false, _wDS, _wdCount = 0, _initComplete, _mixin, _addOnEvent, _processOnEvents, _initUserOnload, _delayWaitForEI, _waitForEI, _setVersionInfo, _handleFocus, _strings, _initMovie, _domContentLoaded, _didDCLoaded, _getDocument, _createMovie, _catchError, _setPolling, _initDebug, _debugLevels = ['log', 'info', 'warn', 'error'], _defaultFlashVersion = 8, _disableObject, _failSafely, _normalizeMovieURL, _oRemoved = null, _oRemovedHTML = null, _str, _flashBlockHandler, _getSWFCSS, _toggleDebug, _loopFix, _policyFix, _complain, _idCheck, _waitingForEI = false, _initPending = false, _smTimer, _onTimer, _startTimer, _stopTimer, _needsFlash = null, _featureCheck, _html5OK, _html5CanPlay, _html5Ext, _html5Unload, _domContentLoadedIE, _testHTML5, _event, _slice = Array.prototype.slice, _useGlobalHTML5Audio = false, _hasFlash, _detectFlash, _badSafariFix, _html5_events, _showSupport,\r
- _is_iDevice = _ua.match(/(ipad|iphone|ipod)/i), _is_firefox = _ua.match(/firefox/i), _is_android = _ua.match(/droid/i), _isIE = _ua.match(/msie/i), _isWebkit = _ua.match(/webkit/i), _isSafari = (_ua.match(/safari/i) && !_ua.match(/chrome/i)), _isOpera = (_ua.match(/opera/i)),\r
- _likesHTML5 = (_ua.match(/(mobile|pre\/|xoom)/i) || _is_iDevice),\r
- _isBadSafari = (!_wl.match(/usehtml5audio/i) && !_wl.match(/sm2\-ignorebadua/i) && _isSafari && _ua.match(/OS X 10_6_([3-7])/i)),\r
- _hasConsole = (typeof console !== 'undefined' && typeof console.log !== 'undefined'), _isFocused = (typeof _doc.hasFocus !== 'undefined'?_doc.hasFocus():null), _tryInitOnFocus = (_isSafari && typeof _doc.hasFocus === 'undefined'), _okToDisable = !_tryInitOnFocus, _flashMIME = /(mp3|mp4|mpa)/i,\r
- _emptyURL = 'about:blank',\r
- _overHTTP = (_doc.location?_doc.location.protocol.match(/http/i):null),\r
- _http = (!_overHTTP ? 'http:/'+'/' : ''),\r
- _netStreamMimeTypes = /^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|mp4v|3gp|3g2)\s*(?:$|;)/i,\r
- _netStreamTypes = ['mpeg4', 'aac', 'flv', 'mov', 'mp4', 'm4v', 'f4v', 'm4a', 'mp4v', '3gp', '3g2'],\r
- _netStreamPattern = new RegExp('\\.(' + _netStreamTypes.join('|') + ')(\\?.*)?$', 'i');\r
- this.mimePattern = /^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i;\r
- this.useAltURL = !_overHTTP;\r
- this._global_a = null;\r
- if (_likesHTML5) {\r
- _s.useHTML5Audio = true;\r
- _s.preferFlash = false;\r
- if (_is_iDevice) {\r
- _s.ignoreFlash = true;\r
- _useGlobalHTML5Audio = true;\r
- }\r
- }\r
- this.ok = function() {\r
- return (_needsFlash?(_didInit && !_disabled):(_s.useHTML5Audio && _s.hasHTML5));\r
- };\r
- this.supported = this.ok;\r
- this.getMovie = function(smID) {\r
- return _id(smID) || _doc[smID] || _win[smID];\r
- };\r
- this.createSound = function(oOptions) {\r
- var _cs = _sm+'.createSound(): ',\r
- thisOptions = null, oSound = null, _tO = null;\r
- if (!_didInit || !_s.ok()) {\r
- _complain(_cs + _str(!_didInit?'notReady':'notOK'));\r
- return false;\r
- }\r
- if (arguments.length === 2) {\r
- oOptions = {\r
- 'id': arguments[0],\r
- 'url': arguments[1]\r
- };\r
- }\r
- thisOptions = _mixin(oOptions);\r
- _tO = thisOptions;\r
- if (_idCheck(_tO.id, true)) {\r
- return _s.sounds[_tO.id];\r
- }\r
- function make() {\r
- thisOptions = _loopFix(thisOptions);\r
- _s.sounds[_tO.id] = new SMSound(_tO);\r
- _s.soundIDs.push(_tO.id);\r
- return _s.sounds[_tO.id];\r
- }\r
- if (_html5OK(_tO)) {\r
- oSound = make();\r
- oSound._setup_html5(_tO);\r
- } else {\r
- if (_fV > 8) {\r
- if (_tO.isMovieStar === null) {\r
- _tO.isMovieStar = (_tO.serverURL || (_tO.type ? _tO.type.match(_netStreamMimeTypes) : false) || _tO.url.match(_netStreamPattern));\r
- }\r
- if (_tO.isMovieStar) {\r
- if (_tO.usePeakData) {\r
- _tO.usePeakData = false;\r
- }\r
- }\r
- }\r
- _tO = _policyFix(_tO, _cs);\r
- oSound = make();\r
- if (_fV === 8) {\r
- _s.o._createSound(_tO.id, _tO.loops||1, _tO.usePolicyFile);\r
- } else {\r
- _s.o._createSound(_tO.id, _tO.url, _tO.usePeakData, _tO.useWaveformData, _tO.useEQData, _tO.isMovieStar, (_tO.isMovieStar?_tO.bufferTime:false), _tO.loops||1, _tO.serverURL, _tO.duration||null, _tO.autoPlay, true, _tO.autoLoad, _tO.usePolicyFile);\r
- if (!_tO.serverURL) {\r
- oSound.connected = true;\r
- if (_tO.onconnect) {\r
- _tO.onconnect.apply(oSound);\r
- }\r
- }\r
- }\r
- if (!_tO.serverURL && (_tO.autoLoad || _tO.autoPlay)) {\r
- oSound.load(_tO);\r
- }\r
- }\r
- if (!_tO.serverURL && _tO.autoPlay) {\r
- oSound.play();\r
- }\r
- return oSound;\r
- };\r
- this.destroySound = function(sID, _bFromSound) {\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
- var oS = _s.sounds[sID], i;\r
- oS._iO = {};\r
- oS.stop();\r
- oS.unload();\r
- for (i = 0; i < _s.soundIDs.length; i++) {\r
- if (_s.soundIDs[i] === sID) {\r
- _s.soundIDs.splice(i, 1);\r
- break;\r
- }\r
- }\r
- if (!_bFromSound) {\r
- oS.destruct(true);\r
- }\r
- oS = null;\r
- delete _s.sounds[sID];\r
- return true;\r
- };\r
- this.load = function(sID, oOptions) {\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
- return _s.sounds[sID].load(oOptions);\r
- };\r
- this.unload = function(sID) {\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
- return _s.sounds[sID].unload();\r
- };\r
- this.onposition = function(sID, nPosition, oMethod, oScope) {\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
- return _s.sounds[sID].onposition(nPosition, oMethod, oScope);\r
- };\r
- this.play = function(sID, oOptions) {\r
- var fN = _sm+'.play(): ';\r
- if (!_didInit || !_s.ok()) {\r
- _complain(fN + _str(!_didInit?'notReady':'notOK'));\r
- return false;\r
- }\r
- if (!_idCheck(sID)) {\r
- if (!(oOptions instanceof Object)) {\r
- oOptions = {\r
- url: oOptions\r
- };\r
- }\r
- if (oOptions && oOptions.url) {\r
- oOptions.id = sID;\r
- return _s.createSound(oOptions).play();\r
- } else {\r
- return false;\r
- }\r
- }\r
- return _s.sounds[sID].play(oOptions);\r
- };\r
- this.start = this.play;\r
- this.setPosition = function(sID, nMsecOffset) {\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
- return _s.sounds[sID].setPosition(nMsecOffset);\r
- };\r
- this.stop = function(sID) {\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
- return _s.sounds[sID].stop();\r
- };\r
- this.stopAll = function() {\r
- var oSound;\r
- for (oSound in _s.sounds) {\r
- if (_s.sounds.hasOwnProperty(oSound)) {\r
- _s.sounds[oSound].stop();\r
- }\r
- }\r
- };\r
- this.pause = function(sID) {\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
- return _s.sounds[sID].pause();\r
- };\r
- this.pauseAll = function() {\r
- var i;\r
- for (i = _s.soundIDs.length; i--;) {\r
- _s.sounds[_s.soundIDs[i]].pause();\r
- }\r
- };\r
- this.resume = function(sID) {\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
- return _s.sounds[sID].resume();\r
- };\r
- this.resumeAll = function() {\r
- var i;\r
- for (i = _s.soundIDs.length; i--;) {\r
- _s.sounds[_s.soundIDs[i]].resume();\r
- }\r
- };\r
- this.togglePause = function(sID) {\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
- return _s.sounds[sID].togglePause();\r
- };\r
- this.setPan = function(sID, nPan) {\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
- return _s.sounds[sID].setPan(nPan);\r
- };\r
- this.setVolume = function(sID, nVol) {\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
- return _s.sounds[sID].setVolume(nVol);\r
- };\r
- this.mute = function(sID) {\r
- var fN = _sm+'.mute(): ',\r
- i = 0;\r
- if (typeof sID !== 'string') {\r
- sID = null;\r
- }\r
- if (!sID) {\r
- for (i = _s.soundIDs.length; i--;) {\r
- _s.sounds[_s.soundIDs[i]].mute();\r
- }\r
- _s.muted = true;\r
- } else {\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
- return _s.sounds[sID].mute();\r
- }\r
- return true;\r
- };\r
- this.muteAll = function() {\r
- _s.mute();\r
- };\r
- this.unmute = function(sID) {\r
- var fN = _sm+'.unmute(): ', i;\r
- if (typeof sID !== 'string') {\r
- sID = null;\r
- }\r
- if (!sID) {\r
- for (i = _s.soundIDs.length; i--;) {\r
- _s.sounds[_s.soundIDs[i]].unmute();\r
- }\r
- _s.muted = false;\r
- } else {\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
- return _s.sounds[sID].unmute();\r
- }\r
- return true;\r
- };\r
- this.unmuteAll = function() {\r
- _s.unmute();\r
- };\r
- this.toggleMute = function(sID) {\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
- return _s.sounds[sID].toggleMute();\r
- };\r
- this.getMemoryUse = function() {\r
- var ram = 0;\r
- if (_s.o && _fV !== 8) {\r
- ram = parseInt(_s.o._getMemoryUse(), 10);\r
- }\r
- return ram;\r
- };\r
- this.disable = function(bNoDisable) {\r
- var i;\r
- if (typeof bNoDisable === 'undefined') {\r
- bNoDisable = false;\r
- }\r
- if (_disabled) {\r
- return false;\r
- }\r
- _disabled = true;\r
- for (i = _s.soundIDs.length; i--;) {\r
- _disableObject(_s.sounds[_s.soundIDs[i]]);\r
- }\r
- _initComplete(bNoDisable);\r
- _event.remove(_win, 'load', _initUserOnload);\r
- return true;\r
- };\r
- this.canPlayMIME = function(sMIME) {\r
- var result;\r
- if (_s.hasHTML5) {\r
- result = _html5CanPlay({type:sMIME});\r
- }\r
- if (!_needsFlash || result) {\r
- return result;\r
- } else {\r
- return (sMIME ? !!((_fV > 8 ? sMIME.match(_netStreamMimeTypes) : null) || sMIME.match(_s.mimePattern)) : null);\r
- }\r
- };\r
- this.canPlayURL = function(sURL) {\r
- var result;\r
- if (_s.hasHTML5) {\r
- result = _html5CanPlay({url: sURL});\r
- }\r
- if (!_needsFlash || result) {\r
- return result;\r
- } else {\r
- return (sURL ? !!(sURL.match(_s.filePattern)) : null);\r
- }\r
- };\r
- this.canPlayLink = function(oLink) {\r
- if (typeof oLink.type !== 'undefined' && oLink.type) {\r
- if (_s.canPlayMIME(oLink.type)) {\r
- return true;\r
- }\r
- }\r
- return _s.canPlayURL(oLink.href);\r
- };\r
- this.getSoundById = function(sID, _suppressDebug) {\r
- if (!sID) {\r
- throw new Error(_sm+'.getSoundById(): sID is null/undefined');\r
- }\r
- var result = _s.sounds[sID];\r
- return result;\r
- };\r
- this.onready = function(oMethod, oScope) {\r
- var sType = 'onready';\r
- if (oMethod && oMethod instanceof Function) {\r
- if (!oScope) {\r
- oScope = _win;\r
- }\r
- _addOnEvent(sType, oMethod, oScope);\r
- _processOnEvents();\r
- return true;\r
- } else {\r
- throw _str('needFunction', sType);\r
- }\r
- };\r
- this.ontimeout = function(oMethod, oScope) {\r
- var sType = 'ontimeout';\r
- if (oMethod && oMethod instanceof Function) {\r
- if (!oScope) {\r
- oScope = _win;\r
- }\r
- _addOnEvent(sType, oMethod, oScope);\r
- _processOnEvents({type:sType});\r
- return true;\r
- } else {\r
- throw _str('needFunction', sType);\r
- }\r
- };\r
- this._writeDebug = function(sText, sType, _bTimestamp) {\r
- return true;\r
- };\r
- this._wD = this._writeDebug;\r
- this._debug = function() {\r
- };\r
- this.reboot = function() {\r
- var i, j;\r
- for (i = _s.soundIDs.length; i--;) {\r
- _s.sounds[_s.soundIDs[i]].destruct();\r
- }\r
- try {\r
- if (_isIE) {\r
- _oRemovedHTML = _s.o.innerHTML;\r
- }\r
- _oRemoved = _s.o.parentNode.removeChild(_s.o);\r
- } catch(e) {\r
- }\r
- _oRemovedHTML = _oRemoved = _needsFlash = null;\r
- _s.enabled = _didDCLoaded = _didInit = _waitingForEI = _initPending = _didAppend = _appendSuccess = _disabled = _s.swfLoaded = false;\r
- _s.soundIDs = _s.sounds = [];\r
- _s.o = null;\r
- for (i in _on_queue) {\r
- if (_on_queue.hasOwnProperty(i)) {\r
- for (j = _on_queue[i].length; j--;) {\r
- _on_queue[i][j].fired = false;\r
- }\r
- }\r
- }\r
- _win.setTimeout(_s.beginDelayedInit, 20);\r
- };\r
- this.getMoviePercent = function() {\r
- return (_s.o && typeof _s.o.PercentLoaded !== 'undefined' ? _s.o.PercentLoaded() : null);\r
- };\r
- this.beginDelayedInit = function() {\r
- _windowLoaded = true;\r
- _domContentLoaded();\r
- setTimeout(function() {\r
- if (_initPending) {\r
- return false;\r
- }\r
- _createMovie();\r
- _initMovie();\r
- _initPending = true;\r
- return true;\r
- }, 20);\r
- _delayWaitForEI();\r
- };\r
- this.destruct = function() {\r
- _s.disable(true);\r
- };\r
- SMSound = function(oOptions) {\r
- var _t = this, _resetProperties, _stop_html5_timer, _start_html5_timer;\r
- this.sID = oOptions.id;\r
- this.url = oOptions.url;\r
- this.options = _mixin(oOptions);\r
- this.instanceOptions = this.options;\r
- this._iO = this.instanceOptions;\r
- this.pan = this.options.pan;\r
- this.volume = this.options.volume;\r
- this._lastURL = null;\r
- this.isHTML5 = false;\r
- this._a = null;\r
- this.id3 = {};\r
- this._debug = function() {\r
- };\r
- this.load = function(oOptions) {\r
- var oS = null;\r
- if (typeof oOptions !== 'undefined') {\r
- _t._iO = _mixin(oOptions, _t.options);\r
- _t.instanceOptions = _t._iO;\r
- } else {\r
- oOptions = _t.options;\r
- _t._iO = oOptions;\r
- _t.instanceOptions = _t._iO;\r
- if (_t._lastURL && _t._lastURL !== _t.url) {\r
- _t._iO.url = _t.url;\r
- _t.url = null;\r
- }\r
- }\r
- if (!_t._iO.url) {\r
- _t._iO.url = _t.url;\r
- }\r
- if (_t._iO.url === _t.url && _t.readyState !== 0 && _t.readyState !== 2) {\r
- return _t;\r
- }\r
- _t._lastURL = _t.url;\r
- _t.loaded = false;\r
- _t.readyState = 1;\r
- _t.playState = 0;\r
- if (_html5OK(_t._iO)) {\r
- oS = _t._setup_html5(_t._iO);\r
- if (!oS._called_load) {\r
- _t._html5_canplay = false;\r
- oS.load();\r
- oS._called_load = true;\r
- if (_t._iO.autoPlay) {\r
- _t.play();\r
- }\r
- } else {\r
- }\r
- } else {\r
- try {\r
- _t.isHTML5 = false;\r
- _t._iO = _policyFix(_loopFix(_t._iO));\r
- if (_fV === 8) {\r
- _s.o._load(_t.sID, _t._iO.url, _t._iO.stream, _t._iO.autoPlay, (_t._iO.whileloading?1:0), _t._iO.loops||1, _t._iO.usePolicyFile);\r
- } else {\r
- _s.o._load(_t.sID, _t._iO.url, !!(_t._iO.stream), !!(_t._iO.autoPlay), _t._iO.loops||1, !!(_t._iO.autoLoad), _t._iO.usePolicyFile);\r
- }\r
- } catch(e) {\r
- _catchError({type:'SMSOUND_LOAD_JS_EXCEPTION', fatal:true});\r
- }\r
- }\r
- return _t;\r
- };\r
- this.unload = function() {\r
- if (_t.readyState !== 0) {\r
- if (!_t.isHTML5) {\r
- if (_fV === 8) {\r
- _s.o._unload(_t.sID, _emptyURL);\r
- } else {\r
- _s.o._unload(_t.sID);\r
- }\r
- } else {\r
- _stop_html5_timer();\r
- if (_t._a) {\r
- _t._a.pause();\r
- _html5Unload(_t._a);\r
- }\r
- }\r
- _resetProperties();\r
- }\r
- return _t;\r
- };\r
- this.destruct = function(_bFromSM) {\r
- if (!_t.isHTML5) {\r
- _t._iO.onfailure = null;\r
- _s.o._destroySound(_t.sID);\r
- } else {\r
- _stop_html5_timer();\r
- if (_t._a) {\r
- _t._a.pause();\r
- _html5Unload(_t._a);\r
- if (!_useGlobalHTML5Audio) {\r
- _t._remove_html5_events();\r
- }\r
- _t._a._t = null;\r
- _t._a = null;\r
- }\r
- }\r
- if (!_bFromSM) {\r
- _s.destroySound(_t.sID, true);\r
- }\r
- };\r
- this.play = function(oOptions, _updatePlayState) {\r
- var fN = 'SMSound.play(): ', allowMulti, a;\r
- _updatePlayState = _updatePlayState === undefined ? true : _updatePlayState;\r
- if (!oOptions) {\r
- oOptions = {};\r
- }\r
- _t._iO = _mixin(oOptions, _t._iO);\r
- _t._iO = _mixin(_t._iO, _t.options);\r
- _t.instanceOptions = _t._iO;\r
- if (_t._iO.serverURL && !_t.connected) {\r
- if (!_t.getAutoPlay()) {\r
- _t.setAutoPlay(true);\r
- }\r
- return _t;\r
- }\r
- if (_html5OK(_t._iO)) {\r
- _t._setup_html5(_t._iO);\r
- _start_html5_timer();\r
- }\r
- if (_t.playState === 1 && !_t.paused) {\r
- allowMulti = _t._iO.multiShot;\r
- if (!allowMulti) {\r
- return _t;\r
- } else {\r
- }\r
- }\r
- if (!_t.loaded) {\r
- if (_t.readyState === 0) {\r
- if (!_t.isHTML5) {\r
- _t._iO.autoPlay = true;\r
- }\r
- _t.load(_t._iO);\r
- } else if (_t.readyState === 2) {\r
- return _t;\r
- } else {\r
- }\r
- } else {\r
- }\r
- if (!_t.isHTML5 && _fV === 9 && _t.position > 0 && _t.position === _t.duration) {\r
- _t._iO.position = 0;\r
- }\r
- if (_t.paused && _t.position && _t.position > 0) {\r
- _t.resume();\r
- } else {\r
- _t.playState = 1;\r
- _t.paused = false;\r
- if (!_t.instanceCount || _t._iO.multiShotEvents || (!_t.isHTML5 && _fV > 8 && !_t.getAutoPlay())) {\r
- _t.instanceCount++;\r
- }\r
- _t.position = (typeof _t._iO.position !== 'undefined' && !isNaN(_t._iO.position)?_t._iO.position:0);\r
- if (!_t.isHTML5) {\r
- _t._iO = _policyFix(_loopFix(_t._iO));\r
- }\r
- if (_t._iO.onplay && _updatePlayState) {\r
- _t._iO.onplay.apply(_t);\r
- _t._onplay_called = true;\r
- }\r
- _t.setVolume(_t._iO.volume, true);\r
- _t.setPan(_t._iO.pan, true);\r
- if (!_t.isHTML5) {\r
- _s.o._start(_t.sID, _t._iO.loops || 1, (_fV === 9?_t._iO.position:_t._iO.position / 1000));\r
- } else {\r
- _start_html5_timer();\r
- a = _t._setup_html5();\r
- _t.setPosition(_t._iO.position);\r
- a.play();\r
- }\r
- }\r
- return _t;\r
- };\r
- this.start = this.play;\r
- this.stop = function(bAll) {\r
- if (_t.playState === 1) {\r
- _t._onbufferchange(0);\r
- _t.resetOnPosition(0);\r
- _t.paused = false;\r
- if (!_t.isHTML5) {\r
- _t.playState = 0;\r
- }\r
- if (_t._iO.onstop) {\r
- _t._iO.onstop.apply(_t);\r
- }\r
- if (!_t.isHTML5) {\r
- _s.o._stop(_t.sID, bAll);\r
- if (_t._iO.serverURL) {\r
- _t.unload();\r
- }\r
- } else {\r
- if (_t._a) {\r
- _t.setPosition(0);\r
- _t._a.pause();\r
- _t.playState = 0;\r
- _t._onTimer();\r
- _stop_html5_timer();\r
- }\r
- }\r
- _t.instanceCount = 0;\r
- _t._iO = {};\r
- }\r
- return _t;\r
- };\r
- this.setAutoPlay = function(autoPlay) {\r
- _t._iO.autoPlay = autoPlay;\r
- if (!_t.isHTML5) {\r
- _s.o._setAutoPlay(_t.sID, autoPlay);\r
- if (autoPlay) {\r
- if (!_t.instanceCount && _t.readyState === 1) {\r
- _t.instanceCount++;\r
- }\r
- }\r
- }\r
- };\r
- this.getAutoPlay = function() {\r
- return _t._iO.autoPlay;\r
- };\r
- this.setPosition = function(nMsecOffset) {\r
- if (nMsecOffset === undefined) {\r
- nMsecOffset = 0;\r
- }\r
- var original_pos,\r
- position, position1K,\r
- offset = (_t.isHTML5 ? Math.max(nMsecOffset,0) : Math.min(_t.duration || _t._iO.duration, Math.max(nMsecOffset, 0)));\r
- original_pos = _t.position;\r
- _t.position = offset;\r
- position1K = _t.position/1000;\r
- _t.resetOnPosition(_t.position);\r
- _t._iO.position = offset;\r
- if (!_t.isHTML5) {\r
- position = (_fV === 9 ? _t.position : position1K);\r
- if (_t.readyState && _t.readyState !== 2) {\r
- _s.o._setPosition(_t.sID, position, (_t.paused || !_t.playState));\r
- }\r
- } else if (_t._a) {\r
- if (_t._html5_canplay) {\r
- if (_t._a.currentTime !== position1K) {\r
- try {\r
- _t._a.currentTime = position1K;\r
- if (_t.playState === 0 || _t.paused) {\r
- _t._a.pause();\r
- }\r
- } catch(e) {\r
- }\r
- }\r
- } else {\r
- }\r
- }\r
- if (_t.isHTML5) {\r
- if (_t.paused) {\r
- _t._onTimer(true);\r
- }\r
- }\r
- return _t;\r
- };\r
- this.pause = function(_bCallFlash) {\r
- if (_t.paused || (_t.playState === 0 && _t.readyState !== 1)) {\r
- return _t;\r
- }\r
- _t.paused = true;\r
- if (!_t.isHTML5) {\r
- if (_bCallFlash || _bCallFlash === undefined) {\r
- _s.o._pause(_t.sID);\r
- }\r
- } else {\r
- _t._setup_html5().pause();\r
- _stop_html5_timer();\r
- }\r
- if (_t._iO.onpause) {\r
- _t._iO.onpause.apply(_t);\r
- }\r
- return _t;\r
- };\r
- this.resume = function() {\r
- if (!_t.paused) {\r
- return _t;\r
- }\r
- _t.paused = false;\r
- _t.playState = 1;\r
- if (!_t.isHTML5) {\r
- if (_t._iO.isMovieStar) {\r
- _t.setPosition(_t.position);\r
- }\r
- _s.o._pause(_t.sID);\r
- } else {\r
- _t._setup_html5().play();\r
- _start_html5_timer();\r
- }\r
- if (!_t._onplay_called && _t._iO.onplay) {\r
- _t._iO.onplay.apply(_t);\r
- _t._onplay_called = true;\r
- } else if (_t._iO.onresume) {\r
- _t._iO.onresume.apply(_t);\r
- }\r
- return _t;\r
- };\r
- this.togglePause = function() {\r
- if (_t.playState === 0) {\r
- _t.play({\r
- position: (_fV === 9 && !_t.isHTML5 ? _t.position : _t.position / 1000)\r
- });\r
- return _t;\r
- }\r
- if (_t.paused) {\r
- _t.resume();\r
- } else {\r
- _t.pause();\r
- }\r
- return _t;\r
- };\r
- this.setPan = function(nPan, bInstanceOnly) {\r
- if (typeof nPan === 'undefined') {\r
- nPan = 0;\r
- }\r
- if (typeof bInstanceOnly === 'undefined') {\r
- bInstanceOnly = false;\r
- }\r
- if (!_t.isHTML5) {\r
- _s.o._setPan(_t.sID, nPan);\r
- }\r
- _t._iO.pan = nPan;\r
- if (!bInstanceOnly) {\r
- _t.pan = nPan;\r
- _t.options.pan = nPan;\r
- }\r
- return _t;\r
- };\r
- this.setVolume = function(nVol, _bInstanceOnly) {\r
- if (typeof nVol === 'undefined') {\r
- nVol = 100;\r
- }\r
- if (typeof _bInstanceOnly === 'undefined') {\r
- _bInstanceOnly = false;\r
- }\r
- if (!_t.isHTML5) {\r
- _s.o._setVolume(_t.sID, (_s.muted && !_t.muted) || _t.muted?0:nVol);\r
- } else if (_t._a) {\r
- _t._a.volume = Math.max(0, Math.min(1, nVol/100));\r
- }\r
- _t._iO.volume = nVol;\r
- if (!_bInstanceOnly) {\r
- _t.volume = nVol;\r
- _t.options.volume = nVol;\r
- }\r
- return _t;\r
- };\r
- this.mute = function() {\r
- _t.muted = true;\r
- if (!_t.isHTML5) {\r
- _s.o._setVolume(_t.sID, 0);\r
- } else if (_t._a) {\r
- _t._a.muted = true;\r
- }\r
- return _t;\r
- };\r
- this.unmute = function() {\r
- _t.muted = false;\r
- var hasIO = typeof _t._iO.volume !== 'undefined';\r
- if (!_t.isHTML5) {\r
- _s.o._setVolume(_t.sID, hasIO?_t._iO.volume:_t.options.volume);\r
- } else if (_t._a) {\r
- _t._a.muted = false;\r
- }\r
- return _t;\r
- };\r
- this.toggleMute = function() {\r
- return (_t.muted?_t.unmute():_t.mute());\r
- };\r
- this.onposition = function(nPosition, oMethod, oScope) {\r
- _t._onPositionItems.push({\r
- position: nPosition,\r
- method: oMethod,\r
- scope: (typeof oScope !== 'undefined'?oScope:_t),\r
- fired: false\r
- });\r
- return _t;\r
- };\r
- this.processOnPosition = function() {\r
- var i, item, j = _t._onPositionItems.length;\r
- if (!j || !_t.playState || _t._onPositionFired >= j) {\r
- return false;\r
- }\r
- for (i=j; i--;) {\r
- item = _t._onPositionItems[i];\r
- if (!item.fired && _t.position >= item.position) {\r
- item.fired = true;\r
- _s._onPositionFired++;\r
- item.method.apply(item.scope,[item.position]);\r
- }\r
- }\r
- return true;\r
- };\r
- this.resetOnPosition = function(nPosition) {\r
- var i, item, j = _t._onPositionItems.length;\r
- if (!j) {\r
- return false;\r
- }\r
- for (i=j; i--;) {\r
- item = _t._onPositionItems[i];\r
- if (item.fired && nPosition <= item.position) {\r
- item.fired = false;\r
- _s._onPositionFired--;\r
- }\r
- }\r
- return true;\r
- };\r
- _start_html5_timer = function() {\r
- if (_t.isHTML5) {\r
- _startTimer(_t);\r
- }\r
- };\r
- _stop_html5_timer = function() {\r
- if (_t.isHTML5) {\r
- _stopTimer(_t);\r
- }\r
- };\r
- _resetProperties = function() {\r
- _t._onPositionItems = [];\r
- _t._onPositionFired = 0;\r
- _t._hasTimer = null;\r
- _t._onplay_called = false;\r
- _t._a = null;\r
- _t._html5_canplay = false;\r
- _t.bytesLoaded = null;\r
- _t.bytesTotal = null;\r
- _t.position = null;\r
- _t.duration = (_t._iO && _t._iO.duration?_t._iO.duration:null);\r
- _t.durationEstimate = null;\r
- _t.failures = 0;\r
- _t.loaded = false;\r
- _t.playState = 0;\r
- _t.paused = false;\r
- _t.readyState = 0;\r
- _t.muted = false;\r
- _t.isBuffering = false;\r
- _t.instanceOptions = {};\r
- _t.instanceCount = 0;\r
- _t.peakData = {\r
- left: 0,\r
- right: 0\r
- };\r
- _t.waveformData = {\r
- left: [],\r
- right: []\r
- };\r
- _t.eqData = [];\r
- _t.eqData.left = [];\r
- _t.eqData.right = [];\r
- };\r
- _resetProperties();\r
- this._onTimer = function(bForce) {\r
- var time, x = {};\r
- if (_t._hasTimer || bForce) {\r
- if (_t._a && (bForce || ((_t.playState > 0 || _t.readyState === 1) && !_t.paused))) {\r
- _t.duration = _t._get_html5_duration();\r
- _t.durationEstimate = _t.duration;\r
- time = _t._a.currentTime?_t._a.currentTime*1000:0;\r
- _t._whileplaying(time,x,x,x,x);\r
- return true;\r
- } else {\r
- return false;\r
- }\r
- }\r
- };\r
- this._get_html5_duration = function() {\r
- var d = (_t._a ? _t._a.duration*1000 : (_t._iO ? _t._iO.duration : undefined)),\r
- result = (d && !isNaN(d) && d !== Infinity ? d : (_t._iO ? _t._iO.duration : null));\r
- return result;\r
- };\r
- this._setup_html5 = function(oOptions) {\r
- var _iO = _mixin(_t._iO, oOptions), d = decodeURI,\r
- _a = _useGlobalHTML5Audio ? _s._global_a : _t._a,\r
- _dURL = d(_iO.url),\r
- _oldIO = (_a && _a._t ? _a._t.instanceOptions : null);\r
- if (_a) {\r
- if (_a._t && _oldIO.url === _iO.url && (!_t._lastURL || (_t._lastURL === _oldIO.url))) {\r
- return _a;\r
- }\r
- if (_useGlobalHTML5Audio && _a._t && _a._t.playState && _iO.url !== _oldIO.url) {\r
- _a._t.stop();\r
- }\r
- _resetProperties();\r
- _a.src = _iO.url;\r
- _t.url = _iO.url;\r
- _t._lastURL = _iO.url;\r
- _a._called_load = false;\r
- } else {\r
- _a = new Audio(_iO.url);\r
- _a._called_load = false;\r
- if (_is_android) {\r
- _a._called_load = true;\r
- }\r
- if (_useGlobalHTML5Audio) {\r
- _s._global_a = _a;\r
- }\r
- }\r
- _t.isHTML5 = true;\r
- _t._a = _a;\r
- _a._t = _t;\r
- _t._add_html5_events();\r
- _a.loop = (_iO.loops>1?'loop':'');\r
- if (_iO.autoLoad || _iO.autoPlay) {\r
- _a.autobuffer = 'auto';\r
- _a.preload = 'auto';\r
- _t.load();\r
- _a._called_load = true;\r
- } else {\r
- _a.autobuffer = false;\r
- _a.preload = 'none';\r
- }\r
- _a.loop = (_iO.loops>1?'loop':'');\r
- return _a;\r
- };\r
- this._add_html5_events = function() {\r
- if (_t._a._added_events) {\r
- return false;\r
- }\r
- var f;\r
- function add(oEvt, oFn, bCapture) {\r
- return _t._a ? _t._a.addEventListener(oEvt, oFn, bCapture||false) : null;\r
- }\r
- _t._a._added_events = true;\r
- for (f in _html5_events) {\r
- if (_html5_events.hasOwnProperty(f)) {\r
- add(f, _html5_events[f]);\r
- }\r
- }\r
- return true;\r
- };\r
- this._remove_html5_events = function() {\r
- var f;\r
- function remove(oEvt, oFn, bCapture) {\r
- return (_t._a ? _t._a.removeEventListener(oEvt, oFn, bCapture||false) : null);\r
- }\r
- _t._a._added_events = false;\r
- for (f in _html5_events) {\r
- if (_html5_events.hasOwnProperty(f)) {\r
- remove(f, _html5_events[f]);\r
- }\r
- }\r
- };\r
- this._onload = function(nSuccess) {\r
- var fN = 'SMSound._onload(): ', loadOK = !!(nSuccess);\r
- _t.loaded = loadOK;\r
- _t.readyState = loadOK?3:2;\r
- _t._onbufferchange(0);\r
- if (_t._iO.onload) {\r
- _t._iO.onload.apply(_t, [loadOK]);\r
- }\r
- return true;\r
- };\r
- this._onbufferchange = function(nIsBuffering) {\r
- var fN = 'SMSound._onbufferchange()';\r
- if (_t.playState === 0) {\r
- return false;\r
- }\r
- if ((nIsBuffering && _t.isBuffering) || (!nIsBuffering && !_t.isBuffering)) {\r
- return false;\r
- }\r
- _t.isBuffering = (nIsBuffering === 1);\r
- if (_t._iO.onbufferchange) {\r
- _t._iO.onbufferchange.apply(_t);\r
- }\r
- return true;\r
- };\r
- this._onsuspend = function () {\r
- if (_t._iO.onsuspend) {\r
- _t._iO.onsuspend.apply(_t);\r
- }\r
- return true;\r
- };\r
- this._onfailure = function(msg, level, code) {\r
- _t.failures++;\r
- if (_t._iO.onfailure && _t.failures === 1) {\r
- _t._iO.onfailure(_t, msg, level, code);\r
- } else {\r
- }\r
- };\r
- this._onfinish = function() {\r
- var _io_onfinish = _t._iO.onfinish;\r
- _t._onbufferchange(0);\r
- _t.resetOnPosition(0);\r
- if (_t.instanceCount) {\r
- _t.instanceCount--;\r
- if (!_t.instanceCount) {\r
- _t.playState = 0;\r
- _t.paused = false;\r
- _t.instanceCount = 0;\r
- _t.instanceOptions = {};\r
- _t._iO = {};\r
- _stop_html5_timer();\r
- }\r
- if (!_t.instanceCount || _t._iO.multiShotEvents) {\r
- if (_io_onfinish) {\r
- _io_onfinish.apply(_t);\r
- }\r
- }\r
- }\r
- };\r
- this._whileloading = function(nBytesLoaded, nBytesTotal, nDuration, nBufferLength) {\r
- _t.bytesLoaded = nBytesLoaded;\r
- _t.bytesTotal = nBytesTotal;\r
- _t.duration = Math.floor(nDuration);\r
- _t.bufferLength = nBufferLength;\r
- if (!_t._iO.isMovieStar) {\r
- if (_t._iO.duration) {\r
- _t.durationEstimate = (_t.duration > _t._iO.duration) ? _t.duration : _t._iO.duration;\r
- } else {\r
- _t.durationEstimate = parseInt((_t.bytesTotal / _t.bytesLoaded) * _t.duration, 10);\r
- }\r
- if (_t.durationEstimate === undefined) {\r
- _t.durationEstimate = _t.duration;\r
- }\r
- if (_t.readyState !== 3 && _t._iO.whileloading) {\r
- _t._iO.whileloading.apply(_t);\r
- }\r
- } else {\r
- _t.durationEstimate = _t.duration;\r
- if (_t.readyState !== 3 && _t._iO.whileloading) {\r
- _t._iO.whileloading.apply(_t);\r
- }\r
- }\r
- };\r
- this._whileplaying = function(nPosition, oPeakData, oWaveformDataLeft, oWaveformDataRight, oEQData) {\r
- if (isNaN(nPosition) || nPosition === null) {\r
- return false;\r
- }\r
- _t.position = nPosition;\r
- _t.processOnPosition();\r
- if (!_t.isHTML5 && _fV > 8) {\r
- if (_t._iO.usePeakData && typeof oPeakData !== 'undefined' && oPeakData) {\r
- _t.peakData = {\r
- left: oPeakData.leftPeak,\r
- right: oPeakData.rightPeak\r
- };\r
- }\r
- if (_t._iO.useWaveformData && typeof oWaveformDataLeft !== 'undefined' && oWaveformDataLeft) {\r
- _t.waveformData = {\r
- left: oWaveformDataLeft.split(','),\r
- right: oWaveformDataRight.split(',')\r
- };\r
- }\r
- if (_t._iO.useEQData) {\r
- if (typeof oEQData !== 'undefined' && oEQData && oEQData.leftEQ) {\r
- var eqLeft = oEQData.leftEQ.split(',');\r
- _t.eqData = eqLeft;\r
- _t.eqData.left = eqLeft;\r
- if (typeof oEQData.rightEQ !== 'undefined' && oEQData.rightEQ) {\r
- _t.eqData.right = oEQData.rightEQ.split(',');\r
- }\r
- }\r
- }\r
- }\r
- if (_t.playState === 1) {\r
- if (!_t.isHTML5 && _fV === 8 && !_t.position && _t.isBuffering) {\r
- _t._onbufferchange(0);\r
- }\r
- if (_t._iO.whileplaying) {\r
- _t._iO.whileplaying.apply(_t);\r
- }\r
- }\r
- return true;\r
- };\r
- this._onid3 = function(oID3PropNames, oID3Data) {\r
- var oData = [], i, j;\r
- for (i = 0, j = oID3PropNames.length; i < j; i++) {\r
- oData[oID3PropNames[i]] = oID3Data[i];\r
- }\r
- _t.id3 = _mixin(_t.id3, oData);\r
- if (_t._iO.onid3) {\r
- _t._iO.onid3.apply(_t);\r
- }\r
- };\r
- this._onconnect = function(bSuccess) {\r
- var fN = 'SMSound._onconnect(): ';\r
- bSuccess = (bSuccess === 1);\r
- _t.connected = bSuccess;\r
- if (bSuccess) {\r
- _t.failures = 0;\r
- if (_idCheck(_t.sID)) {\r
- if (_t.getAutoPlay()) {\r
- _t.play(undefined, _t.getAutoPlay());\r
- } else if (_t._iO.autoLoad) {\r
- _t.load();\r
- }\r
- }\r
- if (_t._iO.onconnect) {\r
- _t._iO.onconnect.apply(_t,[bSuccess]);\r
- }\r
- }\r
- };\r
- this._ondataerror = function(sError) {\r
- if (_t.playState > 0) {\r
- if (_t._iO.ondataerror) {\r
- _t._iO.ondataerror.apply(_t);\r
- }\r
- }\r
- };\r
- };\r
- _getDocument = function() {\r
- return (_doc.body || _doc._docElement || _doc.getElementsByTagName('div')[0]);\r
- };\r
- _id = function(sID) {\r
- return _doc.getElementById(sID);\r
- };\r
- _mixin = function(oMain, oAdd) {\r
- var o1 = {}, i, o2, o;\r
- for (i in oMain) {\r
- if (oMain.hasOwnProperty(i)) {\r
- o1[i] = oMain[i];\r
- }\r
- }\r
- o2 = (typeof oAdd === 'undefined'?_s.defaultOptions:oAdd);\r
- for (o in o2) {\r
- if (o2.hasOwnProperty(o) && typeof o1[o] === 'undefined') {\r
- o1[o] = o2[o];\r
- }\r
- }\r
- return o1;\r
- };\r
- _event = (function() {\r
- var old = (_win.attachEvent),\r
- evt = {\r
- add: (old?'attachEvent':'addEventListener'),\r
- remove: (old?'detachEvent':'removeEventListener')\r
- };\r
- function getArgs(oArgs) {\r
- var args = _slice.call(oArgs), len = args.length;\r
- if (old) {\r
- args[1] = 'on' + args[1];\r
- if (len > 3) {\r
- args.pop();\r
- }\r
- } else if (len === 3) {\r
- args.push(false);\r
- }\r
- return args;\r
- }\r
- function apply(args, sType) {\r
- var element = args.shift(),\r
- method = [evt[sType]];\r
- if (old) {\r
- element[method](args[0], args[1]);\r
- } else {\r
- element[method].apply(element, args);\r
- }\r
- }\r
- function add() {\r
- apply(getArgs(arguments), 'add');\r
- }\r
- function remove() {\r
- apply(getArgs(arguments), 'remove');\r
- }\r
- return {\r
- 'add': add,\r
- 'remove': remove\r
- };\r
- }());\r
- function _html5_event(oFn) {\r
- return function(e) {\r
- if (!this._t || !this._t._a) {\r
- return null;\r
- } else {\r
- return oFn.call(this, e);\r
- }\r
- };\r
- }\r
- _html5_events = {\r
- abort: _html5_event(function(e) {\r
- }),\r
- canplay: _html5_event(function(e) {\r
- if (this._t._html5_canplay) {\r
- return true;\r
- }\r
- this._t._html5_canplay = true;\r
- this._t._onbufferchange(0);\r
- var position1K = (!isNaN(this._t.position)?this._t.position/1000:null);\r
- if (this._t.position && this.currentTime !== position1K) {\r
- try {\r
- this.currentTime = position1K;\r
- } catch(ee) {\r
- }\r
- }\r
- }),\r
- load: _html5_event(function(e) {\r
- if (!this._t.loaded) {\r
- this._t._onbufferchange(0);\r
- this._t._whileloading(this._t.bytesTotal, this._t.bytesTotal, this._t._get_html5_duration());\r
- this._t._onload(true);\r
- }\r
- }),\r
- emptied: _html5_event(function(e) {\r
- }),\r
- ended: _html5_event(function(e) {\r
- this._t._onfinish();\r
- }),\r
- error: _html5_event(function(e) {\r
- this._t._onload(false);\r
- }),\r
- loadeddata: _html5_event(function(e) {\r
- var t = this._t,\r
- bytesTotal = t.bytesTotal || 1;\r
- if (!t._loaded && !_isSafari) {\r
- t.duration = t._get_html5_duration();\r
- t._whileloading(bytesTotal, bytesTotal, t._get_html5_duration());\r
- t._onload(true);\r
- }\r
- }),\r
- loadedmetadata: _html5_event(function(e) {\r
- }),\r
- loadstart: _html5_event(function(e) {\r
- this._t._onbufferchange(1);\r
- }),\r
- play: _html5_event(function(e) {\r
- this._t._onbufferchange(0);\r
- }),\r
- playing: _html5_event(function(e) {\r
- this._t._onbufferchange(0);\r
- }),\r
- progress: _html5_event(function(e) {\r
- if (this._t.loaded) {\r
- return false;\r
- }\r
- var i, j, str, buffered = 0,\r
- isProgress = (e.type === 'progress'),\r
- ranges = e.target.buffered,\r
- loaded = (e.loaded||0),\r
- total = (e.total||1);\r
- if (ranges && ranges.length) {\r
- for (i=ranges.length; i--;) {\r
- buffered = (ranges.end(i) - ranges.start(i));\r
- }\r
- loaded = buffered/e.target.duration;\r
- }\r
- if (!isNaN(loaded)) {\r
- this._t._onbufferchange(0);\r
- this._t._whileloading(loaded, total, this._t._get_html5_duration());\r
- if (loaded && total && loaded === total) {\r
- _html5_events.load.call(this, e);\r
- }\r
- }\r
- }),\r
- ratechange: _html5_event(function(e) {\r
- }),\r
- suspend: _html5_event(function(e) {\r
- _html5_events.progress.call(this, e);\r
- this._t._onsuspend();\r
- }),\r
- stalled: _html5_event(function(e) {\r
- }),\r
- timeupdate: _html5_event(function(e) {\r
- this._t._onTimer();\r
- }),\r
- waiting: _html5_event(function(e) {\r
- this._t._onbufferchange(1);\r
- })\r
- };\r
- _html5OK = function(iO) {\r
- return (!iO.serverURL && (iO.type?_html5CanPlay({type:iO.type}):_html5CanPlay({url:iO.url})||_s.html5Only));\r
- };\r
- _html5Unload = function(oAudio) {\r
- if (oAudio) {\r
- oAudio.src = (_is_firefox ? '' : _emptyURL);\r
- }\r
- };\r
- _html5CanPlay = function(o) {\r
- if (!_s.useHTML5Audio || !_s.hasHTML5) {\r
- return false;\r
- }\r
- var url = (o.url || null),\r
- mime = (o.type || null),\r
- aF = _s.audioFormats,\r
- result,\r
- offset,\r
- fileExt,\r
- item;\r
- function preferFlashCheck(kind) {\r
- return (_s.preferFlash && _hasFlash && !_s.ignoreFlash && (typeof _s.flash[kind] !== 'undefined' && _s.flash[kind]));\r
- }\r
- if (mime && _s.html5[mime] !== 'undefined') {\r
- return (_s.html5[mime] && !preferFlashCheck(mime));\r
- }\r
- if (!_html5Ext) {\r
- _html5Ext = [];\r
- for (item in aF) {\r
- if (aF.hasOwnProperty(item)) {\r
- _html5Ext.push(item);\r
- if (aF[item].related) {\r
- _html5Ext = _html5Ext.concat(aF[item].related);\r
- }\r
- }\r
- }\r
- _html5Ext = new RegExp('\\.('+_html5Ext.join('|')+')(\\?.*)?$','i');\r
- }\r
- fileExt = (url ? url.toLowerCase().match(_html5Ext) : null);\r
- if (!fileExt || !fileExt.length) {\r
- if (!mime) {\r
- return false;\r
- } else {\r
- offset = mime.indexOf(';');\r
- fileExt = (offset !== -1?mime.substr(0,offset):mime).substr(6);\r
- }\r
- } else {\r
- fileExt = fileExt[1];\r
- }\r
- if (fileExt && typeof _s.html5[fileExt] !== 'undefined') {\r
- return (_s.html5[fileExt] && !preferFlashCheck(fileExt));\r
- } else {\r
- mime = 'audio/'+fileExt;\r
- result = _s.html5.canPlayType({type:mime});\r
- _s.html5[fileExt] = result;\r
- return (result && _s.html5[mime] && !preferFlashCheck(mime));\r
- }\r
- };\r
- _testHTML5 = function() {\r
- if (!_s.useHTML5Audio || typeof Audio === 'undefined') {\r
- return false;\r
- }\r
- var a = (typeof Audio !== 'undefined' ? (_isOpera ? new Audio(null) : new Audio()) : null),\r
- item, support = {}, aF, i;\r
- function _cp(m) {\r
- var canPlay, i, j, isOK = false;\r
- if (!a || typeof a.canPlayType !== 'function') {\r
- return false;\r
- }\r
- if (m instanceof Array) {\r
- for (i=0, j=m.length; i<j && !isOK; i++) {\r
- if (_s.html5[m[i]] || a.canPlayType(m[i]).match(_s.html5Test)) {\r
- isOK = true;\r
- _s.html5[m[i]] = true;\r
- _s.flash[m[i]] = !!(_s.preferFlash && _hasFlash && m[i].match(_flashMIME));\r
- }\r
- }\r
- return isOK;\r
- } else {\r
- canPlay = (a && typeof a.canPlayType === 'function' ? a.canPlayType(m) : false);\r
- return !!(canPlay && (canPlay.match(_s.html5Test)));\r
- }\r
- }\r
- aF = _s.audioFormats;\r
- for (item in aF) {\r
- if (aF.hasOwnProperty(item)) {\r
- support[item] = _cp(aF[item].type);\r
- support['audio/'+item] = support[item];\r
- if (_s.preferFlash && !_s.ignoreFlash && item.match(_flashMIME)) {\r
- _s.flash[item] = true;\r
- } else {\r
- _s.flash[item] = false;\r
- }\r
- if (aF[item] && aF[item].related) {\r
- for (i=aF[item].related.length; i--;) {\r
- support['audio/'+aF[item].related[i]] = support[item];\r
- _s.html5[aF[item].related[i]] = support[item];\r
- _s.flash[aF[item].related[i]] = support[item];\r
- }\r
- }\r
- }\r
- }\r
- support.canPlayType = (a?_cp:null);\r
- _s.html5 = _mixin(_s.html5, support);\r
- return true;\r
- };\r
- _strings = {\r
- };\r
- _str = function() {\r
- };\r
- _loopFix = function(sOpt) {\r
- if (_fV === 8 && sOpt.loops > 1 && sOpt.stream) {\r
- sOpt.stream = false;\r
- }\r
- return sOpt;\r
- };\r
- _policyFix = function(sOpt, sPre) {\r
- if (sOpt && !sOpt.usePolicyFile && (sOpt.onid3 || sOpt.usePeakData || sOpt.useWaveformData || sOpt.useEQData)) {\r
- sOpt.usePolicyFile = true;\r
- }\r
- return sOpt;\r
- };\r
- _complain = function(sMsg) {\r
- };\r
- _doNothing = function() {\r
- return false;\r
- };\r
- _disableObject = function(o) {\r
- var oProp;\r
- for (oProp in o) {\r
- if (o.hasOwnProperty(oProp) && typeof o[oProp] === 'function') {\r
- o[oProp] = _doNothing;\r
- }\r
- }\r
- oProp = null;\r
- };\r
- _failSafely = function(bNoDisable) {\r
- if (typeof bNoDisable === 'undefined') {\r
- bNoDisable = false;\r
- }\r
- if (_disabled || bNoDisable) {\r
- _s.disable(bNoDisable);\r
- }\r
- };\r
- _normalizeMovieURL = function(smURL) {\r
- var urlParams = null, url;\r
- if (smURL) {\r
- if (smURL.match(/\.swf(\?.*)?$/i)) {\r
- urlParams = smURL.substr(smURL.toLowerCase().lastIndexOf('.swf?') + 4);\r
- if (urlParams) {\r
- return smURL;\r
- }\r
- } else if (smURL.lastIndexOf('/') !== smURL.length - 1) {\r
- smURL += '/';\r
- }\r
- }\r
- url = (smURL && smURL.lastIndexOf('/') !== - 1 ? smURL.substr(0, smURL.lastIndexOf('/') + 1) : './') + _s.movieURL;\r
- if (_s.noSWFCache) {\r
- url += ('?ts=' + new Date().getTime());\r
- }\r
- return url;\r
- };\r
- _setVersionInfo = function() {\r
- _fV = parseInt(_s.flashVersion, 10);\r
- if (_fV !== 8 && _fV !== 9) {\r
- _s.flashVersion = _fV = _defaultFlashVersion;\r
- }\r
- var isDebug = (_s.debugMode || _s.debugFlash?'_debug.swf':'.swf');\r
- if (_s.useHTML5Audio && !_s.html5Only && _s.audioFormats.mp4.required && _fV < 9) {\r
- _s.flashVersion = _fV = 9;\r
- }\r
- _s.version = _s.versionNumber + (_s.html5Only?' (HTML5-only mode)':(_fV === 9?' (AS3/Flash 9)':' (AS2/Flash 8)'));\r
- if (_fV > 8) {\r
- _s.defaultOptions = _mixin(_s.defaultOptions, _s.flash9Options);\r
- _s.features.buffering = true;\r
- _s.defaultOptions = _mixin(_s.defaultOptions, _s.movieStarOptions);\r
- _s.filePatterns.flash9 = new RegExp('\\.(mp3|' + _netStreamTypes.join('|') + ')(\\?.*)?$', 'i');\r
- _s.features.movieStar = true;\r
- } else {\r
- _s.features.movieStar = false;\r
- }\r
- _s.filePattern = _s.filePatterns[(_fV !== 8?'flash9':'flash8')];\r
- _s.movieURL = (_fV === 8?'soundmanager2.swf':'soundmanager2_flash9.swf').replace('.swf', isDebug);\r
- _s.features.peakData = _s.features.waveformData = _s.features.eqData = (_fV > 8);\r
- };\r
- _setPolling = function(bPolling, bHighPerformance) {\r
- if (!_s.o) {\r
- return false;\r
- }\r
- _s.o._setPolling(bPolling, bHighPerformance);\r
- };\r
- _initDebug = function() {\r
- if (_s.debugURLParam.test(_wl)) {\r
- _s.debugMode = true;\r
- }\r
- };\r
- _idCheck = this.getSoundById;\r
- _getSWFCSS = function() {\r
- var css = [];\r
- if (_s.debugMode) {\r
- css.push(_s.swfCSS.sm2Debug);\r
- }\r
- if (_s.debugFlash) {\r
- css.push(_s.swfCSS.flashDebug);\r
- }\r
- if (_s.useHighPerformance) {\r
- css.push(_s.swfCSS.highPerf);\r
- }\r
- return css.join(' ');\r
- };\r
- _flashBlockHandler = function() {\r
- var name = _str('fbHandler'),\r
- p = _s.getMoviePercent(),\r
- css = _s.swfCSS,\r
- error = {type:'FLASHBLOCK'};\r
- if (_s.html5Only) {\r
- return false;\r
- }\r
- if (!_s.ok()) {\r
- if (_needsFlash) {\r
- _s.oMC.className = _getSWFCSS() + ' ' + css.swfDefault + ' ' + (p === null?css.swfTimedout:css.swfError);\r
- }\r
- _s.didFlashBlock = true;\r
- _processOnEvents({type:'ontimeout', ignoreInit:true, error:error});\r
- _catchError(error);\r
- } else {\r
- if (_s.didFlashBlock) {\r
- }\r
- if (_s.oMC) {\r
- _s.oMC.className = [_getSWFCSS(), css.swfDefault, css.swfLoaded + (_s.didFlashBlock?' '+css.swfUnblocked:'')].join(' ');\r
- }\r
- }\r
- };\r
- _addOnEvent = function(sType, oMethod, oScope) {\r
- if (typeof _on_queue[sType] === 'undefined') {\r
- _on_queue[sType] = [];\r
- }\r
- _on_queue[sType].push({\r
- 'method': oMethod,\r
- 'scope': (oScope || null),\r
- 'fired': false\r
- });\r
- };\r
- _processOnEvents = function(oOptions) {\r
- if (!oOptions) {\r
- oOptions = {\r
- type: 'onready'\r
- };\r
- }\r
- if (!_didInit && oOptions && !oOptions.ignoreInit) {\r
- return false;\r
- }\r
- if (oOptions.type === 'ontimeout' && _s.ok()) {\r
- return false;\r
- }\r
- var status = {\r
- success: (oOptions && oOptions.ignoreInit?_s.ok():!_disabled)\r
- },\r
- srcQueue = (oOptions && oOptions.type?_on_queue[oOptions.type]||[]:[]),\r
- queue = [], i, j,\r
- args = [status],\r
- canRetry = (_needsFlash && _s.useFlashBlock && !_s.ok());\r
- if (oOptions.error) {\r
- args[0].error = oOptions.error;\r
- }\r
- for (i = 0, j = srcQueue.length; i < j; i++) {\r
- if (srcQueue[i].fired !== true) {\r
- queue.push(srcQueue[i]);\r
- }\r
- }\r
- if (queue.length) {\r
- for (i = 0, j = queue.length; i < j; i++) {\r
- if (queue[i].scope) {\r
- queue[i].method.apply(queue[i].scope, args);\r
- } else {\r
- queue[i].method.apply(this, args);\r
- }\r
- if (!canRetry) {\r
- queue[i].fired = true;\r
- }\r
- }\r
- }\r
- return true;\r
- };\r
- _initUserOnload = function() {\r
- _win.setTimeout(function() {\r
- if (_s.useFlashBlock) {\r
- _flashBlockHandler();\r
- }\r
- _processOnEvents();\r
- if (_s.onload instanceof Function) {\r
- _s.onload.apply(_win);\r
- }\r
- if (_s.waitForWindowLoad) {\r
- _event.add(_win, 'load', _initUserOnload);\r
- }\r
- },1);\r
- };\r
- _detectFlash = function() {\r
- if (_hasFlash !== undefined) {\r
- return _hasFlash;\r
- }\r
- var hasPlugin = false, n = navigator, nP = n.plugins, obj, type, types, AX = _win.ActiveXObject;\r
- if (nP && nP.length) {\r
- type = 'application/x-shockwave-flash';\r
- types = n.mimeTypes;\r
- if (types && types[type] && types[type].enabledPlugin && types[type].enabledPlugin.description) {\r
- hasPlugin = true;\r
- }\r
- } else if (typeof AX !== 'undefined') {\r
- try {\r
- obj = new AX('ShockwaveFlash.ShockwaveFlash');\r
- } catch(e) {\r
- }\r
- hasPlugin = (!!obj);\r
- }\r
- _hasFlash = hasPlugin;\r
- return hasPlugin;\r
- };\r
- _featureCheck = function() {\r
- var needsFlash, item,\r
- isSpecial = (_is_iDevice && !!(_ua.match(/os (1|2|3_0|3_1)/i)));\r
- if (isSpecial) {\r
- _s.hasHTML5 = false;\r
- _s.html5Only = true;\r
- if (_s.oMC) {\r
- _s.oMC.style.display = 'none';\r
- }\r
- return false;\r
- }\r
- if (_s.useHTML5Audio) {\r
- if (!_s.html5 || !_s.html5.canPlayType) {\r
- _s.hasHTML5 = false;\r
- return true;\r
- } else {\r
- _s.hasHTML5 = true;\r
- }\r
- if (_isBadSafari) {\r
- if (_detectFlash()) {\r
- return true;\r
- }\r
- }\r
- } else {\r
- return true;\r
- }\r
- for (item in _s.audioFormats) {\r
- if (_s.audioFormats.hasOwnProperty(item)) {\r
- if ((_s.audioFormats[item].required && !_s.html5.canPlayType(_s.audioFormats[item].type)) || _s.flash[item] || _s.flash[_s.audioFormats[item].type]) {\r
- needsFlash = true;\r
- }\r
- }\r
- }\r
- if (_s.ignoreFlash) {\r
- needsFlash = false;\r
- }\r
- _s.html5Only = (_s.hasHTML5 && _s.useHTML5Audio && !needsFlash);\r
- return (!_s.html5Only);\r
- };\r
- _startTimer = function(oSound) {\r
- if (!oSound._hasTimer) {\r
- oSound._hasTimer = true;\r
- }\r
- };\r
- _stopTimer = function(oSound) {\r
- if (oSound._hasTimer) {\r
- oSound._hasTimer = false;\r
- }\r
- };\r
- _catchError = function(options) {\r
- options = (typeof options !== 'undefined' ? options : {});\r
- if (_s.onerror instanceof Function) {\r
- _s.onerror.apply(_win, [{type:(typeof options.type !== 'undefined' ? options.type : null)}]);\r
- }\r
- if (typeof options.fatal !== 'undefined' && options.fatal) {\r
- _s.disable();\r
- }\r
- };\r
- _badSafariFix = function() {\r
- if (!_isBadSafari || !_detectFlash()) {\r
- return false;\r
- }\r
- var aF = _s.audioFormats, i, item;\r
- for (item in aF) {\r
- if (aF.hasOwnProperty(item)) {\r
- if (item === 'mp3' || item === 'mp4') {\r
- _s.html5[item] = false;\r
- if (aF[item] && aF[item].related) {\r
- for (i = aF[item].related.length; i--;) {\r
- _s.html5[aF[item].related[i]] = false;\r
- }\r
- }\r
- }\r
- }\r
- }\r
- };\r
- this._setSandboxType = function(sandboxType) {\r
- };\r
- this._externalInterfaceOK = function(flashDate) {\r
- if (_s.swfLoaded) {\r
- return false;\r
- }\r
- var eiTime = new Date().getTime();\r
- _s.swfLoaded = true;\r
- _tryInitOnFocus = false;\r
- if (_isBadSafari) {\r
- _badSafariFix();\r
- }\r
- if (_isIE) {\r
- setTimeout(_init, 100);\r
- } else {\r
- _init();\r
- }\r
- };\r
- _createMovie = function(smID, smURL) {\r
- if (_didAppend && _appendSuccess) {\r
- return false;\r
- }\r
- function _initMsg() {\r
- }\r
- if (_s.html5Only) {\r
- _setVersionInfo();\r
- _initMsg();\r
- _s.oMC = _id(_s.movieID);\r
- _init();\r
- _didAppend = true;\r
- _appendSuccess = true;\r
- return false;\r
- }\r
- var remoteURL = (smURL || _s.url),\r
- localURL = (_s.altURL || remoteURL),\r
- swfTitle = 'JS/Flash audio component (SoundManager 2)',\r
- oEmbed, oMovie, oTarget = _getDocument(), tmp, movieHTML, oEl, extraClass = _getSWFCSS(),\r
- s, x, sClass, side = 'auto', isRTL = null,\r
- html = _doc.getElementsByTagName('html')[0];\r
- isRTL = (html && html.dir && html.dir.match(/rtl/i));\r
- smID = (typeof smID === 'undefined'?_s.id:smID);\r
- function param(name, value) {\r
- return '<param name="'+name+'" value="'+value+'" />';\r
- }\r
- _setVersionInfo();\r
- _s.url = _normalizeMovieURL(_overHTTP?remoteURL:localURL);\r
- smURL = _s.url;\r
- _s.wmode = (!_s.wmode && _s.useHighPerformance ? 'transparent' : _s.wmode);\r
- if (_s.wmode !== null && (_ua.match(/msie 8/i) || (!_isIE && !_s.useHighPerformance)) && navigator.platform.match(/win32|win64/i)) {\r
- _s.specialWmodeCase = true;\r
- _s.wmode = null;\r
- }\r
- oEmbed = {\r
- 'name': smID,\r
- 'id': smID,\r
- 'src': smURL,\r
- 'width': side,\r
- 'height': side,\r
- 'quality': 'high',\r
- 'allowScriptAccess': _s.allowScriptAccess,\r
- 'bgcolor': _s.bgColor,\r
- 'pluginspage': _http+'www.macromedia.com/go/getflashplayer',\r
- 'title': swfTitle,\r
- 'type': 'application/x-shockwave-flash',\r
- 'wmode': _s.wmode,\r
- 'hasPriority': 'true'\r
- };\r
- if (_s.debugFlash) {\r
- oEmbed.FlashVars = 'debug=1';\r
- }\r
- if (!_s.wmode) {\r
- delete oEmbed.wmode;\r
- }\r
- if (_isIE) {\r
- oMovie = _doc.createElement('div');\r
- movieHTML = [\r
- '<object id="' + smID + '" data="' + smURL + '" type="' + oEmbed.type + '" title="' + oEmbed.title +'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="' + _http+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" width="' + oEmbed.width + '" height="' + oEmbed.height + '">',\r
- param('movie', smURL),\r
- param('AllowScriptAccess', _s.allowScriptAccess),\r
- param('quality', oEmbed.quality),\r
- (_s.wmode? param('wmode', _s.wmode): ''),\r
- param('bgcolor', _s.bgColor),\r
- param('hasPriority', 'true'),\r
- (_s.debugFlash ? param('FlashVars', oEmbed.FlashVars) : ''),\r
- '</object>'\r
- ].join('');\r
- } else {\r
- oMovie = _doc.createElement('embed');\r
- for (tmp in oEmbed) {\r
- if (oEmbed.hasOwnProperty(tmp)) {\r
- oMovie.setAttribute(tmp, oEmbed[tmp]);\r
- }\r
- }\r
- }\r
- _initDebug();\r
- extraClass = _getSWFCSS();\r
- oTarget = _getDocument();\r
- if (oTarget) {\r
- _s.oMC = (_id(_s.movieID) || _doc.createElement('div'));\r
- if (!_s.oMC.id) {\r
- _s.oMC.id = _s.movieID;\r
- _s.oMC.className = _s.swfCSS.swfDefault + ' ' + extraClass;\r
- s = null;\r
- oEl = null;\r
- if (!_s.useFlashBlock) {\r
- if (_s.useHighPerformance) {\r
- s = {\r
- 'position': 'fixed',\r
- 'width': '8px',\r
- 'height': '8px',\r
- 'bottom': '0px',\r
- 'left': '0px',\r
- 'overflow': 'hidden'\r
- };\r
- } else {\r
- s = {\r
- 'position': 'absolute',\r
- 'width': '6px',\r
- 'height': '6px',\r
- 'top': '-9999px',\r
- 'left': '-9999px'\r
- };\r
- if (isRTL) {\r
- s.left = Math.abs(parseInt(s.left,10))+'px';\r
- }\r
- }\r
- }\r
- if (_isWebkit) {\r
- _s.oMC.style.zIndex = 10000;\r
- }\r
- if (!_s.debugFlash) {\r
- for (x in s) {\r
- if (s.hasOwnProperty(x)) {\r
- _s.oMC.style[x] = s[x];\r
- }\r
- }\r
- }\r
- try {\r
- if (!_isIE) {\r
- _s.oMC.appendChild(oMovie);\r
- }\r
- oTarget.appendChild(_s.oMC);\r
- if (_isIE) {\r
- oEl = _s.oMC.appendChild(_doc.createElement('div'));\r
- oEl.className = _s.swfCSS.swfBox;\r
- oEl.innerHTML = movieHTML;\r
- }\r
- _appendSuccess = true;\r
- } catch(e) {\r
- throw new Error(_str('domError')+' \n'+e.toString());\r
- }\r
- } else {\r
- sClass = _s.oMC.className;\r
- _s.oMC.className = (sClass?sClass+' ':_s.swfCSS.swfDefault) + (extraClass?' '+extraClass:'');\r
- _s.oMC.appendChild(oMovie);\r
- if (_isIE) {\r
- oEl = _s.oMC.appendChild(_doc.createElement('div'));\r
- oEl.className = _s.swfCSS.swfBox;\r
- oEl.innerHTML = movieHTML;\r
- }\r
- _appendSuccess = true;\r
- }\r
- }\r
- _didAppend = true;\r
- _initMsg();\r
- return true;\r
- };\r
- _initMovie = function() {\r
- if (_s.html5Only) {\r
- _createMovie();\r
- return false;\r
- }\r
- if (_s.o) {\r
- return false;\r
- }\r
- _s.o = _s.getMovie(_s.id);\r
- if (!_s.o) {\r
- if (!_oRemoved) {\r
- _createMovie(_s.id, _s.url);\r
- } else {\r
- if (!_isIE) {\r
- _s.oMC.appendChild(_oRemoved);\r
- } else {\r
- _s.oMC.innerHTML = _oRemovedHTML;\r
- }\r
- _oRemoved = null;\r
- _didAppend = true;\r
- }\r
- _s.o = _s.getMovie(_s.id);\r
- }\r
- if (_s.oninitmovie instanceof Function) {\r
- setTimeout(_s.oninitmovie, 1);\r
- }\r
- return true;\r
- };\r
- _delayWaitForEI = function() {\r
- setTimeout(_waitForEI, 1000);\r
- };\r
- _waitForEI = function() {\r
- if (_waitingForEI) {\r
- return false;\r
- }\r
- _waitingForEI = true;\r
- _event.remove(_win, 'load', _delayWaitForEI);\r
- if (_tryInitOnFocus && !_isFocused) {\r
- return false;\r
- }\r
- var p;\r
- if (!_didInit) {\r
- p = _s.getMoviePercent();\r
- }\r
- setTimeout(function() {\r
- p = _s.getMoviePercent();\r
- if (!_didInit && _okToDisable) {\r
- if (p === null) {\r
- if (_s.useFlashBlock || _s.flashLoadTimeout === 0) {\r
- if (_s.useFlashBlock) {\r
- _flashBlockHandler();\r
- }\r
- } else {\r
- _failSafely(true);\r
- }\r
- } else {\r
- if (_s.flashLoadTimeout === 0) {\r
- } else {\r
- _failSafely(true);\r
- }\r
- }\r
- }\r
- }, _s.flashLoadTimeout);\r
- };\r
- _handleFocus = function() {\r
- function cleanup() {\r
- _event.remove(_win, 'focus', _handleFocus);\r
- _event.remove(_win, 'load', _handleFocus);\r
- }\r
- if (_isFocused || !_tryInitOnFocus) {\r
- cleanup();\r
- return true;\r
- }\r
- _okToDisable = true;\r
- _isFocused = true;\r
- if (_isSafari && _tryInitOnFocus) {\r
- _event.remove(_win, 'mousemove', _handleFocus);\r
- }\r
- _waitingForEI = false;\r
- cleanup();\r
- return true;\r
- };\r
- _showSupport = function() {\r
- var item, tests = [];\r
- if (_s.useHTML5Audio && _s.hasHTML5) {\r
- for (item in _s.audioFormats) {\r
- if (_s.audioFormats.hasOwnProperty(item)) {\r
- tests.push(item + ': ' + _s.html5[item] + (!_s.html5[item] && _hasFlash && _s.flash[item] ? ' (using flash)' : (_s.preferFlash && _s.flash[item] && _hasFlash ? ' (preferring flash)': (!_s.html5[item] ? ' (' + (_s.audioFormats[item].required ? 'required, ':'') + 'and no flash support)' : ''))));\r
- }\r
- }\r
- }\r
- };\r
- _initComplete = function(bNoDisable) {\r
- if (_didInit) {\r
- return false;\r
- }\r
- if (_s.html5Only) {\r
- _didInit = true;\r
- _initUserOnload();\r
- return true;\r
- }\r
- var wasTimeout = (_s.useFlashBlock && _s.flashLoadTimeout && !_s.getMoviePercent()),\r
- error;\r
- if (!wasTimeout) {\r
- _didInit = true;\r
- if (_disabled) {\r
- error = {type: (!_hasFlash && _needsFlash ? 'NO_FLASH' : 'INIT_TIMEOUT')};\r
- }\r
- }\r
- if (_disabled || bNoDisable) {\r
- if (_s.useFlashBlock && _s.oMC) {\r
- _s.oMC.className = _getSWFCSS() + ' ' + (_s.getMoviePercent() === null?_s.swfCSS.swfTimedout:_s.swfCSS.swfError);\r
- }\r
- _processOnEvents({type:'ontimeout', error:error});\r
- _catchError(error);\r
- return false;\r
- } else {\r
- }\r
- if (_s.waitForWindowLoad && !_windowLoaded) {\r
- _event.add(_win, 'load', _initUserOnload);\r
- return false;\r
- } else {\r
- _initUserOnload();\r
- }\r
- return true;\r
- };\r
- _init = function() {\r
- if (_didInit) {\r
- return false;\r
- }\r
- function _cleanup() {\r
- _event.remove(_win, 'load', _s.beginDelayedInit);\r
- }\r
- if (_s.html5Only) {\r
- if (!_didInit) {\r
- _cleanup();\r
- _s.enabled = true;\r
- _initComplete();\r
- }\r
- return true;\r
- }\r
- _initMovie();\r
- try {\r
- _s.o._externalInterfaceTest(false);\r
- _setPolling(true, (_s.flashPollingInterval || (_s.useHighPerformance ? 10 : 50)));\r
- if (!_s.debugMode) {\r
- _s.o._disableDebug();\r
- }\r
- _s.enabled = true;\r
- if (!_s.html5Only) {\r
- _event.add(_win, 'unload', _doNothing);\r
- }\r
- } catch(e) {\r
- _catchError({type:'JS_TO_FLASH_EXCEPTION', fatal:true});\r
- _failSafely(true);\r
- _initComplete();\r
- return false;\r
- }\r
- _initComplete();\r
- _cleanup();\r
- return true;\r
- };\r
- _domContentLoaded = function() {\r
- if (_didDCLoaded) {\r
- return false;\r
- }\r
- _didDCLoaded = true;\r
- _initDebug();\r
- if (!_hasFlash && _s.hasHTML5) {\r
- _s.useHTML5Audio = true;\r
- _s.preferFlash = false;\r
- }\r
- _testHTML5();\r
- _s.html5.usingFlash = _featureCheck();\r
- _needsFlash = _s.html5.usingFlash;\r
- _showSupport();\r
- if (!_hasFlash && _needsFlash) {\r
- _s.flashLoadTimeout = 1;\r
- }\r
- if (_doc.removeEventListener) {\r
- _doc.removeEventListener('DOMContentLoaded', _domContentLoaded, false);\r
- }\r
- _initMovie();\r
- return true;\r
- };\r
- _domContentLoadedIE = function() {\r
- if (_doc.readyState === 'complete') {\r
- _domContentLoaded();\r
- _doc.detachEvent('onreadystatechange', _domContentLoadedIE);\r
- }\r
- return true;\r
- };\r
- _detectFlash();\r
- _event.add(_win, 'focus', _handleFocus);\r
- _event.add(_win, 'load', _handleFocus);\r
- _event.add(_win, 'load', _delayWaitForEI);\r
- if (_isSafari && _tryInitOnFocus) {\r
- _event.add(_win, 'mousemove', _handleFocus);\r
- }\r
- if (_doc.addEventListener) {\r
- _doc.addEventListener('DOMContentLoaded', _domContentLoaded, false);\r
- } else if (_doc.attachEvent) {\r
- _doc.attachEvent('onreadystatechange', _domContentLoadedIE);\r
- } else {\r
- _catchError({type:'NO_DOM2_EVENTS', fatal:true});\r
- }\r
- if (_doc.readyState === 'complete') {\r
- setTimeout(_domContentLoaded,100);\r
- }\r
-}\r
-// SM2_DEFER details: http://www.schillmania.com/projects/soundmanager2/doc/getstarted/#lazy-loading\r
-if (typeof SM2_DEFER === 'undefined' || !SM2_DEFER) {\r
- soundManager = new SoundManager();\r
-}\r
-window.SoundManager = SoundManager;\r
-window.soundManager = soundManager;\r
-}(window));
\ No newline at end of file
+++ /dev/null
-/** @license\r
- *\r
- * SoundManager 2: JavaScript Sound for the Web\r
- * ----------------------------------------------\r
- * http://schillmania.com/projects/soundmanager2/\r
- *\r
- * Copyright (c) 2007, Scott Schiller. All rights reserved.\r
- * Code provided under the BSD License:\r
- * http://schillmania.com/projects/soundmanager2/license.txt\r
- *\r
- * V2.97a.20111030\r
- */\r
-\r
-/*global window, SM2_DEFER, sm2Debugger, console, document, navigator, setTimeout, setInterval, clearInterval, Audio */\r
-/* jslint regexp: true, sloppy: true, white: true, nomen: true, plusplus: true */\r
-\r
-/**\r
- * About this file\r
- * ---------------\r
- * This is the fully-commented source version of the SoundManager 2 API,\r
- * recommended for use during development and testing.\r
- *\r
- * See soundmanager2-nodebug-jsmin.js for an optimized build (~10KB with gzip.)\r
- * http://schillmania.com/projects/soundmanager2/doc/getstarted/#basic-inclusion\r
- * Alternately, serve this file with gzip for 75% compression savings (~30KB over HTTP.)\r
- *\r
- * You may notice <d> and </d> comments in this source; these are delimiters for\r
- * debug blocks which are removed in the -nodebug builds, further optimizing code size.\r
- */\r
-\r
-(function(window) {\r
-\r
-var soundManager = null;\r
-\r
-/**\r
- * The SoundManager constructor.\r
- *\r
- * @constructor\r
- * @param {string} smURL Optional: Path to SWF files\r
- * @param {string} smID Optional: The ID to use for the SWF container element\r
- * @this {SoundManager}\r
- * @return {SoundManager} The new SoundManager instance\r
- */\r
-\r
-function SoundManager(smURL, smID) {\r
-\r
- // Top-level configuration options\r
-\r
- this.flashVersion = 8; // version of flash to require, either 8 or 9. Some API features require Flash 9.\r
- this.debugMode = true; // enable debugging output (div#soundmanager-debug, OR console if available+configured)\r
- this.debugFlash = false; // enable debugging output inside SWF, troubleshoot Flash/browser issues\r
- this.useConsole = true; // use firebug/safari console.log()-type debug console if available\r
- this.consoleOnly = false; // if console is being used, do not create/write to #soundmanager-debug\r
- this.waitForWindowLoad = false; // force SM2 to wait for window.onload() before trying to call soundManager.onload()\r
- this.bgColor = '#ffffff'; // movie (.swf) background color, eg. '#000000'\r
- this.useHighPerformance = false; // position:fixed flash movie can help increase js/flash speed, minimize lag\r
- this.flashPollingInterval = null; // msec affecting whileplaying/loading callback frequency. If null, default of 50 msec is used.\r
- this.flashLoadTimeout = 1000; // msec to wait for flash movie to load before failing (0 = infinity)\r
- this.wmode = null; // string: flash rendering mode - null, transparent, opaque (last two allow layering of HTML on top)\r
- this.allowScriptAccess = 'always'; // for scripting the SWF (object/embed property), either 'always' or 'sameDomain'\r
- this.useFlashBlock = false; // *requires flashblock.css, see demos* - allow recovery from flash blockers. Wait indefinitely and apply timeout CSS to SWF, if applicable.\r
- this.useHTML5Audio = true; // use HTML5 Audio() where API is supported (most Safari, Chrome versions), Firefox (no MP3/MP4.) Ideally, transparent vs. Flash API where possible.\r
- this.html5Test = /^(probably|maybe)$/i; // HTML5 Audio() format support test. Use /^probably$/i; if you want to be more conservative.\r
- this.preferFlash = true; // overrides useHTML5audio. if true and flash support present, will try to use flash for MP3/MP4 as needed since HTML5 audio support is still quirky in browsers.\r
- this.noSWFCache = false; // if true, appends ?ts={date} to break aggressive SWF caching.\r
-\r
- this.audioFormats = {\r
-\r
- /**\r
- * determines HTML5 support + flash requirements.\r
- * if no support (via flash and/or HTML5) for a "required" format, SM2 will fail to start.\r
- * flash fallback is used for MP3 or MP4 if HTML5 can't play it (or if preferFlash = true)\r
- * multiple MIME types may be tested while trying to get a positive canPlayType() response.\r
- */\r
-\r
- 'mp3': {\r
- 'type': ['audio/mpeg; codecs="mp3"', 'audio/mpeg', 'audio/mp3', 'audio/MPA', 'audio/mpa-robust'],\r
- 'required': true\r
- },\r
-\r
- 'mp4': {\r
- 'related': ['aac','m4a'], // additional formats under the MP4 container\r
- 'type': ['audio/mp4; codecs="mp4a.40.2"', 'audio/aac', 'audio/x-m4a', 'audio/MP4A-LATM', 'audio/mpeg4-generic'],\r
- 'required': false\r
-\r
- },\r
-\r
- 'ogg': {\r
- 'type': ['audio/ogg; codecs=vorbis'],\r
- 'required': false\r
- },\r
-\r
- 'wav': {\r
- 'type': ['audio/wav; codecs="1"', 'audio/wav', 'audio/wave', 'audio/x-wav'],\r
- 'required': false\r
- }\r
-\r
- };\r
-\r
- this.defaultOptions = {\r
-\r
- /**\r
- * the default configuration for sound objects made with createSound() and related methods\r
- * eg., volume, auto-load behaviour and so forth\r
- */\r
-\r
- 'autoLoad': false, // enable automatic loading (otherwise .load() will be called on demand with .play(), the latter being nicer on bandwidth - if you want to .load yourself, you also can)\r
- 'stream': true, // allows playing before entire file has loaded (recommended)\r
- 'autoPlay': false, // enable playing of file as soon as possible (much faster if "stream" is true)\r
- 'loops': 1, // how many times to repeat the sound (position will wrap around to 0, setPosition() will break out of loop when >0)\r
- 'onid3': null, // callback function for "ID3 data is added/available"\r
- 'onload': null, // callback function for "load finished"\r
- 'whileloading': null, // callback function for "download progress update" (X of Y bytes received)\r
- 'onplay': null, // callback for "play" start\r
- 'onpause': null, // callback for "pause"\r
- 'onresume': null, // callback for "resume" (pause toggle)\r
- 'whileplaying': null, // callback during play (position update)\r
- 'onstop': null, // callback for "user stop"\r
- 'onfailure': null, // callback function for when playing fails\r
- 'onfinish': null, // callback function for "sound finished playing"\r
- 'multiShot': true, // let sounds "restart" or layer on top of each other when played multiple times, rather than one-shot/one at a time\r
- 'multiShotEvents': false, // fire multiple sound events (currently onfinish() only) when multiShot is enabled\r
- 'position': null, // offset (milliseconds) to seek to within loaded sound data.\r
- 'pan': 0, // "pan" settings, left-to-right, -100 to 100\r
- 'type': null, // MIME-like hint for file pattern / canPlay() tests, eg. audio/mp3\r
- 'usePolicyFile': false, // enable crossdomain.xml request for audio on remote domains (for ID3/waveform access)\r
- 'volume': 100 // self-explanatory. 0-100, the latter being the max.\r
-\r
- };\r
-\r
- this.flash9Options = {\r
-\r
- /**\r
- * flash 9-only options,\r
- * merged into defaultOptions if flash 9 is being used\r
- */\r
-\r
- 'isMovieStar': null, // "MovieStar" MPEG4 audio mode. Null (default) = auto detect MP4, AAC etc. based on URL. true = force on, ignore URL\r
- 'usePeakData': false, // enable left/right channel peak (level) data\r
- 'useWaveformData': false, // enable sound spectrum (raw waveform data) - NOTE: May increase CPU load.\r
- 'useEQData': false, // enable sound EQ (frequency spectrum data) - NOTE: May increase CPU load.\r
- 'onbufferchange': null, // callback for "isBuffering" property change\r
- 'ondataerror': null // callback for waveform/eq data access error (flash playing audio in other tabs/domains)\r
-\r
- };\r
-\r
- this.movieStarOptions = {\r
-\r
- /**\r
- * flash 9.0r115+ MPEG4 audio options,\r
- * merged into defaultOptions if flash 9+movieStar mode is enabled\r
- */\r
-\r
- 'bufferTime': 3, // seconds of data to buffer before playback begins (null = flash default of 0.1 seconds - if AAC playback is gappy, try increasing.)\r
- 'serverURL': null, // rtmp: FMS or FMIS server to connect to, required when requesting media via RTMP or one of its variants\r
- 'onconnect': null, // rtmp: callback for connection to flash media server\r
- 'duration': null // rtmp: song duration (msec)\r
-\r
- };\r
-\r
- // HTML attributes (id + class names) for the SWF container\r
-\r
- this.movieID = 'sm2-container';\r
- this.id = (smID || 'sm2movie');\r
-\r
- this.swfCSS = {\r
-\r
- 'swfBox': 'sm2-object-box',\r
- 'swfDefault': 'movieContainer',\r
- 'swfError': 'swf_error', // SWF loaded, but SM2 couldn't start (other error)\r
- 'swfTimedout': 'swf_timedout',\r
- 'swfLoaded': 'swf_loaded',\r
- 'swfUnblocked': 'swf_unblocked', // or loaded OK\r
- 'sm2Debug': 'sm2_debug',\r
- 'highPerf': 'high_performance',\r
- 'flashDebug': 'flash_debug'\r
-\r
- };\r
-\r
- this.debugID = 'soundmanager-debug';\r
- this.debugURLParam = /([#?&])debug=1/i;\r
-\r
- // dynamic attributes\r
-\r
- this.versionNumber = 'V2.97a.20111030';\r
- this.version = null;\r
- this.movieURL = null;\r
- this.url = (smURL || null);\r
- this.altURL = null;\r
- this.swfLoaded = false;\r
- this.enabled = false;\r
- this.o = null;\r
- this.oMC = null;\r
- this.sounds = {};\r
- this.soundIDs = [];\r
- this.muted = false;\r
- this.specialWmodeCase = false;\r
- this.didFlashBlock = false;\r
- this.filePattern = null;\r
-\r
- this.filePatterns = {\r
-\r
- 'flash8': /\.mp3(\?.*)?$/i,\r
- 'flash9': /\.mp3(\?.*)?$/i\r
-\r
- };\r
-\r
- // support indicators, set at init\r
-\r
- this.features = {\r
-\r
- 'buffering': false,\r
- 'peakData': false,\r
- 'waveformData': false,\r
- 'eqData': false,\r
- 'movieStar': false\r
-\r
- };\r
-\r
- // flash sandbox info, used primarily in troubleshooting\r
-\r
- this.sandbox = {\r
-\r
- // <d>\r
- 'type': null,\r
- 'types': {\r
- 'remote': 'remote (domain-based) rules',\r
- 'localWithFile': 'local with file access (no internet access)',\r
- 'localWithNetwork': 'local with network (internet access only, no local access)',\r
- 'localTrusted': 'local, trusted (local+internet access)'\r
- },\r
- 'description': null,\r
- 'noRemote': null,\r
- 'noLocal': null\r
- // </d>\r
-\r
- };\r
-\r
- /**\r
- * basic HTML5 Audio() support test\r
- * try...catch because of IE 9 "not implemented" nonsense\r
- * https://github.com/Modernizr/Modernizr/issues/224\r
- */\r
-\r
- this.hasHTML5 = (function() {\r
- try {\r
- return (typeof Audio !== 'undefined' && typeof new Audio().canPlayType !== 'undefined');\r
- } catch(e) {\r
- return false;\r
- }\r
- }());\r
-\r
- /**\r
- * format support (html5/flash)\r
- * stores canPlayType() results based on audioFormats.\r
- * eg. { mp3: boolean, mp4: boolean }\r
- * treat as read-only.\r
- */\r
-\r
- this.html5 = {\r
- 'usingFlash': null // set if/when flash fallback is needed\r
- };\r
-\r
- this.flash = {};\r
-\r
- this.html5Only = false; // determined at init time\r
- this.ignoreFlash = false; // used for special cases (eg. iPad/iPhone/palm OS?)\r
-\r
- /**\r
- * a few private internals (OK, a lot. :D)\r
- */\r
-\r
- var SMSound,\r
- _s = this, _sm = 'soundManager', _smc = _sm+'::', _h5 = 'HTML5::', _id, _ua = navigator.userAgent, _win = window, _wl = _win.location.href.toString(), _doc = document, _doNothing, _init, _fV, _on_queue = [], _debugOpen = true, _debugTS, _didAppend = false, _appendSuccess = false, _didInit = false, _disabled = false, _windowLoaded = false, _wDS, _wdCount = 0, _initComplete, _mixin, _addOnEvent, _processOnEvents, _initUserOnload, _delayWaitForEI, _waitForEI, _setVersionInfo, _handleFocus, _strings, _initMovie, _domContentLoaded, _didDCLoaded, _getDocument, _createMovie, _catchError, _setPolling, _initDebug, _debugLevels = ['log', 'info', 'warn', 'error'], _defaultFlashVersion = 8, _disableObject, _failSafely, _normalizeMovieURL, _oRemoved = null, _oRemovedHTML = null, _str, _flashBlockHandler, _getSWFCSS, _toggleDebug, _loopFix, _policyFix, _complain, _idCheck, _waitingForEI = false, _initPending = false, _smTimer, _onTimer, _startTimer, _stopTimer, _needsFlash = null, _featureCheck, _html5OK, _html5CanPlay, _html5Ext, _html5Unload, _domContentLoadedIE, _testHTML5, _event, _slice = Array.prototype.slice, _useGlobalHTML5Audio = false, _hasFlash, _detectFlash, _badSafariFix, _html5_events, _showSupport,\r
- _is_iDevice = _ua.match(/(ipad|iphone|ipod)/i), _is_firefox = _ua.match(/firefox/i), _is_android = _ua.match(/droid/i), _isIE = _ua.match(/msie/i), _isWebkit = _ua.match(/webkit/i), _isSafari = (_ua.match(/safari/i) && !_ua.match(/chrome/i)), _isOpera = (_ua.match(/opera/i)), \r
- _likesHTML5 = (_ua.match(/(mobile|pre\/|xoom)/i) || _is_iDevice),\r
- _isBadSafari = (!_wl.match(/usehtml5audio/i) && !_wl.match(/sm2\-ignorebadua/i) && _isSafari && _ua.match(/OS X 10_6_([3-7])/i)), // Safari 4 and 5 occasionally fail to load/play HTML5 audio on Snow Leopard 10.6.3 through 10.6.7 due to bug(s) in QuickTime X and/or other underlying frameworks. :/ Confirmed bug. https://bugs.webkit.org/show_bug.cgi?id=32159\r
- _hasConsole = (typeof console !== 'undefined' && typeof console.log !== 'undefined'), _isFocused = (typeof _doc.hasFocus !== 'undefined'?_doc.hasFocus():null), _tryInitOnFocus = (_isSafari && typeof _doc.hasFocus === 'undefined'), _okToDisable = !_tryInitOnFocus, _flashMIME = /(mp3|mp4|mpa)/i,\r
- _emptyURL = 'about:blank', // safe URL to unload, or load nothing from (flash 8 + most HTML5 UAs)\r
- _overHTTP = (_doc.location?_doc.location.protocol.match(/http/i):null),\r
- _http = (!_overHTTP ? 'http:/'+'/' : ''),\r
- // mp3, mp4, aac etc.\r
- _netStreamMimeTypes = /^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|mp4v|3gp|3g2)\s*(?:$|;)/i,\r
- // Flash v9.0r115+ "moviestar" formats\r
- _netStreamTypes = ['mpeg4', 'aac', 'flv', 'mov', 'mp4', 'm4v', 'f4v', 'm4a', 'mp4v', '3gp', '3g2'],\r
- _netStreamPattern = new RegExp('\\.(' + _netStreamTypes.join('|') + ')(\\?.*)?$', 'i');\r
- this.mimePattern = /^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i; // default mp3 set\r
-\r
- // use altURL if not "online"\r
- this.useAltURL = !_overHTTP;\r
- this._global_a = null;\r
-\r
- if (_likesHTML5) {\r
-\r
- // prefer HTML5 for mobile + tablet-like devices, probably more reliable vs. flash at this point.\r
- _s.useHTML5Audio = true;\r
- _s.preferFlash = false;\r
-\r
- if (_is_iDevice) {\r
- // by default, use global feature. iOS onfinish() -> next may fail otherwise.\r
- _s.ignoreFlash = true;\r
- _useGlobalHTML5Audio = true;\r
- }\r
-\r
- }\r
-\r
- /**\r
- * Public SoundManager API\r
- * -----------------------\r
- */\r
-\r
- this.ok = function() {\r
-\r
- return (_needsFlash?(_didInit && !_disabled):(_s.useHTML5Audio && _s.hasHTML5));\r
-\r
- };\r
-\r
- this.supported = this.ok; // legacy\r
-\r
- this.getMovie = function(smID) {\r
-\r
- // safety net: some old browsers differ on SWF references, possibly related to ExternalInterface / flash version\r
- return _id(smID) || _doc[smID] || _win[smID];\r
-\r
- };\r
-\r
- /**\r
- * Creates a SMSound sound object instance.\r
- *\r
- * @param {object} oOptions Sound options (at minimum, id and url are required.)\r
- * @return {object} SMSound The new SMSound object.\r
- */\r
-\r
- this.createSound = function(oOptions) {\r
-\r
- var _cs = _sm+'.createSound(): ',\r
- thisOptions = null, oSound = null, _tO = null;\r
-\r
- if (!_didInit || !_s.ok()) {\r
- _complain(_cs + _str(!_didInit?'notReady':'notOK'));\r
- return false;\r
- }\r
-\r
- if (arguments.length === 2) {\r
- // function overloading in JS! :) ..assume simple createSound(id,url) use case\r
- oOptions = {\r
- 'id': arguments[0],\r
- 'url': arguments[1]\r
- };\r
- }\r
-\r
- // inherit from defaultOptions\r
- thisOptions = _mixin(oOptions);\r
-\r
- // alias\r
- _tO = thisOptions;\r
-\r
- // <d>\r
- if (_tO.id.toString().charAt(0).match(/^[0-9]$/)) {\r
- _s._wD(_cs + _str('badID', _tO.id), 2);\r
- }\r
-\r
- _s._wD(_cs + _tO.id + ' (' + _tO.url + ')', 1);\r
- // </d>\r
-\r
- if (_idCheck(_tO.id, true)) {\r
- _s._wD(_cs + _tO.id + ' exists', 1);\r
- return _s.sounds[_tO.id];\r
- }\r
-\r
- function make() {\r
-\r
- thisOptions = _loopFix(thisOptions);\r
- _s.sounds[_tO.id] = new SMSound(_tO);\r
- _s.soundIDs.push(_tO.id);\r
- return _s.sounds[_tO.id];\r
-\r
- }\r
-\r
- if (_html5OK(_tO)) {\r
-\r
- oSound = make();\r
- _s._wD('Loading sound '+_tO.id+' via HTML5');\r
- oSound._setup_html5(_tO);\r
-\r
- } else {\r
-\r
- if (_fV > 8) {\r
- if (_tO.isMovieStar === null) {\r
- // attempt to detect MPEG-4 formats\r
- _tO.isMovieStar = (_tO.serverURL || (_tO.type ? _tO.type.match(_netStreamMimeTypes) : false) || _tO.url.match(_netStreamPattern));\r
- }\r
- // <d>\r
- if (_tO.isMovieStar) {\r
- _s._wD(_cs + 'using MovieStar handling');\r
- }\r
- // </d>\r
- if (_tO.isMovieStar) {\r
- if (_tO.usePeakData) {\r
- _wDS('noPeak');\r
- _tO.usePeakData = false;\r
- }\r
- // <d>\r
- if (_tO.loops > 1) {\r
- _wDS('noNSLoop');\r
- }\r
- // </d>\r
- }\r
- }\r
-\r
- _tO = _policyFix(_tO, _cs);\r
- oSound = make();\r
-\r
- if (_fV === 8) {\r
- _s.o._createSound(_tO.id, _tO.loops||1, _tO.usePolicyFile);\r
- } else {\r
- _s.o._createSound(_tO.id, _tO.url, _tO.usePeakData, _tO.useWaveformData, _tO.useEQData, _tO.isMovieStar, (_tO.isMovieStar?_tO.bufferTime:false), _tO.loops||1, _tO.serverURL, _tO.duration||null, _tO.autoPlay, true, _tO.autoLoad, _tO.usePolicyFile);\r
- if (!_tO.serverURL) {\r
- // We are connected immediately\r
- oSound.connected = true;\r
- if (_tO.onconnect) {\r
- _tO.onconnect.apply(oSound);\r
- }\r
- }\r
- }\r
-\r
- if (!_tO.serverURL && (_tO.autoLoad || _tO.autoPlay)) {\r
- // call load for non-rtmp streams\r
- oSound.load(_tO);\r
- }\r
-\r
- }\r
-\r
- // rtmp will play in onconnect\r
- if (!_tO.serverURL && _tO.autoPlay) {\r
- oSound.play();\r
- }\r
-\r
- return oSound;\r
-\r
- };\r
-\r
- /**\r
- * Destroys a SMSound sound object instance.\r
- *\r
- * @param {string} sID The ID of the sound to destroy\r
- */\r
-\r
- this.destroySound = function(sID, _bFromSound) {\r
-\r
- // explicitly destroy a sound before normal page unload, etc.\r
-\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
-\r
- var oS = _s.sounds[sID], i;\r
-\r
- // Disable all callbacks while the sound is being destroyed\r
- oS._iO = {};\r
-\r
- oS.stop();\r
- oS.unload();\r
-\r
- for (i = 0; i < _s.soundIDs.length; i++) {\r
- if (_s.soundIDs[i] === sID) {\r
- _s.soundIDs.splice(i, 1);\r
- break;\r
- }\r
- }\r
-\r
- if (!_bFromSound) {\r
- // ignore if being called from SMSound instance\r
- oS.destruct(true);\r
- }\r
-\r
- oS = null;\r
- delete _s.sounds[sID];\r
-\r
- return true;\r
-\r
- };\r
-\r
- /**\r
- * Calls the load() method of a SMSound object by ID.\r
- *\r
- * @param {string} sID The ID of the sound\r
- * @param {object} oOptions Optional: Sound options\r
- */\r
-\r
- this.load = function(sID, oOptions) {\r
-\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
- return _s.sounds[sID].load(oOptions);\r
-\r
- };\r
-\r
- /**\r
- * Calls the unload() method of a SMSound object by ID.\r
- *\r
- * @param {string} sID The ID of the sound\r
- */\r
-\r
- this.unload = function(sID) {\r
-\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
-\r
- return _s.sounds[sID].unload();\r
-\r
- };\r
-\r
- /**\r
- * Calls the onposition() method of a SMSound object by ID.\r
- *\r
- * @param {string} sID The ID of the sound\r
- * @param {number} nPosition The position to watch for\r
- * @param {function} oMethod The relevant callback to fire\r
- * @param {object} oScope Optional: The scope to apply the callback to\r
- * @return {SMSound} The SMSound object\r
- */\r
-\r
- this.onposition = function(sID, nPosition, oMethod, oScope) {\r
-\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
- return _s.sounds[sID].onposition(nPosition, oMethod, oScope);\r
-\r
- };\r
-\r
- /**\r
- * Calls the play() method of a SMSound object by ID.\r
- *\r
- * @param {string} sID The ID of the sound\r
- * @param {object} oOptions Optional: Sound options\r
- * @return {SMSound} The SMSound object\r
- */\r
-\r
- this.play = function(sID, oOptions) {\r
-\r
- var fN = _sm+'.play(): ';\r
-\r
- if (!_didInit || !_s.ok()) {\r
- _complain(fN + _str(!_didInit?'notReady':'notOK'));\r
- return false;\r
- }\r
-\r
- if (!_idCheck(sID)) {\r
- if (!(oOptions instanceof Object)) {\r
- oOptions = {\r
- url: oOptions\r
- }; // overloading use case: play('mySound','/path/to/some.mp3');\r
- }\r
- if (oOptions && oOptions.url) {\r
- // overloading use case, create+play: .play('someID',{url:'/path/to.mp3'});\r
- _s._wD(fN + 'attempting to create "' + sID + '"', 1);\r
- oOptions.id = sID;\r
- return _s.createSound(oOptions).play();\r
- } else {\r
- return false;\r
- }\r
- }\r
-\r
- return _s.sounds[sID].play(oOptions);\r
-\r
- };\r
-\r
- this.start = this.play; // just for convenience\r
-\r
- /**\r
- * Calls the setPosition() method of a SMSound object by ID.\r
- *\r
- * @param {string} sID The ID of the sound\r
- * @param {number} nMsecOffset Position (milliseconds)\r
- * @return {SMSound} The SMSound object\r
- */\r
-\r
- this.setPosition = function(sID, nMsecOffset) {\r
-\r
- if (!_idCheck(sID)) {\r
- return false;\r
-\r
- }\r
- return _s.sounds[sID].setPosition(nMsecOffset);\r
-\r
- };\r
-\r
- /**\r
- * Calls the stop() method of a SMSound object by ID.\r
- *\r
- * @param {string} sID The ID of the sound\r
- * @return {SMSound} The SMSound object\r
- */\r
-\r
- this.stop = function(sID) {\r
-\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
- _s._wD(_sm+'.stop(' + sID + ')', 1);\r
- return _s.sounds[sID].stop();\r
-\r
- };\r
-\r
- /**\r
- * Stops all currently-playing sounds.\r
- */\r
-\r
- this.stopAll = function() {\r
-\r
- var oSound;\r
- _s._wD(_sm+'.stopAll()', 1);\r
-\r
- for (oSound in _s.sounds) {\r
- if (_s.sounds.hasOwnProperty(oSound)) {\r
- // apply only to sound objects\r
- _s.sounds[oSound].stop();\r
- }\r
- }\r
-\r
- };\r
-\r
- /**\r
- * Calls the pause() method of a SMSound object by ID.\r
- *\r
- * @param {string} sID The ID of the sound\r
- * @return {SMSound} The SMSound object\r
- */\r
-\r
- this.pause = function(sID) {\r
-\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
- return _s.sounds[sID].pause();\r
-\r
- };\r
-\r
- /**\r
- * Pauses all currently-playing sounds.\r
- */\r
-\r
- this.pauseAll = function() {\r
-\r
- var i;\r
- for (i = _s.soundIDs.length; i--;) {\r
- _s.sounds[_s.soundIDs[i]].pause();\r
- }\r
-\r
- };\r
-\r
- /**\r
- * Calls the resume() method of a SMSound object by ID.\r
- *\r
- * @param {string} sID The ID of the sound\r
- * @return {SMSound} The SMSound object\r
- */\r
-\r
- this.resume = function(sID) {\r
-\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
- return _s.sounds[sID].resume();\r
-\r
- };\r
-\r
- /**\r
- * Resumes all currently-paused sounds.\r
- */\r
-\r
- this.resumeAll = function() {\r
-\r
- var i;\r
- for (i = _s.soundIDs.length; i--;) {\r
- _s.sounds[_s.soundIDs[i]].resume();\r
- }\r
-\r
- };\r
-\r
- /**\r
- * Calls the togglePause() method of a SMSound object by ID.\r
- *\r
- * @param {string} sID The ID of the sound\r
- * @return {SMSound} The SMSound object\r
- */\r
-\r
- this.togglePause = function(sID) {\r
-\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
- return _s.sounds[sID].togglePause();\r
-\r
- };\r
-\r
- /**\r
- * Calls the setPan() method of a SMSound object by ID.\r
- *\r
- * @param {string} sID The ID of the sound\r
- * @param {number} nPan The pan value (-100 to 100)\r
- * @return {SMSound} The SMSound object\r
- */\r
-\r
- this.setPan = function(sID, nPan) {\r
-\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
- return _s.sounds[sID].setPan(nPan);\r
-\r
- };\r
-\r
- /**\r
- * Calls the setVolume() method of a SMSound object by ID.\r
- *\r
- * @param {string} sID The ID of the sound\r
- * @param {number} nVol The volume value (0 to 100)\r
- * @return {SMSound} The SMSound object\r
- */\r
-\r
- this.setVolume = function(sID, nVol) {\r
-\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
- return _s.sounds[sID].setVolume(nVol);\r
-\r
- };\r
-\r
- /**\r
- * Calls the mute() method of either a single SMSound object by ID, or all sound objects.\r
- *\r
- * @param {string} sID Optional: The ID of the sound (if omitted, all sounds will be used.)\r
- */\r
-\r
- this.mute = function(sID) {\r
-\r
- var fN = _sm+'.mute(): ',\r
- i = 0;\r
-\r
- if (typeof sID !== 'string') {\r
- sID = null;\r
- }\r
-\r
- if (!sID) {\r
- _s._wD(fN + 'Muting all sounds');\r
- for (i = _s.soundIDs.length; i--;) {\r
- _s.sounds[_s.soundIDs[i]].mute();\r
- }\r
- _s.muted = true;\r
- } else {\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
- _s._wD(fN + 'Muting "' + sID + '"');\r
- return _s.sounds[sID].mute();\r
- }\r
-\r
- return true;\r
-\r
- };\r
-\r
- /**\r
- * Mutes all sounds.\r
- */\r
-\r
- this.muteAll = function() {\r
-\r
- _s.mute();\r
-\r
- };\r
-\r
- /**\r
- * Calls the unmute() method of either a single SMSound object by ID, or all sound objects.\r
- *\r
- * @param {string} sID Optional: The ID of the sound (if omitted, all sounds will be used.)\r
- */\r
-\r
- this.unmute = function(sID) {\r
-\r
- var fN = _sm+'.unmute(): ', i;\r
-\r
- if (typeof sID !== 'string') {\r
- sID = null;\r
- }\r
-\r
- if (!sID) {\r
-\r
- _s._wD(fN + 'Unmuting all sounds');\r
- for (i = _s.soundIDs.length; i--;) {\r
- _s.sounds[_s.soundIDs[i]].unmute();\r
- }\r
- _s.muted = false;\r
-\r
- } else {\r
-\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
- _s._wD(fN + 'Unmuting "' + sID + '"');\r
- return _s.sounds[sID].unmute();\r
-\r
- }\r
-\r
- return true;\r
-\r
- };\r
-\r
- /**\r
- * Unmutes all sounds.\r
- */\r
-\r
- this.unmuteAll = function() {\r
-\r
- _s.unmute();\r
-\r
- };\r
-\r
- /**\r
- * Calls the toggleMute() method of a SMSound object by ID.\r
- *\r
- * @param {string} sID The ID of the sound\r
- * @return {SMSound} The SMSound object\r
- */\r
-\r
- this.toggleMute = function(sID) {\r
-\r
- if (!_idCheck(sID)) {\r
- return false;\r
- }\r
-\r
- return _s.sounds[sID].toggleMute();\r
-\r
- };\r
-\r
- /**\r
- * Retrieves the memory used by the flash plugin.\r
- *\r
- * @return {number} The amount of memory in use\r
- */\r
-\r
- this.getMemoryUse = function() {\r
-\r
- // flash-only\r
- var ram = 0;\r
-\r
- if (_s.o && _fV !== 8) {\r
- ram = parseInt(_s.o._getMemoryUse(), 10);\r
- }\r
-\r
- return ram;\r
-\r
- };\r
-\r
- /**\r
- * Undocumented: NOPs soundManager and all SMSound objects.\r
- */\r
-\r
- this.disable = function(bNoDisable) {\r
-\r
- // destroy all functions\r
- var i;\r
-\r
- if (typeof bNoDisable === 'undefined') {\r
- bNoDisable = false;\r
- }\r
-\r
- if (_disabled) {\r
- return false;\r
- }\r
-\r
- _disabled = true;\r
- _wDS('shutdown', 1);\r
-\r
- for (i = _s.soundIDs.length; i--;) {\r
- _disableObject(_s.sounds[_s.soundIDs[i]]);\r
- }\r
-\r
- // fire "complete", despite fail\r
- _initComplete(bNoDisable);\r
- _event.remove(_win, 'load', _initUserOnload);\r
-\r
- return true;\r
-\r
- };\r
-\r
- /**\r
- * Determines playability of a MIME type, eg. 'audio/mp3'.\r
- */\r
-\r
- this.canPlayMIME = function(sMIME) {\r
-\r
- var result;\r
-\r
- if (_s.hasHTML5) {\r
- result = _html5CanPlay({type:sMIME});\r
- }\r
-\r
- if (!_needsFlash || result) {\r
- // no flash, or OK\r
- return result;\r
- } else {\r
- // if flash 9, test netStream (movieStar) types as well.\r
- return (sMIME ? !!((_fV > 8 ? sMIME.match(_netStreamMimeTypes) : null) || sMIME.match(_s.mimePattern)) : null);\r
- }\r
-\r
- };\r
-\r
- /**\r
- * Determines playability of a URL based on audio support.\r
- *\r
- * @param {string} sURL The URL to test\r
- * @return {boolean} URL playability\r
- */\r
-\r
- this.canPlayURL = function(sURL) {\r
-\r
- var result;\r
-\r
- if (_s.hasHTML5) {\r
- result = _html5CanPlay({url: sURL});\r
- }\r
-\r
- if (!_needsFlash || result) {\r
- // no flash, or OK\r
- return result;\r
- } else {\r
- return (sURL ? !!(sURL.match(_s.filePattern)) : null);\r
- }\r
-\r
- };\r
-\r
- /**\r
- * Determines playability of an HTML DOM <a> object (or similar object literal) based on audio support.\r
- *\r
- * @param {object} oLink an HTML DOM <a> object or object literal including href and/or type attributes\r
- * @return {boolean} URL playability\r
- */\r
-\r
- this.canPlayLink = function(oLink) {\r
-\r
- if (typeof oLink.type !== 'undefined' && oLink.type) {\r
- if (_s.canPlayMIME(oLink.type)) {\r
- return true;\r
- }\r
- }\r
-\r
- return _s.canPlayURL(oLink.href);\r
-\r
- };\r
-\r
- /**\r
- * Retrieves a SMSound object by ID.\r
- *\r
- * @param {string} sID The ID of the sound\r
- * @return {SMSound} The SMSound object\r
- */\r
-\r
- this.getSoundById = function(sID, _suppressDebug) {\r
-\r
- if (!sID) {\r
- throw new Error(_sm+'.getSoundById(): sID is null/undefined');\r
- }\r
-\r
- var result = _s.sounds[sID];\r
-\r
- // <d>\r
- if (!result && !_suppressDebug) {\r
- _s._wD('"' + sID + '" is an invalid sound ID.', 2);\r
- }\r
- // </d>\r
-\r
- return result;\r
-\r
- };\r
-\r
- /**\r
- * Queues a callback for execution when SoundManager has successfully initialized.\r
- *\r
- * @param {function} oMethod The callback method to fire\r
- * @param {object} oScope Optional: The scope to apply to the callback\r
- */\r
-\r
- this.onready = function(oMethod, oScope) {\r
-\r
- var sType = 'onready';\r
-\r
- if (oMethod && oMethod instanceof Function) {\r
-\r
- // <d>\r
- if (_didInit) {\r
- _s._wD(_str('queue', sType));\r
- }\r
- // </d>\r
-\r
- if (!oScope) {\r
- oScope = _win;\r
- }\r
-\r
- _addOnEvent(sType, oMethod, oScope);\r
- _processOnEvents();\r
-\r
- return true;\r
-\r
- } else {\r
-\r
- throw _str('needFunction', sType);\r
-\r
- }\r
-\r
- };\r
-\r
- /**\r
- * Queues a callback for execution when SoundManager has failed to initialize.\r
- *\r
- * @param {function} oMethod The callback method to fire\r
- * @param {object} oScope Optional: The scope to apply to the callback\r
- */\r
-\r
- this.ontimeout = function(oMethod, oScope) {\r
-\r
- var sType = 'ontimeout';\r
-\r
- if (oMethod && oMethod instanceof Function) {\r
-\r
- // <d>\r
- if (_didInit) {\r
- _s._wD(_str('queue', sType));\r
- }\r
- // </d>\r
-\r
- if (!oScope) {\r
- oScope = _win;\r
- }\r
-\r
- _addOnEvent(sType, oMethod, oScope);\r
- _processOnEvents({type:sType});\r
-\r
- return true;\r
-\r
- } else {\r
-\r
- throw _str('needFunction', sType);\r
-\r
- }\r
-\r
- };\r
-\r
- /**\r
- * Writes console.log()-style debug output to a console or in-browser element.\r
- * Applies when SoundManager.debugMode = true\r
- *\r
- * @param {string} sText The console message\r
- * @param {string} sType Optional: Log type of 'info', 'warn' or 'error'\r
- * @param {object} Optional: The scope to apply to the callback\r
- */\r
-\r
- this._writeDebug = function(sText, sType, _bTimestamp) {\r
-\r
- // pseudo-private console.log()-style output\r
- // <d>\r
-\r
- var sDID = 'soundmanager-debug', o, oItem, sMethod;\r
-\r
- if (!_s.debugMode) {\r
- return false;\r
- }\r
-\r
- if (typeof _bTimestamp !== 'undefined' && _bTimestamp) {\r
- sText = sText + ' | ' + new Date().getTime();\r
- }\r
-\r
- if (_hasConsole && _s.useConsole) {\r
- sMethod = _debugLevels[sType];\r
- if (typeof console[sMethod] !== 'undefined') {\r
- console[sMethod](sText);\r
- } else {\r
- console.log(sText);\r
- }\r
- if (_s.useConsoleOnly) {\r
- return true;\r
- }\r
- }\r
-\r
- try {\r
-\r
- o = _id(sDID);\r
-\r
- if (!o) {\r
- return false;\r
- }\r
-\r
- oItem = _doc.createElement('div');\r
-\r
- if (++_wdCount % 2 === 0) {\r
- oItem.className = 'sm2-alt';\r
- }\r
-\r
- if (typeof sType === 'undefined') {\r
- sType = 0;\r
- } else {\r
- sType = parseInt(sType, 10);\r
- }\r
-\r
- oItem.appendChild(_doc.createTextNode(sText));\r
-\r
- if (sType) {\r
- if (sType >= 2) {\r
- oItem.style.fontWeight = 'bold';\r
- }\r
- if (sType === 3) {\r
- oItem.style.color = '#ff3333';\r
- }\r
- }\r
-\r
- // top-to-bottom\r
- // o.appendChild(oItem);\r
-\r
- // bottom-to-top\r
- o.insertBefore(oItem, o.firstChild);\r
-\r
- } catch(e) {\r
- // oh well\r
- }\r
-\r
- o = null;\r
- // </d>\r
-\r
- return true;\r
-\r
- };\r
-\r
- // alias\r
- this._wD = this._writeDebug;\r
-\r
- /**\r
- * Provides debug / state information on all SMSound objects.\r
- */\r
-\r
- this._debug = function() {\r
-\r
- // <d>\r
- var i, j;\r
- _wDS('currentObj', 1);\r
-\r
- for (i = 0, j = _s.soundIDs.length; i < j; i++) {\r
- _s.sounds[_s.soundIDs[i]]._debug();\r
- }\r
- // </d>\r
-\r
- };\r
-\r
- /**\r
- * Restarts and re-initializes the SoundManager instance.\r
- */\r
-\r
- this.reboot = function() {\r
-\r
- // attempt to reset and init SM2\r
- _s._wD(_sm+'.reboot()');\r
-\r
- // <d>\r
- if (_s.soundIDs.length) {\r
- _s._wD('Destroying ' + _s.soundIDs.length + ' SMSound objects...');\r
- }\r
- // </d>\r
-\r
- var i, j;\r
-\r
- for (i = _s.soundIDs.length; i--;) {\r
- _s.sounds[_s.soundIDs[i]].destruct();\r
- }\r
-\r
- // trash ze flash\r
-\r
- try {\r
- if (_isIE) {\r
- _oRemovedHTML = _s.o.innerHTML;\r
- }\r
- _oRemoved = _s.o.parentNode.removeChild(_s.o);\r
- _s._wD('Flash movie removed.');\r
- } catch(e) {\r
- // uh-oh.\r
- _wDS('badRemove', 2);\r
- }\r
-\r
- // actually, force recreate of movie.\r
- _oRemovedHTML = _oRemoved = _needsFlash = null;\r
-\r
- _s.enabled = _didDCLoaded = _didInit = _waitingForEI = _initPending = _didAppend = _appendSuccess = _disabled = _s.swfLoaded = false;\r
- _s.soundIDs = _s.sounds = [];\r
- _s.o = null;\r
-\r
- for (i in _on_queue) {\r
- if (_on_queue.hasOwnProperty(i)) {\r
- for (j = _on_queue[i].length; j--;) {\r
- _on_queue[i][j].fired = false;\r
- }\r
- }\r
- }\r
-\r
- _s._wD(_sm + ': Rebooting...');\r
- _win.setTimeout(_s.beginDelayedInit, 20);\r
-\r
- };\r
-\r
- /**\r
- * Undocumented: Determines the SM2 flash movie's load progress.\r
- *\r
- * @return {number or null} Percent loaded, or if invalid/unsupported, null.\r
- */\r
-\r
- this.getMoviePercent = function() {\r
-\r
- return (_s.o && typeof _s.o.PercentLoaded !== 'undefined' ? _s.o.PercentLoaded() : null);\r
-\r
- };\r
-\r
- /**\r
- * Additional helper for manually invoking SM2's init process after DOM Ready / window.onload().\r
- */\r
-\r
- this.beginDelayedInit = function() {\r
-\r
- _windowLoaded = true;\r
- _domContentLoaded();\r
-\r
- setTimeout(function() {\r
-\r
- if (_initPending) {\r
- return false;\r
- }\r
-\r
- _createMovie();\r
- _initMovie();\r
- _initPending = true;\r
-\r
- return true;\r
-\r
- }, 20);\r
-\r
- _delayWaitForEI();\r
-\r
- };\r
-\r
- /**\r
- * Destroys the SoundManager instance and all SMSound instances.\r
- */\r
-\r
- this.destruct = function() {\r
-\r
- _s._wD(_sm+'.destruct()');\r
- _s.disable(true);\r
-\r
- };\r
-\r
- /**\r
- * SMSound() (sound object) constructor\r
- * ------------------------------------\r
- *\r
- * @param {object} oOptions Sound options (id and url are required attributes)\r
- * @return {SMSound} The new SMSound object\r
- */\r
-\r
- SMSound = function(oOptions) {\r
-\r
- var _t = this, _resetProperties, _stop_html5_timer, _start_html5_timer;\r
- this.sID = oOptions.id;\r
- this.url = oOptions.url;\r
- this.options = _mixin(oOptions);\r
-\r
- // per-play-instance-specific options\r
- this.instanceOptions = this.options;\r
-\r
- // short alias\r
- this._iO = this.instanceOptions;\r
-\r
- // assign property defaults\r
- this.pan = this.options.pan;\r
- this.volume = this.options.volume;\r
- this._lastURL = null;\r
- this.isHTML5 = false;\r
- this._a = null;\r
-\r
- /**\r
- * SMSound() public methods\r
- * ------------------------\r
- */\r
-\r
- this.id3 = {};\r
-\r
- /**\r
- * Writes SMSound object parameters to debug console\r
- */\r
-\r
- this._debug = function() {\r
-\r
- // <d>\r
- // pseudo-private console.log()-style output\r
-\r
- if (_s.debugMode) {\r
-\r
- var stuff = null, msg = [], sF, sfBracket, maxLength = 64;\r
-\r
- for (stuff in _t.options) {\r
- if (_t.options[stuff] !== null) {\r
- if (_t.options[stuff] instanceof Function) {\r
- // handle functions specially\r
- sF = _t.options[stuff].toString();\r
- // normalize spaces\r
- sF = sF.replace(/\s\s+/g, ' ');\r
- sfBracket = sF.indexOf('{');\r
- msg.push(' ' + stuff + ': {' + sF.substr(sfBracket + 1, (Math.min(Math.max(sF.indexOf('\n') - 1, maxLength), maxLength))).replace(/\n/g, '') + '... }');\r
- } else {\r
- msg.push(' ' + stuff + ': ' + _t.options[stuff]);\r
- }\r
- }\r
- }\r
-\r
- _s._wD('SMSound() merged options: {\n' + msg.join(', \n') + '\n}');\r
-\r
- }\r
- // </d>\r
-\r
- };\r
-\r
- // <d>\r
- this._debug();\r
- // </d>\r
-\r
- /**\r
- * Begins loading a sound per its *url*.\r
- *\r
- * @param {object} oOptions Optional: Sound options\r
- * @return {SMSound} The SMSound object\r
- */\r
-\r
- this.load = function(oOptions) {\r
-\r
- var oS = null;\r
-\r
- if (typeof oOptions !== 'undefined') {\r
- _t._iO = _mixin(oOptions, _t.options);\r
- _t.instanceOptions = _t._iO;\r
- } else {\r
- oOptions = _t.options;\r
- _t._iO = oOptions;\r
- _t.instanceOptions = _t._iO;\r
- if (_t._lastURL && _t._lastURL !== _t.url) {\r
- _wDS('manURL');\r
- _t._iO.url = _t.url;\r
- _t.url = null;\r
- }\r
- }\r
-\r
- if (!_t._iO.url) {\r
- _t._iO.url = _t.url;\r
- }\r
-\r
- _s._wD('SMSound.load(): ' + _t._iO.url, 1);\r
-\r
- if (_t._iO.url === _t.url && _t.readyState !== 0 && _t.readyState !== 2) {\r
- _wDS('onURL', 1);\r
- return _t;\r
- }\r
-\r
- _t._lastURL = _t.url;\r
- _t.loaded = false;\r
- _t.readyState = 1;\r
- _t.playState = 0;\r
-\r
- // TODO: If switching from HTML5 -> flash (or vice versa), stop currently-playing audio.\r
-\r
- if (_html5OK(_t._iO)) {\r
-\r
- oS = _t._setup_html5(_t._iO);\r
- if (!oS._called_load) {\r
- _s._wD(_h5+'load: '+_t.sID);\r
- _t._html5_canplay = false;\r
- oS.load();\r
- oS._called_load = true;\r
- if (_t._iO.autoPlay) {\r
- _t.play();\r
- }\r
- } else {\r
- _s._wD(_h5+'ignoring request to load again: '+_t.sID);\r
- }\r
-\r
- } else {\r
-\r
- try {\r
- _t.isHTML5 = false;\r
- _t._iO = _policyFix(_loopFix(_t._iO));\r
- if (_fV === 8) {\r
- _s.o._load(_t.sID, _t._iO.url, _t._iO.stream, _t._iO.autoPlay, (_t._iO.whileloading?1:0), _t._iO.loops||1, _t._iO.usePolicyFile);\r
- } else {\r
- _s.o._load(_t.sID, _t._iO.url, !!(_t._iO.stream), !!(_t._iO.autoPlay), _t._iO.loops||1, !!(_t._iO.autoLoad), _t._iO.usePolicyFile);\r
- }\r
- } catch(e) {\r
- _wDS('smError', 2);\r
- _debugTS('onload', false);\r
- _catchError({type:'SMSOUND_LOAD_JS_EXCEPTION', fatal:true});\r
-\r
- }\r
-\r
- }\r
-\r
- return _t;\r
-\r
- };\r
-\r
- /**\r
- * Unloads a sound, canceling any open HTTP requests.\r
- *\r
- * @return {SMSound} The SMSound object\r
- */\r
-\r
- this.unload = function() {\r
-\r
- // Flash 8/AS2 can't "close" a stream - fake it by loading an empty URL\r
- // Flash 9/AS3: Close stream, preventing further load\r
- // HTML5: Most UAs will use empty URL\r
-\r
- if (_t.readyState !== 0) {\r
-\r
- _s._wD('SMSound.unload(): "' + _t.sID + '"');\r
-\r
- if (!_t.isHTML5) {\r
- if (_fV === 8) {\r
- _s.o._unload(_t.sID, _emptyURL);\r
- } else {\r
- _s.o._unload(_t.sID);\r
- }\r
- } else {\r
- _stop_html5_timer();\r
- if (_t._a) {\r
- _t._a.pause();\r
- _html5Unload(_t._a);\r
- }\r
- }\r
-\r
- // reset load/status flags\r
- _resetProperties();\r
-\r
- }\r
-\r
- return _t;\r
-\r
- };\r
-\r
- /**\r
- * Unloads and destroys a sound.\r
- */\r
-\r
- this.destruct = function(_bFromSM) {\r
-\r
- _s._wD('SMSound.destruct(): "' + _t.sID + '"');\r
-\r
- if (!_t.isHTML5) {\r
-\r
- // kill sound within Flash\r
- // Disable the onfailure handler\r
- _t._iO.onfailure = null;\r
- _s.o._destroySound(_t.sID);\r
-\r
- } else {\r
-\r
- _stop_html5_timer();\r
-\r
- if (_t._a) {\r
- _t._a.pause();\r
- _html5Unload(_t._a);\r
- if (!_useGlobalHTML5Audio) {\r
- _t._remove_html5_events();\r
- }\r
- // break obvious circular reference\r
- _t._a._t = null;\r
- _t._a = null;\r
- }\r
-\r
- }\r
-\r
- if (!_bFromSM) {\r
- // ensure deletion from controller\r
- _s.destroySound(_t.sID, true);\r
-\r
- }\r
-\r
- };\r
-\r
- /**\r
- * Begins playing a sound.\r
- *\r
- * @param {object} oOptions Optional: Sound options\r
- * @return {SMSound} The SMSound object\r
- */\r
-\r
- this.play = function(oOptions, _updatePlayState) {\r
-\r
- var fN = 'SMSound.play(): ', allowMulti, a;\r
-\r
- _updatePlayState = _updatePlayState === undefined ? true : _updatePlayState; // default to true\r
-\r
- if (!oOptions) {\r
- oOptions = {};\r
- }\r
-\r
- _t._iO = _mixin(oOptions, _t._iO);\r
- _t._iO = _mixin(_t._iO, _t.options);\r
- _t.instanceOptions = _t._iO;\r
-\r
- // RTMP-only\r
- if (_t._iO.serverURL && !_t.connected) {\r
- if (!_t.getAutoPlay()) {\r
- _s._wD(fN+' Netstream not connected yet - setting autoPlay');\r
- _t.setAutoPlay(true);\r
- }\r
- // play will be called in _onconnect()\r
- return _t;\r
- }\r
-\r
- if (_html5OK(_t._iO)) {\r
- _t._setup_html5(_t._iO);\r
- _start_html5_timer();\r
- }\r
-\r
- if (_t.playState === 1 && !_t.paused) {\r
- allowMulti = _t._iO.multiShot;\r
- if (!allowMulti) {\r
- _s._wD(fN + '"' + _t.sID + '" already playing (one-shot)', 1);\r
- return _t;\r
- } else {\r
- _s._wD(fN + '"' + _t.sID + '" already playing (multi-shot)', 1);\r
- }\r
- }\r
-\r
- if (!_t.loaded) {\r
-\r
- if (_t.readyState === 0) {\r
-\r
- _s._wD(fN + 'Attempting to load "' + _t.sID + '"', 1);\r
- // try to get this sound playing ASAP\r
- if (!_t.isHTML5) {\r
- // assign directly because setAutoPlay() increments the instanceCount\r
- _t._iO.autoPlay = true;\r
- }\r
- _t.load(_t._iO);\r
-\r
- } else if (_t.readyState === 2) {\r
-\r
- _s._wD(fN + 'Could not load "' + _t.sID + '" - exiting', 2);\r
- return _t;\r
-\r
- } else {\r
-\r
- _s._wD(fN + '"' + _t.sID + '" is loading - attempting to play..', 1);\r
-\r
- }\r
-\r
- } else {\r
-\r
- _s._wD(fN + '"' + _t.sID + '"');\r
-\r
- }\r
-\r
- if (!_t.isHTML5 && _fV === 9 && _t.position > 0 && _t.position === _t.duration) {\r
- // flash 9 needs a position reset if play() is called while at the end of a sound.\r
- _s._wD(fN + '"' + _t.sID + '": Sound at end, resetting to position:0');\r
- _t._iO.position = 0;\r
- }\r
-\r
- /**\r
- * Streams will pause when their buffer is full if they are being loaded.\r
- * In this case paused is true, but the song hasn't started playing yet.\r
- * If we just call resume() the onplay() callback will never be called.\r
- * So only call resume() if the position is > 0.\r
- * Another reason is because options like volume won't have been applied yet.\r
- */\r
-\r
- if (_t.paused && _t.position && _t.position > 0) {\r
-\r
- // https://gist.github.com/37b17df75cc4d7a90bf6\r
- _s._wD(fN + '"' + _t.sID + '" is resuming from paused state',1);\r
- _t.resume();\r
-\r
- } else {\r
-\r
- _s._wD(fN+'"'+ _t.sID+'" is starting to play');\r
- _t.playState = 1;\r
- _t.paused = false;\r
-\r
- if (!_t.instanceCount || _t._iO.multiShotEvents || (!_t.isHTML5 && _fV > 8 && !_t.getAutoPlay())) {\r
- _t.instanceCount++;\r
- }\r
-\r
- _t.position = (typeof _t._iO.position !== 'undefined' && !isNaN(_t._iO.position)?_t._iO.position:0);\r
-\r
- if (!_t.isHTML5) {\r
- _t._iO = _policyFix(_loopFix(_t._iO));\r
- }\r
-\r
- if (_t._iO.onplay && _updatePlayState) {\r
- _t._iO.onplay.apply(_t);\r
- _t._onplay_called = true;\r
- }\r
-\r
- _t.setVolume(_t._iO.volume, true);\r
- _t.setPan(_t._iO.pan, true);\r
-\r
- if (!_t.isHTML5) {\r
- _s.o._start(_t.sID, _t._iO.loops || 1, (_fV === 9?_t._iO.position:_t._iO.position / 1000));\r
- } else {\r
- _start_html5_timer();\r
- a = _t._setup_html5();\r
- _t.setPosition(_t._iO.position);\r
- a.play();\r
- }\r
-\r
- }\r
-\r
- return _t;\r
-\r
- };\r
-\r
- // just for convenience\r
- this.start = this.play;\r
-\r
- /**\r
- * Stops playing a sound (and optionally, all sounds)\r
- *\r
- * @param {boolean} bAll Optional: Whether to stop all sounds\r
- * @return {SMSound} The SMSound object\r
- */\r
-\r
- this.stop = function(bAll) {\r
-\r
- if (_t.playState === 1) {\r
-\r
- _t._onbufferchange(0);\r
- _t.resetOnPosition(0);\r
- _t.paused = false;\r
-\r
- if (!_t.isHTML5) {\r
- _t.playState = 0;\r
- }\r
-\r
- if (_t._iO.onstop) {\r
- _t._iO.onstop.apply(_t);\r
- }\r
-\r
- if (!_t.isHTML5) {\r
-\r
- _s.o._stop(_t.sID, bAll);\r
- // hack for netStream: just unload\r
- if (_t._iO.serverURL) {\r
- _t.unload();\r
- }\r
-\r
- } else {\r
-\r
- if (_t._a) {\r
-\r
- // act like Flash, though\r
- _t.setPosition(0);\r
-\r
- // html5 has no stop()\r
- _t._a.pause();\r
-\r
- _t.playState = 0;\r
-\r
- // and update UI\r
- _t._onTimer();\r
-\r
- _stop_html5_timer();\r
-\r
- }\r
-\r
- }\r
-\r
- _t.instanceCount = 0;\r
- _t._iO = {};\r
-\r
- }\r
-\r
- return _t;\r
-\r
- };\r
-\r
- /**\r
- * Undocumented/internal: Sets autoPlay for RTMP.\r
- *\r
- * @param {boolean} autoPlay state\r
- */\r
-\r
- this.setAutoPlay = function(autoPlay) {\r
-\r
- _s._wD('sound '+_t.sID+' turned autoplay ' + (autoPlay ? 'on' : 'off'));\r
- _t._iO.autoPlay = autoPlay;\r
-\r
- if (!_t.isHTML5) {\r
- _s.o._setAutoPlay(_t.sID, autoPlay);\r
- if (autoPlay) {\r
- // only increment the instanceCount if the sound isn't loaded (TODO: verify RTMP)\r
- if (!_t.instanceCount && _t.readyState === 1) {\r
- _t.instanceCount++;\r
- _s._wD('sound '+_t.sID+' incremented instance count to '+_t.instanceCount);\r
- }\r
- }\r
- }\r
-\r
- };\r
-\r
- /**\r
- * Undocumented/internal: Returns the autoPlay boolean.\r
- *\r
- * @return {boolean} The current autoPlay value\r
- */\r
-\r
- this.getAutoPlay = function() {\r
-\r
- return _t._iO.autoPlay;\r
-\r
- };\r
-\r
- /**\r
- * Sets the position of a sound.\r
- *\r
- * @param {number} nMsecOffset Position (milliseconds)\r
- * @return {SMSound} The SMSound object\r
- */\r
-\r
- this.setPosition = function(nMsecOffset) {\r
-\r
- if (nMsecOffset === undefined) {\r
- nMsecOffset = 0;\r
- }\r
-\r
- var original_pos,\r
- position, position1K,\r
- // Use the duration from the instance options, if we don't have a track duration yet.\r
- // position >= 0 and <= current available (loaded) duration\r
- offset = (_t.isHTML5 ? Math.max(nMsecOffset,0) : Math.min(_t.duration || _t._iO.duration, Math.max(nMsecOffset, 0)));\r
-\r
- original_pos = _t.position;\r
- _t.position = offset;\r
- position1K = _t.position/1000;\r
- _t.resetOnPosition(_t.position);\r
- _t._iO.position = offset;\r
-\r
- if (!_t.isHTML5) {\r
-\r
- position = (_fV === 9 ? _t.position : position1K);\r
- if (_t.readyState && _t.readyState !== 2) {\r
- // if paused or not playing, will not resume (by playing)\r
- _s.o._setPosition(_t.sID, position, (_t.paused || !_t.playState));\r
- }\r
-\r
- } else if (_t._a) {\r
-\r
- // Set the position in the canplay handler if the sound is not ready yet\r
- if (_t._html5_canplay) {\r
- if (_t._a.currentTime !== position1K) {\r
- /*\r
- * DOM/JS errors/exceptions to watch out for:\r
- * if seek is beyond (loaded?) position, "DOM exception 11"\r
- * "INDEX_SIZE_ERR": DOM exception 1\r
- */\r
- _s._wD('setPosition('+position1K+'): setting position');\r
- try {\r
- _t._a.currentTime = position1K;\r
- if (_t.playState === 0 || _t.paused) {\r
- // allow seek without auto-play/resume\r
- _t._a.pause();\r
- }\r
- } catch(e) {\r
- _s._wD('setPosition('+position1K+'): setting position failed: '+e.message, 2);\r
- }\r
- }\r
- } else {\r
- _s._wD('setPosition('+position1K+'): delaying, sound not ready');\r
- }\r
-\r
- }\r
-\r
- if (_t.isHTML5) {\r
- if (_t.paused) {\r
- // if paused, refresh UI right away\r
- // force update\r
- _t._onTimer(true);\r
- }\r
- }\r
-\r
- return _t;\r
-\r
- };\r
-\r
- /**\r
- * Pauses sound playback.\r
- *\r
- * @return {SMSound} The SMSound object\r
- */\r
-\r
- this.pause = function(_bCallFlash) {\r
-\r
- if (_t.paused || (_t.playState === 0 && _t.readyState !== 1)) {\r
- return _t;\r
- }\r
-\r
- _s._wD('SMSound.pause()');\r
- _t.paused = true;\r
-\r
- if (!_t.isHTML5) {\r
- if (_bCallFlash || _bCallFlash === undefined) {\r
- _s.o._pause(_t.sID);\r
- }\r
- } else {\r
- _t._setup_html5().pause();\r
- _stop_html5_timer();\r
- }\r
-\r
- if (_t._iO.onpause) {\r
- _t._iO.onpause.apply(_t);\r
- }\r
-\r
- return _t;\r
-\r
- };\r
-\r
- /**\r
- * Resumes sound playback.\r
- *\r
- * @return {SMSound} The SMSound object\r
- */\r
-\r
- /**\r
- * When auto-loaded streams pause on buffer full they have a playState of 0.\r
- * We need to make sure that the playState is set to 1 when these streams "resume".\r
- * When a paused stream is resumed, we need to trigger the onplay() callback if it\r
- * hasn't been called already. In this case since the sound is being played for the\r
- * first time, I think it's more appropriate to call onplay() rather than onresume().\r
- */\r
-\r
- this.resume = function() {\r
-\r
- if (!_t.paused) {\r
- return _t;\r
- }\r
-\r
- _s._wD('SMSound.resume()');\r
- _t.paused = false;\r
- _t.playState = 1;\r
-\r
- if (!_t.isHTML5) {\r
- if (_t._iO.isMovieStar) {\r
- // Bizarre Webkit bug (Chrome reported via 8tracks.com dudes): AAC content paused for 30+ seconds(?) will not resume without a reposition.\r
- _t.setPosition(_t.position);\r
- }\r
- // flash method is toggle-based (pause/resume)\r
- _s.o._pause(_t.sID);\r
- } else {\r
- _t._setup_html5().play();\r
- _start_html5_timer();\r
- }\r
-\r
- if (!_t._onplay_called && _t._iO.onplay) {\r
- _t._iO.onplay.apply(_t);\r
- _t._onplay_called = true;\r
- } else if (_t._iO.onresume) {\r
- _t._iO.onresume.apply(_t);\r
- }\r
-\r
- return _t;\r
-\r
- };\r
-\r
- /**\r
- * Toggles sound playback.\r
- *\r
- * @return {SMSound} The SMSound object\r
- */\r
-\r
- this.togglePause = function() {\r
-\r
- _s._wD('SMSound.togglePause()');\r
-\r
- if (_t.playState === 0) {\r
- _t.play({\r
- position: (_fV === 9 && !_t.isHTML5 ? _t.position : _t.position / 1000)\r
- });\r
- return _t;\r
- }\r
-\r
- if (_t.paused) {\r
- _t.resume();\r
- } else {\r
- _t.pause();\r
- }\r
-\r
- return _t;\r
-\r
- };\r
-\r
- /**\r
- * Sets the panning (L-R) effect.\r
- *\r
- * @param {number} nPan The pan value (-100 to 100)\r
- * @return {SMSound} The SMSound object\r
- */\r
-\r
- this.setPan = function(nPan, bInstanceOnly) {\r
-\r
- if (typeof nPan === 'undefined') {\r
- nPan = 0;\r
- }\r
-\r
- if (typeof bInstanceOnly === 'undefined') {\r
- bInstanceOnly = false;\r
- }\r
-\r
- if (!_t.isHTML5) {\r
- _s.o._setPan(_t.sID, nPan);\r
- } // else { no HTML5 pan? }\r
-\r
- _t._iO.pan = nPan;\r
-\r
- if (!bInstanceOnly) {\r
- _t.pan = nPan;\r
- _t.options.pan = nPan;\r
- }\r
-\r
- return _t;\r
-\r
- };\r
-\r
- /**\r
- * Sets the volume.\r
- *\r
- * @param {number} nVol The volume value (0 to 100)\r
- * @return {SMSound} The SMSound object\r
- */\r
-\r
- this.setVolume = function(nVol, _bInstanceOnly) {\r
-\r
- if (typeof nVol === 'undefined') {\r
- nVol = 100;\r
- }\r
-\r
- if (typeof _bInstanceOnly === 'undefined') {\r
- _bInstanceOnly = false;\r
- }\r
-\r
- if (!_t.isHTML5) {\r
- _s.o._setVolume(_t.sID, (_s.muted && !_t.muted) || _t.muted?0:nVol);\r
- } else if (_t._a) {\r
- _t._a.volume = Math.max(0, Math.min(1, nVol/100)); // valid range: 0-1\r
- }\r
-\r
- _t._iO.volume = nVol;\r
-\r
- if (!_bInstanceOnly) {\r
- _t.volume = nVol;\r
- _t.options.volume = nVol;\r
- }\r
-\r
- return _t;\r
-\r
- };\r
-\r
- /**\r
- * Mutes the sound.\r
- *\r
- * @return {SMSound} The SMSound object\r
- */\r
-\r
- this.mute = function() {\r
-\r
- _t.muted = true;\r
-\r
- if (!_t.isHTML5) {\r
- _s.o._setVolume(_t.sID, 0);\r
- } else if (_t._a) {\r
- _t._a.muted = true;\r
- }\r
-\r
- return _t;\r
-\r
- };\r
-\r
- /**\r
- * Unmutes the sound.\r
- *\r
- * @return {SMSound} The SMSound object\r
- */\r
-\r
- this.unmute = function() {\r
-\r
- _t.muted = false;\r
- var hasIO = typeof _t._iO.volume !== 'undefined';\r
-\r
- if (!_t.isHTML5) {\r
- _s.o._setVolume(_t.sID, hasIO?_t._iO.volume:_t.options.volume);\r
- } else if (_t._a) {\r
- _t._a.muted = false;\r
- }\r
-\r
- return _t;\r
-\r
- };\r
-\r
- /**\r
- * Toggles the muted state of a sound.\r
- *\r
- * @return {SMSound} The SMSound object\r
- */\r
-\r
- this.toggleMute = function() {\r
-\r
- return (_t.muted?_t.unmute():_t.mute());\r
-\r
- };\r
-\r
- /**\r
- * Calls the onposition() method of a SMSound object.\r
- *\r
- * @param {number} nPosition The position to watch for\r
- * @param {function} oMethod The relevant callback to fire\r
- * @param {object} oScope Optional: The scope to apply the callback to\r
- * @return {SMSound} The SMSound object\r
- */\r
-\r
- this.onposition = function(nPosition, oMethod, oScope) {\r
-\r
- // TODO: allow for ranges, too? eg. (nPosition instanceof Array)\r
-\r
- _t._onPositionItems.push({\r
- position: nPosition,\r
- method: oMethod,\r
- scope: (typeof oScope !== 'undefined'?oScope:_t),\r
- fired: false\r
- });\r
-\r
- return _t;\r
-\r
- };\r
-\r
- /**\r
- * TODO: This should be marked as pseudo-private.\r
- */\r
-\r
- this.processOnPosition = function() {\r
-\r
- var i, item, j = _t._onPositionItems.length;\r
-\r
- if (!j || !_t.playState || _t._onPositionFired >= j) {\r
- return false;\r
- }\r
-\r
- for (i=j; i--;) {\r
- item = _t._onPositionItems[i];\r
- if (!item.fired && _t.position >= item.position) {\r
- item.fired = true;\r
- _s._onPositionFired++;\r
- item.method.apply(item.scope,[item.position]);\r
- }\r
- }\r
-\r
- return true;\r
-\r
- };\r
-\r
- this.resetOnPosition = function(nPosition) {\r
-\r
- // reset "fired" for items interested in this position\r
- var i, item, j = _t._onPositionItems.length;\r
-\r
- if (!j) {\r
- return false;\r
- }\r
-\r
- for (i=j; i--;) {\r
- item = _t._onPositionItems[i];\r
- if (item.fired && nPosition <= item.position) {\r
- item.fired = false;\r
- _s._onPositionFired--;\r
- }\r
- }\r
-\r
- return true;\r
-\r
- };\r
-\r
- /**\r
- * SoundManager() private internals\r
- * --------------------------------\r
- */\r
-\r
- _start_html5_timer = function() {\r
-\r
- if (_t.isHTML5) {\r
- _startTimer(_t);\r
- }\r
-\r
- };\r
-\r
- _stop_html5_timer = function() {\r
-\r
- if (_t.isHTML5) {\r
- _stopTimer(_t);\r
- }\r
-\r
- };\r
-\r
- _resetProperties = function() {\r
-\r
- _t._onPositionItems = [];\r
- _t._onPositionFired = 0;\r
- _t._hasTimer = null;\r
- _t._onplay_called = false;\r
- _t._a = null;\r
- _t._html5_canplay = false;\r
- _t.bytesLoaded = null;\r
- _t.bytesTotal = null;\r
- _t.position = null;\r
- _t.duration = (_t._iO && _t._iO.duration?_t._iO.duration:null);\r
- _t.durationEstimate = null;\r
- _t.failures = 0;\r
- _t.loaded = false;\r
- _t.playState = 0;\r
- _t.paused = false;\r
-\r
- // 0 = uninitialised, 1 = loading, 2 = failed/error, 3 = loaded/success\r
- _t.readyState = 0;\r
-\r
- _t.muted = false;\r
- _t.isBuffering = false;\r
- _t.instanceOptions = {};\r
- _t.instanceCount = 0;\r
-\r
- _t.peakData = {\r
- left: 0,\r
- right: 0\r
- };\r
-\r
- _t.waveformData = {\r
- left: [],\r
- right: []\r
- };\r
-\r
- // legacy: 1D array\r
- _t.eqData = [];\r
-\r
- _t.eqData.left = [];\r
- _t.eqData.right = [];\r
-\r
- };\r
-\r
- _resetProperties();\r
-\r
- /**\r
- * Pseudo-private SMSound internals\r
- * --------------------------------\r
- */\r
-\r
- this._onTimer = function(bForce) {\r
-\r
- // HTML5-only _whileplaying() etc.\r
-\r
- var time, x = {};\r
-\r
- if (_t._hasTimer || bForce) {\r
-\r
- // TODO: May not need to track readyState (1 = loading)\r
-\r
- if (_t._a && (bForce || ((_t.playState > 0 || _t.readyState === 1) && !_t.paused))) {\r
-\r
- _t.duration = _t._get_html5_duration();\r
- _t.durationEstimate = _t.duration;\r
- time = _t._a.currentTime?_t._a.currentTime*1000:0;\r
- _t._whileplaying(time,x,x,x,x);\r
- return true;\r
-\r
- } else {\r
-\r
- _s._wD('_onTimer: Warn for "'+_t.sID+'": '+(!_t._a?'Could not find element. ':'')+(_t.playState === 0?'playState bad, 0?':'playState = '+_t.playState+', OK'));\r
- return false;\r
-\r
- }\r
-\r
- }\r
-\r
- };\r
-\r
- this._get_html5_duration = function() {\r
-\r
- var d = (_t._a ? _t._a.duration*1000 : (_t._iO ? _t._iO.duration : undefined)),\r
- result = (d && !isNaN(d) && d !== Infinity ? d : (_t._iO ? _t._iO.duration : null));\r
-\r
- return result;\r
-\r
- };\r
-\r
- this._setup_html5 = function(oOptions) {\r
-\r
- var _iO = _mixin(_t._iO, oOptions), d = decodeURI,\r
- _a = _useGlobalHTML5Audio ? _s._global_a : _t._a,\r
- _dURL = d(_iO.url),\r
- _oldIO = (_a && _a._t ? _a._t.instanceOptions : null);\r
-\r
- if (_a) {\r
-\r
- if (_a._t && _oldIO.url === _iO.url && (!_t._lastURL || (_t._lastURL === _oldIO.url))) {\r
- // same url, ignore request\r
- return _a; \r
- }\r
-\r
- _s._wD('setting new URL on existing object: ' + _dURL + (_t._lastURL ? ', old URL: ' + _t._lastURL : ''));\r
-\r
- /**\r
- * "First things first, I, Poppa.." (reset the previous state of the old sound, if playing)\r
- * Fixes case with devices that can only play one sound at a time\r
- * Otherwise, other sounds in mid-play will be terminated without warning and in a stuck state\r
- */\r
-\r
- if (_useGlobalHTML5Audio && _a._t && _a._t.playState && _iO.url !== _oldIO.url) {\r
- _a._t.stop();\r
- }\r
-\r
- // new URL, so reset load/playstate and so on\r
- _resetProperties();\r
-\r
- _a.src = _iO.url;\r
- _t.url = _iO.url;\r
- _t._lastURL = _iO.url;\r
- _a._called_load = false;\r
-\r
- } else {\r
-\r
- _s._wD('creating HTML5 Audio() element with URL: '+_dURL);\r
- _a = new Audio(_iO.url);\r
-\r
- _a._called_load = false;\r
-\r
- // android (seen in 2.3/Honeycomb) sometimes fails first .load() -> .play(), results in playback failure and ended() events?\r
- if (_is_android) {\r
- _a._called_load = true;\r
- }\r
-\r
- if (_useGlobalHTML5Audio) {\r
- _s._global_a = _a;\r
- }\r
-\r
- }\r
- _t.isHTML5 = true;\r
-\r
- // store a ref on the track\r
- _t._a = _a;\r
-\r
- // store a ref on the audio\r
- _a._t = _t;\r
-\r
- _t._add_html5_events();\r
- _a.loop = (_iO.loops>1?'loop':'');\r
-\r
- if (_iO.autoLoad || _iO.autoPlay) {\r
-\r
- // early HTML5 implementation (non-standard)\r
- _a.autobuffer = 'auto';\r
-\r
- // standard\r
- _a.preload = 'auto';\r
-\r
- _t.load();\r
- _a._called_load = true;\r
-\r
- } else {\r
-\r
- // early HTML5 implementation (non-standard)\r
- _a.autobuffer = false;\r
-\r
- // standard\r
- _a.preload = 'none';\r
-\r
- }\r
-\r
- // boolean instead of "loop", for webkit? - spec says string. http://www.w3.org/TR/html-markup/audio.html#audio.attrs.loop\r
- _a.loop = (_iO.loops>1?'loop':'');\r
-\r
- return _a;\r
-\r
- };\r
-\r
- this._add_html5_events = function() {\r
-\r
- if (_t._a._added_events) {\r
- return false;\r
- }\r
-\r
- var f;\r
-\r
- function add(oEvt, oFn, bCapture) {\r
- return _t._a ? _t._a.addEventListener(oEvt, oFn, bCapture||false) : null;\r
- }\r
-\r
- _s._wD(_h5+'adding event listeners: '+_t.sID);\r
- _t._a._added_events = true;\r
-\r
- for (f in _html5_events) {\r
- if (_html5_events.hasOwnProperty(f)) {\r
- add(f, _html5_events[f]);\r
- }\r
- }\r
-\r
- return true;\r
-\r
- };\r
-\r
- this._remove_html5_events = function() {\r
-\r
- // Remove event listeners\r
-\r
- var f;\r
-\r
- function remove(oEvt, oFn, bCapture) {\r
- return (_t._a ? _t._a.removeEventListener(oEvt, oFn, bCapture||false) : null);\r
- }\r
-\r
- _s._wD(_h5+'removing event listeners: '+_t.sID);\r
- _t._a._added_events = false;\r
-\r
- for (f in _html5_events) {\r
- if (_html5_events.hasOwnProperty(f)) {\r
- remove(f, _html5_events[f]);\r
- }\r
- }\r
-\r
- };\r
-\r
- /**\r
- * Pseudo-private event internals\r
- * ------------------------------\r
- */\r
-\r
- this._onload = function(nSuccess) {\r
-\r
-\r
- var fN = 'SMSound._onload(): ', loadOK = !!(nSuccess);\r
- _s._wD(fN + '"' + _t.sID + '"' + (loadOK?' loaded.':' failed to load? - ' + _t.url), (loadOK?1:2));\r
- // <d>\r
-\r
- if (!loadOK && !_t.isHTML5) {\r
- if (_s.sandbox.noRemote === true) {\r
- _s._wD(fN + _str('noNet'), 1);\r
- }\r
- if (_s.sandbox.noLocal === true) {\r
- _s._wD(fN + _str('noLocal'), 1);\r
- }\r
- }\r
- // </d>\r
-\r
- _t.loaded = loadOK;\r
- _t.readyState = loadOK?3:2;\r
- _t._onbufferchange(0);\r
-\r
- if (_t._iO.onload) {\r
- _t._iO.onload.apply(_t, [loadOK]);\r
- }\r
-\r
- return true;\r
-\r
- };\r
-\r
- this._onbufferchange = function(nIsBuffering) {\r
-\r
- var fN = 'SMSound._onbufferchange()';\r
-\r
- if (_t.playState === 0) {\r
- // ignore if not playing\r
- return false;\r
- }\r
-\r
- if ((nIsBuffering && _t.isBuffering) || (!nIsBuffering && !_t.isBuffering)) {\r
- return false;\r
- }\r
-\r
- _t.isBuffering = (nIsBuffering === 1);\r
- if (_t._iO.onbufferchange) {\r
- _s._wD(fN + ': ' + nIsBuffering);\r
- _t._iO.onbufferchange.apply(_t);\r
- }\r
-\r
- return true;\r
-\r
- };\r
-\r
- /**\r
- * Notify Mobile Safari that user action is required\r
- * to continue playing / loading the audio file.\r
- */\r
-\r
- this._onsuspend = function () {\r
-\r
- if (_t._iO.onsuspend) {\r
- _s._wD('SMSound._onsuspend()');\r
- _t._iO.onsuspend.apply(_t);\r
- }\r
-\r
- return true;\r
-\r
- };\r
-\r
- /**\r
- * flash 9/movieStar + RTMP-only method, should fire only once at most\r
- * at this point we just recreate failed sounds rather than trying to reconnect\r
- */\r
-\r
- this._onfailure = function(msg, level, code) {\r
-\r
- _t.failures++;\r
- _s._wD('SMSound._onfailure(): "'+_t.sID+'" count '+_t.failures);\r
-\r
- if (_t._iO.onfailure && _t.failures === 1) {\r
- _t._iO.onfailure(_t, msg, level, code);\r
- } else {\r
- _s._wD('SMSound._onfailure(): ignoring');\r
- }\r
-\r
- };\r
-\r
- this._onfinish = function() {\r
-\r
- // store local copy before it gets trashed..\r
- var _io_onfinish = _t._iO.onfinish;\r
- _t._onbufferchange(0);\r
- _t.resetOnPosition(0);\r
-\r
- // reset some state items\r
- if (_t.instanceCount) {\r
-\r
- _t.instanceCount--;\r
- if (!_t.instanceCount) {\r
- // reset instance options\r
- _t.playState = 0;\r
- _t.paused = false;\r
- _t.instanceCount = 0;\r
- _t.instanceOptions = {};\r
- _t._iO = {};\r
- _stop_html5_timer();\r
- }\r
-\r
- if (!_t.instanceCount || _t._iO.multiShotEvents) {\r
- // fire onfinish for last, or every instance\r
- if (_io_onfinish) {\r
- _s._wD('SMSound._onfinish(): "' + _t.sID + '"');\r
- _io_onfinish.apply(_t);\r
- }\r
- }\r
-\r
- }\r
-\r
- };\r
-\r
- this._whileloading = function(nBytesLoaded, nBytesTotal, nDuration, nBufferLength) {\r
-\r
- _t.bytesLoaded = nBytesLoaded;\r
- _t.bytesTotal = nBytesTotal;\r
- _t.duration = Math.floor(nDuration);\r
- _t.bufferLength = nBufferLength;\r
-\r
- if (!_t._iO.isMovieStar) {\r
-\r
- if (_t._iO.duration) {\r
- // use options, if specified and larger\r
- _t.durationEstimate = (_t.duration > _t._iO.duration) ? _t.duration : _t._iO.duration;\r
- } else {\r
- _t.durationEstimate = parseInt((_t.bytesTotal / _t.bytesLoaded) * _t.duration, 10);\r
-\r
- }\r
-\r
- if (_t.durationEstimate === undefined) {\r
- _t.durationEstimate = _t.duration;\r
- }\r
-\r
- if (_t.readyState !== 3 && _t._iO.whileloading) {\r
- _t._iO.whileloading.apply(_t);\r
- }\r
-\r
- } else {\r
-\r
- _t.durationEstimate = _t.duration;\r
- if (_t.readyState !== 3 && _t._iO.whileloading) {\r
- _t._iO.whileloading.apply(_t);\r
- }\r
-\r
- }\r
-\r
- };\r
-\r
- this._whileplaying = function(nPosition, oPeakData, oWaveformDataLeft, oWaveformDataRight, oEQData) {\r
-\r
- if (isNaN(nPosition) || nPosition === null) {\r
- // flash safety net\r
- return false;\r
- }\r
-\r
- _t.position = nPosition;\r
- _t.processOnPosition();\r
-\r
- if (!_t.isHTML5 && _fV > 8) {\r
-\r
- if (_t._iO.usePeakData && typeof oPeakData !== 'undefined' && oPeakData) {\r
- _t.peakData = {\r
- left: oPeakData.leftPeak,\r
- right: oPeakData.rightPeak\r
- };\r
- }\r
-\r
- if (_t._iO.useWaveformData && typeof oWaveformDataLeft !== 'undefined' && oWaveformDataLeft) {\r
- _t.waveformData = {\r
- left: oWaveformDataLeft.split(','),\r
- right: oWaveformDataRight.split(',')\r
- };\r
- }\r
-\r
- if (_t._iO.useEQData) {\r
- if (typeof oEQData !== 'undefined' && oEQData && oEQData.leftEQ) {\r
- var eqLeft = oEQData.leftEQ.split(',');\r
- _t.eqData = eqLeft;\r
- _t.eqData.left = eqLeft;\r
- if (typeof oEQData.rightEQ !== 'undefined' && oEQData.rightEQ) {\r
- _t.eqData.right = oEQData.rightEQ.split(',');\r
- }\r
- }\r
- }\r
-\r
- }\r
-\r
- if (_t.playState === 1) {\r
-\r
- // special case/hack: ensure buffering is false if loading from cache (and not yet started)\r
- if (!_t.isHTML5 && _fV === 8 && !_t.position && _t.isBuffering) {\r
- _t._onbufferchange(0);\r
- }\r
-\r
- if (_t._iO.whileplaying) {\r
- // flash may call after actual finish\r
- _t._iO.whileplaying.apply(_t);\r
- }\r
-\r
- }\r
-\r
- return true;\r
-\r
- };\r
-\r
- this._onid3 = function(oID3PropNames, oID3Data) {\r
-\r
- // oID3PropNames: string array (names)\r
- // ID3Data: string array (data)\r
- _s._wD('SMSound._onid3(): "' + this.sID + '" ID3 data received.');\r
-\r
- var oData = [], i, j;\r
-\r
- for (i = 0, j = oID3PropNames.length; i < j; i++) {\r
- oData[oID3PropNames[i]] = oID3Data[i];\r
- }\r
- _t.id3 = _mixin(_t.id3, oData);\r
-\r
- if (_t._iO.onid3) {\r
- _t._iO.onid3.apply(_t);\r
- }\r
-\r
- };\r
-\r
- // flash/RTMP-only\r
-\r
- this._onconnect = function(bSuccess) {\r
-\r
- var fN = 'SMSound._onconnect(): ';\r
- bSuccess = (bSuccess === 1);\r
- _s._wD(fN+'"'+_t.sID+'"'+(bSuccess?' connected.':' failed to connect? - '+_t.url), (bSuccess?1:2));\r
- _t.connected = bSuccess;\r
-\r
- if (bSuccess) {\r
-\r
- _t.failures = 0;\r
-\r
- if (_idCheck(_t.sID)) {\r
- if (_t.getAutoPlay()) {\r
- // only update the play state if auto playing\r
- _t.play(undefined, _t.getAutoPlay());\r
- } else if (_t._iO.autoLoad) {\r
- _t.load();\r
- }\r
- }\r
-\r
- if (_t._iO.onconnect) {\r
- _t._iO.onconnect.apply(_t,[bSuccess]);\r
- }\r
-\r
- }\r
-\r
- };\r
-\r
- this._ondataerror = function(sError) {\r
-\r
- // flash 9 wave/eq data handler\r
- // hack: called at start, and end from flash at/after onfinish()\r
- if (_t.playState > 0) {\r
- _s._wD('SMSound._ondataerror(): ' + sError);\r
- if (_t._iO.ondataerror) {\r
- _t._iO.ondataerror.apply(_t);\r
- }\r
- }\r
-\r
- };\r
-\r
- }; // SMSound()\r
-\r
- /**\r
- * Private SoundManager internals\r
- * ------------------------------\r
- */\r
-\r
- _getDocument = function() {\r
-\r
- return (_doc.body || _doc._docElement || _doc.getElementsByTagName('div')[0]);\r
-\r
- };\r
-\r
- _id = function(sID) {\r
-\r
- return _doc.getElementById(sID);\r
-\r
- };\r
-\r
- _mixin = function(oMain, oAdd) {\r
-\r
- // non-destructive merge\r
- var o1 = {}, i, o2, o;\r
-\r
- // clone c1\r
- for (i in oMain) {\r
- if (oMain.hasOwnProperty(i)) {\r
- o1[i] = oMain[i];\r
- }\r
- }\r
-\r
- o2 = (typeof oAdd === 'undefined'?_s.defaultOptions:oAdd);\r
- for (o in o2) {\r
- if (o2.hasOwnProperty(o) && typeof o1[o] === 'undefined') {\r
- o1[o] = o2[o];\r
- }\r
- }\r
- return o1;\r
-\r
- };\r
-\r
- _event = (function() {\r
-\r
- var old = (_win.attachEvent),\r
- evt = {\r
- add: (old?'attachEvent':'addEventListener'),\r
- remove: (old?'detachEvent':'removeEventListener')\r
- };\r
-\r
- function getArgs(oArgs) {\r
-\r
- var args = _slice.call(oArgs), len = args.length;\r
-\r
- if (old) {\r
- // prefix\r
- args[1] = 'on' + args[1];\r
- if (len > 3) {\r
- // no capture\r
- args.pop();\r
- }\r
- } else if (len === 3) {\r
- args.push(false);\r
- }\r
- return args;\r
-\r
- }\r
-\r
- function apply(args, sType) {\r
-\r
- var element = args.shift(),\r
- method = [evt[sType]];\r
-\r
- if (old) {\r
- element[method](args[0], args[1]);\r
- } else {\r
- element[method].apply(element, args);\r
- }\r
-\r
- }\r
-\r
- function add() {\r
-\r
- apply(getArgs(arguments), 'add');\r
-\r
- }\r
-\r
- function remove() {\r
-\r
- apply(getArgs(arguments), 'remove');\r
-\r
- }\r
-\r
- return {\r
- 'add': add,\r
- 'remove': remove\r
- };\r
-\r
- }());\r
-\r
- /**\r
- * Internal HTML5 event handling\r
- * -----------------------------\r
- */\r
-\r
- function _html5_event(oFn) {\r
-\r
- // wrap html5 event handlers so we don't call them on destroyed sounds\r
-\r
- return function(e) {\r
-\r
- if (!this._t || !this._t._a) {\r
- // <d>\r
- if (this._t && this._t.sID) {\r
- _s._wD(_h5+'ignoring '+e.type+': '+this._t.sID);\r
- } else {\r
- _s._wD(_h5+'ignoring '+e.type);\r
- }\r
- // </d>\r
- return null;\r
- } else {\r
- return oFn.call(this, e);\r
- }\r
-\r
- };\r
-\r
- }\r
-\r
- _html5_events = {\r
-\r
- // HTML5 event-name-to-handler map\r
-\r
- abort: _html5_event(function(e) {\r
-\r
- _s._wD(_h5+'abort: '+this._t.sID);\r
-\r
- }),\r
-\r
- // enough has loaded to play\r
-\r
- canplay: _html5_event(function(e) {\r
-\r
- if (this._t._html5_canplay) {\r
- // this event has already fired. ignore.\r
- return true;\r
- }\r
-\r
- this._t._html5_canplay = true;\r
- _s._wD(_h5+'canplay: '+this._t.sID+', '+this._t.url);\r
- this._t._onbufferchange(0);\r
- var position1K = (!isNaN(this._t.position)?this._t.position/1000:null);\r
-\r
- // set the position if position was set before the sound loaded\r
- if (this._t.position && this.currentTime !== position1K) {\r
- _s._wD(_h5+'canplay: setting position to '+position1K);\r
- try {\r
- this.currentTime = position1K;\r
- } catch(ee) {\r
- _s._wD(_h5+'setting position failed: '+ee.message, 2);\r
- }\r
- }\r
-\r
- }),\r
-\r
- load: _html5_event(function(e) {\r
-\r
- if (!this._t.loaded) {\r
- this._t._onbufferchange(0);\r
- // should be 1, and the same\r
- this._t._whileloading(this._t.bytesTotal, this._t.bytesTotal, this._t._get_html5_duration());\r
- this._t._onload(true);\r
- }\r
-\r
- }),\r
-\r
- emptied: _html5_event(function(e) {\r
-\r
- _s._wD(_h5+'emptied: '+this._t.sID);\r
-\r
- }),\r
-\r
- ended: _html5_event(function(e) {\r
-\r
- _s._wD(_h5+'ended: '+this._t.sID);\r
- this._t._onfinish();\r
-\r
- }),\r
-\r
- error: _html5_event(function(e) {\r
-\r
- _s._wD(_h5+'error: '+this.error.code);\r
- // call load with error state?\r
- this._t._onload(false);\r
-\r
- }),\r
-\r
- loadeddata: _html5_event(function(e) {\r
-\r
- var t = this._t,\r
- // at least 1 byte, so math works\r
- bytesTotal = t.bytesTotal || 1;\r
-\r
- _s._wD(_h5+'loadeddata: '+this._t.sID);\r
-\r
- // safari seems to nicely report progress events, eventually totalling 100%\r
- if (!t._loaded && !_isSafari) {\r
- t.duration = t._get_html5_duration();\r
- // fire whileloading() with 100% values\r
- t._whileloading(bytesTotal, bytesTotal, t._get_html5_duration());\r
- t._onload(true);\r
- }\r
-\r
- }),\r
-\r
- loadedmetadata: _html5_event(function(e) {\r
-\r
- _s._wD(_h5+'loadedmetadata: '+this._t.sID);\r
-\r
- }),\r
-\r
- loadstart: _html5_event(function(e) {\r
-\r
- _s._wD(_h5+'loadstart: '+this._t.sID);\r
- // assume buffering at first\r
- this._t._onbufferchange(1);\r
-\r
- }),\r
-\r
- play: _html5_event(function(e) {\r
-\r
- _s._wD(_h5+'play: '+this._t.sID+', '+this._t.url);\r
- // once play starts, no buffering\r
- this._t._onbufferchange(0);\r
-\r
- }),\r
-\r
- // TODO: verify if this is actually implemented anywhere yet.\r
- playing: _html5_event(function(e) {\r
-\r
- _s._wD(_h5+'playing: '+this._t.sID+', '+this._t.url);\r
-\r
- // once play starts, no buffering\r
- this._t._onbufferchange(0);\r
-\r
- }),\r
-\r
- progress: _html5_event(function(e) {\r
-\r
- if (this._t.loaded) {\r
- return false;\r
- }\r
-\r
- var i, j, str, buffered = 0,\r
- isProgress = (e.type === 'progress'),\r
- ranges = e.target.buffered,\r
-\r
- // firefox 3.6 implements e.loaded/total (bytes)\r
- loaded = (e.loaded||0),\r
-\r
- total = (e.total||1);\r
-\r
- if (ranges && ranges.length) {\r
-\r
- // if loaded is 0, try TimeRanges implementation as % of load\r
- // https://developer.mozilla.org/en/DOM/TimeRanges\r
-\r
- for (i=ranges.length; i--;) {\r
- buffered = (ranges.end(i) - ranges.start(i));\r
- }\r
-\r
- // linear case, buffer sum; does not account for seeking and HTTP partials / byte ranges\r
- loaded = buffered/e.target.duration;\r
-\r
- // <d>\r
- if (isProgress && ranges.length > 1) {\r
- str = [];\r
- j = ranges.length;\r
- for (i=0; i<j; i++) {\r
- str.push(e.target.buffered.start(i) +'-'+ e.target.buffered.end(i));\r
- }\r
- _s._wD(_h5+'progress: timeRanges: '+str.join(', '));\r
- }\r
-\r
- if (isProgress && !isNaN(loaded)) {\r
- _s._wD(_h5+'progress: '+this._t.sID+': ' + Math.floor(loaded*100)+'% loaded');\r
- }\r
- // </d>\r
-\r
- }\r
-\r
- if (!isNaN(loaded)) {\r
-\r
- // if progress, likely not buffering\r
- this._t._onbufferchange(0);\r
- this._t._whileloading(loaded, total, this._t._get_html5_duration());\r
- if (loaded && total && loaded === total) {\r
- // in case "onload" doesn't fire (eg. gecko 1.9.2)\r
- _html5_events.load.call(this, e);\r
- }\r
-\r
- }\r
-\r
- }),\r
-\r
- ratechange: _html5_event(function(e) {\r
-\r
- _s._wD(_h5+'ratechange: '+this._t.sID);\r
-\r
- }),\r
-\r
- suspend: _html5_event(function(e) {\r
-\r
- // download paused/stopped, may have finished (eg. onload)\r
-\r
- _s._wD(_h5+'suspend: '+this._t.sID);\r
- _html5_events.progress.call(this, e);\r
- this._t._onsuspend();\r
-\r
- }),\r
-\r
- stalled: _html5_event(function(e) {\r
-\r
- _s._wD(_h5+'stalled: '+this._t.sID);\r
-\r
- }),\r
-\r
- timeupdate: _html5_event(function(e) {\r
-\r
- this._t._onTimer();\r
-\r
- }),\r
-\r
- waiting: _html5_event(function(e) {\r
-\r
- // see also: seeking\r
- _s._wD(_h5+'waiting: '+this._t.sID);\r
-\r
- // playback faster than download rate, etc.\r
- this._t._onbufferchange(1);\r
-\r
- })\r
-\r
- };\r
-\r
- _html5OK = function(iO) {\r
-\r
- // Use type, if specified. If HTML5-only mode, no other options, so just give 'er\r
- return (!iO.serverURL && (iO.type?_html5CanPlay({type:iO.type}):_html5CanPlay({url:iO.url})||_s.html5Only));\r
-\r
- };\r
-\r
- _html5Unload = function(oAudio) {\r
-\r
- /**\r
- * Internal method: Unload media, and cancel any current/pending network requests.\r
- * Firefox can load an empty URL, which allegedly destroys the decoder and stops the download.\r
- * https://developer.mozilla.org/En/Using_audio_and_video_in_Firefox#Stopping_the_download_of_media\r
- * Other UA behaviour is unclear, so everyone else gets an about:blank-style URL.\r
- */\r
-\r
- if (oAudio) {\r
- // Firefox likes '' for unload, most other UAs don't and fail to unload.\r
- oAudio.src = (_is_firefox ? '' : _emptyURL);\r
- }\r
-\r
- };\r
-\r
- _html5CanPlay = function(o) {\r
-\r
- /**\r
- * Try to find MIME, test and return truthiness\r
- * o = {\r
- * url: '/path/to/an.mp3',\r
- * type: 'audio/mp3'\r
- * }\r
- */\r
-\r
- if (!_s.useHTML5Audio || !_s.hasHTML5) {\r
- return false;\r
- }\r
-\r
- var url = (o.url || null),\r
- mime = (o.type || null),\r
- aF = _s.audioFormats,\r
- result,\r
- offset,\r
- fileExt,\r
- item;\r
-\r
- function preferFlashCheck(kind) {\r
-\r
- // whether flash should play a given type\r
- return (_s.preferFlash && _hasFlash && !_s.ignoreFlash && (typeof _s.flash[kind] !== 'undefined' && _s.flash[kind]));\r
-\r
- }\r
-\r
- // account for known cases like audio/mp3\r
-\r
- if (mime && _s.html5[mime] !== 'undefined') {\r
- return (_s.html5[mime] && !preferFlashCheck(mime));\r
- }\r
-\r
- if (!_html5Ext) {\r
- _html5Ext = [];\r
- for (item in aF) {\r
- if (aF.hasOwnProperty(item)) {\r
- _html5Ext.push(item);\r
- if (aF[item].related) {\r
- _html5Ext = _html5Ext.concat(aF[item].related);\r
- }\r
- }\r
- }\r
- _html5Ext = new RegExp('\\.('+_html5Ext.join('|')+')(\\?.*)?$','i');\r
- }\r
-\r
- // TODO: Strip URL queries, etc.\r
- fileExt = (url ? url.toLowerCase().match(_html5Ext) : null);\r
-\r
- if (!fileExt || !fileExt.length) {\r
- if (!mime) {\r
- return false;\r
- } else {\r
- // audio/mp3 -> mp3, result should be known\r
- offset = mime.indexOf(';');\r
- // strip "audio/X; codecs.."\r
- fileExt = (offset !== -1?mime.substr(0,offset):mime).substr(6);\r
- }\r
- } else {\r
- // match the raw extension name - "mp3", for example\r
- fileExt = fileExt[1];\r
- }\r
-\r
- if (fileExt && typeof _s.html5[fileExt] !== 'undefined') {\r
- // result known\r
- return (_s.html5[fileExt] && !preferFlashCheck(fileExt));\r
- } else {\r
- mime = 'audio/'+fileExt;\r
- result = _s.html5.canPlayType({type:mime});\r
- _s.html5[fileExt] = result;\r
- // _s._wD('canPlayType, found result: '+result);\r
- return (result && _s.html5[mime] && !preferFlashCheck(mime));\r
- }\r
-\r
- };\r
-\r
- _testHTML5 = function() {\r
-\r
- if (!_s.useHTML5Audio || typeof Audio === 'undefined') {\r
- return false;\r
- }\r
-\r
- // double-whammy: Opera 9.64 throws WRONG_ARGUMENTS_ERR if no parameter passed to Audio(), and Webkit + iOS happily tries to load "null" as a URL. :/\r
- var a = (typeof Audio !== 'undefined' ? (_isOpera ? new Audio(null) : new Audio()) : null),\r
- item, support = {}, aF, i;\r
-\r
- function _cp(m) {\r
-\r
- var canPlay, i, j, isOK = false;\r
-\r
- if (!a || typeof a.canPlayType !== 'function') {\r
- return false;\r
- }\r
-\r
- if (m instanceof Array) {\r
- // iterate through all mime types, return any successes\r
- for (i=0, j=m.length; i<j && !isOK; i++) {\r
- if (_s.html5[m[i]] || a.canPlayType(m[i]).match(_s.html5Test)) {\r
- isOK = true;\r
- _s.html5[m[i]] = true;\r
-\r
- // if flash can play and preferred, also mark it for use.\r
- _s.flash[m[i]] = !!(_s.preferFlash && _hasFlash && m[i].match(_flashMIME));\r
-\r
- }\r
- }\r
- return isOK;\r
- } else {\r
- canPlay = (a && typeof a.canPlayType === 'function' ? a.canPlayType(m) : false);\r
- return !!(canPlay && (canPlay.match(_s.html5Test)));\r
- }\r
-\r
- }\r
-\r
- // test all registered formats + codecs\r
-\r
- aF = _s.audioFormats;\r
-\r
- for (item in aF) {\r
- if (aF.hasOwnProperty(item)) {\r
- support[item] = _cp(aF[item].type);\r
-\r
- // write back generic type too, eg. audio/mp3\r
- support['audio/'+item] = support[item];\r
-\r
- // assign flash\r
- if (_s.preferFlash && !_s.ignoreFlash && item.match(_flashMIME)) {\r
- _s.flash[item] = true;\r
- } else {\r
- _s.flash[item] = false;\r
- }\r
-\r
- // assign result to related formats, too\r
- if (aF[item] && aF[item].related) {\r
- for (i=aF[item].related.length; i--;) {\r
- // eg. audio/m4a\r
- support['audio/'+aF[item].related[i]] = support[item];\r
- _s.html5[aF[item].related[i]] = support[item];\r
- _s.flash[aF[item].related[i]] = support[item];\r
-\r
- }\r
- }\r
- }\r
- }\r
-\r
- support.canPlayType = (a?_cp:null);\r
- _s.html5 = _mixin(_s.html5, support);\r
-\r
- return true;\r
-\r
- };\r
-\r
- _strings = {\r
-\r
- // <d>\r
- notReady: 'Not loaded yet - wait for soundManager.onload()/onready()',\r
- notOK: 'Audio support is not available.',\r
- domError: _smc + 'createMovie(): appendChild/innerHTML call failed. DOM not ready or other error.',\r
- spcWmode: _smc + 'createMovie(): Removing wmode, preventing known SWF loading issue(s)',\r
- swf404: _sm + ': Verify that %s is a valid path.',\r
- tryDebug: 'Try ' + _sm + '.debugFlash = true for more security details (output goes to SWF.)',\r
- checkSWF: 'See SWF output for more debug info.',\r
- localFail: _sm + ': Non-HTTP page (' + _doc.location.protocol + ' URL?) Review Flash player security settings for this special case:\nhttp://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html\nMay need to add/allow path, eg. c:/sm2/ or /users/me/sm2/',\r
- waitFocus: _sm + ': Special case: Waiting for focus-related event..',\r
- waitImpatient: _sm + ': Getting impatient, still waiting for Flash%s...',\r
- waitForever: _sm + ': Waiting indefinitely for Flash (will recover if unblocked)...',\r
- needFunction: _sm + ': Function object expected for %s',\r
- badID: 'Warning: Sound ID "%s" should be a string, starting with a non-numeric character',\r
- currentObj: '--- ' + _sm + '._debug(): Current sound objects ---',\r
- waitEI: _smc + 'initMovie(): Waiting for ExternalInterface call from Flash..',\r
- waitOnload: _sm + ': Waiting for window.onload()',\r
- docLoaded: _sm + ': Document already loaded',\r
- onload: _smc + 'initComplete(): calling soundManager.onload()',\r
- onloadOK: _sm + '.onload() complete',\r
- init: _smc + 'init()',\r
- didInit: _smc + 'init(): Already called?',\r
- flashJS: _sm + ': Attempting to call Flash from JS..',\r
- secNote: 'Flash security note: Network/internet URLs will not load due to security restrictions. Access can be configured via Flash Player Global Security Settings Page: http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html',\r
- badRemove: 'Warning: Failed to remove flash movie.',\r
- noPeak: 'Warning: peakData features unsupported for movieStar formats',\r
- shutdown: _sm + '.disable(): Shutting down',\r
- queue: _sm + ': Queueing %s handler',\r
- smFail: _sm + ': Failed to initialise.',\r
- smError: 'SMSound.load(): Exception: JS-Flash communication failed, or JS error.',\r
- fbTimeout: 'No flash response, applying .'+_s.swfCSS.swfTimedout+' CSS..',\r
- fbLoaded: 'Flash loaded',\r
- fbHandler: _smc+'flashBlockHandler()',\r
- manURL: 'SMSound.load(): Using manually-assigned URL',\r
- onURL: _sm + '.load(): current URL already assigned.',\r
- badFV: _sm + '.flashVersion must be 8 or 9. "%s" is invalid. Reverting to %s.',\r
- as2loop: 'Note: Setting stream:false so looping can work (flash 8 limitation)',\r
- noNSLoop: 'Note: Looping not implemented for MovieStar formats',\r
- needfl9: 'Note: Switching to flash 9, required for MP4 formats.',\r
- mfTimeout: 'Setting flashLoadTimeout = 0 (infinite) for off-screen, mobile flash case',\r
- mfOn: 'mobileFlash::enabling on-screen flash repositioning',\r
- policy: 'Enabling usePolicyFile for data access'\r
- // </d>\r
-\r
- };\r
-\r
- _str = function() {\r
-\r
- // internal string replace helper.\r
- // arguments: o [,items to replace]\r
- // <d>\r
-\r
- // real array, please\r
- var args = _slice.call(arguments),\r
-\r
- // first arg\r
- o = args.shift(),\r
-\r
- str = (_strings && _strings[o]?_strings[o]:''), i, j;\r
- if (str && args && args.length) {\r
- for (i = 0, j = args.length; i < j; i++) {\r
- str = str.replace('%s', args[i]);\r
- }\r
- }\r
-\r
- return str;\r
- // </d>\r
-\r
- };\r
-\r
- _loopFix = function(sOpt) {\r
-\r
- // flash 8 requires stream = false for looping to work\r
- if (_fV === 8 && sOpt.loops > 1 && sOpt.stream) {\r
- _wDS('as2loop');\r
- sOpt.stream = false;\r
- }\r
-\r
- return sOpt;\r
-\r
- };\r
-\r
- _policyFix = function(sOpt, sPre) {\r
-\r
- if (sOpt && !sOpt.usePolicyFile && (sOpt.onid3 || sOpt.usePeakData || sOpt.useWaveformData || sOpt.useEQData)) {\r
- _s._wD((sPre || '') + _str('policy'));\r
- sOpt.usePolicyFile = true;\r
- }\r
-\r
- return sOpt;\r
-\r
- };\r
-\r
- _complain = function(sMsg) {\r
-\r
- // <d>\r
- if (typeof console !== 'undefined' && typeof console.warn !== 'undefined') {\r
- console.warn(sMsg);\r
- } else {\r
- _s._wD(sMsg);\r
- }\r
- // </d>\r
-\r
- };\r
-\r
- _doNothing = function() {\r
-\r
- return false;\r
-\r
- };\r
-\r
- _disableObject = function(o) {\r
-\r
- var oProp;\r
-\r
- for (oProp in o) {\r
- if (o.hasOwnProperty(oProp) && typeof o[oProp] === 'function') {\r
- o[oProp] = _doNothing;\r
- }\r
- }\r
-\r
- oProp = null;\r
-\r
- };\r
-\r
- _failSafely = function(bNoDisable) {\r
-\r
- // general failure exception handler\r
-\r
- if (typeof bNoDisable === 'undefined') {\r
- bNoDisable = false;\r
- }\r
-\r
- if (_disabled || bNoDisable) {\r
- _wDS('smFail', 2);\r
- _s.disable(bNoDisable);\r
- }\r
-\r
- };\r
-\r
- _normalizeMovieURL = function(smURL) {\r
-\r
- var urlParams = null, url;\r
-\r
- if (smURL) {\r
- if (smURL.match(/\.swf(\?.*)?$/i)) {\r
- urlParams = smURL.substr(smURL.toLowerCase().lastIndexOf('.swf?') + 4);\r
- if (urlParams) {\r
- // assume user knows what they're doing\r
- return smURL;\r
- }\r
- } else if (smURL.lastIndexOf('/') !== smURL.length - 1) {\r
- // append trailing slash, if needed\r
- smURL += '/';\r
- }\r
- }\r
-\r
- url = (smURL && smURL.lastIndexOf('/') !== - 1 ? smURL.substr(0, smURL.lastIndexOf('/') + 1) : './') + _s.movieURL;\r
-\r
- if (_s.noSWFCache) {\r
- url += ('?ts=' + new Date().getTime());\r
- }\r
-\r
- return url;\r
-\r
- };\r
-\r
- _setVersionInfo = function() {\r
-\r
- // short-hand for internal use\r
-\r
- _fV = parseInt(_s.flashVersion, 10);\r
-\r
- if (_fV !== 8 && _fV !== 9) {\r
- _s._wD(_str('badFV', _fV, _defaultFlashVersion));\r
- _s.flashVersion = _fV = _defaultFlashVersion;\r
- }\r
-\r
- // debug flash movie, if applicable\r
-\r
- var isDebug = (_s.debugMode || _s.debugFlash?'_debug.swf':'.swf');\r
-\r
- if (_s.useHTML5Audio && !_s.html5Only && _s.audioFormats.mp4.required && _fV < 9) {\r
- _s._wD(_str('needfl9'));\r
- _s.flashVersion = _fV = 9;\r
- }\r
-\r
- _s.version = _s.versionNumber + (_s.html5Only?' (HTML5-only mode)':(_fV === 9?' (AS3/Flash 9)':' (AS2/Flash 8)'));\r
-\r
- // set up default options\r
- if (_fV > 8) {\r
- // +flash 9 base options\r
- _s.defaultOptions = _mixin(_s.defaultOptions, _s.flash9Options);\r
- _s.features.buffering = true;\r
- // +moviestar support\r
- _s.defaultOptions = _mixin(_s.defaultOptions, _s.movieStarOptions);\r
- _s.filePatterns.flash9 = new RegExp('\\.(mp3|' + _netStreamTypes.join('|') + ')(\\?.*)?$', 'i');\r
- _s.features.movieStar = true;\r
- } else {\r
- _s.features.movieStar = false;\r
- }\r
-\r
- // regExp for flash canPlay(), etc.\r
- _s.filePattern = _s.filePatterns[(_fV !== 8?'flash9':'flash8')];\r
-\r
- // if applicable, use _debug versions of SWFs\r
- _s.movieURL = (_fV === 8?'soundmanager2.swf':'soundmanager2_flash9.swf').replace('.swf', isDebug);\r
-\r
- _s.features.peakData = _s.features.waveformData = _s.features.eqData = (_fV > 8);\r
-\r
- };\r
-\r
- _setPolling = function(bPolling, bHighPerformance) {\r
-\r
- if (!_s.o) {\r
- return false;\r
- }\r
-\r
- _s.o._setPolling(bPolling, bHighPerformance);\r
-\r
- };\r
-\r
- _initDebug = function() {\r
-\r
- // starts debug mode, creating output <div> for UAs without console object\r
-\r
- // allow force of debug mode via URL\r
- if (_s.debugURLParam.test(_wl)) {\r
- _s.debugMode = true;\r
- }\r
-\r
- // <d>\r
- if (_id(_s.debugID)) {\r
- return false;\r
- }\r
-\r
- var oD, oDebug, oTarget, oToggle, tmp;\r
-\r
- if (_s.debugMode && !_id(_s.debugID) && ((!_hasConsole || !_s.useConsole) || (_s.useConsole && _hasConsole && !_s.consoleOnly))) {\r
-\r
- oD = _doc.createElement('div');\r
- oD.id = _s.debugID + '-toggle';\r
-\r
- oToggle = {\r
- 'position': 'fixed',\r
- 'bottom': '0px',\r
- 'right': '0px',\r
- 'width': '1.2em',\r
- 'height': '1.2em',\r
- 'lineHeight': '1.2em',\r
- 'margin': '2px',\r
- 'textAlign': 'center',\r
- 'border': '1px solid #999',\r
- 'cursor': 'pointer',\r
- 'background': '#fff',\r
- 'color': '#333',\r
- 'zIndex': 10001\r
- };\r
-\r
- oD.appendChild(_doc.createTextNode('-'));\r
- oD.onclick = _toggleDebug;\r
- oD.title = 'Toggle SM2 debug console';\r
-\r
- if (_ua.match(/msie 6/i)) {\r
- oD.style.position = 'absolute';\r
- oD.style.cursor = 'hand';\r
- }\r
-\r
- for (tmp in oToggle) {\r
- if (oToggle.hasOwnProperty(tmp)) {\r
- oD.style[tmp] = oToggle[tmp];\r
- }\r
- }\r
-\r
- oDebug = _doc.createElement('div');\r
- oDebug.id = _s.debugID;\r
- oDebug.style.display = (_s.debugMode?'block':'none');\r
-\r
- if (_s.debugMode && !_id(oD.id)) {\r
- try {\r
- oTarget = _getDocument();\r
- oTarget.appendChild(oD);\r
- } catch(e2) {\r
- throw new Error(_str('domError')+' \n'+e2.toString());\r
- }\r
- oTarget.appendChild(oDebug);\r
- }\r
-\r
- }\r
-\r
- oTarget = null;\r
- // </d>\r
-\r
- };\r
-\r
- _idCheck = this.getSoundById;\r
-\r
- // <d>\r
- _wDS = function(o, errorLevel) {\r
-\r
- if (!o) {\r
- return '';\r
- } else {\r
- return _s._wD(_str(o), errorLevel);\r
- }\r
-\r
- };\r
-\r
- // last-resort debugging option\r
-\r
- if (_wl.indexOf('sm2-debug=alert') + 1 && _s.debugMode) {\r
- _s._wD = function(sText) {window.alert(sText);};\r
- }\r
-\r
- _toggleDebug = function() {\r
-\r
- var o = _id(_s.debugID),\r
- oT = _id(_s.debugID + '-toggle');\r
-\r
- if (!o) {\r
- return false;\r
- }\r
-\r
- if (_debugOpen) {\r
- // minimize\r
- oT.innerHTML = '+';\r
- o.style.display = 'none';\r
- } else {\r
- oT.innerHTML = '-';\r
- o.style.display = 'block';\r
- }\r
-\r
- _debugOpen = !_debugOpen;\r
-\r
- };\r
-\r
- _debugTS = function(sEventType, bSuccess, sMessage) {\r
-\r
- // troubleshooter debug hooks\r
-\r
- if (typeof sm2Debugger !== 'undefined') {\r
- try {\r
- sm2Debugger.handleEvent(sEventType, bSuccess, sMessage);\r
- } catch(e) {\r
- // oh well\r
- }\r
- }\r
-\r
- return true;\r
-\r
- };\r
- // </d>\r
-\r
- _getSWFCSS = function() {\r
-\r
- var css = [];\r
-\r
- if (_s.debugMode) {\r
- css.push(_s.swfCSS.sm2Debug);\r
- }\r
-\r
- if (_s.debugFlash) {\r
- css.push(_s.swfCSS.flashDebug);\r
- }\r
-\r
- if (_s.useHighPerformance) {\r
- css.push(_s.swfCSS.highPerf);\r
- }\r
-\r
- return css.join(' ');\r
-\r
- };\r
-\r
- _flashBlockHandler = function() {\r
-\r
- // *possible* flash block situation.\r
-\r
- var name = _str('fbHandler'),\r
- p = _s.getMoviePercent(),\r
- css = _s.swfCSS,\r
- error = {type:'FLASHBLOCK'};\r
-\r
- if (_s.html5Only) {\r
- return false;\r
- }\r
-\r
- if (!_s.ok()) {\r
-\r
- if (_needsFlash) {\r
- // make the movie more visible, so user can fix\r
- _s.oMC.className = _getSWFCSS() + ' ' + css.swfDefault + ' ' + (p === null?css.swfTimedout:css.swfError);\r
- _s._wD(name+': '+_str('fbTimeout')+(p?' ('+_str('fbLoaded')+')':''));\r
- }\r
-\r
- _s.didFlashBlock = true;\r
-\r
- // fire onready(), complain lightly\r
- _processOnEvents({type:'ontimeout', ignoreInit:true, error:error});\r
- _catchError(error);\r
-\r
- } else {\r
-\r
- // SM2 loaded OK (or recovered)\r
-\r
- if (_s.didFlashBlock) {\r
- _s._wD(name+': Unblocked');\r
- }\r
-\r
- if (_s.oMC) {\r
- _s.oMC.className = [_getSWFCSS(), css.swfDefault, css.swfLoaded + (_s.didFlashBlock?' '+css.swfUnblocked:'')].join(' ');\r
- }\r
-\r
- }\r
-\r
- };\r
-\r
- _addOnEvent = function(sType, oMethod, oScope) {\r
-\r
- if (typeof _on_queue[sType] === 'undefined') {\r
- _on_queue[sType] = [];\r
- }\r
-\r
- _on_queue[sType].push({\r
- 'method': oMethod,\r
- 'scope': (oScope || null),\r
- 'fired': false\r
- });\r
-\r
- };\r
-\r
- _processOnEvents = function(oOptions) {\r
-\r
- // assume onready, if unspecified\r
-\r
- if (!oOptions) {\r
- oOptions = {\r
- type: 'onready'\r
- };\r
- }\r
-\r
- if (!_didInit && oOptions && !oOptions.ignoreInit) {\r
- // not ready yet.\r
- return false;\r
- }\r
-\r
- if (oOptions.type === 'ontimeout' && _s.ok()) {\r
- // invalid case\r
- return false;\r
- }\r
-\r
- var status = {\r
- success: (oOptions && oOptions.ignoreInit?_s.ok():!_disabled)\r
- },\r
-\r
- // queue specified by type, or none\r
- srcQueue = (oOptions && oOptions.type?_on_queue[oOptions.type]||[]:[]),\r
-\r
- queue = [], i, j,\r
- args = [status],\r
- canRetry = (_needsFlash && _s.useFlashBlock && !_s.ok());\r
-\r
- if (oOptions.error) {\r
- args[0].error = oOptions.error;\r
- }\r
-\r
- for (i = 0, j = srcQueue.length; i < j; i++) {\r
- if (srcQueue[i].fired !== true) {\r
- queue.push(srcQueue[i]);\r
- }\r
- }\r
-\r
- if (queue.length) {\r
- _s._wD(_sm + ': Firing ' + queue.length + ' '+oOptions.type+'() item' + (queue.length === 1?'':'s'));\r
- for (i = 0, j = queue.length; i < j; i++) {\r
- if (queue[i].scope) {\r
- queue[i].method.apply(queue[i].scope, args);\r
- } else {\r
- queue[i].method.apply(this, args);\r
- }\r
- if (!canRetry) {\r
- // flashblock case doesn't count here\r
- queue[i].fired = true;\r
- }\r
- }\r
- }\r
-\r
- return true;\r
-\r
- };\r
-\r
- _initUserOnload = function() {\r
-\r
- _win.setTimeout(function() {\r
-\r
- if (_s.useFlashBlock) {\r
- _flashBlockHandler();\r
- }\r
-\r
- _processOnEvents();\r
-\r
- // call user-defined "onload", scoped to window\r
-\r
- if (_s.onload instanceof Function) {\r
- _wDS('onload', 1);\r
- _s.onload.apply(_win);\r
- _wDS('onloadOK', 1);\r
- }\r
-\r
- if (_s.waitForWindowLoad) {\r
- _event.add(_win, 'load', _initUserOnload);\r
- }\r
-\r
- },1);\r
-\r
- };\r
-\r
- _detectFlash = function() {\r
-\r
- // hat tip: Flash Detect library (BSD, (C) 2007) by Carl "DocYes" S. Yestrau - http://featureblend.com/javascript-flash-detection-library.html / http://featureblend.com/license.txt\r
-\r
- if (_hasFlash !== undefined) {\r
- // this work has already been done.\r
- return _hasFlash;\r
- }\r
-\r
- var hasPlugin = false, n = navigator, nP = n.plugins, obj, type, types, AX = _win.ActiveXObject;\r
-\r
- if (nP && nP.length) {\r
- type = 'application/x-shockwave-flash';\r
- types = n.mimeTypes;\r
- if (types && types[type] && types[type].enabledPlugin && types[type].enabledPlugin.description) {\r
- hasPlugin = true;\r
- }\r
- } else if (typeof AX !== 'undefined') {\r
- try {\r
- obj = new AX('ShockwaveFlash.ShockwaveFlash');\r
- } catch(e) {\r
- // oh well\r
- }\r
- hasPlugin = (!!obj);\r
- }\r
-\r
- _hasFlash = hasPlugin;\r
-\r
- return hasPlugin;\r
-\r
- };\r
-\r
- _featureCheck = function() {\r
-\r
- var needsFlash, item,\r
-\r
- // iPhone <= 3.1 has broken HTML5 audio(), but firmware 3.2 (iPad) + iOS4 works.\r
- isSpecial = (_is_iDevice && !!(_ua.match(/os (1|2|3_0|3_1)/i)));\r
-\r
- if (isSpecial) {\r
-\r
- // has Audio(), but is broken; let it load links directly.\r
- _s.hasHTML5 = false;\r
-\r
- // ignore flash case, however\r
- _s.html5Only = true;\r
-\r
- if (_s.oMC) {\r
- _s.oMC.style.display = 'none';\r
- }\r
-\r
- return false;\r
-\r
- }\r
-\r
- if (_s.useHTML5Audio) {\r
-\r
- if (!_s.html5 || !_s.html5.canPlayType) {\r
- _s._wD('SoundManager: No HTML5 Audio() support detected.');\r
- _s.hasHTML5 = false;\r
- return true;\r
- } else {\r
- _s.hasHTML5 = true;\r
- }\r
- if (_isBadSafari) {\r
- _s._wD(_smc+'Note: Buggy HTML5 Audio in Safari on this OS X release, see https://bugs.webkit.org/show_bug.cgi?id=32159 - '+(!_hasFlash?' would use flash fallback for MP3/MP4, but none detected.':'will use flash fallback for MP3/MP4, if available'),1);\r
- if (_detectFlash()) {\r
- return true;\r
- }\r
- }\r
- } else {\r
-\r
- // flash needed (or, HTML5 needs enabling.)\r
- return true;\r
-\r
- }\r
-\r
- for (item in _s.audioFormats) {\r
- if (_s.audioFormats.hasOwnProperty(item)) {\r
- if ((_s.audioFormats[item].required && !_s.html5.canPlayType(_s.audioFormats[item].type)) || _s.flash[item] || _s.flash[_s.audioFormats[item].type]) {\r
- // flash may be required, or preferred for this format\r
- needsFlash = true;\r
- }\r
- }\r
- }\r
-\r
- // sanity check..\r
- if (_s.ignoreFlash) {\r
- needsFlash = false;\r
- }\r
-\r
- _s.html5Only = (_s.hasHTML5 && _s.useHTML5Audio && !needsFlash);\r
-\r
- return (!_s.html5Only);\r
-\r
- };\r
-\r
- _startTimer = function(oSound) {\r
-\r
- if (!oSound._hasTimer) {\r
- oSound._hasTimer = true;\r
- }\r
-\r
- };\r
-\r
- _stopTimer = function(oSound) {\r
-\r
- if (oSound._hasTimer) {\r
- oSound._hasTimer = false;\r
- }\r
-\r
- };\r
-\r
- _catchError = function(options) {\r
-\r
- options = (typeof options !== 'undefined' ? options : {});\r
-\r
- if (_s.onerror instanceof Function) {\r
- _s.onerror.apply(_win, [{type:(typeof options.type !== 'undefined' ? options.type : null)}]);\r
- }\r
-\r
- if (typeof options.fatal !== 'undefined' && options.fatal) {\r
- _s.disable();\r
- }\r
-\r
- };\r
-\r
- _badSafariFix = function() {\r
-\r
- // special case: "bad" Safari (OS X 10.3 - 10.7) must fall back to flash for MP3/MP4\r
- if (!_isBadSafari || !_detectFlash()) {\r
- // doesn't apply\r
- return false;\r
- }\r
-\r
- var aF = _s.audioFormats, i, item;\r
-\r
- for (item in aF) {\r
- if (aF.hasOwnProperty(item)) {\r
- if (item === 'mp3' || item === 'mp4') {\r
- _s._wD(_sm+': Using flash fallback for '+item+' format');\r
- _s.html5[item] = false;\r
- // assign result to related formats, too\r
- if (aF[item] && aF[item].related) {\r
- for (i = aF[item].related.length; i--;) {\r
- _s.html5[aF[item].related[i]] = false;\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- };\r
-\r
- /**\r
- * Pseudo-private flash/ExternalInterface methods\r
- * ----------------------------------------------\r
- */\r
-\r
- this._setSandboxType = function(sandboxType) {\r
-\r
- // <d>\r
- var sb = _s.sandbox;\r
-\r
- sb.type = sandboxType;\r
- sb.description = sb.types[(typeof sb.types[sandboxType] !== 'undefined'?sandboxType:'unknown')];\r
-\r
- _s._wD('Flash security sandbox type: ' + sb.type);\r
-\r
- if (sb.type === 'localWithFile') {\r
-\r
- sb.noRemote = true;\r
- sb.noLocal = false;\r
- _wDS('secNote', 2);\r
-\r
- } else if (sb.type === 'localWithNetwork') {\r
-\r
- sb.noRemote = false;\r
- sb.noLocal = true;\r
-\r
- } else if (sb.type === 'localTrusted') {\r
-\r
- sb.noRemote = false;\r
- sb.noLocal = false;\r
-\r
- }\r
- // </d>\r
-\r
- };\r
-\r
- this._externalInterfaceOK = function(flashDate) {\r
-\r
- // flash callback confirming flash loaded, EI working etc.\r
- // flashDate = approx. timing/delay info for JS/flash bridge\r
-\r
- if (_s.swfLoaded) {\r
- return false;\r
- }\r
-\r
- var eiTime = new Date().getTime();\r
-\r
- _s._wD(_smc+'externalInterfaceOK()' + (flashDate?' (~' + (eiTime - flashDate) + ' ms)':''));\r
- _debugTS('swf', true);\r
- _debugTS('flashtojs', true);\r
- _s.swfLoaded = true;\r
- _tryInitOnFocus = false;\r
-\r
- if (_isBadSafari) {\r
- _badSafariFix();\r
- }\r
-\r
- if (_isIE) {\r
- // IE needs a timeout OR delay until window.onload - may need TODO: investigating\r
- setTimeout(_init, 100);\r
- } else {\r
- _init();\r
- }\r
-\r
- };\r
-\r
- /**\r
- * Private initialization helpers\r
- * ------------------------------\r
- */\r
-\r
- _createMovie = function(smID, smURL) {\r
-\r
- if (_didAppend && _appendSuccess) {\r
- // ignore if already succeeded\r
- return false;\r
- }\r
-\r
- function _initMsg() {\r
- _s._wD('-- SoundManager 2 ' + _s.version + (!_s.html5Only && _s.useHTML5Audio?(_s.hasHTML5?' + HTML5 audio':', no HTML5 audio support'):'') + (!_s.html5Only ? (_s.useHighPerformance?', high performance mode, ':', ') + (( _s.flashPollingInterval ? 'custom (' + _s.flashPollingInterval + 'ms)' : 'normal') + ' polling') + (_s.wmode?', wmode: ' + _s.wmode:'') + (_s.debugFlash?', flash debug mode':'') + (_s.useFlashBlock?', flashBlock mode':'') : '') + ' --', 1);\r
- }\r
-\r
- if (_s.html5Only) {\r
-\r
- // 100% HTML5 mode\r
- _setVersionInfo();\r
-\r
- _initMsg();\r
- _s.oMC = _id(_s.movieID);\r
- _init();\r
-\r
- // prevent multiple init attempts\r
- _didAppend = true;\r
-\r
- _appendSuccess = true;\r
-\r
- return false;\r
-\r
- }\r
-\r
- // flash path\r
- var remoteURL = (smURL || _s.url),\r
- localURL = (_s.altURL || remoteURL),\r
- swfTitle = 'JS/Flash audio component (SoundManager 2)',\r
- oEmbed, oMovie, oTarget = _getDocument(), tmp, movieHTML, oEl, extraClass = _getSWFCSS(),\r
- s, x, sClass, side = 'auto', isRTL = null,\r
- html = _doc.getElementsByTagName('html')[0];\r
-\r
- isRTL = (html && html.dir && html.dir.match(/rtl/i));\r
- smID = (typeof smID === 'undefined'?_s.id:smID);\r
-\r
- function param(name, value) {\r
- return '<param name="'+name+'" value="'+value+'" />';\r
- }\r
-\r
- // safety check for legacy (change to Flash 9 URL)\r
- _setVersionInfo();\r
- _s.url = _normalizeMovieURL(_overHTTP?remoteURL:localURL);\r
- smURL = _s.url;\r
-\r
- _s.wmode = (!_s.wmode && _s.useHighPerformance ? 'transparent' : _s.wmode);\r
-\r
- if (_s.wmode !== null && (_ua.match(/msie 8/i) || (!_isIE && !_s.useHighPerformance)) && navigator.platform.match(/win32|win64/i)) {\r
- /**\r
- * extra-special case: movie doesn't load until scrolled into view when using wmode = anything but 'window' here\r
- * does not apply when using high performance (position:fixed means on-screen), OR infinite flash load timeout\r
- * wmode breaks IE 8 on Vista + Win7 too in some cases, as of January 2011 (?)\r
- */\r
- _s.specialWmodeCase = true;\r
- _wDS('spcWmode');\r
- _s.wmode = null;\r
- }\r
-\r
- oEmbed = {\r
- 'name': smID,\r
- 'id': smID,\r
- 'src': smURL,\r
- 'width': side,\r
- 'height': side,\r
- 'quality': 'high',\r
- 'allowScriptAccess': _s.allowScriptAccess,\r
- 'bgcolor': _s.bgColor,\r
- 'pluginspage': _http+'www.macromedia.com/go/getflashplayer',\r
- 'title': swfTitle,\r
- 'type': 'application/x-shockwave-flash',\r
- 'wmode': _s.wmode,\r
- // http://help.adobe.com/en_US/as3/mobile/WS4bebcd66a74275c36cfb8137124318eebc6-7ffd.html\r
- 'hasPriority': 'true'\r
- };\r
-\r
- if (_s.debugFlash) {\r
- oEmbed.FlashVars = 'debug=1';\r
- }\r
-\r
- if (!_s.wmode) {\r
- // don't write empty attribute\r
- delete oEmbed.wmode;\r
- }\r
-\r
- if (_isIE) {\r
-\r
- // IE is "special".\r
- oMovie = _doc.createElement('div');\r
- movieHTML = [\r
- '<object id="' + smID + '" data="' + smURL + '" type="' + oEmbed.type + '" title="' + oEmbed.title +'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="' + _http+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" width="' + oEmbed.width + '" height="' + oEmbed.height + '">',\r
- param('movie', smURL),\r
- param('AllowScriptAccess', _s.allowScriptAccess),\r
- param('quality', oEmbed.quality),\r
- (_s.wmode? param('wmode', _s.wmode): ''),\r
- param('bgcolor', _s.bgColor),\r
- param('hasPriority', 'true'),\r
- (_s.debugFlash ? param('FlashVars', oEmbed.FlashVars) : ''),\r
- '</object>'\r
- ].join('');\r
-\r
- } else {\r
-\r
- oMovie = _doc.createElement('embed');\r
- for (tmp in oEmbed) {\r
- if (oEmbed.hasOwnProperty(tmp)) {\r
- oMovie.setAttribute(tmp, oEmbed[tmp]);\r
- }\r
- }\r
-\r
- }\r
-\r
- _initDebug();\r
- extraClass = _getSWFCSS();\r
- oTarget = _getDocument();\r
-\r
- if (oTarget) {\r
-\r
- _s.oMC = (_id(_s.movieID) || _doc.createElement('div'));\r
-\r
- if (!_s.oMC.id) {\r
-\r
- _s.oMC.id = _s.movieID;\r
- _s.oMC.className = _s.swfCSS.swfDefault + ' ' + extraClass;\r
- s = null;\r
- oEl = null;\r
-\r
- if (!_s.useFlashBlock) {\r
- if (_s.useHighPerformance) {\r
- // on-screen at all times\r
- s = {\r
- 'position': 'fixed',\r
- 'width': '8px',\r
- 'height': '8px',\r
- // >= 6px for flash to run fast, >= 8px to start up under Firefox/win32 in some cases. odd? yes.\r
- 'bottom': '0px',\r
- 'left': '0px',\r
- 'overflow': 'hidden'\r
- };\r
- } else {\r
- // hide off-screen, lower priority\r
- s = {\r
- 'position': 'absolute',\r
- 'width': '6px',\r
- 'height': '6px',\r
- 'top': '-9999px',\r
- 'left': '-9999px'\r
- };\r
- if (isRTL) {\r
- s.left = Math.abs(parseInt(s.left,10))+'px';\r
- }\r
- }\r
- }\r
-\r
- if (_isWebkit) {\r
- // soundcloud-reported render/crash fix, safari 5\r
- _s.oMC.style.zIndex = 10000;\r
- }\r
-\r
- if (!_s.debugFlash) {\r
- for (x in s) {\r
- if (s.hasOwnProperty(x)) {\r
- _s.oMC.style[x] = s[x];\r
- }\r
- }\r
- }\r
-\r
- try {\r
- if (!_isIE) {\r
- _s.oMC.appendChild(oMovie);\r
- }\r
- oTarget.appendChild(_s.oMC);\r
- if (_isIE) {\r
- oEl = _s.oMC.appendChild(_doc.createElement('div'));\r
- oEl.className = _s.swfCSS.swfBox;\r
- oEl.innerHTML = movieHTML;\r
- }\r
- _appendSuccess = true;\r
- } catch(e) {\r
- throw new Error(_str('domError')+' \n'+e.toString());\r
- }\r
-\r
- } else {\r
-\r
- // SM2 container is already in the document (eg. flashblock use case)\r
- sClass = _s.oMC.className;\r
- _s.oMC.className = (sClass?sClass+' ':_s.swfCSS.swfDefault) + (extraClass?' '+extraClass:'');\r
- _s.oMC.appendChild(oMovie);\r
- if (_isIE) {\r
- oEl = _s.oMC.appendChild(_doc.createElement('div'));\r
- oEl.className = _s.swfCSS.swfBox;\r
- oEl.innerHTML = movieHTML;\r
- }\r
- _appendSuccess = true;\r
-\r
- }\r
-\r
- }\r
-\r
- _didAppend = true;\r
- _initMsg();\r
- _s._wD(_smc+'createMovie(): Trying to load ' + smURL + (!_overHTTP && _s.altURL?' (alternate URL)':''), 1);\r
-\r
- return true;\r
-\r
- };\r
-\r
- _initMovie = function() {\r
-\r
- if (_s.html5Only) {\r
- _createMovie();\r
- return false;\r
- }\r
-\r
- // attempt to get, or create, movie\r
- // may already exist\r
- if (_s.o) {\r
- return false;\r
- }\r
-\r
- // inline markup case\r
- _s.o = _s.getMovie(_s.id);\r
-\r
- if (!_s.o) {\r
- if (!_oRemoved) {\r
- // try to create\r
- _createMovie(_s.id, _s.url);\r
- } else {\r
- // try to re-append removed movie after reboot()\r
- if (!_isIE) {\r
- _s.oMC.appendChild(_oRemoved);\r
- } else {\r
- _s.oMC.innerHTML = _oRemovedHTML;\r
- }\r
- _oRemoved = null;\r
- _didAppend = true;\r
- }\r
- _s.o = _s.getMovie(_s.id);\r
- }\r
-\r
- // <d>\r
- if (_s.o) {\r
- _wDS('waitEI');\r
- }\r
- // </d>\r
-\r
- if (_s.oninitmovie instanceof Function) {\r
- setTimeout(_s.oninitmovie, 1);\r
- }\r
-\r
- return true;\r
-\r
- };\r
-\r
- _delayWaitForEI = function() {\r
-\r
- setTimeout(_waitForEI, 1000);\r
-\r
- };\r
-\r
- _waitForEI = function() {\r
-\r
- if (_waitingForEI) {\r
- return false;\r
- }\r
-\r
- _waitingForEI = true;\r
- _event.remove(_win, 'load', _delayWaitForEI);\r
-\r
- if (_tryInitOnFocus && !_isFocused) {\r
- // giant Safari 3.1 hack - assume mousemove = focus given lack of focus event\r
- _wDS('waitFocus');\r
- return false;\r
- }\r
-\r
- var p;\r
- if (!_didInit) {\r
- p = _s.getMoviePercent();\r
- _s._wD(_str('waitImpatient', (p === 100?' (SWF loaded)':(p > 0?' (SWF ' + p + '% loaded)':''))));\r
- }\r
-\r
- setTimeout(function() {\r
-\r
- p = _s.getMoviePercent();\r
-\r
- // <d>\r
- if (!_didInit) {\r
- _s._wD(_sm + ': No Flash response within expected time.\nLikely causes: ' + (p === 0?'Loading ' + _s.movieURL + ' may have failed (and/or Flash ' + _fV + '+ not present?), ':'') + 'Flash blocked or JS-Flash security error.' + (_s.debugFlash?' ' + _str('checkSWF'):''), 2);\r
- if (!_overHTTP && p) {\r
- _wDS('localFail', 2);\r
- if (!_s.debugFlash) {\r
- _wDS('tryDebug', 2);\r
- }\r
- }\r
- if (p === 0) {\r
- // if 0 (not null), probably a 404.\r
- _s._wD(_str('swf404', _s.url));\r
- }\r
- _debugTS('flashtojs', false, ': Timed out' + _overHTTP?' (Check flash security or flash blockers)':' (No plugin/missing SWF?)');\r
- }\r
- // </d>\r
-\r
- // give up / time-out, depending\r
-\r
- if (!_didInit && _okToDisable) {\r
- if (p === null) {\r
- // SWF failed. Maybe blocked.\r
- if (_s.useFlashBlock || _s.flashLoadTimeout === 0) {\r
- if (_s.useFlashBlock) {\r
- _flashBlockHandler();\r
- }\r
- _wDS('waitForever');\r
- } else {\r
- // old SM2 behaviour, simply fail\r
- _failSafely(true);\r
- }\r
- } else {\r
- // flash loaded? Shouldn't be a blocking issue, then.\r
- if (_s.flashLoadTimeout === 0) {\r
- _wDS('waitForever');\r
- } else {\r
- _failSafely(true);\r
- }\r
- }\r
- }\r
-\r
- }, _s.flashLoadTimeout);\r
-\r
- };\r
-\r
- _handleFocus = function() {\r
-\r
- function cleanup() {\r
- _event.remove(_win, 'focus', _handleFocus);\r
- _event.remove(_win, 'load', _handleFocus);\r
- }\r
-\r
- if (_isFocused || !_tryInitOnFocus) {\r
- cleanup();\r
- return true;\r
- }\r
-\r
- _okToDisable = true;\r
- _isFocused = true;\r
- _s._wD(_smc+'handleFocus()');\r
-\r
- if (_isSafari && _tryInitOnFocus) {\r
- _event.remove(_win, 'mousemove', _handleFocus);\r
- }\r
-\r
- // allow init to restart\r
- _waitingForEI = false;\r
-\r
- cleanup();\r
- return true;\r
-\r
- };\r
-\r
- _showSupport = function() {\r
-\r
- var item, tests = [];\r
-\r
- if (_s.useHTML5Audio && _s.hasHTML5) {\r
- for (item in _s.audioFormats) {\r
- if (_s.audioFormats.hasOwnProperty(item)) {\r
- tests.push(item + ': ' + _s.html5[item] + (!_s.html5[item] && _hasFlash && _s.flash[item] ? ' (using flash)' : (_s.preferFlash && _s.flash[item] && _hasFlash ? ' (preferring flash)': (!_s.html5[item] ? ' (' + (_s.audioFormats[item].required ? 'required, ':'') + 'and no flash support)' : ''))));\r
- }\r
- }\r
- _s._wD('-- SoundManager 2: HTML5 support tests ('+_s.html5Test+'): '+tests.join(', ')+' --',1);\r
- }\r
-\r
- };\r
-\r
- _initComplete = function(bNoDisable) {\r
-\r
- if (_didInit) {\r
- return false;\r
- }\r
-\r
- if (_s.html5Only) {\r
- // all good.\r
- _s._wD('-- SoundManager 2: loaded --');\r
- _didInit = true;\r
- _initUserOnload();\r
- _debugTS('onload', true);\r
- return true;\r
- }\r
-\r
- var wasTimeout = (_s.useFlashBlock && _s.flashLoadTimeout && !_s.getMoviePercent()),\r
- error;\r
-\r
- if (!wasTimeout) {\r
- _didInit = true;\r
- if (_disabled) {\r
- error = {type: (!_hasFlash && _needsFlash ? 'NO_FLASH' : 'INIT_TIMEOUT')};\r
- }\r
- }\r
-\r
- _s._wD('-- SoundManager 2 ' + (_disabled?'failed to load':'loaded') + ' (' + (_disabled?'security/load error':'OK') + ') --', 1);\r
-\r
- if (_disabled || bNoDisable) {\r
- if (_s.useFlashBlock && _s.oMC) {\r
- _s.oMC.className = _getSWFCSS() + ' ' + (_s.getMoviePercent() === null?_s.swfCSS.swfTimedout:_s.swfCSS.swfError);\r
- }\r
- _processOnEvents({type:'ontimeout', error:error});\r
- _debugTS('onload', false);\r
- _catchError(error);\r
- return false;\r
- } else {\r
- _debugTS('onload', true);\r
- }\r
-\r
- if (_s.waitForWindowLoad && !_windowLoaded) {\r
- _wDS('waitOnload');\r
- _event.add(_win, 'load', _initUserOnload);\r
- return false;\r
- } else {\r
- // <d>\r
- if (_s.waitForWindowLoad && _windowLoaded) {\r
- _wDS('docLoaded');\r
- }\r
- // </d>\r
- _initUserOnload();\r
- }\r
-\r
- return true;\r
-\r
- };\r
-\r
- _init = function() {\r
-\r
- _wDS('init');\r
-\r
- // called after onload()\r
-\r
- if (_didInit) {\r
- _wDS('didInit');\r
- return false;\r
- }\r
-\r
- function _cleanup() {\r
- _event.remove(_win, 'load', _s.beginDelayedInit);\r
- }\r
-\r
- if (_s.html5Only) {\r
- if (!_didInit) {\r
- // we don't need no steenking flash!\r
- _cleanup();\r
- _s.enabled = true;\r
- _initComplete();\r
- }\r
- return true;\r
- }\r
-\r
- // flash path\r
- _initMovie();\r
-\r
- try {\r
-\r
- _wDS('flashJS');\r
-\r
- // attempt to talk to Flash\r
- _s.o._externalInterfaceTest(false);\r
-\r
- // apply user-specified polling interval, OR, if "high performance" set, faster vs. default polling\r
- // (determines frequency of whileloading/whileplaying callbacks, effectively driving UI framerates)\r
- _setPolling(true, (_s.flashPollingInterval || (_s.useHighPerformance ? 10 : 50)));\r
-\r
- if (!_s.debugMode) {\r
- // stop the SWF from making debug output calls to JS\r
- _s.o._disableDebug();\r
- }\r
-\r
- _s.enabled = true;\r
- _debugTS('jstoflash', true);\r
-\r
- if (!_s.html5Only) {\r
- // prevent browser from showing cached page state (or rather, restoring "suspended" page state) via back button, because flash may be dead\r
- // http://www.webkit.org/blog/516/webkit-page-cache-ii-the-unload-event/\r
- _event.add(_win, 'unload', _doNothing);\r
- }\r
-\r
- } catch(e) {\r
-\r
- _s._wD('js/flash exception: ' + e.toString());\r
- _debugTS('jstoflash', false);\r
- _catchError({type:'JS_TO_FLASH_EXCEPTION', fatal:true});\r
- // don't disable, for reboot()\r
- _failSafely(true);\r
- _initComplete();\r
-\r
- return false;\r
-\r
- }\r
-\r
- _initComplete();\r
-\r
- // disconnect events\r
- _cleanup();\r
-\r
- return true;\r
-\r
- };\r
-\r
- _domContentLoaded = function() {\r
-\r
- if (_didDCLoaded) {\r
- return false;\r
- }\r
-\r
- _didDCLoaded = true;\r
- _initDebug();\r
-\r
- /**\r
- * Temporary feature: allow force of HTML5 via URL params: sm2-usehtml5audio=0 or 1\r
- * Ditto for sm2-preferFlash, too.\r
- */\r
- // <d>\r
- (function(){\r
-\r
- var a = 'sm2-usehtml5audio=', l = _wl.toLowerCase(), b = null,\r
- a2 = 'sm2-preferflash=', b2 = null, hasCon = (typeof console !== 'undefined' && typeof console.log !== 'undefined');\r
-\r
- if (l.indexOf(a) !== -1) {\r
- b = (l.charAt(l.indexOf(a)+a.length) === '1');\r
- if (hasCon) {\r
- console.log((b?'Enabling ':'Disabling ')+'useHTML5Audio via URL parameter');\r
- }\r
- _s.useHTML5Audio = b;\r
- }\r
-\r
- if (l.indexOf(a2) !== -1) {\r
- b2 = (l.charAt(l.indexOf(a2)+a2.length) === '1');\r
- if (hasCon) {\r
- console.log((b2?'Enabling ':'Disabling ')+'preferFlash via URL parameter');\r
- }\r
- _s.preferFlash = b2;\r
- }\r
-\r
- }());\r
- // </d>\r
-\r
- if (!_hasFlash && _s.hasHTML5) {\r
- _s._wD('SoundManager: No Flash detected'+(!_s.useHTML5Audio?', enabling HTML5.':'. Trying HTML5-only mode.'));\r
- _s.useHTML5Audio = true;\r
- // make sure we aren't preferring flash, either\r
- // TODO: preferFlash should not matter if flash is not installed. Currently, stuff breaks without the below tweak.\r
- _s.preferFlash = false;\r
- }\r
-\r
- _testHTML5();\r
- _s.html5.usingFlash = _featureCheck();\r
- _needsFlash = _s.html5.usingFlash;\r
- _showSupport();\r
-\r
- if (!_hasFlash && _needsFlash) {\r
- _s._wD('SoundManager: Fatal error: Flash is needed to play some required formats, but is not available.');\r
- // TODO: Fatal here vs. timeout approach, etc.\r
- // hack: fail sooner.\r
- _s.flashLoadTimeout = 1;\r
- }\r
-\r
- if (_doc.removeEventListener) {\r
- _doc.removeEventListener('DOMContentLoaded', _domContentLoaded, false);\r
- }\r
-\r
- _initMovie();\r
- return true;\r
-\r
- };\r
-\r
- _domContentLoadedIE = function() {\r
-\r
- if (_doc.readyState === 'complete') {\r
- _domContentLoaded();\r
- _doc.detachEvent('onreadystatechange', _domContentLoadedIE);\r
- }\r
-\r
- return true;\r
-\r
- };\r
-\r
- // sniff up-front\r
- _detectFlash();\r
-\r
- // focus and window load, init (primarily flash-driven)\r
- _event.add(_win, 'focus', _handleFocus);\r
- _event.add(_win, 'load', _handleFocus);\r
- _event.add(_win, 'load', _delayWaitForEI);\r
-\r
- if (_isSafari && _tryInitOnFocus) {\r
- // massive Safari 3.1 focus detection hack\r
- _event.add(_win, 'mousemove', _handleFocus);\r
- }\r
-\r
- if (_doc.addEventListener) {\r
-\r
- _doc.addEventListener('DOMContentLoaded', _domContentLoaded, false);\r
-\r
- } else if (_doc.attachEvent) {\r
-\r
- _doc.attachEvent('onreadystatechange', _domContentLoadedIE);\r
-\r
- } else {\r
-\r
- // no add/attachevent support - safe to assume no JS -> Flash either\r
- _debugTS('onload', false);\r
- _catchError({type:'NO_DOM2_EVENTS', fatal:true});\r
-\r
- }\r
-\r
- if (_doc.readyState === 'complete') {\r
- // DOMReady has already happened.\r
- setTimeout(_domContentLoaded,100);\r
- }\r
-\r
-} // SoundManager()\r
-\r
-// SM2_DEFER details: http://www.schillmania.com/projects/soundmanager2/doc/getstarted/#lazy-loading\r
-\r
-if (typeof SM2_DEFER === 'undefined' || !SM2_DEFER) {\r
- soundManager = new SoundManager();\r
-}\r
-\r
-/**\r
- * SoundManager public interfaces\r
- * ------------------------------\r
- */\r
-\r
-window.SoundManager = SoundManager; // constructor\r
-window.soundManager = soundManager; // public API, flash callbacks etc.\r
-\r
-}(window));
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (C) 2007-2011 Parisson
- * Copyright (c) 2011 Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
- *
- * This file is part of TimeSide.
- *
- * TimeSide is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * TimeSide is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with TimeSide. If not, see <http://www.gnu.org/licenses/>.
- *
- * Author: Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
- */
-
-/**
- * class fior managing markers in the player. This class extends TimesideArray (see timeside.js), and communicates with the other
- * two TimesideArrays of the player which receive edit events (click, keys events etcetera): the ruler (ruler.js) and the markermapdiv (divmarker.js)
- * All bindings between these three classes are set in in the player (See player.js , in particular loadMarkers method)
- */
-Timeside.classes.MarkerMap = Timeside.classes.TimesideArray.extend({
-
- init: function() {
- this._super();
- },
-
- pFloat: parseFloat, //reference to function parseFloat for faster lookup
- //overridden
- add: function(newMarker) {
- if(!('offset' in newMarker)){
- return -1;
- }
-
- if(typeof newMarker.offset != 'number'){ //check to be sure:
- newMarker.offset = this.pFloat(newMarker.offset);
- }
- if(!('id' in newMarker)){
- newMarker.id = this.$TU.uniqid(); //Timeside.utils.uniqid();
- }
- if(!('isEditable' in newMarker)){
- newMarker.isEditable = false;
- }
- var marker = newMarker;
- var idx = this.insertionIndex(marker);
- if(idx>=0){ //it exists? there is a problem....
- this.debug('markermap.add: adding an already existing marker!!'); //should not happen. however...
- return -1;
- }
-
- idx = -idx-1;
- //we do not call the super add cause we want to insert at a specified index
- this._super(marker,idx);
- //notifies controller.onMarkerMapAdd
-
- this.fire('add', {
- marker: marker,
- index: idx
- });
-
- return idx;
- },
-
- //overridden method. Contrarily to super method,
- //where the first argument is the index (integer), here the
- //the first argument can also be a marker. Its index will be found and, if valid, the super method will be called
- //RETURNS -1 IF SOMETHING HAS GONE WRONG, OTHERWISE THE
- remove: function(markerOrMarkerIndex) {
- var idx = -1;
- if(typeof markerOrMarkerIndex == 'number'){
- idx = markerOrMarkerIndex;
- }else if('id' in markerOrMarkerIndex && 'offset' in markerOrMarkerIndex){
- idx = this.insertionIndex(markerOrMarkerIndex);
- //idx>=0 ONLY if marker has been found
- }
- if(idx<0 || idx>=this.length){
- this.debug('markermap.remove: index out of bounds or marker not found');
- return -1;
- }
- var marker = this._super(idx);
- this.fire('remove',{
- 'index':idx,
- 'marker':marker
- });
- return idx;
- },
-
- //overridden method. Contrarily to super method,
- //where the first argument is the 'from' index, here the
- //the first argument can also be a marker
- move: function(markerOrMarkerIndex, newOffset){
- var oldIndex = -1;
- if(typeof markerOrMarkerIndex == 'number'){
- oldIndex = markerOrMarkerIndex;
- }else if('id' in markerOrMarkerIndex && 'offset' in markerOrMarkerIndex){
- oldIndex = this.insertionIndex(markerOrMarkerIndex);
- //oldIndex>=0 ONLY if marker has been found
- }
- if(oldIndex<0 || oldIndex>=this.length){
- this.debug('markermap.move: index out of bounds or marker not found');
- return -1;
- }
-
- var newIndex = this.insertionIndex(newOffset);
- //select the case:
- if(newIndex<0){ //newindex should ALWAYS be lower than zero, as insertionIndex(number) should not match any marker
- //we didn't move the marker on another marker (newOffset does not correspond to any marker)
- //just return the real insertionIndex
- newIndex = -newIndex-1;
- }
-
- //now: if the isnertionIndex is greater than the marker index (oldIndex),
- //we decrement newIndex cause super.move will first REMOVE the marker and then set it at newIndex
- if(newIndex > oldIndex){
- newIndex--;
- }
- newIndex = this._super(oldIndex,newIndex);
-
- if(newIndex <0){
- this.debug('markermap.move: new index out of bounds');
- return -1;
- }
-
- var markers = this.toArray();
- var marker = markers[newIndex];
- var oldOffset = marker.offset;
- marker.offset = newOffset;
- this.fire('move', {
- marker: marker,
- fromIndex: oldIndex,
- toIndex: newIndex,
- oldOffset: oldOffset
- });
- return newIndex;
- },
-
-
- //returns the insertion index of object in this sorted array by means of a binary search algorithm.
- // A) If object is a marker and:
- // a1) Is found (ie, there is a marker in this map
- // with same offset and same id), returns the index of the marker found, in the range [0, this.length-1]. Otherwise, if
- // a2) Is not found, then returns -(insertionIndex-1), where insertionIndex is the
- // index at which object would be inserted preserving the array order. Note that this assures that a
- // number lower than zero means that object is not present in the array, and viceversa
- // B) If object is a number or a string number (eg, "12.567"), then a marker with offset = object is built and compared
- // against the markers in the map. Note however that in this case that equality between marker's offset is sufficient,
- // as object is not provided with an id. THEREFORE, IF THE MAP CONTAINS SEVERAL MARKERS AT INDICES i, i+1, ... i+n
- // WITH SAME OFFSET == object, THERE IS NO WAY TO DETERMINE WHICH INDEX IN [i, i+1, ... i+n] WILL BE RETURNED.
- // See player.forward and player.rewind for an example of the B) case.
- //LAST NOTE: BE SURE object is either a number (float) or object.offset is a number (float).
- //In case it is not known, If it is a string number such as
- //"4.562" the comparison falis (eg, "2.567" > "10.544") but obviously, no error is thrown in javascript
- //
- insertionIndex: function(object){
- //default comparator function:
- //returns 1 as the first argument is greater than the second
- //returns -1 as the first argument is lower than the second
- //returns 0 if the arguments are equal
- var comparatorFunction = function(markerInMap,newMarker){
- var a = markerInMap.offset;
- var b = newMarker.offset;
- if(a<b){
- return -1;
- }else if(a >b){
- return 1;
- }else{
- var a1 = markerInMap.id;
- var b1 = newMarker.id;
- if(a1<b1){
- return -1;
- }else if(a1>b1){
- return 1;
- }
- }
- return 0;
- };
- if(!(typeof object == 'object')){
- var offset;
- if(typeof object == 'number'){
- offset = object;
- }else{ //to be sure...
- offset = parseFloat(object);
- }
- object = {
- 'offset':offset
- };
- //key will never be found, so return either 1 or -1:
- comparatorFunction = function(markerInMap,newMarker){
- var a = markerInMap.offset;
- var b = newMarker.offset;
- return a < b ? -1 : (a>b ? 1 : 0);
- };
- }
-
- var data = this.toArray();
- var low = 0;
- var high = data.length-1;
-
- while (low <= high) {
- var mid = (low + high) >>> 1;
- //biwise operation is not as fast as in compiled languages such as C and java (see Jslint web page)
- //However (tested on a PC in Chrome, IE and FF), it is faster than the equivalent:
- //var mid = parseInt((low + high)/2);
- //even if we reference parseInt before this loop and we call the variable assigned to it
- var midVal = data[mid];
- var cmp = comparatorFunction(midVal,object);
- if (cmp < 0){
- //the midvalue is lower than the searched index element
- low = mid + 1;
- }else if (cmp > 0){
- //the midvalue is greater than the searched index element
- high = mid - 1;
- }else{
- return mid; // key found
- }
- }
- return -(low + 1); // key not found
- },
-
- //sets isEditable to value
- setEditable: function(markerOrMarkerIndex, value) {
- var idx = -1;
- if(typeof markerOrMarkerIndex == 'number'){
- idx = markerOrMarkerIndex;
- }else if('id' in markerOrMarkerIndex && 'offset' in markerOrMarkerIndex){
- idx = this.insertionIndex(markerOrMarkerIndex);
- //idx>=0 ONLY if marker has been found
- }
- if(idx<0 || idx>=this.length){
- this.debug('markermap.setEditable: index out of bounds or marker not found');
- return -1;
- }
- var marker = this.toArray()[idx];
- var oldVal = marker.isEditable ? true : false;
- marker.isEditable = value;
- this.fire('markerEditStateChanged',{
- 'index':idx,
- 'marker':marker,
- 'oldValue':oldVal,
- 'value':value
- });
- return idx;
- }
-
-}
-);
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (C) 2007-2011 Parisson
- * Copyright (c) 2011 Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
- * Copyright (c) 2010 Olivier Guilyardi <olivier@samalyse.com>
- *
- * This file is part of TimeSide.
- *
- * TimeSide is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * TimeSide is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with TimeSide. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors: Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
- * Olivier Guilyardi <olivier@samalyse.com>
- */
-
-/**
- * The player class to instantiate a new player. Requires all necessary js (timeside, ruler, markermap etcetera...) and
- * jQuery
- */
-
-//playerDiv, sound, durationInMsec, visualizers, markerMap);
-Timeside.classes.Player = Timeside.classes.TimesideClass.extend({
-
- //sound duration is in milliseconds because the soundmanager has that unit,
- //player (according to timeside syntax) has durations in seconds
- // newMarkerCallback must be either a string or a function, the necessary checks is done in Timeside.load
- // (which calls this method)
- //if markersArray is not an array, it defaults to []
- init: function(configObject) {
- this._super();
- var $J = this.$J;
- var me=this;
-
- var msgs = configObject.messages;
- if(msgs){
- for(var k in msgs){
- if(msgs.hasOwnProperty(k)){
- var ms = msgs[k];
- if(typeof ms === 'string'){
- this.msgs[k] = ms;
- }
- }
- }
- }
-
- var onError = configObject.onError;
- if(typeof onError !== 'function'){
- onError = function(msg){};
- }
-
- var onReady = configObject.onReady;
- if(typeof onReady !== 'function'){
- onReady = function(player){};
- }
-
- var onReadyWithImage = configObject.onReadyWithImage;
-
- if(typeof onReadyWithImage === 'function'){
- var onReadyWithImageNamespace = 'imgRefreshed.temp_'+new Date().getTime(); //get an unique namespace
- this.bind(onReadyWithImageNamespace,function(data){
- onReadyWithImage(me);
- me.unbind(onReadyWithImageNamespace);
- });
- }
-
- var container = configObject.container;
- container = container instanceof $J ? container : $J(container);
- container = container.length ? container.eq(0) : undefined;
- if (!container || !container.length){
- onError('container not defined or invalid');
- return;
- }
-
- var sMan = soundManager;
- var sound = configObject.sound;
- var createSound = false;
- if(this.$TU.flashFailed){
- this.soundErrorMsg = 'soundManager error. If your browser does not support HTML5, Flash player (version '+sMan.flashVersion+'+) must be installed.\nIf flash is installed, try to:\n - Reload the page\n - Empty the cache (see browser preferences/options/tools) and reload the page\n - Restart the browser';
- }else{
- if(typeof sound !== 'string' && typeof sound !== 'object'){
- this.soundErrorMsg ='bad sound parameter: specify a a valid soundManager sound-object, an object with at least two properties, url and id, or URL as string';
- }else if(typeof sound === 'string'){
- createSound = true;
- var soundURL = sound;
- sound = {
- id: 'ts-sound',
- autoLoad: false,
- url: soundURL,
- multiShot: false
- };
- //do a raw check to see if it is a soundmanager object
- }else if(!sound.hasWonProperty('sID') || !sound.hasWonProperty('_iO') || !sound.hasWonProperty('url')){
- if(!sound.hasWonProperty('url') || !sound.hasWonProperty('id')){ //it is not a soundManager object, has at least an url???
- this.soundErrorMsg = 'bad sound parameter: object requires properties url and id at minimum';
- }else{
- createSound = true;
- }
- }
- if(createSound){
- var soundOptions = sound;
- if(sMan.canPlayURL(soundOptions.url)){ //this actually checks only if the url is well formed, not if the file is there
- //check if we specified a valid sound duration, otherwise the sound must be loaded
-
- sound = sMan.createSound(soundOptions);
- }else{
- this.soundErrorMsg = 'bad sound parameter (soundManager.canPlayURL returned false)';
- }
- }
- }
- if(this.soundErrorMsg){
- this.getSound = function(){
- return undefined;
- };
- }else{
- // sound.play = function(){
- // alert(this.readyState);
- // };
- this.getSound = function(){
- return sound;
- };
- }
- var soundDurationInMsec = configObject.soundDuration;
- if(typeof soundDurationInMsec !== 'number' || soundDurationInMsec<=0){
- onError('invalid soundDurationInMsec: NaN or not positive');
- return;
- }
-
-
- var soundImgFcn = configObject.soundImage;
-
- if(!(typeof soundImgFcn === 'string' || typeof soundImgFcn === 'function')){
- onError('invalid sound soundImgFcn. Provide a callback(width,height) or a string denoting a valid URL');
- return;
- }else{
- if(typeof soundImgFcn === 'string'){
- var url = soundImgFcn;
- this.imageCallback = new function(w,h){
- return url;
- };
- }else{ //surely a function
- this.imageCallback = soundImgFcn;
- }
- }
-
- var soundImgSize = configObject.imageSize;
- var markersArray = configObject.markersArray;
- var newMarker = configObject.newMarker;
-
-
-
- this.playState = 0; //0: not playing, 1: loading, 2:buffering, 3 playing (sound heard)
- //container is the div #player
-
- this.getContainer = function(){
- return container;
- };
-
-
-
- var sd = this.toSec(soundDurationInMsec);
- this.getSoundDuration = function(){
- return sd;
- };
-
- this.soundPosition = sound.position ? this.toSec(sound.position) : 0;
-
-
-
- //
-
- //initializing markermap and markerui
- var map = new Timeside.classes.MarkerMap();
- this.getMarkerMap = function(){
- return map;
- };
-
- var canAddMarkers = false;
- if(newMarker === true || (typeof newMarker === 'function')){
- canAddMarkers = true;
- if(typeof newMarker === 'function'){
- this.newMarker = newMarker;
- }
- }
-
- //build the innerHTML as array, then join it. This is usually faster than string concatenation in some browsers.
- //Note that the player image (see below) is not created now, however, if it was, it should be given a src
- //as NOT specifying any src for image tags can be harmful,
- //see http://www.nczonline.net/blog/2009/11/30/empty-image-src-can-destroy-your-site/ and
- //http://geekswithblogs.net/bcaraway/archive/2007/08/24/114945.aspx for details
- var html = [
- "<div class='ts-ruler'></div>",
- "<div class='ts-wave'>",
- "<div class='ts-image-canvas'></div>",
- "<div class='ts-image-container'>",
- //lazily created: "<img class='ts-image' src='xyz.png' alt='' />", //not providing a src attribute is harmful. Dummy src attribute
- "</div>",
- "</div>",
- "<div class='ts-control'>",
- "<a class='ts-play ts-button'></a>",
- "<a class='ts-pause ts-button'></a>",
- "<a class='ts-rewind ts-button'></a>",
- "<a class='ts-forward ts-button'></a>",
- "<a class='ts-set-marker ts-button'></a>",
- "<a class='ts-volume-speaker ts-button'></a>",
- "<div class='ts-volume-wrapper-div'>",
- "<a class='ts-volume-bar-container'>",
- "<span class='ts-volume-bar'></span>",
- "</a>",
- "</div>",
- "<div class='ts-wait'></div>",
- "</div>"];
-
- container.html(html.join(''));
-
- var control = container.find('.ts-control');
-
- //bind events to buttons:
- var rewind = control.find('.ts-rewind');
- rewind.attr('href', '#').click(function(e){
- me.rewind.apply(me);
- return false;
- });
-
- var forward = control.find('.ts-forward');
- forward.attr('href', '#').click(function(e){
- me.forward.apply(me);
- return false;
- });
-
- var pause = control.find('.ts-pause');
- pause.attr('href', '#').bind('click', function(){
- me.pause.apply(me);
- return false;
- });
-
- var play = control.find('.ts-play');
- play.attr('href', '#').bind('click', function(){
- me.play.apply(me);
- return false;
- });
-
- var setMarkerButton = control.find('.ts-set-marker');
-
- if(canAddMarkers){
- setMarkerButton.show().attr('href','#').unbind('click').bind('click', function(){
- me.addMarker(me.soundPosition);
- return false;
- });
- }else{
- setMarkerButton.hide().unbind('click');
- }
-
-
- //volume:
- var volumeSpeaker = control.find('.ts-volume-speaker');
- var volumeBarContainer = control.find('.ts-volume-bar-container');
- var volumeBar = volumeBarContainer.find('.ts-volume-bar');
-
- var getVol = function(x){
- var vol = 100*x/volumeBarContainer.width();
- //allow click to easily set to zero or 100, ie set a margin to 5%:
- var margin = 5;
- if (vol < margin){
- vol=0;
- }else if(vol >100-margin){
- vol = 100;
- }
- return vol;
- };
- function setVolume(event,volumeElement){
- var x = event.pageX - volumeElement.offset().left; //using absolute coordinates allows us to
- //avoid using layerX (not supported in all browsers) and clientX (which needs the window scrollLeft variable)
- me.setSoundVolume(getVol(x));
- return false;
- }
- volumeBarContainer.attr('href', '#').click(function(event){
- return setVolume(event,volumeBar);
- });
- volumeSpeaker.attr('href', '#').click(function(){
- me.setSoundVolume(me.getSoundVolume()>0 ? 0 : getVol(volumeBar.outerWidth()));
- return false;
- });
- this.setSoundVolume(this.getSoundVolume());
-
- control.find('a').attr('href', '#') ;
-
- //SET NECESSARY CSS (THIS WILL OVERRIDE CSS SET IN STYLESHEETS):
- //var viewer = container.find('.ts-viewer');
- var wave = container.find('.ts-wave');
- var ruler_ = container.find('.ts-ruler');
- wave.add(control).add(ruler_).css({
- 'position':'relative',
- 'overflow':'hidden'
- });
- //assigning display and title to all anchors
- var subcontrolsToBeSetVisible = control.find('*');
- if(!canAddMarkers){
- subcontrolsToBeSetVisible = subcontrolsToBeSetVisible.filter(':not(a.ts-set-marker)');
- }
- subcontrolsToBeSetVisible.css({
- 'display':'inline-block',
- 'overflow':'hidden'
- });
-
- var waitImg = control.find('.ts-wait');
- waitImg.html('wait').css({
- 'position':'absolute'
- });
-
- var div = control.find('.ts-volume-wrapper-div');
- div.css({
- 'position':'absolute',
- 'left':(volumeSpeaker.position().left+volumeSpeaker.outerWidth(true))+'px',
- 'top':0,
- 'width':'auto',
- 'height':'100%'
- });
- //END NECESSARY CSS
-
- //creating the ruler
- var waveImage = container.find('.ts-image-canvas');
- var ruler = new Timeside.classes.Ruler(ruler_, waveImage, this.getSoundDuration());
- //var ruler = new Timeside.classes.Ruler(viewer, this.getSoundDuration());
- this.getRuler = function(){
- return ruler;
- };
- //bind mouse events:
- ruler.bind('rulermarkermouseevent', function(data){
- var idx = data.index;
- data.marker = idx > -1 ? me.getMarker(idx) : undefined;
- me.fire('markerMouseEvent',data);
- });
-
- //setting image size (if provided) and resize player. Note that _setImageSize (with underscore) is intended to be
- //a private method (faster). setImageSize (without underscore) is the public method to use outside of player object
- if(soundImgSize){
- this._setImageSize(soundImgSize.width,soundImgSize.height,container, wave,true); //calls this.resize which calls ruler.resize
- }else{
- this._setImageSize('','',container, wave,true); //calls this.resize which calls ruler.resize
- }
-
- //binds click for the pointer:
- var v = wave; //.add(ruler);
- v.unbind('click').click(function(evt){
- var w = v.width();
- var x = evt.pageX - v.offset().left; //using absolute coordinates allows us to
- //avoid checking whether or not we are clicking on a vertical marker line, on a subdiv etcetera
- var sd = me.getSoundDuration();
- me.setSoundPosition(sd*x/w);
- });
-
-
-
- //finally, load markers and bind events for markers (see method below):
- //NOTE: loadMarkers ASYNCHRONOUSLY CALLS THE SERVER, SO METHODS WRITTEN AFTER IT MIGHT BE EXECUTED BEFORE
- //loadMarkers has finished its job
- //this.loadMarkers(callback);
- if(!(markersArray) || !(markersArray.length)){
- markersArray = [];
- }
- this.loadMarkers(markersArray);
-
-
- //IE7 BUG: the divs wave and control do not shift downwards after canvas is drawn and covers part of the rulrer.
- //Weird enough (with IE it isn't actually), we have just to set the property we already set in the css:
- //ie, top: auto. This is however useful even if somebody specified a top property on the divs
- ruler_.add(wave).add(control).css('top','auto');
- onReady(this);
- },
-
-
-
- //functions for converting seconds (player unit) to milliseconds (sound manager unit) and viceversa:
- toSec: function(milliseconds){
- return milliseconds/1000;
- },
- toMsec : function(seconds){ //this function has less performances than toSec, as it calls Math.round
- return Math.round(1000*seconds); //however, it is assumed that it is NOT called in loops
- },
- isPlaying : function(){
- var sound = this.getSound();
- if(!sound){
- return false;
- }
- return this.playState;
- /*Numeric value indicating the current playing state of the sound.
- * 0 = stopped/uninitialised
- * 1 = playing or buffering sound (play has been called, waiting for data etc.)
- *Note that a 1 may not always guarantee that sound is being heard, given buffering and autoPlay status.*/
- //return sound && sound.playState==1;
- },
- setSoundPosition: function(newPositionInSeconds){
- //if the player is playing and NOT yet fully loaded, simply calling:
- //this.getSound().setPosition(this.toMsec(newPositionInSeconds));
- //resets the position to zero. So we use this workaround:
- // this.getSound().stop(); //calling this.pause() hides the waiting bar, which is not the case here
- // this.soundPosition = newPositionInSeconds;
- // this.play();
- //however, that causes fast pointer move effect is undesiderable
- //So:
- var wasPlaying = this.isPlaying();
- if(wasPlaying){
- this.getSound().stop(); //dont call this.pause cause it hides the waitbar, if visible and resets the playState
- }
- //update pointer position. If this call is due to a pointer move (mouse release),
- //ruler.isPointerMovingFromMouse=true and the following code has no effect (the pointer is already at the good position)
- var ruler = this.getRuler();
- if(ruler){
- ruler.movePointer(newPositionInSeconds);
- }
- //set sound position:
- var oldSoundPosition = this.soundPosition;
- this.soundPosition = newPositionInSeconds;
-
- //resume playing if it was playing:
- if(wasPlaying){
- var player = this;
-
- //delay a little bit the play resume, this might avoid fast pointer repositioning
- //(it should not be the case, but it happens. why??)
- setTimeout(function(){
- player.play.apply(player);
- },100);
- }
- this.fire('soundPositionSet',{
- player:this,
- oldSoundPosition:oldSoundPosition
- });
-
- },
- showSoundErroMessage: function(){
- alert(this.soundErrorMsg);
- },
- //given a marker at index I, specifies that a marker corss event is fired whenever the sound position (pointer)
- //is in the interval ]markerCrossedOffsetMargin-I,I+markerCrossedOffsetMargin[
- //the value is in seconds
- //markerCrossedOffsetMargin : 0.5,
- play : function(){
-
- if(this.soundErrorMsg){
- alert(this.soundErrorMsg);
- return false;
- }
-
- var player = this;
- var sound = player.getSound();
-
- if(!player || !sound){ //just check. The cases here (especially, sound = undefined, should be
- //together with this.soundErrorMsg != "", so we should have catch the case above
- return false;
- }
-
-
- var fireOnMarkerPosition = function(seconds){}; //does nothing by default
- var map = player.getMarkerMap();
- var markerCrossListeners = player.listenersMap['markerCrossed'];
- //optimizing: if no listeners associated to markerCrossListeners, avoid creating a function
- if(map && map.length && markerCrossListeners){
- var idx = 0;
- if(player.soundPosition>0){
- idx = map.insertionIndex(player.soundPosition);
- if(idx<0){
- idx=-idx-1;
- }
- }
- var len = map.length;
- if(idx>-1 && idx < len){
- var markers = map.toArray();
- var marker = markers[idx];
- var margin = 0.5; //1 second (0.5*2) of margin (before+after)
- var offs = marker.offset;
- var intervalUpperBound = offs+margin;
- var intervalLowerBound = offs-margin;
- var data = { //if you change data, change it also below
- index:idx,
- marker:marker,
- currentSoundPosition: player.soundPosition,
- nextMarkerTimeInterval: undefined
- };
- fireOnMarkerPosition = function(seconds){
- if(marker){
- if(seconds>intervalLowerBound && seconds < intervalUpperBound){
- idx++;
- marker = idx < len ? markers[idx] : undefined;
- offs = marker ? marker.offset : undefined;
- data.currentSoundPosition = seconds;
- data.nextMarkerTimeInterval = marker ? [offs-margin, offs+margin] : undefined;
- player.fire('markerCrossed',data);
-
- if(idx<len){
- intervalUpperBound = offs+margin;
- intervalLowerBound = offs-margin;
- data.index = idx;
- data.marker = marker;
- }
- }
- }
- };
- }
- }
-
- var toSec = player.toSec;
- var ruler = player.getRuler();
- var sPosInMsec = player.toMsec(player.soundPosition);
- var bufferingString = this.msgs.buffering;
- var loadingString = this.msgs.loading;
-
- var updateWaitBar = this.setWait;
- //building immediately data events to be passed instead of bulding them in the loop whileplaying
- var loadData = {
- player:this,
- oldPlayState:0,
- endOfPlayback:false
- };
- var bufferData = {
- player:this,
- oldPlayState:0,
- endOfPlayback:false
- };
- var playData = {
- player:this,
- oldPlayState:0,
- endOfPlayback:false
- };
- var endData = {
- player:this,
- oldPlayState:0,
- endOfPlayback:true
- };
- //done
- var playState = this.playState;
- if(!playState){
- if(loadingString){
- updateWaitBar.apply(this,[loadingString]); //calling setWait of an empty string hides the wait, we dont want it here
- //ps: without apply this in updateWait is the dom window
- }
- loadData.oldPlayState = playState;
- playState = this.playState = 1;
- this.fire('playStateChanged',loadData);
- }
-
- var playOptions = {
-
- position: sPosInMsec,
- whileplaying: function(){
-
- var sPos = this.position;
- var buffering = this.isBuffering || typeof sPos != 'number' || sPos < sPosInMsec;
-
- //var buffering = this.isBuffering; //this refers to the soundmanager sound obj
- //Now, what are we doing here below? we could simply check whether is buffering or not..
- //Unfortunately, when buffering some playState (isBuffering = false) are also fired, randomly
- //ONCE in a while
- //the result is a blinking 'isBuffering' 'isPlaying' state in the wait element displaying the state (not so nice),
- //which is also costly in terms of computation. So, we wait for at least N playstate fired SUBSEQUENTLY, without
- //NO bufferingState fired between them. N is set to minimumNumberOfSubsequentPlayCall. When this happens, we can start moving the
- //pointer as a result of a real play state, and we avoid blinking of the wait element
- switch(buffering){
- case true:
- switch(playState){
- case 2: //do nothing (wait element already displaying)
- break;
- default: //update the wait element showing it:
- bufferData.oldPlayState = playState;
- player.playState = playState = 2;
- player.fire('playStateChanged',bufferData);
- if(bufferingString){
- updateWaitBar.apply(player,[bufferingString]);
- }
- }
- break;
- default:
- switch(playState){
- case 0:
- case 1:
- case 2:
- playData.oldPlayState = playState;
- //currentState = isPlayingId; //set state for future subsequent calls of this case
- player.playState = playState = 3;
- player.fire('playStateChanged',playData);
- //update waitbar
- updateWaitBar.apply(player,[player.isImgRefreshing ? player.msgs.imgRefreshing : '']);
- default: //move pointer
- var sPosInSec = toSec(sPos);
- player.soundPosition = sPosInSec;
- ruler.movePointer(sPosInSec);
- }
- fireOnMarkerPosition(sPosInSec);
- }
-
- },
- onfinish: function() {
-
- //whileplaying is NOT called onsinfish. We must update the pointer:
- //note that for small length sounds (wg, 5 secs) the pointer shifts abruptly from the last
- //whileplaying position to the end. We tried with a setTimeout function but the visual effect is not
- //removed. So we leave this small 'bug'
- endData.oldPlayState = playState;
- player.playState = playState = 0;
- player.fire('playStateChanged',endData);
- ruler.movePointer(player.getSoundDuration());
- updateWaitBar.apply(player,[player.isImgRefreshing ? player.msgs.imgRefreshing : '']);
- //player.fire('endReached');
- }
- };
- //attach onload event only if the sound is NOT already loaded:
- // /*sound.readyState
- // * Numeric value indicating a sound's current load status
- // * 0 = uninitialised
- // * 1 = loading
- // * 2 = failed/error
- // * 3 = loaded/success
- // */
- if(sound.readyState !== 3){
- playOptions.onload = function(success){
- if(!success){
- this.stop();
- player.playState = 0;
- player.setWait(player.isImgRefreshing ? player.msgs.imgRefreshing : '');
- player.soundErrorMsg = 'Error while loading sound: check sound url';
- player.showSoundErroMessage();
- }
- };
- }
- //if the pointer is already at the end of sound, soundmanager does not fire onfinish but starts buffering
- //forever. Therefore, we must check this case here.
- //We use a margin of time of 20 milliseconds (.2 seconds) to indicate that inside this margin the sound is at its end
- if(this.soundPosition + 0.2 >= this.getSoundDuration()){
- playOptions.onfinish();
- }else{
- sound.setVolume(sound.volume); //workaround. Just to be sure. Sometimes it fails when we re-play
- sound.play(playOptions);
- // soundManager.play(sound.sId,{
- // onload: function(success){
- // alert(success);
- // }
- // });
- }
-
- return false;
- },
-
- msgs : {
- loading : 'loading',
- buffering: 'buffering',
- imgRefreshing : 'refreshing img'
- },
- pause: function(){
- var sound = this.getSound();
- //we don't check if it's playing, as the stop must really stop anyway
- //if(sound && this.isPlaying()){
- if(sound){
- var v = this.isPlaying();
- sound.stop();
- var data = {
- player:this,
- oldPlayState:this.playState,
- endOfPlayback:false
- };
- this.playState = 0;
- this.fire('playStateChanged',data);
- this.setWait(this.isImgRefreshing ? this.msgs.imgRefreshing : '');
- }
- return false;
- },
-
- getWaitElement: function(){
- return this.getContainer().find('.ts-control').find('.ts-wait');
- },
-
- setWait: function(msg){
- var wait = undefined;
-
- wait = this.getWaitElement();
- if(!wait || msg === undefined){
- return;
- }
- if(wait.html()!=msg){
- wait.html(msg);
- }
-
- var visible = wait.css('display') != 'none';
-
- if(msg && !visible){
- wait.show();
- this.fire('waitShown');
- }else if(!msg && visible){
- wait.hide();
- this.fire('waitHidden');
- }
- },
-
- /**
- * sets whether or not window resize resizes also this player. When true, a variable _dynamicResize =setInterval(...) is attached to
- * this class. When false, if _dynamicResize is in this class, clearInterval(_dynamicResize) is called and then the key is deleted
- */
- setDynamicResize: function(value){
- var key = '_dynamicResize';
- if(!value && key in this){
- clearInterval(this[key]);
- delete this[key];
- return;
- }
- var wdw = this.$J(window);
- var w = wdw.width();
- //var h = wdw.height();
- var me = this;
- this.dynamicResize = setInterval(function(){
- var newW = wdw.width();
- if(w!=newW){
- w = newW;
- //still wait a second: are we still adjusting the window? (call resize just once):
- setTimeout(function(){
- if(wdw.width()==newW){
- me.resize.apply(me);
- }
- },200);
- }
- },100);
- },
-
- resize: function() {
- var height;
- var container = this.getContainer();
-
- var wave = container.find('.ts-wave');
-
- height = wave.height();
- // if(!height){
- // height = this.minWaveHeight;
- // wave.css('height',height+'px');
- // }
- //if (height) {
- //set image, imagecontainer and canvas (container on imagecontainer for lines and pointer triangles) css
- var elements = wave.find('.ts-image-container').css('zIndex','0')
- .add(wave.find('.ts-image-canvas').css('zIndex','1')); //the two children of ts-wave. Set also the zIndex
- //in order to visualize the canvas OVER the wav image
- var style = {
- width: wave.width(),
- height: height,
- border: 0,
- padding:0,
- margin:0,
- top:0,
- left:0
- };
- elements.css(style);
- elements.css('position','absolute');
- //}
-
- //refreshing images:
- this.refreshImage();
- this.getRuler().resize();
- },
- getImageUrl : function(){
- var image = this.getContainer().find('.ts-image');
- if(image && image.length){
- return image.attr('src');
- }
- return '';
- },
- refreshImage: function(){
- var container = this.getContainer();
- var imageC = container.find('.ts-image-container');
- var image = imageC.find('.ts-image');
-
-
- var size = this.getImageSize();
-
- if(!size.width || !size.height){
- return;
- }
- var imgSrc = this.imageCallback(size.width,size.height);
- var imageNotYetCreated = image.length == 0;
- if(!imageNotYetCreated && image.attr('src')==imgSrc){
- return;
- }
-
- var player= this;
-
- if(imageNotYetCreated){
- image = this.$J('<img/>');
- }
-
- //image inside ts-image-container:
- image.css({
- 'width':'100%',
- 'height':'100%'
- }); // for IE7. Does not seem to hurt IE8, FF, Chrome
-
- var updateWait = function(){};
- var ir = player.msgs.imgRefreshing;
- var we = player.getWaitElement();
- if(ir && we){
- updateWait = function(){
- if(!player.playState || player.playState==3){
- player.setWait('');
- }
- }
- }
- image.load(function(){
- image.unbind('load');
- if(imageNotYetCreated){
- imageC.append(image.addClass('ts-image'));
- }
- updateWait();
- player.isImgRefreshing = false;
- player.fire('imgRefreshed');
- });
- if(ir && we && (!this.playState || this.playState===3)){ //if loading (1) or buffering (2) do not update wait.
- //If not playing (undefined or 0) playing (3) update wait
- this.setWait(ir);
- }
- this.isImgRefreshing = true;
- this.fire('imgRefreshing');
- image.attr('src', imgSrc);
-
- },
- getImageSize: function(){
- var wave = this.getContainer().find('.ts-wave');
- return {
- width: wave.width(),
- height:wave.height()
- }
- },
-
- setImageSize: function(width,height){
- var container = this.getContainer();
- var wave = container.find('.ts-wave');
- this._setImageSize(width,height,container, wave,true);
- },
- //this is intended to be a private method, use setImageSize from outside the player object)
- _setImageSize: function(width,height,jQueryContainerElement, jQueryWaveElement, resize){
- if(width || height){
- var re = /(?:px|ex|em|%)$/;
- if(width){
- width+='';
- width = re.exec(width) ? width : width+'px';
- jQueryContainerElement.css('width',width);
- }
- if(height){
- height+='';
- height = re.exec(height) ? height : height+'px';
- jQueryWaveElement.css('height',height);
- }
- }
- if(resize){
- this.resize();
- }
- },
-
- getSoundVolume :function(){
- var s = this.getSound();
- return s ? s.volume : 0;
- },
- //moves the pointer (and sound position) forward till the next marker or the end of sound
- forward: function() {
- var map = this.getMarkerMap();
- var markers = map.toArray();
- var len = markers.length;
- var offset = this.getSoundDuration();
- var position = this.soundPosition; //parseFloat(this.getSoundPosition());
- var idx = map.insertionIndex(position);
- if(idx<0){
- idx = -idx-1; //cursor is not on a a marker, get the insertion index
- }else{
- //cursor is on a marker. As there might be several markers with the same offset
- //(see MarkerMap.insertionIndex), move to the outmost right
- while(idx<len && markers[idx].offset == position){
- idx++;
- }
- }
-
- if(idx< len){
- offset = markers[idx].offset;
- }
- this.setSoundPosition(offset);
- return false;
- },
- //moves the pointer (and sound position) backward till the previous marker or the start of sound
- rewind: function() {
- var map = this.getMarkerMap();
- var markers = map.toArray();
- var offset = 0;
- var position = this.soundPosition; //parseFloat(this.getSoundPosition());
- var idx = map.insertionIndex(position);
- if(idx<0){
- idx = -idx-1; //cursor is not on a a marker, get the insertion index
- }else{
- //cursor is on a marker. As there might be several markers with the same offset
- //(see MarkerMap.insertionIndex), move to the outmost left
- while(idx>0 && markers[idx-1].offset == position){
- idx--;
- }
- }
- idx--; //move backward (rewind)
- if(idx>=0){
- offset = markers[idx].offset;
- }
- this.setSoundPosition(offset);
- return false;
- },
-
- setSoundVolume: function(volume){
- if(typeof volume != 'number'){ //note: typeof for primitive values, instanceof for the rest
- //see topic http://stackoverflow.com/questions/472418/why-is-4-not-an-instance-of-number
- volume = 100;
- }
- if(volume<0){
- volume = 0;
- }else if(volume>100){
- volume = 100;
- }
- volume = Math.round(volume);
- var sound = this.getSound();
- if(sound){
- sound.setVolume(volume);
- }
- var control = this.getContainer().find('.ts-control');
- var volumeSpeaker = control.find('.ts-volume-speaker');
- var volumeBarContainer = control.find('.ts-volume-bar-container');
- var volumeBar = volumeBarContainer.find('.ts-volume-bar');
- if(volume==0){
- volumeSpeaker.removeClass('ts-volume-speaker-on').addClass('ts-volume-speaker-off');
- volumeBar.css('visibility','hidden');
- }else{
- volumeSpeaker.removeClass('ts-volume-speaker-off').addClass('ts-volume-speaker-on');
- volumeBar.css('visibility','visible');
- volumeBar.css({
- 'height':'100%',
- 'width':volume+'%'
- });
- }
- },
-
- each: function(){
- var map = this.getMarkerMap();
- if(map){
- map.each.apply(map,arguments);
- }
- },
-
- newMarker: function(offset){
- return {
- offset:offset
- };
- },
- addMarker: function(offset){
- var map = this.getMarkerMap();
- if(map){
- map.add(this.newMarker(offset));
- }
- },
-
- removeMarker: function(identifier){ //identifier can be an number (marker index) or a marker (the index will be aearched)
- //see marlermap.remove
- var map = this.getMarkerMap();
- if(map){
- map.remove(identifier);
- }
- },
-
- moveMarker: function(identifier, newOffset){ //identifier can be an number (marker index) or a marker (the index will be aearched)
- var map = this.getMarkerMap();
- if(map){
- map.move(identifier,newOffset);
- }
- },
-
- getMarker: function(index){
- var map = this.getMarkerMap();
- if(map){
- return map.toArray()[index];
- }
- return undefined;
- },
-
- setMarkerEditable: function(identifier, value){
- var map = this.getMarkerMap();
- if(map){
- return map.setEditable(identifier,value);
- }
- return undefined;
- },
-
- //markers is an array of objects with at least the field offset:sconds.milliseconds
- loadMarkers: function(markers){
- //ruler.bind('markermoved',this.markerMoved,this);
- //var $J = this.$J; //reference to jQuery
-
- var player = this;
- //initialize the map.
- var map = this.getMarkerMap();
- //var mapUI = this.getMarkersUI();
- var ruler = this.getRuler();
-
- //TODO: think about if clearing or not: we assign some bindings in the constructor, too:
- // map.clear();
- // ruler.clear();
-
- var rulerAdd = ruler.add;
-
- if(markers){
- //add markers to the map. No listeners associated to it (for the moment)
- for(var i =0; i< markers.length; i++){
- map.add.apply(map,[markers[i]]);
- }
- //add markers to ruler and div
- map.each(function(i,marker){
- //isEditable and id are added if not present
- rulerAdd.apply(ruler,[marker.offset, i, marker.isEditable]);
- });
- }
-
- //the function above calls map.add:
- //add bindings when adding a marker:
- map.bind('add',function(data){
- //mapuiAdd.apply(mapUI,[data.marker, data.index,data.isNew]);
- rulerAdd.apply(ruler,[data.marker.offset, data.index,data.marker.isEditable]);
- player.fire('markerAdded',data);
- });
-
- //2) MOVE
-
- //add the binding when we move a marker on the ruler:
- ruler.bind('markermoved',function(data){
- var soundPos = data.soundPosition;
- var isPointer = data.isPointer;
- if(isPointer){
- player.setSoundPosition(soundPos);
- }else{
- map.move(data.markerElement.getIndex(), soundPos);
- }
- });
-
- //and now add a binding to the map when we move a marker:
-
- map.bind('move', function(data){
- var from = data.fromIndex;
- var to = data.toIndex;
- ruler.move.apply(ruler,[from,to,data.marker.offset]);
- player.fire('markerMoved',data);
- });
-
- //remove
- map.bind('remove',function(data){
- ruler.remove.apply(ruler, [data.index]);
- player.fire('markerRemoved',data);
- });
-
- //edit state changed
- map.bind('markerEditStateChanged',function(data){
- ruler.setEditable.apply(ruler, [data.index, data.value]);
- player.fire('markerEditStateChanged',data);
- });
- }
-});
+++ /dev/null
-/*
- * Copyright (C) 2007-2011 Parisson
- * Copyright (c) 2011 Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
- * Copyright (c) 2010 Olivier Guilyardi <olivier@samalyse.com>
- *
- * This file is part of TimeSide.
- *
- * TimeSide is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * TimeSide is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with TimeSide. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors: Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
- * Olivier Guilyardi <olivier@samalyse.com>
- */
-
-/**
- * Class representing the ruler (upper part) of the player. Requires jQuery
- * and Raphael
- */
-Timeside.classes.Ruler = Timeside.classes.TimesideArray.extend({
- //init constructor: soundDuration is IN SECONDS!!! (float)
- init: function(rulerContainer, waveContainer, soundDuration){
- this._super();
-
- this.getSoundDuration= function(){
- return soundDuration;
- };
-
- this.getWaveContainer =function(){
- return waveContainer;
- };
-
- this.getContainerWidth =function(){
- return waveContainer.width();
- };
-
- this.getRulerContainer = function(){
- return rulerContainer;
- }
- },
-
- resize : function(){
- var duration = this.getSoundDuration(); //in seconds
- if (!duration) {
- this.debug("ruler.resize: Can't draw ruler with a duration of 0");
- return;
- }
-
- var $J = this.$J;
- var rulerContainer = this.getRulerContainer();
-
- //remove all elements not pointer or marker
- rulerContainer.find(':not(a.ts-pointer,a.ts-marker,a.ts-pointer>*,a.ts-marker>*)').remove();
-
- //calculate h with an artifice: create a span (that will be reused later) with the "standard" label
- var firstSpan = $J('<span/>').css({
- 'display':'block',
- 'position':'absolute'
- }).html('00000'); //typical timelabel should be '00:00', with '00000' we assure a bit of extra safety space
- //note also that display and position must be set as below to calculate the proper outerHeight
- rulerContainer.append(firstSpan); //to calculate height, element must be in the document, append it
- var verticalMargin = 1;
- var h = 2*(verticalMargin+firstSpan.outerHeight());
- //h is the default height of the ruler svg (according to ruler font size)
- //to accomodate the necessary space for the labels
- //however, if we set a custom height on the ruler, ie h2 is nonzero:
- var h2 = rulerContainer.height();
- //then, set the custom height as height for the canvas:
- //note that, as markers and pointer have position: absolute, they do not affect div height
- if(h2){
- h = h2;
- }
- var obj = this.calculateRulerElements(rulerContainer.width(),h,firstSpan.outerWidth());
- this.drawRuler(rulerContainer,h,obj.path);
-
- var labels = obj.labels;
- if(labels && labels.length){
- for(var i=0; i <labels.length;i++){
- var span = (i==0 ? firstSpan : $J('<span/>'));
- span.html(labels[i][0]).css({
- 'display':'block',
- 'position':'absolute',
- 'width':'',
- 'height':'',
- 'right':'',
- 'bottom':'',
- 'top':'0',
- 'left':labels[i][1]+'px'
- });
- rulerContainer.append(span);
- }
- }else{
- firstSpan.html(this.makeTimeLabel(0));
- }
-
- var pointer = undefined;
- if('getPointer' in this){
- pointer = this.getPointer();
- }
- if(!pointer){
- pointer = this.add(0,-1);
- this.getPointer = function(){
- return pointer;
- };
- }else{
- pointer.refreshPosition();
-
- }
- this.each(function(i,rulermarker){
- rulermarker.refreshPosition();
- });
-
-
- },
-
- drawRuler: function(rulerContainer,h,rulerLinesPath){
- var cssPref = this.cssPrefix;
- var upperRectClass = cssPref + 'svg-' + 'ruler-upper-rect';
- var rulerLinesClass = cssPref + 'svg-' + 'ruler-lines';
-
- var vml = this.$TU.vml;
- if(vml){
- //we create each time a new Raphael object. This is not a big performance issue
- var paper = Raphael(rulerContainer[0], rulerContainer.width(), h);
- var rect = paper.rect(0,0, rulerContainer.width(), h/2);
- var path = paper.path(rulerLinesPath);
- var attr = vml.getVmlAttr;
- rect.attr(attr(upperRectClass));
- path.attr(attr(rulerLinesClass));
- return;
- }
- //create svg. Note that elements must be created within a namespace (createElementNS)
- //and attributes must be set via .setAttributeNS(null,name,value)
- //in other words, jQuery does not work (maybe in future releases)
- var $J = this.$J;
- var svgNS = "http://www.w3.org/2000/svg";
- var d = document;
- var svg = d.createElementNS(svgNS, "svg:svg");
- svg.setAttributeNS( null, "width", rulerContainer.width()); //TODO: optimize width is called also below
- svg.setAttributeNS( null, "height", h);
- rulerContainer.append($J(svg));
-
- var rect = d.createElementNS(svgNS, "svg:rect");
- rect.setAttributeNS( null, "x", 0);
- rect.setAttributeNS( null, "y", 0);
- rect.setAttributeNS( null, "width", rulerContainer.width());
- rect.setAttributeNS( null, "height", (h/2));
- rect.setAttributeNS( null, "class", upperRectClass);
- svg.appendChild(rect);
- var lines = d.createElementNS(svgNS, "svg:path");
- lines.setAttributeNS( null, "d", rulerLinesPath);
- lines.setAttributeNS( null, "class", rulerLinesClass);
- svg.appendChild(lines);
- },
- /**
- * returns an object with the following properties:
- * path: (string) the path of the ruler to be drawn
- * labels (array) an array of arrays ['text',x,y]
- */
- calculateRulerElements: function(w,h,timeLabelWidth){
-
- var duration = this.getSoundDuration();
-
- var fontLeftMargin = 2; //should be eual or greater to the ruler stroke width, so that
- //the labels are not overlapping the vertical ruler lines
- timeLabelWidth+=fontLeftMargin;
-
- var timeLabelDuration = timeLabelWidth*duration/w;
-
- //determine the ticks:
- var sectionDurations = [1,2,5,10,30,60,120,300,1800,3600,7200,18000,36000];
- //sectionDurations in seconds. Note that 60=1 minute, 3600=1 hour (so the maximum sectionDuration is 36000=10hours)
- var i=0;
- var len = sectionDurations.length;
- while(i<len && timeLabelDuration>sectionDurations[i]){
- i++;
- }
- var sectionDuration = sectionDurations[i];
- var sectionNums = parseInt(0.5+(duration/sectionDurations[i])); //ceil
- var sectionWidth = w*sectionDuration/duration;
-
-
- var tickCounts = [10,5,2,1];
- i=0;
- var tickCount = tickCounts[0];
- while(i<tickCounts.length-1 && tickCounts[i]*2>sectionWidth){
- i++;
- }
- var tickAtHalfSectionWidthHigher = i==0 || i==2; //draw tick at half section higher if ticks are even
- tickCount = tickCounts[i];
- var tickWidth = sectionWidth/tickCount;
- var makeTimeLabel = this.makeTimeLabel;
- var h_1 = h-1; //TODO: use line tickness instead of 1
- var path = new Array(parseInt(0.5+(w/tickWidth)));
- path[0] = ['M 0 '+h_1];
- len = path.length;
- for(i=0; i < len; i+=tickCount){
- for(var j=1; j<tickCount+1; j++){
- var k = i+j;
- var x = (k*tickWidth);
- var y = (j==tickCount ? 0 : tickAtHalfSectionWidthHigher && j==(tickCount)/2 ? .5*h : .75*h);
- var baseline = ' L '+x+' '+h_1;
- path[k] = baseline;
- path[k] += ' L '+x+' '+y;
- path[k] += baseline;
- }
- }
- var labels = new Array(sectionNums);
- for(i=0; i<sectionNums; i++){
- labels[i] = [makeTimeLabel(sectionDuration*i),fontLeftMargin+i*sectionWidth];
- }
- return {
- 'path': path.join(''),
- 'labels':labels
- };
- },
-
- //overridden: Note that the pointer is NOT cleared!!!!!
- clear: function(){
- var markers = this._super();
- //now remove also the labels in the player ruler:
- for( var i=0; i<markers.length; i++){
- markers[i].remove();
- }
- return markers;
- },
-
- //overridden
- remove: function(index){
- var rulermarker = this._super(index);
- rulermarker.remove();
- this.each(index, function(i,rulermarker){
- rulermarker.setIndex(i, true);
- });
- },
-
- //overridden: do not call directly this method, use markermap.move
- move: function(from, to, newOffset){
- to = this._super(from,to);
- if(to <0){ //no move (some error)
- return -1;
- }
- //update label if it is the case:
- var rulermarker = this.toArray()[to];
- var pixelOffset = this.toPixelOffset(newOffset);
- if(rulermarker.positionInPixels != pixelOffset){ //should not be the case if this method is called from a mouse event
- rulermarker.move(pixelOffset);
- }
-
- if(to!=from){
- var i1 = Math.min(from,to);
- var i2 = Math.max(from,to)+1;
- this.each(i1,i2, function(index,rulermarker){
- rulermarker.setIndex(index, true);
- });
- }
- return to;
- },
- //overridden
- //add(offset.-1) adds the pointer, isMovable is ingored
- //add(offset, index, isMovable) adds a marker, movable if isMovable == true
- add: function(offset, index, isMovable){
- var soundPosition;
- var markerClass;
-
- if(index<0){
- soundPosition = offset;
- isMovable = true;
- markerClass='pointer';
- }else{
- soundPosition = offset;
- //isMovable = offset.isEditable;
- markerClass='marker';
- }
-
-
- var pointerOrMarker = new Timeside.classes.RulerMarker(this,this.getWaveContainer(),markerClass);
-
- //call super constructor
- //if it is a pointer, dont add it
- if(markerClass != 'pointer'){
- this._super(pointerOrMarker,index); //add at the end
- //note that setText is called BEFORE move as move must have the proper label width
- this.each(index, function(i,rulermarker){
- rulermarker.setIndex(i,i!=index);//update label width only if it is not this marker added
- });
- }else{
- //note that setText is called BEFORE move as move must have the proper label width
- pointerOrMarker.setText(this.makeTimeLabel(0));
- }
- //proceed with events and other stuff: move (called AFTER setText or setText)
- pointerOrMarker.move(this.toPixelOffset(soundPosition));
- //set mouse events:
- var isPointer = markerClass === 'pointer';
- this._setEditable(pointerOrMarker, isMovable, isPointer);
- return pointerOrMarker;
-
- },
-
- eventNamespace : 'rulerMouseEvent', //namespace for mouse events
- mouseEventType : 'rulermarkermouseevent', //event type for fire TO THE PLAYER. The player then fires markerMouseEvent to outside
-
- setEditable: function(index, value){
- var a = this.toArray();
- if(index>=0 && index < a.length){
- this._setEditable(a[index],value,false);
- }
- },
- //do not call, use setEditable(index,value) instead
- _setEditable: function(pointerOrMarker, value, isPointer){
- var eventNamespace = this.eventNamespace;
- var doc = this.$J(document);
- var lbl = pointerOrMarker.getLabel();
- var me = this;
- var mme = this.mouseEventType;
-
-
- lbl.unbind('.'+eventNamespace); //this should delete all previous events
-
- lbl.bind('mouseenter.'+eventNamespace,function(evt){
- me.fire(mme,{
- eventName: 'mouseenter',
- eventObj: evt,
- index: isPointer ? -1 : pointerOrMarker.getIndex()
- });
- return false;
- });
- lbl.bind('mouseleave.'+eventNamespace,function(evt){
- me.fire(mme,{
- eventName: 'mouseleave',
- eventObj: evt,
- index: isPointer ? -1 : pointerOrMarker.getIndex()
- });
- return false;
- });
-
- //to prevent page scrolling after mouseup, as click is also fired
- lbl.bind('click.'+this.eventNamespace, function(evt){
- return false;
- });
-
-
- lbl.bind('mousedown.'+eventNamespace,function(evt) {
- if(evt.which===1){
- if(value){
- pointerOrMarker.isMovedByMouse = true;
- }
-
- var launchDragStart = true;
-
- var startX = evt.pageX;
- var startPos = lbl.position().left+lbl.width()/2;
-
- evt.stopPropagation(); //dont notify the ruler or other elements;
- var newPos = startPos;
- doc.bind('mousemove.'+eventNamespace, function(evt_){
- //preventClickFire=true;
- if(value){
- var x = evt_.pageX;
- newPos = startPos+(x-startX);
- pointerOrMarker.move(newPos);
- //update the text if pointer
- if(isPointer){
- pointerOrMarker.setText(me.makeTimeLabel(me.toSoundPosition(newPos)));
- }
- }
- if(launchDragStart){
- launchDragStart = false;
- me.fire(mme,{
- eventName: 'dragstart',
- eventObj: evt_,
- index: isPointer ? -1 : pointerOrMarker.getIndex()
- });
- }
- return false;
-
- });
- //to avoid scrolling
- ////TODO: check IE bug on mouseup on the ruler (pointer is moving too)
- //TODO: what happens if the user releases the mouse OUTSIDE the browser???? check bug in IE (mouse release)
- var mouseup = function(evt_){
-
- doc.unbind('mousemove.'+eventNamespace);
- doc.unbind('mouseup.'+eventNamespace);
- evt_.stopPropagation();
- if(value){
- if(newPos !== startPos){
-
- var data = {
- 'markerElement':pointerOrMarker,
- 'soundPosition': me.toSoundPosition.apply(me,[newPos]),
- 'isPointer':isPointer
- };
- me.fire('markermoved',data);
- }
- pointerOrMarker.isMovedByMouse = false;
- }
- if(evt_.pageX !== startX){
- me.fire(mme,{
- eventName: 'dragend',
- eventObj: evt_,
- index: isPointer ? -1 : pointerOrMarker.getIndex()
- });
- }else{
- me.fire(mme,{
- eventName: 'click',
- eventObj: evt_,
- index: isPointer ? -1 : pointerOrMarker.getIndex()
- });
- }
- return false;
- };
- doc.bind('mouseup.'+eventNamespace, mouseup);
- }
-
- me.fire(mme,{
- eventName: 'mousedown',
- eventObj: evt,
- index: isPointer ? -1 : pointerOrMarker.getIndex()
- });
-
-
- return false;
- });
- },
-
- //moves the pointer, does not notify any listener.
- //soundPosition is in seconds (float)
- movePointer : function(soundPosition) {
- var pointer = this.getPointer();
- if (pointer && !pointer.isMovedByMouse) {
- var pixelOffset = this.toPixelOffset(soundPosition);
- //first set text, so the label width is set, then call move:
- pointer.setText(this.makeTimeLabel(soundPosition));
- pointer.move(pixelOffset); //does NOT fire any move method
- }
- return soundPosition;
- },
-
- //soundPosition is in seconds (float)
- toPixelOffset: function(soundPosition) {
- var duration = this.getSoundDuration();
- if (soundPosition < 0){
- soundPosition = 0;
- }else if (soundPosition > duration){
- soundPosition = duration;
- }
- var width = this.getContainerWidth();
- var pixelOffset = (soundPosition / duration) * width;
- return pixelOffset;
- },
-
- //returns the soundPosition is in seconds (float)
- toSoundPosition: function(pixelOffset) {
- var width = this.getContainerWidth();
-
- if (pixelOffset < 0){
- pixelOffset = 0;
- }else if (pixelOffset > width){
- pixelOffset = width;
- }
- var duration = this.getSoundDuration();
- var soundPosition = (pixelOffset / width) *duration;
- return soundPosition;
- }
-});
+++ /dev/null
-/*
- * Copyright (C) 2007-2011 Parisson
- * Copyright (c) 2011 Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
- * Copyright (c) 2010 Olivier Guilyardi <olivier@samalyse.com>
- *
- * This file is part of TimeSide.
- *
- * TimeSide is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * TimeSide is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with TimeSide. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors: Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
- * Olivier Guilyardi <olivier@samalyse.com>
- */
-
-/**
- * Class representing a RulerMarker in TimesideUI
- * Requires jQuery Raphael and all associated player classes. rulerDiv position MUST be relative
- * (if this class is called from within player, it is)
- */
-
-Timeside.classes.RulerMarker = Timeside.classes.TimesideClass.extend({
-
-
- init: function(ruler, waveImgDiv, className) {
- this._super();
- var rulerDiv = ruler.getRulerContainer();
- var $J = this.$J;
-
- var tooltip = '';
-
- var cssPref = this.cssPrefix;
-
- var label = $J('<a/>')
- .addClass(cssPref + className)
- .css({
- display: 'block',
- textAlign: 'center',
- position: 'absolute',
- zIndex: 1000
- }).append($J('<span/>')).attr('href', '#');
-
- if (tooltip){
- label.attr('title', tooltip);
- }
- rulerDiv.append(label);
-
- //rulerDiv MUST HAVE POSITON relative or absolute (it is relative, see player.resize)
- if(className != "pointer"){
- label.css('bottom','0');
- }else{
- label.css('top','0');
- }
-
- //set the index,
- var index = -1;
- this.setIndex = function(idx, optionalUpdateLabelWidth){
- index = idx;
- this.setText(idx+1, optionalUpdateLabelWidth ? true : false);
- };
- this.getIndex = function(){
- return index;
- };
-
- //end=======================================================
- //creating public methods:
- this.getLabel = function(){
- return label;
- };
-
-
- this.getRulerWidth = function(){
- return rulerDiv.width();
- };
- this.getWaveHeight = function(){
- return waveImgDiv.height();
- };
-
- this.positionInPixels = 0;
- this.positionAsViewerRatio = 0;
-
- var arrowBaselineWidth = 9;
-
- var canvas = undefined;
- var canvasClass = cssPref + 'svg-'+className+'-line';
- var vml = this.$TU.vml; //if vml, this class is populated with methods and NOT undefined
- var round = Math.round;
- if(!vml){
- canvas = this.createCanvasSvg(waveImgDiv, arrowBaselineWidth);
- var path = canvas.childNodes[0]; //note that $J(canvas).find('path') does not work in FF at least 3.5
- path.setAttributeNS(null,'class',canvasClass);
- this.moveCanvas = function(pixelOffset){
- pixelOffset = round(pixelOffset);
- canvas.setAttributeNS( null, "transform", "translate("+pixelOffset+",0)");
- };
- this.jQueryCanvas = $J(canvas);
- }else{
- canvas = this.createCanvasVml(waveImgDiv, arrowBaselineWidth);
- this.jQueryCanvas = $J(canvas.node);
- var attributes = vml.getVmlAttr(canvasClass);
- canvas.attr(attributes); //Raphael method
- this.moveCanvas = function(pixelOffset){
- pixelOffset = round(pixelOffset);
- //for some reason, coordinates inside the VML object are stored by raphael with a zoom of 10:
- this.jQueryCanvas.css('left',(10*pixelOffset)+'px');
- };
- //apparently, when resizing the markers loose their attributes. Therefore:
- var r = this.refreshPosition; //reference to current refreshPosition
- this.refreshPosition = function(){
- r.apply(this);
- canvas.attr(attributes);
- }
- }
- },
-
- //sets the text of the marker, if the text changes the marker width and optionalUpdateLabelPosition=true,
- //re-arranges the marker position to be center-aligned with its vertical line (the one lying on the wav image)
- setText: function(text, optionalUpdateLabelPosition) {
- var label = this.getLabel();
- if (label) {
- var oldWidth = label.width();
- label.find('span').html(text);
- var labelWidth = label.width();
- if(oldWidth != labelWidth && optionalUpdateLabelPosition){
- this.refreshLabelPosition();
- }
- }
- return this;
- },
-
- //these methods are executed only if marker is movable (see Ruler.js)
- move : function(pixelOffset) {
- var width = this.getRulerWidth();
- if (this.positionInPixels != pixelOffset) {
- if (pixelOffset < 0) {
- pixelOffset = 0;
- } else if (pixelOffset >= width) {
- pixelOffset = width - 1;
- }
- //defined in the init method (it depends on wehter the current browser supports SVG or not)
- this.moveCanvas(pixelOffset);
-
- this.positionInPixels = pixelOffset;
- this.refreshLabelPosition(width);
- //store relative position (see refreshPosition below)
- this.positionAsViewerRatio = pixelOffset == width-1 ? 1 : pixelOffset/width;
- }
- return this;
- },
-
- refreshLabelPosition : function(optionalContainerWidth){
- if(!(optionalContainerWidth)){
- optionalContainerWidth = this.getRulerWidth();
- }
- var label = this.getLabel();
- var width = optionalContainerWidth;
- var pixelOffset = this.positionInPixels;
- var labelWidth = label.outerWidth(); //consider margins and padding
- var labelPixelOffset = pixelOffset - labelWidth / 2;
- if (labelPixelOffset < 0){
- labelPixelOffset = 0;
- }else if (labelPixelOffset + labelWidth > width){
- labelPixelOffset = width - labelWidth;
- }
- label.css({
- left: this.mRound(labelPixelOffset) + 'px'
- });
-
- },
-
- //function called on ruler.resize. Instead of recreating all markers, simply redraw them
- refreshPosition : function(){
- var width = this.getRulerWidth();
- //store relativePosition:
- var rp = this.positionAsViewerRatio;
- this.move(this.mRound(this.positionAsViewerRatio*width));
- //reset relative position, which does not have to change
- //but in move might have been rounded:
- this.positionAsViewerRatio = rp;
- },
-
-
- remove : function() {
- var label = this.getLabel();
- label.remove();
- this.jQueryCanvas.remove(); //defined in the constructor
- return this;
- },
-
-
- createCanvasSvg: function(container, arrowBaseWidth){
- //create svg. Note that elements must be created within a namespace (createElementNS)
- //and attributes must be set via .setAttributeNS(null,name,value)
- //in other words, jQuery does not work (maybe in future releases)
- var $J = this.$J;
- var svgNS = "http://www.w3.org/2000/svg";
- var d = document;
- var svg = undefined;
- if(container.children().length>0){
- svg = container.children().get(0);
- }else{
- svg = d.createElementNS(svgNS, "svg:svg");
- container.append($J(svg));
- }
- var group = d.createElementNS(svgNS, "svg:g");
- group.setAttributeNS( null, "transform", "translate(0,0)");
-
- var path = d.createElementNS(svgNS, "svg:path");
- path.setAttributeNS( null, "d", this.createCanvasPath(0,arrowBaseWidth));
-
- group.appendChild(path);
- svg.appendChild(group);
-
- return group; //return the group, not the path, as it is the group that will be translated when moving
- },
-
- createCanvasVml: function(container, arrowBaseWidth){
- var vml = this.$TU.vml;
- var paper = vml.Raphael(container.get(0),container.width(),container.height());
- var shape = paper.path(this.createCanvasPath(0, arrowBaseWidth));
- return shape;
- },
-
- //w must be odd. Cause the central line must be centered. Example:
- //
- // xxxxx
- // xxx
- // x
- // x
- // x
- //
- createCanvasPath: function(x,w){
- var halfW = w >>> 1;
- //in order to calculate the line height, we could simply set the wave height. However, due to potential
- //resizing afterwards, the line could not stretch till the bottom (if it overflows it's fine, as the wave div container has
- //overflow = hidden). As we do not want to rebuild the canvas on resize,
- //we assess an height which will 99% overflow the wave height in any case.
- //We use the wave height and the window height, and take 2 times
- //the maximum of those heights:
- var wdwH = this.$J(window).height();
- var waveH = this.getWaveHeight();
- var h = 2* (wdwH > waveH ? wdwH : waveH);
- return 'M '+(x-halfW)+' 0 L '+(x)+' '+(halfW)+' L '+x+' '+h+
- ' L '+ (x+1)+' '+h+' L '+(x+1)+ ' '+(halfW)+' L '+(x+halfW+1)+' 0 z';
- },
-
- //used for faster lookup
- mRound: Math.round
-
-});
+++ /dev/null
-/*
- * Copyright (C) 2007-2011 Parisson
- * Copyright (c) 2011 Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
- * Copyright (c) 2010 Olivier Guilyardi <olivier@samalyse.com>
- *
- * This file is part of TimeSide.
- *
- * TimeSide is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * TimeSide is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with TimeSide. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors: Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
- * Olivier Guilyardi <olivier@samalyse.com>
- */
-
-/**
- * Root javascript file for TimesideUI, to be manually included in your web page (see online doc)
- */
-
-/**
- *global variable housing all Timeside variables/mathods/classes:
- */
-var Timeside = {
- Class:undefined,
- classes:{},
- player:undefined,
- config: {
- /**
- *set to true to see debug messages on the console (only error or warning messages shown)
- */
- debug: false,
- /*
- * timeside scripts to be loaded when Timeside.load is called. URL paths are relative to the timeside folder, which
- * will be determined according to the src attribute of the timeside.js script path (to be included in the <head> of the page)
- */
- timesideScripts: ['rulermarker.js','markermap.js', 'player.js', 'ruler.js'],
- //vml config variables. Used only if svg is NOT supported
- vml : {
- /*
- * raphael script to be loaded when Timeside.load is called and svg is not supported. It will be prepended to the
- * timesideScripts array defined above in config. URL paths are relative to the timeside folder, which
- * will be determined according to the src attribute of the timeside.js script path (to be included in the <head> of the page)
- */
- raphaelScript : 'libs/raphael-min.js',
- /*
- * available attributes which can be converted from css-svg to Raphael attributes (see Raphael.js):
- */
- raphaelAttributes : ["clip-rect", "cursor",'fill', "fill-opacity",'opacity', 'stroke', "stroke-dasharray", "stroke-linecap", "stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width", "text-anchor"]
- }
- },
- utils:{
- /**
- * Returns an uniqid by creating the current local time in millisecond + a random number.
- * Used for markers in markermap. The method is kind of public in order to be more accessible for other functions
- * by calling Timeside.utils.uniqid(), in case it is needed
- */
- uniqid : function() {
- var d = new Date();
- return new String(d.getTime() + '' + Math.floor(Math.random() * 1000000)).substr(0, 18);
- },
- /**
- * vml object which will be populated by vml functions to interface timeside and raphael. See timeside.load.
- * We could implement functions here for code readability, however,
- * we delegate Timeside.load so that if svg is supported memory is free from unused vml methods.
- * IN ANY CASE, svg support can be detected anywhere by calling, eg:
- * var svg = !Timeside.utils.vml;
- */
- vml: undefined,
-
- /**
- * property that will be set to false if soundManager fails to initialize flash
- */
- flashFailed : false
- }
-};
-
-
-/* Simple JavaScript Inheritance
- * By John Resig http://ejohn.org/
- * MIT Licensed.
- * (Inspired by base2 and Prototype)
- */
-
-/*
- * In few words: the lightest and most-comprehensive way to implement inhertance and OOP in javascript. Usages can be found below.
- * Basically,
- * 1) a new Class is instantiated with Class.extend(). This function takes a dictionary
- * of properties/methods which will be put IN THE PROTOTYPE of the class, so that each instance will share the same properties/methods
- * and the latter don't have to be created for each instance separately.
- * 2) If var A = Class.extend({...}) and var B = A.extend({..}), then methods which are found in B will override the same methods in A.
- * In this case, the variable this._super inside the overridden methods will refers to the super-method and can thus be called safely.
- * Consequently, if a _super property/method is implemented in the extend dictionary, it WILL NOT be accessible
- * to the overriding methods of B. Basically, don't use _super as a key of the argument of extend.
- * 3) AFTER the prototype has been populated, the init function, if exists, is called. The latter can be seen as a class constructor in java,
- * with a substantial difference: when executing the init() method the class prototype has already been populated with all inherited methods.
- * Private variable can be declared in the init function, as well as
- * relative getters and setters, if needed. Downside is that the privileged getters and setters can’t be put in the prototype,
- * i.e. they are created for each instance separately, and the _super keyword does not apply to them. Another issue is the overhead of closures in general (basically, write as less as possible
- * in the init function, in particular if the class has to be declared several times)
- * Of course, the this._super keyword of methods implemented in the init constructor does not work
- *
- * EXAMPLE:
- * var MyClass = Class.extend({
- * init: function(optionalArray){ //constructor
- * this._super(); //!!!ERROR: Class is the base class and does not have a super construcor
- * var me = []; //private variable
- * this.count = 6; //set the value of the public property defined below
- * this.getMe = function(){ //public method
- * this._super(); //!!!ERROR: methods defined in the init function don't have acces to _super
- * }
- * this.alert = function(){ //another public method, !!!WARNING: this will be put in the MyClass scope (NOT in the prototype)
- * alert('ok');
- * }
- * },
- * count:0, //public property
- * alert: function(){ //public method. !!!WARNING: this method will be put in the prototype BEFORE the init is called,
- * alert('no'); // so the alert defined above will be actually called
- * }
- * });
- * var MyClass2 = MyClass.extend({
- * init: function(){
- * this._super(); //call the super constructor
- * }
- * alert: function(){ //override a method
- * this._super(); //call the super method, ie alerts 'no'. WARNING: However, as long as there is an alert written
- * //in the init method of the superclass (see above), THAT method will be called
- * }
- * });
- *
- */
-
-
-(function(parent){
-
- var initializing = false, fnTest = /xyz/.test(function(){
- xyz;
- }) ? /\b_super\b/ : /.*/;
-
- /*The xyz test above determines whether the browser can inspect the textual body of a function.
- *If it can, you can perform an optimization by only wrapping an overridden method if it
- *actually calls this._super() somewhere in its body.
- *Since it requires an additional closure and function call overhead to support _super,
- *it’s nice to skip that step if it isn’t needed.
- */
-
- //ADDED BY ME:
- // before was: this.Class = function(){}, where this here is the DomWindow
- // In order to chose where to attach the Class object, we added the argument parent (see above):
- //if parent is undefined, attach Class to the DomWindow (same as before):
- if(!parent){
- parent= window;
- }
- parent.Class = function(){};
-
- //from here on, the code is untouched:
- //
- //We have the base Class implementation (does nothing)
- //and we write here below the method extend which returns the Class with inhertance implemented:
- // Create a new Class that inherits from this class
- parent.Class.extend = function(prop) {
- var _super = this.prototype;
-
- // Instantiate a base class (but only create the instance,
- // don't run the init constructor)
- initializing = true;
- var prototype = new this();
- initializing = false;
-
- // Copy the properties over onto the new prototype
- for (var name in prop) {
- // Check if we're overwriting an existing function
- prototype[name] = typeof prop[name] == "function" &&
- typeof _super[name] == "function" && fnTest.test(prop[name]) ?
- (function(name, fn){
- return function() {
- var tmp = this._super;
-
- // Add a new ._super() method that is the same method
- // but on the super-class
- this._super = _super[name];
-
- // The method only need to be bound temporarily, so we
- // remove it when we're done executing
- var ret = fn.apply(this, arguments);
- this._super = tmp;
-
- return ret;
- };
- })(name, prop[name]) :
- prop[name];
- }
-
- // The dummy class constructor
- function Class() {
- // All construction is actually done in the init method
- if ( !initializing && this.init ){
- this.init.apply(this, arguments);
- }
- }
-
- // Populate our constructed prototype object
- Class.prototype = prototype;
-
- // Enforce the constructor to be what we expect
- Class.constructor = Class;
-
- // And make this class extendable
- Class.extend = arguments.callee;
-
- return Class;
- };
-})(Timeside);
-
-
-
-//Defining the base TimeClass class. Timeside.classes.[Player, Ruler, MarkerMap...] are typical implementations (see js files)
-//Basically we store here static methods which must be accessible in several timside sub-classes
-Timeside.classes.TimesideClass = Timeside.Class.extend({
- //init constructor. Define the 'bind' and 'fire' (TODO: rename as 'trigger'?) methods
- //we do it in the init function so that we can set a private variable storing all
- //listeners. This means we have to re-write all methods
- init: function(){
- //the map for listeners. Must be declared in the init as it's private and NOT shared by all instances
- //(ie, every instance has its own copy)
- this.listenersMap={};
- },
-
- cssPrefix : 'ts-', //actually almost uneuseful, still here for backward compatibility with old code (TODO: remove?)
- $J : jQuery, //reference to jQuery for faster lookup inside methods
- $TU : Timeside.utils, //reference to Timeside variable for faster lookup inside methods
- debugging : false,
- debug : Timeside.config.debug ? function(message) {
- var C = console;
- if (C && C.log) {
- C.log(message);
- }
- } : function(message){},
-
- /**
- * 3 methods defining listeners, events fire and bind (aloing the lines of jQuery.bind, unbind and trigger.
- * the only difference is that 'trigger' is 'fire' here). namespaces are allowed as in jQuery
- */
- bind : function(eventType, callback, optionalThisArgInCallback){
- if(!callback || typeof callback !== 'function'){
- this.debug('TimesideClass.bind: cannot bind '+eventType+' to callback: the latter is null or not a function');
- return;
- }
- if(!eventType){
- this.debug('TimesideClass.bind: eventType is empty in bind');
- return;
- }
- var listenersMap = this.listenersMap;
- if(optionalThisArgInCallback){
- var cb = callback;
- callback = function(data){
- cb.apply(optionalThisArgInCallback,[data]);
- };
- }
-
- if(listenersMap.hasOwnProperty(eventType)){
- listenersMap[eventType].push(callback);
- }else{
- listenersMap[eventType] = [callback];
- }
-
- var idx = eventType.indexOf('.');
- if(idx <= 0 || idx >= eventType.length-1){
- return;
- }
-
- eventType = eventType.substring(0,idx);
-
-
- if(listenersMap.hasOwnProperty(eventType)){
- listenersMap[eventType].push(callback);
- }else{
- listenersMap[eventType] = [callback];
- }
-
- },
- unbind : function(){
- var listenersMap = this.listenersMap;
- var key,keyPlusDot;
- if(arguments.length>0){
- key = arguments[0];
- if(listenersMap.hasOwnProperty(key)){
- var callbacks = listenersMap[key];
- var idx = key.indexOf('.');
- if(idx>0 && idx < key.length-1){
- //key is "eventtype.namespace", delete also functions stored in "eventType", if any
- var baseKey = key.substring(0,idx);
- var baseCallbacks = listenersMap[baseKey];
- if(baseCallbacks){
- for( var i = baseCallbacks.length; i>-1; i--){
- var bc = baseCallbacks[i];
- for( var j = callbacks.length; j>-1; j--){
- if(bc === callbacks[j]){
- baseCallbacks.splice(i,1);
- }
- }
- }
- }
- }else if(idx<0){
- //key is "eventtype", delete also all functions stored in "eventType.namespace", if any
- keyPlusDot = key+'.';
- for(var k in listenersMap){
- if(listenersMap.hasOwnProperty(k) && k.indexOf(keyPlusDot)==0 && k.length > keyPlusDot.length){
- delete listenersMap[k];
- }
- }
- }
- delete listenersMap[key];
- }
- }else{
- for(key in listenersMap){
- if(listenersMap.hasOwnProperty(key)){
- delete listenersMap[key];
- }
- }
- }
- },
- fire : function(key, dataArgument){
- var listenersMap = this.listenersMap;
- if(!(listenersMap.hasOwnProperty(key))){
- return;
- }
- if(arguments.length < 2 || !dataArgument){
- dataArgument = {};
- }
- var callbacks = listenersMap[key];
- var len = callbacks && callbacks.length ? callbacks.length : 0;
- for(var i=0; i<len; i++){
- callbacks[i](dataArgument);
- }
- },
-
- /*
- *formats (ie returns a string representation of) a time which is in the form seconds,milliseconds (eg 07.6750067)
- * formatArray is an array of strings which can be:
- * 'h' hours. Use 'hh' for a zero-padding to 10 (so that 6 hours is rendered as '06')
- * 'm' hours. Use 'mm' for a zero-padding to 10 (so that 6 minutes is rendered as '06')
- * 's' hours. Use 'ss' foar a zero-padding to 10 (so that 6 seconds is rendered as '06')
- * 'D' deciseconds
- * 'C' centiseconds (it will be padded to 10, so that 5 centiseconds will be rendered as '05')
- * 'S' milliseconds (it will be padded to 100, so that 5 milliseconds will be rendered as '005')
- * If formatArray is null or undefined or zero-length, it defaults to ['mm','ss']
- * 'h','m' and 's' will be prepended the separator ':'. For the others, the prepended separator is '.'
- * Examples:
- * makeTimeLabel(607,087) returns '10:07' (formatArray defaults to ['mm','ss'])
- * makeTimeLabel(607,087,['m':'s']) returns '10:7'
- * makeTimeLabel(607,087,['m':'s','C']) returns '10:7.09'
- */
- makeTimeLabel: function(time, formatArray){
- if(!(formatArray)){
- formatArray = ['mm','ss'];
- }
-
- //marker offset is in float format second.decimalPart
- var pInt = parseInt;
- var round = Math.round;
- var factor = 3600;
- var hours = pInt(time/factor);
- time-=hours*factor;
- factor = 60;
- var minutes = pInt(time/factor);
- time-=minutes*factor;
- var seconds = pInt(time);
- time-=seconds;
-
- //here below the function to format a number
- //ceilAsPowerOfTen is the ceil specifiedas integer indicating the relative power of ten
- //(0: return the number as it is, 1: format as "0#" and so on)
- //Examples: format(6) = "6", format(6,1)= "06", format(23,1)= "23"
-
- //first of all, instantiate the power function once (and not inside the function or function's loop):
- //note that minimumNumberOfDigits lower to 2 returns integer as it is
- var mpow = Math.pow; //instantiate mpow once
- var format = function(integer,minimumNumberOfDigits){
- var n = ""+integer;
- var zero = "0"; //instantiating once increases performances???
- for(var i=1; i< minimumNumberOfDigits; i++){
- if(integer<mpow(10,i)){
- n = zero+n;
- }
- }
- return n;
- };
- var ret = [];
- for(var i =0; i<formatArray.length; i++){
- var f = formatArray[i];
- var separator = ":";
- if(f=='h'){
- ret[i]=hours;
- }else if(f=='hh'){
- ret[i]=format(hours,2);
- }else if(f=='m'){
- ret[i]=minutes;
- }else if(f=='mm'){
- ret[i]=format(minutes,2);
- }else if(f=='s'){
- ret[i]=seconds;
- }else if(f=='ss'){
- ret[i]=format(seconds,2);
- }else if(f=='S'){
- separator = ".";
- ret[i]=format(round(time*1000),3);
- }else if(f=='C'){
- separator = ".";
- ret[i]=format(round(time*100),2);
- }else if(f=='D'){
- separator = ".";
- ret[i]= round(time*10);
- }
- if(i>0){
- ret[i] = separator+ret[i];
- }
- }
- return ret.join("");
- }
-});
-
-/**
- * An Array-like implementation that suits the need of Marker mnanagement
- * Ruler, MarkerMap and MarkerMapDiv implement this class
- */
-Timeside.classes.TimesideArray = Timeside.classes.TimesideClass.extend({
- init: function(optionalArray){
- this._super();
- //here methods that CANNOT be overridden
- var me= optionalArray ? optionalArray : [];
- //note that this method written here OVERRIDES the same method written outside init in the children!!!!
- this.toArray = function(returnACopy){
- if(returnACopy){
- var ret = [];
- for(var i=0; i<me.length; i++){
- ret.push(me[i]);
- }
- return ret;
- }
- return me;
- };
- this.length = me.length; //in order to match the javascript array property
- },
- //adds at the end of the array. If index is missing the object is appended at the end
- add : function(object, index){
- var array = this.toArray();
- if(arguments.length<2){
- index = array.length;
- }
- array.splice(index,0,object);
- this.length = array.length; //note that length is a property and must be updated!!!
- return object;
- },
- //removes item at index, returns the removed element
- remove : function(index){
- var array = this.toArray();
- var ret = array.splice(index,1)[0];
- this.length = array.length; //note that length is a property and must be updated!!!
- return ret;
- },
- //Iterate over the array, with the same syntax of jQuery.each, ie, executes a function(index,element)
- //for each element from startIndexInclusive to
- //endIndexExclusive.
- //The only required argument is callback:
- //1) each(callback) iterates over all elements executing callback
- //2) each(m, callback) iterates over the elements from m executing callback
- //3) each(m,n,callback) iterates over the elements from m (inclusive) to n-1 (inclusive) executing callback
-
- //NOTE: writing each : function(startInclusive, endExclusive, callback) throws an error in chrome, as the last
- //argument (even if it is a function) is a number. Why?????
- //Anyway, we write the function arguments as empty
- each : function(){
- var startInclusive, endExclusive, callback;
-
- var arg = arguments;
- var len = arg.length;
- var l = this.length;
- switch(len){
- case 0:
- this.debug('TimesideClass.each: each called without arguments!!!');
- return;
- case 1:
- startInclusive = 0;
- endExclusive = l;
- break;
- case 2:
- if(arg[0] >= l){
- return;
- }
- startInclusive = arg[0]=== undefined ? 0 : arg[0];
- endExclusive = l;
- break;
- default:
- startInclusive = arg[0]=== undefined ? 0 : arg[0];
- endExclusive = arg[1]=== undefined ? l : arg[1];
- }
- callback = arg[len-1];
- if(!(callback instanceof Function)){
- this.debug('TimesideClass.each: callback NOT a function!!!');
- return;
- }
- var me =this.toArray();
- for(var i = startInclusive; i<endExclusive; i++){
- callback(i,me[i]);
- }
-
- },
-
- //clears the array and the events associated to it, ie removes all its elements and calls unbind(). Returns the array of the removed elements
- clear: function(){
- this.unbind();
- var me = this.toArray();
- var l = me.length;
- this.length = 0;
- if(l==0){
- return [];
- }
- return me.splice(0,l);
- },
- //moves the element at position from into position to
- //the element that was at from will be at position to
- //returns:
- //-1 if from or to not integers, or from or to not within the array bounds (lower than zero or greater or equal to this.length)
- //from if from === to (no move)
- //to otherwise (move succesful)
- move : function(from, to){
-
- var pInt = parseInt;
- if(pInt(from)!==from || pInt(to)!==to){ //just a check
- return -1;
- }
- if(from === to){
- return from;
- }
- var me =this.toArray();
- var len = me.length;
- if((from<0 || from>=len)||(to<0 || to>=len)){
- return -1;
- }
- var elm = me.splice(from,1)[0];
- me.splice(to,0,elm);
-
- return to;
- }
-});
-
-
-
-/**
- *Main Timeside method to load player (see Timeside online doc)
- */
-
-Timeside.load =function(config){
-
- var $J = jQuery;
- var win = window;
- var doc = document;
- //function to be called onready or onerror:
- var loadAll = function() {
-
-
- //get the current script path (this file name is timeside.js?... or simplt timeside.js)
- var scripts = $J('script');
- var thisScriptPath = '';
- scripts.each(function(i,s){
- var src = $J(s).attr('src');
- if(src){
- var srcName = src.split(/\//);
- if(srcName.length){
- srcName = srcName[srcName.length-1];
- //is this script ? consider the case here we are loading timeside.js?....
- if(srcName.replace(/\.js(?:\?[^\?]*)*$/,'.js') == 'timeside.js'){
- src[src.length-1] = '';
- thisScriptPath = src.replace(/\/[^\/]+$/, '');
- }
- }
- }
- });
-
- var ts = Timeside;
- var ts_scripts = ts.config.timesideScripts;
- //detect SVG support and load Raphael in case. Copied from Raphael code v 1.5.2:
- var svg = (win.SVGAngle || doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
- if(!svg){
- //add the raphael path. Raphael will be loaded in Timeside.load (see below)
- ts_scripts.splice(0,0,ts.config.vml.raphaelScript);
- //populate the vml object with methods to be used in ruler and rulermarker:
-
- //global private variable:
- //map to store each class name to the relative dictionary for raphael attr function (VML only)
- var classToRaphaelAttr = {};
- //get the raphael attributes for which a conversion css -> raphael_attribute is possible:
- var availableAttrs = ts.config.vml.raphaelAttributes;
- //here below we store Raphael paper objects. var paper = Raphael(htmlElement) is the raphel method to build
- //a new paper object. Internally, the method builds a div embedding vmls inside htmlElement, retriavable via the
- //paper.node property.
- //However, calling again var paper = Raphael(htmlElement) does not use the already created paper,
- //but creates a new paper with a new paper.node (div). Too bad. The possibility to wrap existing paper node
- //into a Raphael paper would be a nice and almost necessary feature, which however is not even
- //planned to be implemented according to raphael developers (see raphael forums).
- //In case of markers lines, we want to draw a new marker
- //on the same raphael paper. Therefore, we store here raphael papers in a map htmlElement -> paper
- var raphael_papers = {};
- ts.utils.vml = {
- getVmlAttr: function(className){
-
- if(classToRaphaelAttr.hasOwnProperty(className)){
- //if(className in classToRaphaelAttr){
- return classToRaphaelAttr[className];
- }
- var d = document;
- var dottedclassName = className.replace(/^\.*/,'.'); //add a dot if not present
- var ssheets = d.styleSheets;
- var len = ssheets.length-1;
-
- var attr = {};
- for(var i=0; i<len; i++){
- var rules = ssheets[i].rules;
- var l = rules.length;
- for(var j=0; j <l; j++){
- var rule = rules[j];
-
- if(rule.selectorText === dottedclassName){
-
- var style = rule.style;
- for(var k =0; k<availableAttrs.length; k++){
- var val = style[availableAttrs[k]];
- if(val){
- attr[availableAttrs[k]] = val;
- }
- }
- }
- }
- }
- classToRaphaelAttr[className] = attr;
- return attr;
- },
-
- Raphael: function(element,w,h){
- //pass jQueryElm.get(0) as first argument, in case)
- if(raphael_papers[element]){
- return raphael_papers[element];
- }
- var paper = Raphael(element,w,h);
- raphael_papers[element] = paper;
- //paper canvas is a div with weird dimensions. You can check it by printing paper.canvas.outerHTML in IE.
- //We set them to 100% so we dont have clipping regions when resizing (maximizing)
- paper.canvas.style.width='100%';
- paper.canvas.style.height='100%';
- paper.canvas.width='100%';
- paper.canvas.height='100%';
- //apparently, there is also a clip style declaration made by raphael. The following code trhows an error in IE7:
- //paper.canvas.style.clip = 'auto';
- //however, even leaving the clip style declaration as it is, it seems to work (the div spans the whole width)
- return paper;
- }
-
- };
- }
-
- ts.player = undefined;
- if(config.onReady && typeof config.onReady === 'function'){
- var oR = config.onReady;
- config.onReady = function(player){
- ts.player = player;
- oR(player);
- };
- }else{
- config.onReady = function(player){
- ts.player = player;
- };
- }
-
- //finally,define the error function
- ts.utils.loadScripts(thisScriptPath,ts_scripts, function() {
- new ts.classes.Player(config); //do not assign it to any variable, we do it only onready
- },config.onError);
- };
-
-
-
-
- $J(win).ready(function(){
- var s = soundManager;
- //grab the case of soundManager init errors:
- s.onerror = function() {
- Timeside.utils.flashFailed = true;
- //end('SoundManager error. If your browser does not support HTML5, Flash player (version '+soundManager.flashVersion+'+) must be installed.\nIf flash is installed, try to:\n - Reload the page\n - Empty the cache (see browser preferences/options/tools) and reload the page\n - Restart the browser');
-
- //and load all anyway:
- loadAll();
- };
-
- //if soundmanager is ready, the callback is executed immetiately
- //onready is executed BEFORE onload, it basically queues several onload events.
- //It it is executed immetiately if soundmanager has already been loaded
- s.onready(function(){loadAll();});
- });
-};
-
-/**
-* Loads scripts asynchronously
-* can take up to four arguments:
-* scriptsOptionalRoot (optional): a string specifying the root (such as '/usr/local/'). IF IT IS A NONEMPTY STRING AND
-* DOES NOT END WITH A SLASH, A SLASH WILL B APPENDED
-* scriptArray: a string array of js script filenames, such as ['script1.js','script2.js']
-* optionalOnOkCallback (optional): callback to be executed when ALL scripts are succesfully loaded
-* optionalOnErrorCallback (optional) a callback receiving a string as argument to be called if some script is not found
-* optionalSynchroLoad (optional): if true scripts are loaded in synchronously, ie each script is loaded only once the
-* previous has been loaded. Otherise (including missing argument) an asynchronous load is performed
-* and the optional onOkCallback is executed once ALL scripts are loaded
-*/
-Timeside.utils.loadScripts = function(scriptsOptionalRoot,scriptArray, optionalOnOkCallback, optionalOnErrorCallback, optionalSynchroLoad){
- //var optionalRoot='', callback=undefined, loadInSeries=false;
- if(!optionalOnOkCallback || typeof optionalOnOkCallback !== 'function'){
- optionalOnOkCallback = function(){};
- }
- if(!optionalOnErrorCallback || typeof optionalOnErrorCallback !== 'function'){
- optionalOnErrorCallback = function(msg){};
- }
-
- if(!scriptArray || !scriptArray.length){
- optionalOnOkCallback();
- return;
- }
- var len = scriptArray.length;
- var i=0;
- if(scriptsOptionalRoot){
- scriptsOptionalRoot = scriptsOptionalRoot.replace(/\/*$/,"/"); //add slash at end if not present
- for(i =0; i<len; i++){
- scriptArray[i] = scriptsOptionalRoot+scriptArray[i];
- }
- }
-
- var $J = jQuery;
- //there is a handy getScript function in jQuery, which however does NOT manage the onError case (script load error)
- //looking at jQuery doc, getScript is the same as the followig ajax request,
- //to which we added the error property to manage errors:
- var loadScript = function(url,onSuccess,onError){
- $J.ajax({
- url: url,
- dataType: 'script',
- success: onSuccess,
- error: function(a,b,errorThrown){
- onError('file "'+url+'" error: '+errorThrown);
- }
- });
- };
- if(optionalSynchroLoad){
- var load = function(index){
- if(index<len){
- loadScript(scriptArray[index],function(){
- load(index+1);
- }, function(msg){
- optionalOnErrorCallback(msg);
- });
- }else if(index==len){
- optionalOnOkCallback();
- }
- };
- load(0);
- }else{
- var count=0;
- var s;
- for(i=0; i <len; i++){
- s = scriptArray[i];
- //this means that onError all scripts will be loaded.
- //However, if everything works fine, asynchornous load (here) should be faster
- loadScript(s, function(){
- count++;
- if(count===len){
- optionalOnOkCallback();
- }
- },function(msg){
- count = len+1; //avoid calling optionalOkOnCallback
- optionalOnErrorCallback(msg);
- });
- }
- }
-};
+++ /dev/null
-/*
-* Style for the timeside player. The player div is supposed to be of class .ts-player. Change if needed
-* For details, see http://code.google.com/p/timeside/wiki/UiGuide?ts=1308677096&updated=UiGuide#CSS_and_skins
-*/
-
-.ts-player {
- padding: 0;
- border: solid 1px #ADADAD;
- margin-top: 2px;
-}
-
-
-.ts-player .ts-ruler{
- color: #ADADAD;
- background-color: #F2F2F2;
- font-size: 10px;
- line-height: 13px;
-}
-/*svg style, MUST BE A SINGLE SELECTOR. FOR INSTANCE, THIS DOES NOT WORK WHEN SVG IS NOT SUPPORTED:
- ".ts-player .ts-ruler .ts-svg-ruler-upper-rect" */
-.ts-svg-ruler-upper-rect{
- fill: #FFFFFF;
- stroke-width:0;
- stroke: #FFFFFF; /*to be sure...*/
-}
-/*svg style, MUST BE A SINGLE SELECTOR. FOR INSTANCE, THIS DOES NOT WORK WHEN SVG IS NOT SUPPORTED:
- ".ts-player .ts-ruler .ts-svg-ruler-lines"*/
-.ts-svg-ruler-lines{
- stroke-width:1;
- stroke: #ADADAD;
-}
-
-/*wave:*/
-.ts-player .ts-wave {
- height: 130px;
-}
-
-/*.ts-player .ts-viewer .ts-marker {*/
-.ts-player .ts-ruler .ts-marker {
- padding: 0 0.5em;
- background: #fff;
- border: 1px solid #92bdd4;
- color: #92bdd4;
- text-decoration: none;
-}
-/*svg style, MUST BE A SINGLE SELECTOR. FOR INSTANCE, THIS DOES NOT WORK WHEN SVG IS NOT SUPPORTED:
- ".ts-player .ts-wave .ts-image-canvas .ts-svg-marker-line" */
-.ts-svg-marker-line {
- fill: #92bdd4;
- stroke-width:0;
-}
-
-/*.ts-player .ts-viewer a.ts-pointer {*/
-.ts-player .ts-ruler a.ts-pointer {
- color: white ;
- background-color: #92bde4;
- padding: 0 0.5em;
- /*border: solid 1px #92bde4;*/
-
- text-decoration: none;
- -moz-border-radius: .3em;
- -webkit-border-radius: .3em;
- border-radius: .3em;
- /*color: #3c4251; #6A0307 !important;*/
-}
-/*svg style, MUST BE A SINGLE SELECTOR. FOR INSTANCE, THIS DOES NOT WORK WHEN SVG IS NOT SUPPORTED:
- ".ts-player .ts-wave .ts-image-canvas .ts-svg-pointer-line" */
-.ts-svg-pointer-line {
- fill: #92bde4;
- stroke-width:0;
-}
-
-.ts-player .ts-wave .ts-image {
- background: #090e0d ;
-}
-
-.ts-player .ts-control {
- background: url('img/player_controlbg.png');
-}
-
- /** display (inline-block) and overflow of a is set inside javascript*/
-.ts-player .ts-control .ts-button {
- background-repeat: no-repeat;
- margin:4px;
- height:21px;
- width:21px;
- /* background-position: 0px 0px;*/
-}
-.ts-player .ts-control .ts-button:hover {
- background-position: 0px -21px;
-}
-.ts-player .ts-control .ts-play {
- background-image: url('img/play.png');
-}
-
-.ts-player .ts-control .ts-pause {
- background-image: url('img/pause.png');
-}
-
-.ts-player .ts-control .ts-rewind {
- background-image: url('img/rewind.png');
-}
-
-.ts-player .ts-control .ts-forward {
- background-image: url('img/forward.png');
-}
-
-.ts-player .ts-control .ts-set-marker {
- background-image: url('img/setmarker.png');
-}
-
-.ts-player .ts-control .ts-volume-speaker-on {
- background-image: url('img/volumeon.png');
- width:24px;
-}
-.ts-player .ts-control .ts-volume-speaker-off {
- background-image: url('img/volumeoff.png');
- width:24px;
-}
-.ts-player .ts-control .ts-volume-bar-container {
- /*background: url('img/controlbg-inverted.png');
- background-position: -3px left;
- background-repeat: repeat-x;*/
- border: 1px solid #a3a4a7;
- height:10px;
- width:42px;
- margin-top:9px;
- -moz-border-radius: 5px;
- -webkit-border-radius: 5px;
- border-radius: 5px;
-
-}
-.ts-player .ts-control .ts-volume-bar { /*width will be changed inside the code*/
- background-color: #ccc;
- -moz-border-radius: 5px;
- -webkit-border-radius: 5px;
- border-radius: 5px;
-}
-/*position is set to absolute inside javascript*/
-.ts-player .ts-control .ts-wait {
- background-repeat: no-repeat;
- background-image: url('img/wait.gif');
- text-align: right;
- right:0;
- height:28px;
- line-height:28px;
- top:0;
- background-position: right center;
- padding-right: 30px;
- font-size: 80%;
- color: #000;
-}
+++ /dev/null
-/*
-* Style for the timeside player. The player div is supposed to be of class .ts-player. Change if needed
-* For details, see http://code.google.com/p/timeside/wiki/UiGuide?ts=1308677096&updated=UiGuide#CSS_and_skins
-*/
-
-.ts-player {
- padding: 0;
- border: solid 1px #ADADAD;
- margin-top: 2px;
-}
-
-
-.ts-player .ts-ruler{
- color: white;
- background-color: #2E2E2E;
- font-size: 10px;
- line-height: 13px;
-}
-/*svg style, MUST BE A SINGLE SELECTOR. FOR INSTANCE, THIS DOES NOT WORK WHEN SVG IS NOT SUPPORTED:
- ".ts-player .ts-ruler .ts-svg-ruler-upper-rect" */
-.ts-svg-ruler-upper-rect{
- fill: #595959;
- stroke-width:0;
- stroke: #595959; /*to be sure...*/
-}
-/*svg style, MUST BE A SINGLE SELECTOR. FOR INSTANCE, THIS DOES NOT WORK WHEN SVG IS NOT SUPPORTED:
- ".ts-player .ts-ruler .ts-svg-ruler-lines"*/
-.ts-svg-ruler-lines{
- stroke-width:1;
- stroke: #ADADAD;
-}
-
-/*wave:*/
-.ts-player .ts-wave {
- height: 130px;
-}
-
-/*.ts-player .ts-viewer .ts-marker {*/
-.ts-player .ts-ruler .ts-marker {
- padding: 0 0.5em;
- background: #e65911;
- color: #FFF;
- text-decoration: none;
-}
-/*svg style, MUST BE A SINGLE SELECTOR. FOR INSTANCE, THIS DOES NOT WORK WHEN SVG IS NOT SUPPORTED:
- ".ts-player .ts-wave .ts-image-canvas .ts-svg-marker-line" */
-.ts-svg-marker-line {
- fill: #e65911;
- stroke-width:0;
-}
-
-/*.ts-player .ts-viewer a.ts-pointer {*/
-.ts-player .ts-ruler a.ts-pointer {
- color: #BB0000;
- background-color: white;
- padding: 0 0.5em;
- border: solid 1px #BB0000;
-
- text-decoration: none;
- -moz-border-radius: .3em;
- -webkit-border-radius: .3em;
- border-radius: .3em;
- /*color: #3c4251; #6A0307 !important;*/
-}
-/*svg style, MUST BE A SINGLE SELECTOR. FOR INSTANCE, THIS DOES NOT WORK WHEN SVG IS NOT SUPPORTED:
- ".ts-player .ts-wave .ts-image-canvas .ts-svg-pointer-line" */
-.ts-svg-pointer-line {
- fill: #BB0000;
- stroke-width:0;
-}
-
-.ts-player .ts-wave .ts-image {
- background: #090e0d ;
-}
-
-.ts-player .ts-control {
- background: url('img/controlbg.png');
-}
-
- /** display (inline-block) and overflow of a is set inside javascript*/
-.ts-player .ts-control .ts-button {
- background-repeat: no-repeat;
- height:28px;
- width:28px;
-}
-.ts-player .ts-control .ts-play {
- background-image: url('img/play.png');
-}
-
-.ts-player .ts-control .ts-pause {
- background-image: url('img/pause.png');
-}
-
-.ts-player .ts-control .ts-rewind {
- background-image: url('img/rewind.png');
-}
-
-.ts-player .ts-control .ts-forward {
- background-image: url('img/forward.png');
-}
-
-.ts-player .ts-control .ts-set-marker {
- background-image: url('img/setmarker.png');
-}
-
-.ts-player .ts-control .ts-volume-speaker-on {
- background-image: url('img/volumeon.png');
- width:24px;
-}
-.ts-player .ts-control .ts-volume-speaker-off {
- background-image: url('img/volumeoff.png');
- width:24px;
-}
-.ts-player .ts-control .ts-volume-bar-container {
- background: url('img/controlbg-inverted.png');
- background-position: -3px left;
- background-repeat: repeat-x;
- height:10px;
- width:42px;
- margin-top:9px;
- -moz-border-radius: 5px;
- -webkit-border-radius: 5px;
- border-radius: 5px;
-
-}
-.ts-player .ts-control .ts-volume-bar { /*width will be changed inside the code*/
- background-color: #e4eaf1;
- -moz-border-radius: 5px;
- -webkit-border-radius: 5px;
- border-radius: 5px;
-}
-/*position is set to absolute inside javascript*/
-.ts-player .ts-control .ts-wait {
- background-repeat: no-repeat;
- background-image: url('img/wait3.gif');
- text-align: right;
- right:0;
- height:28px;
- line-height:28px;
- top:0;
- background-position: right center;
- padding-right: 60px;
- font-size: 80%;
- color:white;
-}
\ No newline at end of file
+++ /dev/null
-/*
-VideoJS Default Styles (http://videojs.com)
-Version GENERATED_AT_BUILD
-*/
-
-/*
-REQUIRED STYLES (be careful overriding)
-================================================================================ */
-/* When loading the player, the video tag is replaced with a DIV,
- that will hold the video tag or object tag for other playback methods.
- The div contains the video playback element (Flash or HTML5) and controls, and sets the width and height of the video.
-
- ** If you want to add some kind of border/padding (e.g. a frame), or special positioning, use another containing element.
- Otherwise you risk messing up control positioning and full window mode. **
-*/
-.video-js {
- background-color: #000; position: relative; padding: 0;
-
- /* Start with 10px for base font size so other dimensions can be em based and easily calculable. */
- font-size: 10px;
-
- /* Allow poster to be vertially aligned. */
- vertical-align: middle;
- /* display: table-cell; */ /*This works in Safari but not Firefox.*/
-}
-
-/* Playback technology elements expand to the width/height of the containing div. <video> or <object> */
-.video-js .vjs-tech { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
-
-/* Fix for Firefox 9 fullscreen (only if it is enabled). Not needed when checking fullScreenEnabled. */
-.video-js:-moz-full-screen { position: absolute; }
-
-/* Fullscreen Styles */
-body.vjs-full-window {
- padding: 0; margin: 0;
- height: 100%; overflow-y: auto; /* Fix for IE6 full-window. http://www.cssplay.co.uk/layouts/fixed.html */
-}
-.video-js.vjs-fullscreen {
- position: fixed; overflow: hidden; z-index: 1000; left: 0; top: 0; bottom: 0; right: 0; width: 100% !important; height: 100% !important;
- _position: absolute; /* IE6 Full-window (underscore hack) */
-}
-.video-js:-webkit-full-screen {
- width: 100% !important; height: 100% !important;
-}
-
-/* Poster Styles */
-.vjs-poster {
- margin: 0 auto; padding: 0; cursor: pointer;
-
- /* Scale with the size of the player div. Works when poster is vertically shorter, but stretches when it's less wide. */
- position: relative; width: 100%; max-height: 100%;
-}
-
-/* Text Track Styles */
-/* Overall track holder for both captions and subtitles */
-.video-js .vjs-text-track-display { text-align: center; position: absolute; bottom: 4em; left: 1em; right: 1em; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; }
-/* Individual tracks */
-.video-js .vjs-text-track {
- display: none; color: #fff; font-size: 1.4em; text-align: center; margin-bottom: 0.1em;
- /* Transparent black background, or fallback to all black (IE6) */
- background: rgb(0, 0, 0); background: rgba(0, 0, 0, 0.50);
-}
-.video-js .vjs-subtitles { color: #fff; }
-.video-js .vjs-captions { color: #fc6; }
-.vjs-tt-cue { display: block; }
-
-/* Fading sytles, used to fade control bar. */
-.vjs-fade-in {
- visibility: visible !important; /* Needed to make sure things hide in older browsers too. */
- opacity: 1 !important;
-
- -webkit-transition: visibility 0s linear 0s, opacity 0.3s linear;
- -moz-transition: visibility 0s linear 0s, opacity 0.3s linear;
- -ms-transition: visibility 0s linear 0s, opacity 0.3s linear;
- -o-transition: visibility 0s linear 0s, opacity 0.3s linear;
- transition: visibility 0s linear 0s, opacity 0.3s linear;
-}
-.vjs-fade-out {
- visibility: hidden !important;
- opacity: 0 !important;
-
- -webkit-transition: visibility 0s linear 1.5s,opacity 1.5s linear;
- -moz-transition: visibility 0s linear 1.5s,opacity 1.5s linear;
- -ms-transition: visibility 0s linear 1.5s,opacity 1.5s linear;
- -o-transition: visibility 0s linear 1.5s,opacity 1.5s linear;
- transition: visibility 0s linear 1.5s,opacity 1.5s linear;
-}
-
-/* DEFAULT SKIN (override in another file to create new skins)
-================================================================================
-Instead of editing this file, I recommend creating your own skin CSS file to be included after this file,
-so you can upgrade to newer versions easier. You can remove all these styles by removing the 'vjs-default-skin' class from the tag. */
-
-/* The default control bar. Created by bar.js */
-.vjs-default-skin .vjs-controls {
- position: absolute;
- bottom: 0; /* Distance from the bottom of the box/video. Keep 0. Use height to add more bottom margin. */
- left: 0; right: 0; /* 100% width of div */
- margin: 0; padding: 0; /* Controls are absolutely position, so no padding necessary */
- height: 2.6em; /* Including any margin you want above or below control items */
- color: #fff; border-top: 1px solid #404040;
-
- /* CSS Gradient */
- /* Can use the Ultimate CSS Gradient Generator: http://www.colorzilla.com/gradient-editor/ */
- background: #242424; /* Old browsers */
- background: -moz-linear-gradient(top, #242424 50%, #1f1f1f 50%, #171717 100%); /* FF3.6+ */
- background: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(50%,#242424), color-stop(50%,#1f1f1f), color-stop(100%,#171717)); /* Chrome,Safari4+ */
- background: -webkit-linear-gradient(top, #242424 50%,#1f1f1f 50%,#171717 100%); /* Chrome10+,Safari5.1+ */
- background: -o-linear-gradient(top, #242424 50%,#1f1f1f 50%,#171717 100%); /* Opera11.10+ */
- background: -ms-linear-gradient(top, #242424 50%,#1f1f1f 50%,#171717 100%); /* IE10+ */
- /* Filter was causing a lot of weird issues in IE. Elements would stop showing up, or other styles would break. */
- /*filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#242424', endColorstr='#171717',GradientType=0 );*/ /* IE6-9 */
- background: linear-gradient(top, #242424 50%,#1f1f1f 50%,#171717 100%); /* W3C */
-
- /* Start hidden and with 0 opacity. Opacity is used to fade in modern browsers. */
- /* Can't use display block to hide initially because widths of slider handles aren't calculated and avaialbe for positioning correctly. */
- visibility: hidden;
- opacity: 0;
-}
-
-/* General styles for individual controls. */
-.vjs-default-skin .vjs-control {
- position: relative; float: left;
- text-align: center; margin: 0; padding: 0;
- height: 2.6em; width: 2.6em;
-}
-
-.vjs-default-skin .vjs-control:focus {
- outline: 0;
-/* background-color: #555;*/
-}
-
-/* Hide control text visually, but have it available for screenreaders: h5bp.com/v */
-.vjs-default-skin .vjs-control-text { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
-
-
-/* Play/Pause
--------------------------------------------------------------------------------- */
-.vjs-default-skin .vjs-play-control { width: 5em; cursor: pointer !important; }
-/* Play Icon */
-.vjs-default-skin.vjs-paused .vjs-play-control div { width: 15px; height: 17px; background: url('video-js.png'); margin: 0.5em auto 0; }
-.vjs-default-skin.vjs-playing .vjs-play-control div { width: 15px; height: 17px; background: url('video-js.png') -25px 0; margin: 0.5em auto 0; }
-
-/* Rewind
--------------------------------------------------------------------------------- */
-.vjs-default-skin .vjs-rewind-control { width: 5em; cursor: pointer !important; }
-.vjs-default-skin .vjs-rewind-control div { width: 19px; height: 16px; background: url('video-js.png'); margin: 0.5em auto 0; }
-
-/* Volume/Mute
--------------------------------------------------------------------------------- */
-.vjs-default-skin .vjs-mute-control { width: 3.8em; cursor: pointer !important; float: right; }
-.vjs-default-skin .vjs-mute-control div { width: 22px; height: 16px; background: url('video-js.png') -75px -25px; margin: 0.5em auto 0; }
-.vjs-default-skin .vjs-mute-control.vjs-vol-0 div { background: url('video-js.png') 0 -25px; }
-.vjs-default-skin .vjs-mute-control.vjs-vol-1 div { background: url('video-js.png') -25px -25px; }
-.vjs-default-skin .vjs-mute-control.vjs-vol-2 div { background: url('video-js.png') -50px -25px; }
-
-
-.vjs-default-skin .vjs-volume-control { width: 5em; float: right; }
-.vjs-default-skin .vjs-volume-bar {
- position: relative; width: 5em; height: 0.6em; margin: 1em auto 0; cursor: pointer !important;
-
- -moz-border-radius: 0.3em; -webkit-border-radius: 0.3em; border-radius: 0.3em;
-
- background: #666;
- background: -moz-linear-gradient(top, #333, #666);
- background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#333), to(#666));
- background: -webkit-linear-gradient(top, #333, #666);
- background: -o-linear-gradient(top, #333, #666);
- background: -ms-linear-gradient(top, #333, #666);
- background: linear-gradient(top, #333, #666);
-}
-.vjs-default-skin .vjs-volume-level {
- position: absolute; top: 0; left: 0; height: 0.6em;
-
- -moz-border-radius: 0.3em; -webkit-border-radius: 0.3em; border-radius: 0.3em;
-
- background: #fff;
- background: -moz-linear-gradient(top, #fff, #ccc);
- background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#fff), to(#ccc));
- background: -webkit-linear-gradient(top, #fff, #ccc);
- background: -o-linear-gradient(top, #fff, #ccc);
- background: -ms-linear-gradient(top, #fff, #ccc);
- background: linear-gradient(top, #fff, #ccc);
-}
-.vjs-default-skin .vjs-volume-handle {
- position: absolute; top: -0.2em; width: 0.8em; height: 0.8em; background: #ccc; left: 0;
- border: 1px solid #fff;
- -moz-border-radius: 0.6em; -webkit-border-radius: 0.6em; border-radius: 0.6em;
-}
-
-/* Progress
--------------------------------------------------------------------------------- */
-.vjs-default-skin div.vjs-progress-control {
- position: absolute;
- left: 4.8em; right: 4.8em; /* Leave room for time displays. */
- height: 1.0em; width: auto;
- top: -1.3em; /* Set above the rest of the controls. And leave room for 2px of borders (progress bottom and controls top). */
- border-bottom: 1px solid #1F1F1F;
- border-top: 1px solid #222;
-
- /* CSS Gradient */
- background: #333;
- background: -moz-linear-gradient(top, #222, #333);
- background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#222), to(#333));
- background: -webkit-linear-gradient(top, #222, #333);
- background: -o-linear-gradient(top, #333, #222);
- background: -ms-linear-gradient(top, #333, #222);
- background: linear-gradient(top, #333, #222);
-
-
- /* 1px top shadow */
-/* -webkit-box-shadow: 0px -1px 0px 0px rgba(0, 0, 0, 0.15); -moz-box-shadow: 0px -1px 0px 0px rgba(0, 0, 0, 0.15); box-shadow: 0px -1px 0px 0px rgba(0, 0, 0, 0.15);*/
-}
-
-/* Box containing play and load progresses. Also acts as seek scrubber. */
-.vjs-default-skin .vjs-progress-holder {
- position: relative; cursor: pointer !important; /*overflow: hidden;*/
- padding: 0; margin: 0; /* Placement within the progress control item */
- height: 1.0em;
- -moz-border-radius: 0.6em; -webkit-border-radius: 0.6em; border-radius: 0.6em;
-
- /* CSS Gradient */
- background: #111;
- background: -moz-linear-gradient(top, #111, #262626);
- background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#111), to(#262626));
- background: -webkit-linear-gradient(top, #111, #262626);
- background: -o-linear-gradient(top, #111, #262626);
- background: -ms-linear-gradient(top, #111, #262626);
- background: linear-gradient(top, #111, #262626);
-}
-.vjs-default-skin .vjs-progress-holder .vjs-play-progress,
-.vjs-default-skin .vjs-progress-holder .vjs-load-progress { /* Progress Bars */
- position: absolute; display: block; height: 1.0em; margin: 0; padding: 0;
- left: 0; top: 0; /*Needed for IE6*/
- -moz-border-radius: 0.6em; -webkit-border-radius: 0.6em; border-radius: 0.6em;
-
- /*width: 0;*/
-}
-
-.vjs-default-skin .vjs-play-progress {
- /* CSS Gradient. */
- background: #fff; /* Old browsers */
- background: -moz-linear-gradient(top, #fff 0%, #d6d6d6 50%, #fff 100%);
- background: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%,#fff), color-stop(50%,#d6d6d6), color-stop(100%,#fff));
- background: -webkit-linear-gradient(top, #fff 0%,#d6d6d6 50%,#fff 100%);
- background: -o-linear-gradient(top, #fff 0%,#d6d6d6 50%,#fff 100%);
- background: -ms-linear-gradient(top, #fff 0%,#d6d6d6 50%,#fff 100%);
- background: linear-gradient(top, #fff 0%,#d6d6d6 50%,#fff 100%);
-
- background: #efefef;
- background: -moz-linear-gradient(top, #efefef 0%, #f5f5f5 50%, #dbdbdb 50%, #f1f1f1 100%);
- background: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%,#efefef), color-stop(50%,#f5f5f5), color-stop(50%,#dbdbdb), color-stop(100%,#f1f1f1));
- background: -webkit-linear-gradient(top, #efefef 0%,#f5f5f5 50%,#dbdbdb 50%,#f1f1f1 100%);
- background: -o-linear-gradient(top, #efefef 0%,#f5f5f5 50%,#dbdbdb 50%,#f1f1f1 100%);
- background: -ms-linear-gradient(top, #efefef 0%,#f5f5f5 50%,#dbdbdb 50%,#f1f1f1 100%);
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#efefef', endColorstr='#f1f1f1',GradientType=0 );
- background: linear-gradient(top, #efefef 0%,#f5f5f5 50%,#dbdbdb 50%,#f1f1f1 100%);
-}
-.vjs-default-skin .vjs-load-progress {
- opacity: 0.8;
-
- /* CSS Gradient */
- background: #666;
- background: -moz-linear-gradient(top, #666, #333);
- background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#666), to(#333));
- background: -webkit-linear-gradient(top, #666, #333);
- background: -o-linear-gradient(top, #666, #333);
- background: -ms-linear-gradient(top, #666, #333);
- background: linear-gradient(top, #666, #333);
-}
-
-.vjs-default-skin div.vjs-seek-handle {
- position: absolute;
- width: 16px; height: 16px; /* Match img pixles */
- margin-top: -0.3em;
- left: 0; top: 0; /*Needed for IE6*/
-
- background: url('video-js.png') 0 -50px;
- /* CSS Curved Corners. Needed to make shadows curved. */
- -moz-border-radius: 0.8em; -webkit-border-radius: 0.8em; border-radius: 0.8em;
- /* CSS Shadows */
- -webkit-box-shadow: 0 2px 4px 0 #000; -moz-box-shadow: 0 2px 4px 0 #000; box-shadow: 0 2px 4px 0 #000;
-}
-/* Time Display
--------------------------------------------------------------------------------- */
-.vjs-default-skin .vjs-time-controls {
- position: absolute;
- right: 0;
- height: 1.0em; width: 4.8em;
- top: -1.3em;
- border-bottom: 1px solid #1F1F1F;
- border-top: 1px solid #222;
- background-color: #333;
-
- font-size: 1em; line-height: 1.0em; font-weight: normal; font-family: Helvetica, Arial, sans-serif;
-
- background: #333;
- background: -moz-linear-gradient(top, #222, #333);
- background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#222), to(#333));
- background: -webkit-linear-gradient(top, #222, #333);
- background: -o-linear-gradient(top, #333, #222);
- background: -ms-linear-gradient(top, #333, #222);
- background: linear-gradient(top, #333, #222);
-
- /* 1px top shadow */
-/* -webkit-box-shadow: 0px -1px 0px 0px rgba(0, 0, 0, 0.15); -moz-box-shadow: 0px -1px 0px 0px rgba(0, 0, 0, 0.15); box-shadow: 0px -1px 0px 0px rgba(0, 0, 0, 0.15);*/
-}
-
-.vjs-default-skin .vjs-current-time { left: 0; }
-
-.vjs-default-skin .vjs-duration { right: 0; display: none; }
-.vjs-default-skin .vjs-remaining-time { right: 0; }
-
-.vjs-time-divider { display:none; }
-
-.vjs-default-skin .vjs-time-control { font-size: 1em; line-height: 1; font-weight: normal; font-family: Helvetica, Arial, sans-serif; }
-.vjs-default-skin .vjs-time-control span { line-height: 25px; /* Centering vertically */ }
-
-/* Fullscreen
--------------------------------------------------------------------------------- */
-.vjs-secondary-controls { float: right; }
-
-.vjs-default-skin .vjs-fullscreen-control { width: 3.8em; cursor: pointer !important; float: right; }
-.vjs-default-skin .vjs-fullscreen-control div { width: 16px; height: 16px; background: url('video-js.png') -50px 0; margin: 0.5em auto 0; }
-
-.vjs-default-skin.vjs-fullscreen .vjs-fullscreen-control div { background: url('video-js.png') -75px 0; }
-
-
-/* Big Play Button (at start)
----------------------------------------------------------*/
-.vjs-default-skin .vjs-big-play-button {
- display: block; /* Start hidden */ z-index: 2;
- position: absolute; top: 50%; left: 50%; width: 8.0em; height: 8.0em; margin: -42px 0 0 -42px; text-align: center; vertical-align: center; cursor: pointer !important;
- border: 0.2em solid #fff; opacity: 0.95;
- -webkit-border-radius: 25px; -moz-border-radius: 25px; border-radius: 25px;
-
- background: #454545;
- background: -moz-linear-gradient(top, #454545 0%, #232323 50%, #161616 50%, #3f3f3f 100%);
- background: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%,#454545), color-stop(50%,#232323), color-stop(50%,#161616), color-stop(100%,#3f3f3f));
- background: -webkit-linear-gradient(top, #454545 0%,#232323 50%,#161616 50%,#3f3f3f 100%);
- background: -o-linear-gradient(top, #454545 0%,#232323 50%,#161616 50%,#3f3f3f 100%);
- background: -ms-linear-gradient(top, #454545 0%,#232323 50%,#161616 50%,#3f3f3f 100%);
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#454545', endColorstr='#3f3f3f',GradientType=0 );
- background: linear-gradient(top, #454545 0%,#232323 50%,#161616 50%,#3f3f3f 100%);
-
- /* CSS Shadows */
- -webkit-box-shadow: 4px 4px 8px #000; -moz-box-shadow: 4px 4px 8px #000; box-shadow: 4px 4px 8px #000;
-}
-
-.vjs-default-skin div.vjs-big-play-button:hover {
- -webkit-box-shadow: 0 0 80px #fff; -moz-box-shadow: 0 0 80px #fff; box-shadow: 0 0 80px #fff;
-}
-
-.vjs-default-skin div.vjs-big-play-button span {
- position: absolute; top: 50%; left: 50%;
- display: block; width: 35px; height: 42px;
- margin: -20px 0 0 -15px; /* Using negative margin to center image. */
- background: url('video-js.png') -100px 0;
-}
-
-/* Loading Spinner
----------------------------------------------------------*/
-/* CSS Spinners by Kilian Valkhof - http://kilianvalkhof.com/2010/css-xhtml/css3-loading-spinners-without-images/ */
-.vjs-loading-spinner {
- display: none;
- position: absolute; top: 50%; left: 50%; width: 55px; height: 55px;
- margin: -28px 0 0 -28px;
- -webkit-animation-name: rotatethis;
- -webkit-animation-duration:1s;
- -webkit-animation-iteration-count:infinite;
- -webkit-animation-timing-function:linear;
- -moz-animation-name: rotatethis;
- -moz-animation-duration:1s;
- -moz-animation-iteration-count:infinite;
- -moz-animation-timing-function:linear;
-}
-
-@-webkit-keyframes rotatethis {
- 0% {-webkit-transform:scale(0.6) rotate(0deg); }
- 12.5% {-webkit-transform:scale(0.6) rotate(0deg); }
- 12.51% {-webkit-transform:scale(0.6) rotate(45deg); }
- 25% {-webkit-transform:scale(0.6) rotate(45deg); }
- 25.01% {-webkit-transform:scale(0.6) rotate(90deg);}
- 37.5% {-webkit-transform:scale(0.6) rotate(90deg);}
- 37.51% {-webkit-transform:scale(0.6) rotate(135deg);}
- 50% {-webkit-transform:scale(0.6) rotate(135deg);}
- 50.01% {-webkit-transform:scale(0.6) rotate(180deg);}
- 62.5% {-webkit-transform:scale(0.6) rotate(180deg);}
- 62.51% {-webkit-transform:scale(0.6) rotate(225deg);}
- 75% {-webkit-transform:scale(0.6) rotate(225deg);}
- 75.01% {-webkit-transform:scale(0.6) rotate(270deg);}
- 87.5% {-webkit-transform:scale(0.6) rotate(270deg);}
- 87.51% {-webkit-transform:scale(0.6) rotate(315deg);}
- 100% {-webkit-transform:scale(0.6) rotate(315deg);}
-}
-
-@-moz-keyframes rotatethis {
- 0% {-moz-transform:scale(0.6) rotate(0deg);}
- 12.5% {-moz-transform:scale(0.6) rotate(0deg);}
- 12.51% {-moz-transform:scale(0.6) rotate(45deg);}
- 25% {-moz-transform:scale(0.6) rotate(45deg);}
- 25.01% {-moz-transform:scale(0.6) rotate(90deg);}
- 37.5% {-moz-transform:scale(0.6) rotate(90deg);}
- 37.51% {-moz-transform:scale(0.6) rotate(135deg);}
- 50% {-moz-transform:scale(0.6) rotate(135deg);}
- 50.01% {-moz-transform:scale(0.6) rotate(180deg);}
- 62.5% {-moz-transform:scale(0.6) rotate(180deg);}
- 62.51% {-moz-transform:scale(0.6) rotate(225deg);}
- 75% {-moz-transform:scale(0.6) rotate(225deg);}
- 75.01% {-moz-transform:scale(0.6) rotate(270deg);}
- 87.5% {-moz-transform:scale(0.6) rotate(270deg);}
- 87.51% {-moz-transform:scale(0.6) rotate(315deg);}
- 100% {-moz-transform:scale(0.6) rotate(315deg);}
-}
-/* Each circle */
-div.vjs-loading-spinner .ball1 { opacity: 0.12; position:absolute; left: 20px; top: 0px; width: 13px; height: 13px; background: #fff;
- border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
-
-div.vjs-loading-spinner .ball2 { opacity: 0.25; position:absolute; left: 34px; top: 6px; width: 13px; height: 13px; background: #fff;
- border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
-
-div.vjs-loading-spinner .ball3 { opacity: 0.37; position:absolute; left: 40px; top: 20px; width: 13px; height: 13px; background: #fff;
- border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
-
-div.vjs-loading-spinner .ball4 { opacity: 0.50; position:absolute; left: 34px; top: 34px; width: 13px; height: 13px; background: #fff;
- border-radius: 10px; -webkit-border-radius: 10px; -moz-border-radius: 15px; border: 1px solid #ccc; }
-
-div.vjs-loading-spinner .ball5 { opacity: 0.62; position:absolute; left: 20px; top: 40px; width: 13px; height: 13px; background: #fff;
- border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
-
-div.vjs-loading-spinner .ball6 { opacity: 0.75; position:absolute; left: 6px; top: 34px; width: 13px; height: 13px; background: #fff;
- border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
-
-div.vjs-loading-spinner .ball7 { opacity: 0.87; position:absolute; left: 0px; top: 20px; width: 13px; height: 13px; background: #fff;
- border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
-
-div.vjs-loading-spinner .ball8 { opacity: 1.00; position:absolute; left: 6px; top: 6px; width: 13px; height: 13px; background: #fff;
- border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
-
-/* Menu Buttons (Captions/Subtitles/etc.)
--------------------------------------------------------------------------------- */
-.vjs-default-skin .vjs-menu-button {
- float: right; margin: 0.2em 0.5em 0 0; padding: 0; width: 3em; height: 2em; cursor: pointer !important;
-
- border: 1px solid #111; -moz-border-radius: 0.3em; -webkit-border-radius: 0.3em; border-radius: 0.3em;
-
- background: #4d4d4d;
- background: -moz-linear-gradient(top, #4d4d4d 0%, #3f3f3f 50%, #333333 50%, #252525 100%);
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#4d4d4d), color-stop(50%,#3f3f3f), color-stop(50%,#333333), color-stop(100%,#252525));
- background: -webkit-linear-gradient(top, #4d4d4d 0%,#3f3f3f 50%,#333333 50%,#252525 100%);
- background: -o-linear-gradient(top, #4d4d4d 0%,#3f3f3f 50%,#333333 50%,#252525 100%);
- background: -ms-linear-gradient(top, #4d4d4d 0%,#3f3f3f 50%,#333333 50%,#252525 100%);
- background: linear-gradient(top, #4d4d4d 0%,#3f3f3f 50%,#333333 50%,#252525 100%);
-}
-/* Button Icon */
-.vjs-default-skin .vjs-menu-button div { background: url('video-js.png') 0px -75px no-repeat; width: 16px; height: 16px; margin: 0.2em auto 0; padding: 0; }
-
-/* Button Pop-up Menu */
-.vjs-default-skin .vjs-menu-button ul {
- display: none; /* Start hidden. Hover will show. */
- opacity: 0.8;
- padding: 0; margin: 0;
- position: absolute; width: 10em; bottom: 2em; max-height: 15em;
- left: -3.5em; /* Width of menu - width of button / 2 */
- background-color: #111;
- border: 2px solid #333;
- -moz-border-radius: 0.7em; -webkit-border-radius: 1em; border-radius: .5em;
- -webkit-box-shadow: 0 2px 4px 0 #000; -moz-box-shadow: 0 2px 4px 0 #000; box-shadow: 0 2px 4px 0 #000;
- overflow: auto;
-}
-
-.vjs-default-skin .vjs-menu-button:focus ul,
-.vjs-default-skin .vjs-menu-button:hover ul { display: block; list-style: none; }
-.vjs-default-skin .vjs-menu-button ul li { list-style: none; margin: 0; padding: 0.3em 0 0.3em 20px; line-height: 1.4em; font-size: 1.2em; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; text-align: left; }
-.vjs-default-skin .vjs-menu-button ul li.vjs-selected { text-decoration: underline; background: url('video-js.png') -125px -50px no-repeat; }
-.vjs-default-skin .vjs-menu-button ul li:focus,
-.vjs-default-skin .vjs-menu-button ul li:hover,
-.vjs-default-skin .vjs-menu-button ul li.vjs-selected:focus,
-.vjs-default-skin .vjs-menu-button ul li.vjs-selected:hover { background-color: #ccc; color: #111; outline: 0; }
-.vjs-default-skin .vjs-menu-button ul li.vjs-menu-title {
- text-align: center; text-transform: uppercase; font-size: 1em; line-height: 2em; padding: 0; margin: 0 0 0.3em 0;
-
- color: #fff; font-weight: bold;
-
- cursor: default;
-
- background: #4d4d4d;
- background: -moz-linear-gradient(top, #4d4d4d 0%, #3f3f3f 50%, #333333 50%, #252525 100%);
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#4d4d4d), color-stop(50%,#3f3f3f), color-stop(50%,#333333), color-stop(100%,#252525));
- background: -webkit-linear-gradient(top, #4d4d4d 0%,#3f3f3f 50%,#333333 50%,#252525 100%);
- background: -o-linear-gradient(top, #4d4d4d 0%,#3f3f3f 50%,#333333 50%,#252525 100%);
- background: -ms-linear-gradient(top, #4d4d4d 0%,#3f3f3f 50%,#333333 50%,#252525 100%);
- background: linear-gradient(top, #4d4d4d 0%,#3f3f3f 50%,#333333 50%,#252525 100%);
-}
-
-/* Subtitles Button */
-.vjs-default-skin .vjs-captions-button div { background-position: -25px -75px; }
-.vjs-default-skin .vjs-chapters-button div { background-position: -100px -75px; }
-.vjs-default-skin .vjs-chapters-button ul { width: 20em; left: -8.5em; /* Width of menu - width of button / 2 */ }
\ No newline at end of file
+++ /dev/null
-.video-js{background-color:#000;position:relative;padding:0;font-size:10px;vertical-align:middle}.video-js .vjs-tech{position:absolute;top:0;left:0;width:100%;height:100%}.video-js:-moz-full-screen{position:absolute}body.vjs-full-window{padding:0;margin:0;height:100%;overflow-y:auto}.video-js.vjs-fullscreen{position:fixed;overflow:hidden;z-index:1000;left:0;top:0;bottom:0;right:0;width:100%!important;height:100%!important;_position:absolute}.video-js:-webkit-full-screen{width:100%!important;height:100%!important}.vjs-poster{margin:0 auto;padding:0;cursor:pointer;position:relative;width:100%;max-height:100%}.video-js .vjs-text-track-display{text-align:center;position:absolute;bottom:4em;left:1em;right:1em;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}.video-js .vjs-text-track{display:none;color:#fff;font-size:1.4em;text-align:center;margin-bottom:.1em;background:#000;background:rgba(0,0,0,0.50)}.video-js .vjs-subtitles{color:#fff}.video-js .vjs-captions{color:#fc6}.vjs-tt-cue{display:block}.vjs-fade-in{visibility:visible!important;opacity:1!important;-webkit-transition:visibility 0s linear 0s,opacity .3s linear;-moz-transition:visibility 0s linear 0s,opacity .3s linear;-ms-transition:visibility 0s linear 0s,opacity .3s linear;-o-transition:visibility 0s linear 0s,opacity .3s linear;transition:visibility 0s linear 0s,opacity .3s linear}.vjs-fade-out{visibility:hidden!important;opacity:0!important;-webkit-transition:visibility 0s linear 1.5s,opacity 1.5s linear;-moz-transition:visibility 0s linear 1.5s,opacity 1.5s linear;-ms-transition:visibility 0s linear 1.5s,opacity 1.5s linear;-o-transition:visibility 0s linear 1.5s,opacity 1.5s linear;transition:visibility 0s linear 1.5s,opacity 1.5s linear}.vjs-default-skin .vjs-controls{position:absolute;bottom:0;left:0;right:0;margin:0;padding:0;height:2.6em;color:#fff;border-top:1px solid #404040;background:#242424;background:-moz-linear-gradient(top,#242424 50%,#1f1f1f 50%,#171717 100%);background:-webkit-gradient(linear,0% 0,0% 100%,color-stop(50%,#242424),color-stop(50%,#1f1f1f),color-stop(100%,#171717));background:-webkit-linear-gradient(top,#242424 50%,#1f1f1f 50%,#171717 100%);background:-o-linear-gradient(top,#242424 50%,#1f1f1f 50%,#171717 100%);background:-ms-linear-gradient(top,#242424 50%,#1f1f1f 50%,#171717 100%);background:linear-gradient(top,#242424 50%,#1f1f1f 50%,#171717 100%);visibility:hidden;opacity:0}.vjs-default-skin .vjs-control{position:relative;float:left;text-align:center;margin:0;padding:0;height:2.6em;width:2.6em}.vjs-default-skin .vjs-control:focus{outline:0}.vjs-default-skin .vjs-control-text{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.vjs-default-skin .vjs-play-control{width:5em;cursor:pointer!important}.vjs-default-skin.vjs-paused .vjs-play-control div{width:15px;height:17px;background:url('video-js.png');margin:.5em auto 0}.vjs-default-skin.vjs-playing .vjs-play-control div{width:15px;height:17px;background:url('video-js.png') -25px 0;margin:.5em auto 0}.vjs-default-skin .vjs-rewind-control{width:5em;cursor:pointer!important}.vjs-default-skin .vjs-rewind-control div{width:19px;height:16px;background:url('video-js.png');margin:.5em auto 0}.vjs-default-skin .vjs-mute-control{width:3.8em;cursor:pointer!important;float:right}.vjs-default-skin .vjs-mute-control div{width:22px;height:16px;background:url('video-js.png') -75px -25px;margin:.5em auto 0}.vjs-default-skin .vjs-mute-control.vjs-vol-0 div{background:url('video-js.png') 0 -25px}.vjs-default-skin .vjs-mute-control.vjs-vol-1 div{background:url('video-js.png') -25px -25px}.vjs-default-skin .vjs-mute-control.vjs-vol-2 div{background:url('video-js.png') -50px -25px}.vjs-default-skin .vjs-volume-control{width:5em;float:right}.vjs-default-skin .vjs-volume-bar{position:relative;width:5em;height:.6em;margin:1em auto 0;cursor:pointer!important;-moz-border-radius:.3em;-webkit-border-radius:.3em;border-radius:.3em;background:#666;background:-moz-linear-gradient(top,#333,#666);background:-webkit-gradient(linear,0% 0,0% 100%,from(#333),to(#666));background:-webkit-linear-gradient(top,#333,#666);background:-o-linear-gradient(top,#333,#666);background:-ms-linear-gradient(top,#333,#666);background:linear-gradient(top,#333,#666)}.vjs-default-skin .vjs-volume-level{position:absolute;top:0;left:0;height:.6em;-moz-border-radius:.3em;-webkit-border-radius:.3em;border-radius:.3em;background:#fff;background:-moz-linear-gradient(top,#fff,#ccc);background:-webkit-gradient(linear,0% 0,0% 100%,from(#fff),to(#ccc));background:-webkit-linear-gradient(top,#fff,#ccc);background:-o-linear-gradient(top,#fff,#ccc);background:-ms-linear-gradient(top,#fff,#ccc);background:linear-gradient(top,#fff,#ccc)}.vjs-default-skin .vjs-volume-handle{position:absolute;top:-0.2em;width:.8em;height:.8em;background:#ccc;left:0;border:1px solid #fff;-moz-border-radius:.6em;-webkit-border-radius:.6em;border-radius:.6em}.vjs-default-skin div.vjs-progress-control{position:absolute;left:4.8em;right:4.8em;height:1.0em;width:auto;top:-1.3em;border-bottom:1px solid #1f1f1f;border-top:1px solid #222;background:#333;background:-moz-linear-gradient(top,#222,#333);background:-webkit-gradient(linear,0% 0,0% 100%,from(#222),to(#333));background:-webkit-linear-gradient(top,#222,#333);background:-o-linear-gradient(top,#333,#222);background:-ms-linear-gradient(top,#333,#222);background:linear-gradient(top,#333,#222)}.vjs-default-skin .vjs-progress-holder{position:relative;cursor:pointer!important;padding:0;margin:0;height:1.0em;-moz-border-radius:.6em;-webkit-border-radius:.6em;border-radius:.6em;background:#111;background:-moz-linear-gradient(top,#111,#262626);background:-webkit-gradient(linear,0% 0,0% 100%,from(#111),to(#262626));background:-webkit-linear-gradient(top,#111,#262626);background:-o-linear-gradient(top,#111,#262626);background:-ms-linear-gradient(top,#111,#262626);background:linear-gradient(top,#111,#262626)}.vjs-default-skin .vjs-progress-holder .vjs-play-progress,.vjs-default-skin .vjs-progress-holder .vjs-load-progress{position:absolute;display:block;height:1.0em;margin:0;padding:0;left:0;top:0;-moz-border-radius:.6em;-webkit-border-radius:.6em;border-radius:.6em}.vjs-default-skin .vjs-play-progress{background:#fff;background:-moz-linear-gradient(top,#fff 0,#d6d6d6 50%,#fff 100%);background:-webkit-gradient(linear,0% 0,0% 100%,color-stop(0%,#fff),color-stop(50%,#d6d6d6),color-stop(100%,#fff));background:-webkit-linear-gradient(top,#fff 0,#d6d6d6 50%,#fff 100%);background:-o-linear-gradient(top,#fff 0,#d6d6d6 50%,#fff 100%);background:-ms-linear-gradient(top,#fff 0,#d6d6d6 50%,#fff 100%);background:linear-gradient(top,#fff 0,#d6d6d6 50%,#fff 100%);background:#efefef;background:-moz-linear-gradient(top,#efefef 0,#f5f5f5 50%,#dbdbdb 50%,#f1f1f1 100%);background:-webkit-gradient(linear,0% 0,0% 100%,color-stop(0%,#efefef),color-stop(50%,#f5f5f5),color-stop(50%,#dbdbdb),color-stop(100%,#f1f1f1));background:-webkit-linear-gradient(top,#efefef 0,#f5f5f5 50%,#dbdbdb 50%,#f1f1f1 100%);background:-o-linear-gradient(top,#efefef 0,#f5f5f5 50%,#dbdbdb 50%,#f1f1f1 100%);background:-ms-linear-gradient(top,#efefef 0,#f5f5f5 50%,#dbdbdb 50%,#f1f1f1 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#efefef',endColorstr='#f1f1f1',GradientType=0);background:linear-gradient(top,#efefef 0,#f5f5f5 50%,#dbdbdb 50%,#f1f1f1 100%)}.vjs-default-skin .vjs-load-progress{opacity:.8;background:#666;background:-moz-linear-gradient(top,#666,#333);background:-webkit-gradient(linear,0% 0,0% 100%,from(#666),to(#333));background:-webkit-linear-gradient(top,#666,#333);background:-o-linear-gradient(top,#666,#333);background:-ms-linear-gradient(top,#666,#333);background:linear-gradient(top,#666,#333)}.vjs-default-skin div.vjs-seek-handle{position:absolute;width:16px;height:16px;margin-top:-0.3em;left:0;top:0;background:url('video-js.png') 0 -50px;-moz-border-radius:.8em;-webkit-border-radius:.8em;border-radius:.8em;-webkit-box-shadow:0 2px 4px 0 #000;-moz-box-shadow:0 2px 4px 0 #000;box-shadow:0 2px 4px 0 #000}.vjs-default-skin .vjs-time-controls{position:absolute;right:0;height:1.0em;width:4.8em;top:-1.3em;border-bottom:1px solid #1f1f1f;border-top:1px solid #222;background-color:#333;font-size:1em;line-height:1.0em;font-weight:normal;font-family:Helvetica,Arial,sans-serif;background:#333;background:-moz-linear-gradient(top,#222,#333);background:-webkit-gradient(linear,0% 0,0% 100%,from(#222),to(#333));background:-webkit-linear-gradient(top,#222,#333);background:-o-linear-gradient(top,#333,#222);background:-ms-linear-gradient(top,#333,#222);background:linear-gradient(top,#333,#222)}.vjs-default-skin .vjs-current-time{left:0}.vjs-default-skin .vjs-duration{right:0;display:none}.vjs-default-skin .vjs-remaining-time{right:0}.vjs-time-divider{display:none}.vjs-default-skin .vjs-time-control{font-size:1em;line-height:1;font-weight:normal;font-family:Helvetica,Arial,sans-serif}.vjs-default-skin .vjs-time-control span{line-height:25px}.vjs-secondary-controls{float:right}.vjs-default-skin .vjs-fullscreen-control{width:3.8em;cursor:pointer!important;float:right}.vjs-default-skin .vjs-fullscreen-control div{width:16px;height:16px;background:url('video-js.png') -50px 0;margin:.5em auto 0}.vjs-default-skin.vjs-fullscreen .vjs-fullscreen-control div{background:url('video-js.png') -75px 0}.vjs-default-skin .vjs-big-play-button{display:block;z-index:2;position:absolute;top:50%;left:50%;width:8.0em;height:8.0em;margin:-42px 0 0 -42px;text-align:center;vertical-align:center;cursor:pointer!important;border:.2em solid #fff;opacity:.95;-webkit-border-radius:25px;-moz-border-radius:25px;border-radius:25px;background:#454545;background:-moz-linear-gradient(top,#454545 0,#232323 50%,#161616 50%,#3f3f3f 100%);background:-webkit-gradient(linear,0% 0,0% 100%,color-stop(0%,#454545),color-stop(50%,#232323),color-stop(50%,#161616),color-stop(100%,#3f3f3f));background:-webkit-linear-gradient(top,#454545 0,#232323 50%,#161616 50%,#3f3f3f 100%);background:-o-linear-gradient(top,#454545 0,#232323 50%,#161616 50%,#3f3f3f 100%);background:-ms-linear-gradient(top,#454545 0,#232323 50%,#161616 50%,#3f3f3f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#454545',endColorstr='#3f3f3f',GradientType=0);background:linear-gradient(top,#454545 0,#232323 50%,#161616 50%,#3f3f3f 100%);-webkit-box-shadow:4px 4px 8px #000;-moz-box-shadow:4px 4px 8px #000;box-shadow:4px 4px 8px #000}.vjs-default-skin div.vjs-big-play-button:hover{-webkit-box-shadow:0 0 80px #fff;-moz-box-shadow:0 0 80px #fff;box-shadow:0 0 80px #fff}.vjs-default-skin div.vjs-big-play-button span{position:absolute;top:50%;left:50%;display:block;width:35px;height:42px;margin:-20px 0 0 -15px;background:url('video-js.png') -100px 0}.vjs-loading-spinner{display:none;position:absolute;top:50%;left:50%;width:55px;height:55px;margin:-28px 0 0 -28px;-webkit-animation-name:rotatethis;-webkit-animation-duration:1s;-webkit-animation-iteration-count:infinite;-webkit-animation-timing-function:linear;-moz-animation-name:rotatethis;-moz-animation-duration:1s;-moz-animation-iteration-count:infinite;-moz-animation-timing-function:linear}@-webkit-keyframes rotatethis{0%{-webkit-transform:scale(0.6) rotate(0deg)}12.5%{-webkit-transform:scale(0.6) rotate(0deg)}12.51%{-webkit-transform:scale(0.6) rotate(45deg)}25%{-webkit-transform:scale(0.6) rotate(45deg)}25.01%{-webkit-transform:scale(0.6) rotate(90deg)}37.5%{-webkit-transform:scale(0.6) rotate(90deg)}37.51%{-webkit-transform:scale(0.6) rotate(135deg)}50%{-webkit-transform:scale(0.6) rotate(135deg)}50.01%{-webkit-transform:scale(0.6) rotate(180deg)}62.5%{-webkit-transform:scale(0.6) rotate(180deg)}62.51%{-webkit-transform:scale(0.6) rotate(225deg)}75%{-webkit-transform:scale(0.6) rotate(225deg)}75.01%{-webkit-transform:scale(0.6) rotate(270deg)}87.5%{-webkit-transform:scale(0.6) rotate(270deg)}87.51%{-webkit-transform:scale(0.6) rotate(315deg)}100%{-webkit-transform:scale(0.6) rotate(315deg)}}@-moz-keyframes rotatethis{0%{-moz-transform:scale(0.6) rotate(0deg)}12.5%{-moz-transform:scale(0.6) rotate(0deg)}12.51%{-moz-transform:scale(0.6) rotate(45deg)}25%{-moz-transform:scale(0.6) rotate(45deg)}25.01%{-moz-transform:scale(0.6) rotate(90deg)}37.5%{-moz-transform:scale(0.6) rotate(90deg)}37.51%{-moz-transform:scale(0.6) rotate(135deg)}50%{-moz-transform:scale(0.6) rotate(135deg)}50.01%{-moz-transform:scale(0.6) rotate(180deg)}62.5%{-moz-transform:scale(0.6) rotate(180deg)}62.51%{-moz-transform:scale(0.6) rotate(225deg)}75%{-moz-transform:scale(0.6) rotate(225deg)}75.01%{-moz-transform:scale(0.6) rotate(270deg)}87.5%{-moz-transform:scale(0.6) rotate(270deg)}87.51%{-moz-transform:scale(0.6) rotate(315deg)}100%{-moz-transform:scale(0.6) rotate(315deg)}}div.vjs-loading-spinner .ball1{opacity:.12;position:absolute;left:20px;top:0;width:13px;height:13px;background:#fff;border-radius:13px;-webkit-border-radius:13px;-moz-border-radius:13px;border:1px solid #ccc}div.vjs-loading-spinner .ball2{opacity:.25;position:absolute;left:34px;top:6px;width:13px;height:13px;background:#fff;border-radius:13px;-webkit-border-radius:13px;-moz-border-radius:13px;border:1px solid #ccc}div.vjs-loading-spinner .ball3{opacity:.37;position:absolute;left:40px;top:20px;width:13px;height:13px;background:#fff;border-radius:13px;-webkit-border-radius:13px;-moz-border-radius:13px;border:1px solid #ccc}div.vjs-loading-spinner .ball4{opacity:.50;position:absolute;left:34px;top:34px;width:13px;height:13px;background:#fff;border-radius:10px;-webkit-border-radius:10px;-moz-border-radius:15px;border:1px solid #ccc}div.vjs-loading-spinner .ball5{opacity:.62;position:absolute;left:20px;top:40px;width:13px;height:13px;background:#fff;border-radius:13px;-webkit-border-radius:13px;-moz-border-radius:13px;border:1px solid #ccc}div.vjs-loading-spinner .ball6{opacity:.75;position:absolute;left:6px;top:34px;width:13px;height:13px;background:#fff;border-radius:13px;-webkit-border-radius:13px;-moz-border-radius:13px;border:1px solid #ccc}div.vjs-loading-spinner .ball7{opacity:.87;position:absolute;left:0;top:20px;width:13px;height:13px;background:#fff;border-radius:13px;-webkit-border-radius:13px;-moz-border-radius:13px;border:1px solid #ccc}div.vjs-loading-spinner .ball8{opacity:1.00;position:absolute;left:6px;top:6px;width:13px;height:13px;background:#fff;border-radius:13px;-webkit-border-radius:13px;-moz-border-radius:13px;border:1px solid #ccc}.vjs-default-skin .vjs-menu-button{float:right;margin:.2em .5em 0 0;padding:0;width:3em;height:2em;cursor:pointer!important;border:1px solid #111;-moz-border-radius:.3em;-webkit-border-radius:.3em;border-radius:.3em;background:#4d4d4d;background:-moz-linear-gradient(top,#4d4d4d 0,#3f3f3f 50%,#333 50%,#252525 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#4d4d4d),color-stop(50%,#3f3f3f),color-stop(50%,#333),color-stop(100%,#252525));background:-webkit-linear-gradient(top,#4d4d4d 0,#3f3f3f 50%,#333 50%,#252525 100%);background:-o-linear-gradient(top,#4d4d4d 0,#3f3f3f 50%,#333 50%,#252525 100%);background:-ms-linear-gradient(top,#4d4d4d 0,#3f3f3f 50%,#333 50%,#252525 100%);background:linear-gradient(top,#4d4d4d 0,#3f3f3f 50%,#333 50%,#252525 100%)}.vjs-default-skin .vjs-menu-button div{background:url('video-js.png') 0 -75px no-repeat;width:16px;height:16px;margin:.2em auto 0;padding:0}.vjs-default-skin .vjs-menu-button ul{display:none;opacity:.8;padding:0;margin:0;position:absolute;width:10em;bottom:2em;max-height:15em;left:-3.5em;background-color:#111;border:2px solid #333;-moz-border-radius:.7em;-webkit-border-radius:1em;border-radius:.5em;-webkit-box-shadow:0 2px 4px 0 #000;-moz-box-shadow:0 2px 4px 0 #000;box-shadow:0 2px 4px 0 #000;overflow:auto}.vjs-default-skin .vjs-menu-button:focus ul,.vjs-default-skin .vjs-menu-button:hover ul{display:block;list-style:none}.vjs-default-skin .vjs-menu-button ul li{list-style:none;margin:0;padding:.3em 0 .3em 20px;line-height:1.4em;font-size:1.2em;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;text-align:left}.vjs-default-skin .vjs-menu-button ul li.vjs-selected{text-decoration:underline;background:url('video-js.png') -125px -50px no-repeat}.vjs-default-skin .vjs-menu-button ul li:focus,.vjs-default-skin .vjs-menu-button ul li:hover,.vjs-default-skin .vjs-menu-button ul li.vjs-selected:focus,.vjs-default-skin .vjs-menu-button ul li.vjs-selected:hover{background-color:#ccc;color:#111;outline:0}.vjs-default-skin .vjs-menu-button ul li.vjs-menu-title{text-align:center;text-transform:uppercase;font-size:1em;line-height:2em;padding:0;margin:0 0 .3em 0;color:#fff;font-weight:bold;cursor:default;background:#4d4d4d;background:-moz-linear-gradient(top,#4d4d4d 0,#3f3f3f 50%,#333 50%,#252525 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#4d4d4d),color-stop(50%,#3f3f3f),color-stop(50%,#333),color-stop(100%,#252525));background:-webkit-linear-gradient(top,#4d4d4d 0,#3f3f3f 50%,#333 50%,#252525 100%);background:-o-linear-gradient(top,#4d4d4d 0,#3f3f3f 50%,#333 50%,#252525 100%);background:-ms-linear-gradient(top,#4d4d4d 0,#3f3f3f 50%,#333 50%,#252525 100%);background:linear-gradient(top,#4d4d4d 0,#3f3f3f 50%,#333 50%,#252525 100%)}.vjs-default-skin .vjs-captions-button div{background-position:-25px -75px}.vjs-default-skin .vjs-chapters-button div{background-position:-100px -75px}.vjs-default-skin .vjs-chapters-button ul{width:20em;left:-8.5em}
\ No newline at end of file
+++ /dev/null
-/*!
-Video.js - HTML5 Video Player
-Version GENERATED_AT_BUILD
-
-LGPL v3 LICENSE INFO
-This file is part of Video.js. Copyright 2011 Zencoder, Inc.
-
-Video.js is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-Video.js is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with Video.js. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-// Self-executing function to prevent global vars and help with minification
-;(function(window, undefined){
- var document = window.document;// HTML5 Shiv. Must be in <head> to support older browsers.
-document.createElement("video");document.createElement("audio");
-
-var VideoJS = function(id, addOptions, ready){
- var tag; // Element of ID
-
- // Allow for element or ID to be passed in
- // String ID
- if (typeof id == "string") {
-
- // Adjust for jQuery ID syntax
- if (id.indexOf("#") === 0) {
- id = id.slice(1);
- }
-
- // If a player instance has already been created for this ID return it.
- if (_V_.players[id]) {
- return _V_.players[id];
-
- // Otherwise get element for ID
- } else {
- tag = _V_.el(id)
- }
-
- // ID is a media element
- } else {
- tag = id;
- }
-
- // Check for a useable element
- if (!tag || !tag.nodeName) { // re: nodeName, could be a box div also
- throw new TypeError("The element or ID supplied is not valid. (VideoJS)"); // Returns
- }
-
- // Element may have a player attr referring to an already created player instance.
- // If not, set up a new player and return the instance.
- return tag.player || new _V_.Player(tag, addOptions, ready);
-},
-
-// Shortcut
-_V_ = VideoJS,
-
-// CDN Version. Used to target right flash swf.
-CDN_VERSION = "GENERATED_CDN_VSN";
-
-VideoJS.players = {};
-
-VideoJS.options = {
-
- // Default order of fallback technology
- techOrder: ["html5","flash"],
- // techOrder: ["flash","html5"],
-
- html5: {},
- flash: { swf: "http://vjs.zencdn.net/c/video-js.swf" },
-
- // Default of web browser is 300x150. Should rely on source width/height.
- width: 300,
- height: 150,
-
- // defaultVolume: 0.85,
- defaultVolume: 0.00, // The freakin seaguls are driving me crazy!
-
- // Included control sets
- components: {
- "posterImage": {},
- "textTrackDisplay": {},
- "loadingSpinner": {},
- "bigPlayButton": {},
- "controlBar": {}
- }
-
- // components: [
- // "poster",
- // "loadingSpinner",
- // "bigPlayButton",
- // { name: "controlBar", options: {
- // components: [
- // "playToggle",
- // "fullscreenToggle",
- // "currentTimeDisplay",
- // "timeDivider",
- // "durationDisplay",
- // "remainingTimeDisplay",
- // { name: "progressControl", options: {
- // components: [
- // { name: "seekBar", options: {
- // components: [
- // "loadProgressBar",
- // "playProgressBar",
- // "seekHandle"
- // ]}
- // }
- // ]}
- // },
- // { name: "volumeControl", options: {
- // components: [
- // { name: "volumeBar", options: {
- // components: [
- // "volumeLevel",
- // "volumeHandle"
- // ]}
- // }
- // ]}
- // },
- // "muteToggle"
- // ]
- // }},
- // "subtitlesDisplay"/*, "replay"*/
- // ]
-};
-
-// Set CDN Version of swf
-if (CDN_VERSION != "GENERATED_CDN_VSN") {
- _V_.options.flash.swf = "http://vjs.zencdn.net/"+CDN_VERSION+"/video-js.swf"
-}_V_.merge = function(obj1, obj2, safe){
- // Make sure second object exists
- if (!obj2) { obj2 = {}; };
-
- for (var attrname in obj2){
- if (obj2.hasOwnProperty(attrname) && (!safe || !obj1.hasOwnProperty(attrname))) { obj1[attrname]=obj2[attrname]; }
- }
- return obj1;
-};
-_V_.extend = function(obj){ this.merge(this, obj, true); };
-
-_V_.extend({
- tech: {}, // Holder for playback technology settings
- controlSets: {}, // Holder for control set definitions
-
- // Device Checks
- isIE: function(){ return !+"\v1"; },
- isFF: function(){ return !!_V_.ua.match("Firefox") },
- isIPad: function(){ return navigator.userAgent.match(/iPad/i) !== null; },
- isIPhone: function(){ return navigator.userAgent.match(/iPhone/i) !== null; },
- isIOS: function(){ return VideoJS.isIPhone() || VideoJS.isIPad(); },
- iOSVersion: function() {
- var match = navigator.userAgent.match(/OS (\d+)_/i);
- if (match && match[1]) { return match[1]; }
- },
- isAndroid: function(){ return navigator.userAgent.match(/Android.*AppleWebKit/i) !== null; },
- androidVersion: function() {
- var match = navigator.userAgent.match(/Android (\d+)\./i);
- if (match && match[1]) { return match[1]; }
- },
-
- testVid: document.createElement("video"),
- ua: navigator.userAgent,
- support: {},
-
- each: function(arr, fn){
- if (!arr || arr.length === 0) { return; }
- for (var i=0,j=arr.length; i<j; i++) {
- fn.call(this, arr[i], i);
- }
- },
-
- eachProp: function(obj, fn){
- if (!obj) { return; }
- for (var name in obj) {
- if (obj.hasOwnProperty(name)) {
- fn.call(this, name, obj[name]);
- }
- }
- },
-
- el: function(id){ return document.getElementById(id); },
- createElement: function(tagName, attributes){
- var el = document.createElement(tagName),
- attrname;
- for (attrname in attributes){
- if (attributes.hasOwnProperty(attrname)) {
- if (attrname.indexOf("-") !== -1) {
- el.setAttribute(attrname, attributes[attrname]);
- } else {
- el[attrname] = attributes[attrname];
- }
- }
- }
- return el;
- },
-
- insertFirst: function(node, parent){
- if (parent.firstChild) {
- parent.insertBefore(node, parent.firstChild);
- } else {
- parent.appendChild(node);
- }
- },
-
- addClass: function(element, classToAdd){
- if ((" "+element.className+" ").indexOf(" "+classToAdd+" ") == -1) {
- element.className = element.className === "" ? classToAdd : element.className + " " + classToAdd;
- }
- },
-
- removeClass: function(element, classToRemove){
- if (element.className.indexOf(classToRemove) == -1) { return; }
- var classNames = element.className.split(" ");
- classNames.splice(classNames.indexOf(classToRemove),1);
- element.className = classNames.join(" ");
- },
-
- // Attempt to block the ability to select text while dragging controls
- blockTextSelection: function(){
- document.body.focus();
- document.onselectstart = function () { return false; };
- },
- // Turn off text selection blocking
- unblockTextSelection: function(){ document.onselectstart = function () { return true; }; },
-
- // Return seconds as H:MM:SS or M:SS
- // Supplying a guide (in seconds) will include enough leading zeros to cover the length of the guide
- formatTime: function(seconds, guide) {
- guide = guide || seconds; // Default to using seconds as guide
- var s = Math.floor(seconds % 60),
- m = Math.floor(seconds / 60 % 60),
- h = Math.floor(seconds / 3600),
- gm = Math.floor(guide / 60 % 60),
- gh = Math.floor(guide / 3600);
-
- // Check if we need to show hours
- h = (h > 0 || gh > 0) ? h + ":" : "";
-
- // If hours are showing, we may need to add a leading zero.
- // Always show at least one digit of minutes.
- m = (((h || gm >= 10) && m < 10) ? "0" + m : m) + ":";
-
- // Check if leading zero is need for seconds
- s = (s < 10) ? "0" + s : s;
-
- return h + m + s;
- },
-
- uc: function(string){
- return string.charAt(0).toUpperCase() + string.slice(1);
- },
-
- // Return the relative horizonal position of an event as a value from 0-1
- getRelativePosition: function(x, relativeElement){
- return Math.max(0, Math.min(1, (x - _V_.findPosX(relativeElement)) / relativeElement.offsetWidth));
- },
-
- getComputedStyleValue: function(element, style){
- return window.getComputedStyle(element, null).getPropertyValue(style);
- },
-
- trim: function(string){ return string.toString().replace(/^\s+/, "").replace(/\s+$/, ""); },
- round: function(num, dec) {
- if (!dec) { dec = 0; }
- return Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
- },
-
- isEmpty: function(object) {
- for (var prop in object) {
- return false;
- }
- return true;
- },
-
- // Mimic HTML5 TimeRange Spec.
- createTimeRange: function(start, end){
- return {
- length: 1,
- start: function() { return start; },
- end: function() { return end; }
- };
- },
-
- /* Element Data Store. Allows for binding data to an element without putting it directly on the element.
- Ex. Event listneres are stored here.
- (also from jsninja.com)
- ================================================================================ */
- cache: {}, // Where the data is stored
- guid: 1, // Unique ID for the element
- expando: "vdata" + (new Date).getTime(), // Unique attribute to store element's guid in
-
- // Returns the cache object where data for the element is stored
- getData: function(elem){
- var id = elem[_V_.expando];
- if (!id) {
- id = elem[_V_.expando] = _V_.guid++;
- _V_.cache[id] = {};
- }
- return _V_.cache[id];
- },
- // Delete data for the element from the cache and the guid attr from element
- removeData: function(elem){
- var id = elem[_V_.expando];
- if (!id) { return; }
- // Remove all stored data
- delete _V_.cache[id];
- // Remove the expando property from the DOM node
- try {
- delete elem[_V_.expando];
- } catch(e) {
- if (elem.removeAttribute) {
- elem.removeAttribute(_V_.expando);
- } else {
- // IE doesn't appear to support removeAttribute on the document element
- elem[_V_.expando] = null;
- }
- }
- },
-
- /* Proxy (a.k.a Bind or Context). A simple method for changing the context of a function
- It also stores a unique id on the function so it can be easily removed from events
- ================================================================================ */
- proxy: function(context, fn, uid) {
- // Make sure the function has a unique ID
- if (!fn.guid) { fn.guid = _V_.guid++; }
-
- // Create the new function that changes the context
- var ret = function() {
- return fn.apply(context, arguments);
- }
-
- // Allow for the ability to individualize this function
- // Needed in the case where multiple objects might share the same prototype
- // IF both items add an event listener with the same function, then you try to remove just one
- // it will remove both because they both have the same guid.
- // when using this, you need to use the proxy method when you remove the listener as well.
- ret.guid = (uid) ? uid + "_" + fn.guid : fn.guid;
-
- return ret;
- },
-
- get: function(url, onSuccess, onError){
- // if (netscape.security.PrivilegeManager.enablePrivilege) {
- // netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
- // }
-
- var local = (url.indexOf("file:") == 0 || (window.location.href.indexOf("file:") == 0 && url.indexOf("http:") == -1));
-
- if (typeof XMLHttpRequest == "undefined") {
- XMLHttpRequest = function () {
- try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e) {}
- try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (f) {}
- try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (g) {}
- throw new Error("This browser does not support XMLHttpRequest.");
- };
- }
-
- var request = new XMLHttpRequest();
-
- try {
- request.open("GET", url);
- } catch(e) {
- _V_.log("VideoJS XMLHttpRequest (open)", e);
- // onError(e);
- return false;
- }
-
- request.onreadystatechange = _V_.proxy(this, function() {
- if (request.readyState == 4) {
- if (request.status == 200 || local && request.status == 0) {
- onSuccess(request.responseText);
- } else {
- if (onError) {
- onError();
- }
- }
- }
- });
-
- try {
- request.send();
- } catch(e) {
- _V_.log("VideoJS XMLHttpRequest (send)", e);
- if (onError) {
- onError(e);
- }
- }
- },
-
- /* Local Storage
- ================================================================================ */
- setLocalStorage: function(key, value){
- // IE was throwing errors referencing the var anywhere without this
- var localStorage = window.localStorage || false;
- if (!localStorage) { return; }
- try {
- localStorage[key] = value;
- } catch(e) {
- if (e.code == 22 || e.code == 1014) { // Webkit == 22 / Firefox == 1014
- _V_.log("LocalStorage Full (VideoJS)", e);
- } else {
- _V_.log("LocalStorage Error (VideoJS)", e);
- }
- }
- },
-
- // Get abosolute version of relative URL. Used to tell flash correct URL.
- // http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue
- getAbsoluteURL: function(url){
-
- // Check if absolute URL
- if (!url.match(/^https?:\/\//)) {
- // Convert to absolute URL. Flash hosted off-site needs an absolute URL.
- url = _V_.createElement('div', {
- innerHTML: '<a href="'+url+'">x</a>'
- }).firstChild.href;
- }
-
- return url;
- }
-
-});
-
-// usage: log('inside coolFunc', this, arguments);
-// paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
-_V_.log = function(){
- _V_.log.history = _V_.log.history || [];// store logs to an array for reference
- _V_.log.history.push(arguments);
- if(window.console) {
- arguments.callee = arguments.callee.caller;
- var newarr = [].slice.call(arguments);
- (typeof console.log === 'object' ? _V_.log.apply.call(console.log, console, newarr) : console.log.apply(console, newarr));
- }
-};
-
-// make it safe to use console.log always
-(function(b){function c(){}for(var d="assert,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,timeStamp,profile,profileEnd,time,timeEnd,trace,warn".split(","),a;a=d.pop();){b[a]=b[a]||c}})((function(){try
-{console.log();return window.console;}catch(err){return window.console={};}})());
-
-// Offset Left
-// getBoundingClientRect technique from John Resig http://ejohn.org/blog/getboundingclientrect-is-awesome/
-if ("getBoundingClientRect" in document.documentElement) {
- _V_.findPosX = function(el) {
- var box;
-
- try {
- box = el.getBoundingClientRect();
- } catch(e) {}
-
- if (!box) { return 0; }
-
- var docEl = document.documentElement,
- body = document.body,
- clientLeft = docEl.clientLeft || body.clientLeft || 0,
- scrollLeft = window.pageXOffset || body.scrollLeft,
- left = box.left + scrollLeft - clientLeft;
-
- return left;
- };
-} else {
- _V_.findPosX = function(el) {
- var curleft = el.offsetLeft;
- // _V_.log(obj.className, obj.offsetLeft)
- while(el = obj.offsetParent) {
- if (el.className.indexOf("video-js") == -1) {
- // _V_.log(el.offsetParent, "OFFSETLEFT", el.offsetLeft)
- // _V_.log("-webkit-full-screen", el.webkitMatchesSelector("-webkit-full-screen"));
- // _V_.log("-webkit-full-screen", el.querySelectorAll(".video-js:-webkit-full-screen"));
- } else {
- }
- curleft += el.offsetLeft;
- }
- return curleft;
- };
-}// Javascript JSON implementation
-// (Parse Method Only)
-// https://github.com/douglascrockford/JSON-js/blob/master/json2.js
-
-var JSON;
-if (!JSON) { JSON = {}; }
-
-(function(){
- var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
-
- if (typeof JSON.parse !== 'function') {
- JSON.parse = function (text, reviver) {
- var j;
-
- function walk(holder, key) {
- var k, v, value = holder[key];
- if (value && typeof value === 'object') {
- for (k in value) {
- if (Object.prototype.hasOwnProperty.call(value, k)) {
- v = walk(value, k);
- if (v !== undefined) {
- value[k] = v;
- } else {
- delete value[k];
- }
- }
- }
- }
- return reviver.call(holder, key, value);
- }
- text = String(text);
- cx.lastIndex = 0;
- if (cx.test(text)) {
- text = text.replace(cx, function (a) {
- return '\\u' +
- ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- });
- }
-
- if (/^[\],:{}\s]*$/
- .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
- .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
- .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
-
- j = eval('(' + text + ')');
-
- return typeof reviver === 'function' ?
- walk({'': j}, '') : j;
- }
-
- throw new SyntaxError('JSON.parse');
- };
- }
-}());
-// Event System (J.Resig - Secrets of a JS Ninja http://jsninja.com/ [Go read it, really])
-// (Book version isn't completely usable, so fixed some things and borrowed from jQuery where it's working)
-//
-// This should work very similarly to jQuery's events, however it's based off the book version which isn't as
-// robust as jquery's, so there's probably some differences.
-//
-// When you add an event listener using _V_.addEvent,
-// it stores the handler function in seperate cache object,
-// and adds a generic handler to the element's event,
-// along with a unique id (guid) to the element.
-
-_V_.extend({
-
- // Add an event listener to element
- // It stores the handler function in a separate cache object
- // and adds a generic handler to the element's event,
- // along with a unique id (guid) to the element.
- on: function(elem, type, fn){
- var data = _V_.getData(elem), handlers;
-
- // We only need to generate one handler per element
- if (data && !data.handler) {
- // Our new meta-handler that fixes the event object and the context
- data.handler = function(event){
- event = _V_.fixEvent(event);
- var handlers = _V_.getData(elem).events[event.type];
- // Go through and call all the real bound handlers
- if (handlers) {
-
- // Copy handlers so if handlers are added/removed during the process it doesn't throw everything off.
- var handlersCopy = [];
- _V_.each(handlers, function(handler, i){
- handlersCopy[i] = handler;
- })
-
- for (var i = 0, l = handlersCopy.length; i < l; i++) {
- handlersCopy[i].call(elem, event);
- }
- }
- };
- }
-
- // We need a place to store all our event data
- if (!data.events) { data.events = {}; }
-
- // And a place to store the handlers for this event type
- handlers = data.events[type];
-
- if (!handlers) {
- handlers = data.events[ type ] = [];
-
- // Attach our meta-handler to the element, since one doesn't exist
- if (document.addEventListener) {
- elem.addEventListener(type, data.handler, false);
- } else if (document.attachEvent) {
- elem.attachEvent("on" + type, data.handler);
- }
- }
-
- if (!fn.guid) { fn.guid = _V_.guid++; }
-
- handlers.push(fn);
- },
- // Deprecated name for 'on' function
- addEvent: function(){ return _V_.on.apply(this, arguments); },
-
- off: function(elem, type, fn) {
- var data = _V_.getData(elem), handlers;
- // If no events exist, nothing to unbind
- if (!data.events) { return; }
-
- // Are we removing all bound events?
- if (!type) {
- for (type in data.events) {
- _V_.cleanUpEvents(elem, type);
- }
- return;
- }
-
- // And a place to store the handlers for this event type
- handlers = data.events[type];
-
- // If no handlers exist, nothing to unbind
- if (!handlers) { return; }
-
- // See if we're only removing a single handler
- if (fn && fn.guid) {
- for (var i = 0; i < handlers.length; i++) {
- // We found a match (don't stop here, there could be a couple bound)
- if (handlers[i].guid === fn.guid) {
- // Remove the handler from the array of handlers
- handlers.splice(i--, 1);
- }
- }
- }
-
- _V_.cleanUpEvents(elem, type);
- },
- // Deprecated name for 'on' function
- removeEvent: function(){ return _V_.off.apply(this, arguments); },
-
- cleanUpEvents: function(elem, type) {
- var data = _V_.getData(elem);
- // Remove the events of a particular type if there are none left
-
- if (data.events[type].length === 0) {
- delete data.events[type];
-
- // Remove the meta-handler from the element
- if (document.removeEventListener) {
- elem.removeEventListener(type, data.handler, false);
- } else if (document.detachEvent) {
- elem.detachEvent("on" + type, data.handler);
- }
- }
-
- // Remove the events object if there are no types left
- if (_V_.isEmpty(data.events)) {
- delete data.events;
- delete data.handler;
- }
-
- // Finally remove the expando if there is no data left
- if (_V_.isEmpty(data)) {
- _V_.removeData(elem);
- }
- },
-
- fixEvent: function(event) {
- if (event[_V_.expando]) { return event; }
- // store a copy of the original event object
- // and "clone" to set read-only properties
- var originalEvent = event;
- event = new _V_.Event(originalEvent);
-
- for ( var i = _V_.Event.props.length, prop; i; ) {
- prop = _V_.Event.props[ --i ];
- event[prop] = originalEvent[prop];
- }
-
- // Fix target property, if necessary
- if (!event.target) { event.target = event.srcElement || document; }
-
- // check if target is a textnode (safari)
- if (event.target.nodeType === 3) { event.target = event.target.parentNode; }
-
- // Add relatedTarget, if necessary
- if (!event.relatedTarget && event.fromElement) {
- event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
- }
-
- // Calculate pageX/Y if missing and clientX/Y available
- if ( event.pageX == null && event.clientX != null ) {
- var eventDocument = event.target.ownerDocument || document,
- doc = eventDocument.documentElement,
- body = eventDocument.body;
-
- event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
- event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
- }
-
- // Add which for key events
- if (event.which == null && (event.charCode != null || event.keyCode != null)) {
- event.which = event.charCode != null ? event.charCode : event.keyCode;
- }
-
- // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
- if ( !event.metaKey && event.ctrlKey ) {
- event.metaKey = event.ctrlKey;
- }
-
- // Add which for click: 1 === left; 2 === middle; 3 === right
- // Note: button is not normalized, so don't use it
- if ( !event.which && event.button !== undefined ) {
- event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
- }
-
- return event;
- },
-
- trigger: function(elem, event) {
- var data = _V_.getData(elem),
- parent = elem.parentNode || elem.ownerDocument,
- type = event.type || event,
- handler;
-
- if (data) { handler = data.handler }
-
- // Added in attion to book. Book code was broke.
- event = typeof event === "object" ?
- event[_V_.expando] ?
- event :
- new _V_.Event(type, event) :
- new _V_.Event(type);
-
- event.type = type;
- if (handler) {
- handler.call(elem, event);
- }
-
- // Clean up the event in case it is being reused
- event.result = undefined;
- event.target = elem;
-
- // Bubble the event up the tree to the document,
- // Unless it's been explicitly stopped
- // if (parent && !event.isPropagationStopped()) {
- // _V_.triggerEvent(parent, event);
- //
- // // We're at the top document so trigger the default action
- // } else if (!parent && !event.isDefaultPrevented()) {
- // // log(type);
- // var targetData = _V_.getData(event.target);
- // // log(targetData);
- // var targetHandler = targetData.handler;
- // // log("2");
- // if (event.target[event.type]) {
- // // Temporarily disable the bound handler,
- // // don't want to execute it twice
- // if (targetHandler) {
- // targetData.handler = function(){};
- // }
- //
- // // Trigger the native event (click, focus, blur)
- // event.target[event.type]();
- //
- // // Restore the handler
- // if (targetHandler) {
- // targetData.handler = targetHandler;
- // }
- // }
- // }
- },
- // Deprecated name for 'on' function
- triggerEvent: function(){ return _V_.trigger.apply(this, arguments); },
-
- one: function(elem, type, fn) {
- _V_.on(elem, type, function(){
- _V_.off(elem, type, arguments.callee)
- fn.apply(this, arguments);
- });
- }
-});
-
-// Custom Event object for standardizing event objects between browsers.
-_V_.Event = function(src, props){
- // Event object
- if (src && src.type) {
- this.originalEvent = src;
- this.type = src.type;
-
- // Events bubbling up the document may have been marked as prevented
- // by a handler lower down the tree; reflect the correct value.
- this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
- src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
-
- // Event type
- } else {
- this.type = src;
- }
-
- // Put explicitly provided properties onto the event object
- if (props) { _V_.merge(this, props); }
-
- this.timeStamp = (new Date).getTime();
-
- // Mark it as fixed
- this[_V_.expando] = true;
-};
-
-_V_.Event.prototype = {
- preventDefault: function() {
- this.isDefaultPrevented = returnTrue;
-
- var e = this.originalEvent;
- if (!e) { return; }
-
- // if preventDefault exists run it on the original event
- if (e.preventDefault) {
- e.preventDefault();
- // otherwise set the returnValue property of the original event to false (IE)
- } else {
- e.returnValue = false;
- }
- },
- stopPropagation: function() {
- this.isPropagationStopped = returnTrue;
-
- var e = this.originalEvent;
- if (!e) { return; }
- // if stopPropagation exists run it on the original event
- if (e.stopPropagation) { e.stopPropagation(); }
- // otherwise set the cancelBubble property of the original event to true (IE)
- e.cancelBubble = true;
- },
- stopImmediatePropagation: function() {
- this.isImmediatePropagationStopped = returnTrue;
- this.stopPropagation();
- },
- isDefaultPrevented: returnFalse,
- isPropagationStopped: returnFalse,
- isImmediatePropagationStopped: returnFalse
-};
-_V_.Event.props = "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" ");
-
-function returnTrue(){ return true; }
-function returnFalse(){ return false; }
-
-// Using John Resig's Class implementation http://ejohn.org/blog/simple-javascript-inheritance/
-// (function(){var initializing=false, fnTest=/xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; _V_.Class = function(){}; _V_.Class.extend = function(prop) { var _super = this.prototype; initializing = true; var prototype = new this(); initializing = false; for (var name in prop) { prototype[name] = typeof prop[name] == "function" && typeof _super[name] == "function" && fnTest.test(prop[name]) ? (function(name, fn){ return function() { var tmp = this._super; this._super = _super[name]; var ret = fn.apply(this, arguments); this._super = tmp; return ret; }; })(name, prop[name]) : prop[name]; } function Class() { if ( !initializing && this.init ) this.init.apply(this, arguments); } Class.prototype = prototype; Class.constructor = Class; Class.extend = arguments.callee; return Class;};})();
-(function(){
- var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
- _V_.Class = function(){};
- _V_.Class.extend = function(prop) {
- var _super = this.prototype;
- initializing = true;
- var prototype = new this();
- initializing = false;
- for (var name in prop) {
- prototype[name] = typeof prop[name] == "function" &&
- typeof _super[name] == "function" && fnTest.test(prop[name]) ?
- (function(name, fn){
- return function() {
- var tmp = this._super;
- this._super = _super[name];
- var ret = fn.apply(this, arguments);
- this._super = tmp;
- return ret;
- };
- })(name, prop[name]) :
- prop[name];
- }
- function Class() {
- if ( !initializing && this.init ) {
- return this.init.apply(this, arguments);
-
- // Attempting to recreate accessing function form of class.
- } else if (!initializing) {
- return arguments.callee.prototype.init()
- }
- }
- Class.prototype = prototype;
- Class.constructor = Class;
- Class.extend = arguments.callee;
- return Class;
- };
-})();
-
-/* Player Component- Base class for all UI objects
-================================================================================ */
-_V_.Component = _V_.Class.extend({
-
- init: function(player, options){
- this.player = player;
-
- // Allow for overridding default component options
- options = this.options = _V_.merge(this.options || {}, options);
-
- // Create element if one wasn't provided in options
- if (options.el) {
- this.el = options.el;
- } else {
- this.el = this.createElement();
- }
-
- // Add any components in options
- this.initComponents();
- },
-
- destroy: function(){},
-
- createElement: function(type, attrs){
- return _V_.createElement(type || "div", attrs);
- },
-
- buildCSSClass: function(){
- // Child classes can include a function that does:
- // return "CLASS NAME" + this._super();
- return "";
- },
-
- initComponents: function(){
- var options = this.options;
- if (options && options.components) {
- // Loop through components and add them to the player
- this.eachProp(options.components, function(name, opts){
-
- // Allow waiting to add components until a specific event is called
- var tempAdd = this.proxy(function(){
- // Set property name on player. Could cause conflicts with other prop names, but it's worth making refs easy.
- this[name] = this.addComponent(name, opts);
- });
-
- if (opts.loadEvent) {
- this.one(opts.loadEvent, tempAdd)
- } else {
- tempAdd();
- }
- });
- }
- },
-
- // Add child components to this component.
- // Will generate a new child component and then append child component's element to this component's element.
- // Takes either the name of the UI component class, or an object that contains a name, UI Class, and options.
- addComponent: function(name, options){
- var component, componentClass;
-
- // If string, create new component with options
- if (typeof name == "string") {
-
- // Make sure options is at least an empty object to protect against errors
- options = options || {};
-
- // Assume name of set is a lowercased name of the UI Class (PlayButton, etc.)
- componentClass = options.componentClass || _V_.uc(name);
-
- // Create a new object & element for this controls set
- // If there's no .player, this is a player
- component = new _V_[componentClass](this.player || this, options);
-
- } else {
- component = name;
- }
-
- // Add the UI object's element to the container div (box)
- this.el.appendChild(component.el);
-
- // Return so it can stored on parent object if desired.
- return component;
- },
-
- removeComponent: function(component){
- this.el.removeChild(component.el);
- },
-
- /* Display
- ================================================================================ */
- show: function(){
- this.el.style.display = "block";
- },
-
- hide: function(){
- this.el.style.display = "none";
- },
-
- fadeIn: function(){
- this.removeClass("vjs-fade-out");
- this.addClass("vjs-fade-in");
- },
-
- fadeOut: function(){
- this.removeClass("vjs-fade-in");
- this.addClass("vjs-fade-out");
- },
-
- lockShowing: function(){
- var style = this.el.style;
- style.display = "block";
- style.opacity = 1;
- style.visiblity = "visible";
- },
-
- unlockShowing: function(){
- var style = this.el.style;
- style.display = "";
- style.opacity = "";
- style.visiblity = "";
- },
-
- addClass: function(classToAdd){
- _V_.addClass(this.el, classToAdd);
- },
-
- removeClass: function(classToRemove){
- _V_.removeClass(this.el, classToRemove);
- },
-
- /* Events
- ================================================================================ */
- on: function(type, fn, uid){
- return _V_.on(this.el, type, _V_.proxy(this, fn));
- },
- // Deprecated name for 'on' function
- addEvent: function(){ return this.on.apply(this, arguments); },
-
- off: function(type, fn){
- return _V_.off(this.el, type, fn);
- },
- // Deprecated name for 'off' function
- removeEvent: function(){ return this.off.apply(this, arguments); },
-
- trigger: function(type, e){
- return _V_.trigger(this.el, type, e);
- },
- // Deprecated name for 'off' function
- triggerEvent: function(){ return this.trigger.apply(this, arguments); },
-
- one: function(type, fn) {
- _V_.one(this.el, type, _V_.proxy(this, fn));
- },
-
- /* Ready - Trigger functions when component is ready
- ================================================================================ */
- ready: function(fn){
- if (!fn) return this;
-
- if (this.isReady) {
- fn.call(this);
- } else {
- if (this.readyQueue === undefined) {
- this.readyQueue = [];
- }
- this.readyQueue.push(fn);
- }
-
- return this;
- },
-
- triggerReady: function(){
- this.isReady = true;
- if (this.readyQueue && this.readyQueue.length > 0) {
- // Call all functions in ready queue
- this.each(this.readyQueue, function(fn){
- fn.call(this);
- });
-
- // Reset Ready Queue
- this.readyQueue = [];
-
- // Allow for using event listeners also, in case you want to do something everytime a source is ready.
- this.trigger("ready");
- }
- },
-
- /* Utility
- ================================================================================ */
- each: function(arr, fn){ _V_.each.call(this, arr, fn); },
-
- eachProp: function(obj, fn){ _V_.eachProp.call(this, obj, fn); },
-
- extend: function(obj){ _V_.merge(this, obj) },
-
- // More easily attach 'this' to functions
- proxy: function(fn, uid){ return _V_.proxy(this, fn, uid); }
-
-});/* UI Component- Base class for all UI objects
-================================================================================ */
-_V_.Player = _V_.Component.extend({
-
- init: function(tag, addOptions, ready){
-
- this.tag = tag; // Store the original tag used to set options
-
- var el = this.el = _V_.createElement("div"), // Div to contain video and controls
- options = this.options = {};
-
- // Set Options
- _V_.merge(options, _V_.options); // Copy Global Defaults
- _V_.merge(options, this.getVideoTagSettings()); // Override with Video Tag Options
- _V_.merge(options, addOptions); // Override/extend with options from setup call
-
- // Add callback to ready queue
- this.ready(ready);
-
- // Store controls setting, and then remove immediately so native controls don't flash.
- tag.removeAttribute("controls");
-
- // Poster will be handled by a manual <img>
- tag.removeAttribute("poster");
-
- // Make player findable on elements
- tag.player = el.player = this;
-
- // Make sure tag ID exists
- tag.id = tag.id || "vjs_video_" + _V_.guid++;
-
- // Give video tag properties to box
- // ID will now reference box, not the video tag
- this.id = el.id = tag.id;
- el.className = tag.className;
-
- // Make player easily findable by ID
- _V_.players[el.id] = this;
-
- // Make box use width/height of tag, or default 300x150
- el.setAttribute("width", options.width);
- el.setAttribute("height", options.height);
-
- // Enforce with CSS since width/height attrs don't work on divs
- el.style.width = options.width+"px";
- el.style.height = options.height+"px";
-
- // Update tag id/class for use as HTML5 playback tech
- // Might think we should do this after embedding in container so .vjs-tech class
- // doesn't flash 100% width/height, but class only applies with .video-js parent
- tag.id += "_html5_api";
- tag.className = "vjs-tech";
-
- // Remove width/height attrs from tag so CSS can make it 100% width/height
- tag.removeAttribute("width");
- tag.removeAttribute("height");
-
- // Wrap video tag in div (el/box) container
- tag.parentNode.insertBefore(el, tag);
- el.appendChild(tag); // Breaks iPhone, fixed in HTML5 setup.
-
- // Empty video tag sources and tracks so the built-in player doesn't use them also.
- if (tag.hasChildNodes()) {
- var nrOfChildNodes = tag.childNodes.length;
- for (var i=0,j=tag.childNodes;i<nrOfChildNodes;i++) {
- if (j[0].nodeName.toLowerCase() == "source" || j[0].nodeName.toLowerCase() == "track") {
- tag.removeChild(j[0]);
- }
- }
- }
-
- // Cache for video property values.
- this.values = {};
-
- this.addClass("vjs-paused");
-
- this.on("ended", this.onEnded);
- this.on("play", this.onPlay);
- this.on("pause", this.onPause);
- this.on("progress", this.onProgress);
- this.on("error", this.onError);
-
- // When the API is ready, loop through the components and add to the player.
- if (options.controls) {
- this.ready(function(){
- this.initComponents();
- });
- }
-
- // Tracks defined in tracks.js
- this.textTracks = [];
- if (options.tracks && options.tracks.length > 0) {
- this.addTextTracks(options.tracks);
- }
-
- // If there are no sources when the player is initialized,
- // load the first supported playback technology.
- if (!options.sources || options.sources.length == 0) {
- for (var i=0,j=options.techOrder; i<j.length; i++) {
- var techName = j[i],
- tech = _V_[techName];
-
- // Check if the browser supports this technology
- if (tech.isSupported()) {
- this.loadTech(techName);
- break;
- }
- }
- } else {
- // Loop through playback technologies (HTML5, Flash) and check for support. Then load the best source.
- // A few assumptions here:
- // All playback technologies respect preload false.
- this.src(options.sources);
- }
- },
-
- destroy: function(){
- // Ensure that tracking progress and time progress will stop and plater deleted
- this.stopTrackingProgress();
- this.stopTrackingCurrentTime();
- _V_.players[this.id] = null;
- delete _V_.players[this.id];
- this.tech.destroy();
- this.el.parentNode.removeChild(this.el);
- },
-
- createElement: function(type, options){},
-
- getVideoTagSettings: function(){
- var options = {
- sources: [],
- tracks: []
- },
- tag = this.tag,
- getAttribute = "getAttribute"; // For better minification
-
- options.src = tag[getAttribute]("src");
- options.controls = tag[getAttribute]("controls") !== null;
- options.poster = tag[getAttribute]("poster");
- options.preload = tag[getAttribute]("preload");
- options.autoplay = tag[getAttribute]("autoplay") !== null; // hasAttribute not IE <8 compatible
- options.loop = tag[getAttribute]("loop") !== null;
- options.muted = tag[getAttribute]("muted") !== null;
-
- options.width = tag[getAttribute]("width");
- options.height = tag[getAttribute]("height");
-
- if (this.tag.hasChildNodes()) {
- for (var c,i=0,j=this.tag.childNodes;i<j.length;i++) {
- c = j[i];
- if (c.nodeName.toLowerCase() == "source") {
- options.sources.push({
- src: c[getAttribute]('src'),
- type: c[getAttribute]('type'),
- media: c[getAttribute]('media'),
- title: c[getAttribute]('title')
- });
- }
- if (c.nodeName.toLowerCase() == "track") {
- options.tracks.push({
- src: c[getAttribute]("src"),
- kind: c[getAttribute]("kind"),
- srclang: c[getAttribute]("srclang"),
- label: c[getAttribute]("label"),
- 'default': c[getAttribute]("default") !== null,
- title: c[getAttribute]("title")
- });
- }
- }
- }
- return options;
- },
-
- /* PLayback Technology (tech)
- ================================================================================ */
- // Load/Create an instance of playback technlogy including element and API methods
- // And append playback element in player div.
- loadTech: function(techName, source){
-
- // Pause and remove current playback technology
- if (this.tech) {
- this.unloadTech();
-
- // If the first time loading, HTML5 tag will exist but won't be initialized
- // So we need to remove it if we're not loading HTML5
- } else if (techName != "html5" && this.tag) {
- this.el.removeChild(this.tag);
- this.tag = false;
- }
-
- this.techName = techName;
-
- // Turn off API access because we're loading a new tech that might load asynchronously
- this.isReady = false;
-
- var techReady = function(){
- this.player.triggerReady();
-
- // Manually track progress in cases where the browser/flash player doesn't report it.
- if (!this.support.progressEvent) {
- this.player.manualProgressOn();
- }
-
- // Manually track timeudpates in cases where the browser/flash player doesn't report it.
- if (!this.support.timeupdateEvent) {
- this.player.manualTimeUpdatesOn();
- }
- }
-
- // Grab tech-specific options from player options and add source and parent element to use.
- var techOptions = _V_.merge({ source: source, parentEl: this.el }, this.options[techName])
-
- if (source) {
- if (source.src == this.values.src && this.values.currentTime > 0) {
- techOptions.startTime = this.values.currentTime;
- }
-
- this.values.src = source.src;
- }
-
- // Initialize tech instance
- this.tech = new _V_[techName](this, techOptions);
- this.tech.ready(techReady);
- },
-
- unloadTech: function(){
- this.tech.destroy();
-
- // Turn off any manual progress or timeupdate tracking
- if (this.manualProgress) { this.manualProgressOff(); }
-
- if (this.manualTimeUpdates) { this.manualTimeUpdatesOff(); }
-
- this.tech = false;
- },
-
- // There's many issues around changing the size of a Flash (or other plugin) object.
- // First is a plugin reload issue in Firefox that has been around for 11 years: https://bugzilla.mozilla.org/show_bug.cgi?id=90268
- // Then with the new fullscreen API, Mozilla and webkit browsers will reload the flash object after going to fullscreen.
- // To get around this, we're unloading the tech, caching source and currentTime values, and reloading the tech once the plugin is resized.
- // reloadTech: function(betweenFn){
- // _V_.log("unloadingTech")
- // this.unloadTech();
- // _V_.log("unloadedTech")
- // if (betweenFn) { betweenFn.call(); }
- // _V_.log("LoadingTech")
- // this.loadTech(this.techName, { src: this.values.src })
- // _V_.log("loadedTech")
- // },
-
- /* Fallbacks for unsupported event types
- ================================================================================ */
- // Manually trigger progress events based on changes to the buffered amount
- // Many flash players and older HTML5 browsers don't send progress or progress-like events
- manualProgressOn: function(){
- this.manualProgress = true;
-
- // Trigger progress watching when a source begins loading
- this.trackProgress();
-
- // Watch for a native progress event call on the tech element
- // In HTML5, some older versions don't support the progress event
- // So we're assuming they don't, and turning off manual progress if they do.
- this.tech.on("progress", function(){
-
- // Remove this listener from the element
- this.removeEvent("progress", arguments.callee);
-
- // Update known progress support for this playback technology
- this.support.progressEvent = true;
-
- // Turn off manual progress tracking
- this.player.manualProgressOff();
- });
- },
-
- manualProgressOff: function(){
- this.manualProgress = false;
- this.stopTrackingProgress();
- },
-
- trackProgress: function(){
- this.progressInterval = setInterval(_V_.proxy(this, function(){
- // Don't trigger unless buffered amount is greater than last time
- // log(this.values.bufferEnd, this.buffered().end(0), this.duration())
- /* TODO: update for multiple buffered regions */
- if (this.values.bufferEnd < this.buffered().end(0)) {
- this.trigger("progress");
- } else if (this.bufferedPercent() == 1) {
- this.stopTrackingProgress();
- this.trigger("progress"); // Last update
- }
- }), 500);
- },
- stopTrackingProgress: function(){ clearInterval(this.progressInterval); },
-
- /* Time Tracking -------------------------------------------------------------- */
- manualTimeUpdatesOn: function(){
- this.manualTimeUpdates = true;
-
- this.on("play", this.trackCurrentTime);
- this.on("pause", this.stopTrackingCurrentTime);
- // timeupdate is also called by .currentTime whenever current time is set
-
- // Watch for native timeupdate event
- this.tech.on("timeupdate", function(){
-
- // Remove this listener from the element
- this.removeEvent("timeupdate", arguments.callee);
-
- // Update known progress support for this playback technology
- this.support.timeupdateEvent = true;
-
- // Turn off manual progress tracking
- this.player.manualTimeUpdatesOff();
- });
- },
-
- manualTimeUpdatesOff: function(){
- this.manualTimeUpdates = false;
- this.stopTrackingCurrentTime();
- this.removeEvent("play", this.trackCurrentTime);
- this.removeEvent("pause", this.stopTrackingCurrentTime);
- },
-
- trackCurrentTime: function(){
- if (this.currentTimeInterval) { this.stopTrackingCurrentTime(); }
- this.currentTimeInterval = setInterval(_V_.proxy(this, function(){
- this.trigger("timeupdate");
- }), 250); // 42 = 24 fps // 250 is what Webkit uses // FF uses 15
- },
-
- // Turn off play progress tracking (when paused or dragging)
- stopTrackingCurrentTime: function(){ clearInterval(this.currentTimeInterval); },
-
- /* Player event handlers (how the player reacts to certain events)
- ================================================================================ */
- onEnded: function(){
- if (this.options.loop) {
- this.currentTime(0);
- this.play();
- } else {
- this.pause();
- this.currentTime(0);
- this.pause();
- }
- },
-
- onPlay: function(){
- _V_.removeClass(this.el, "vjs-paused");
- _V_.addClass(this.el, "vjs-playing");
- },
-
- onPause: function(){
- _V_.removeClass(this.el, "vjs-playing");
- _V_.addClass(this.el, "vjs-paused");
- },
-
- onProgress: function(){
- // Add custom event for when source is finished downloading.
- if (this.bufferedPercent() == 1) {
- this.trigger("loadedalldata");
- }
- },
-
- onError: function(e) {
- _V_.log("Video Error", e);
- },
-
-/* Player API
-================================================================================ */
-
- // Pass values to the playback tech
- techCall: function(method, arg){
-
- // If it's not ready yet, call method when it is
- if (!this.tech.isReady) {
- this.tech.ready(function(){
- this[method](arg);
- });
-
- // Otherwise call method now
- } else {
- try {
- this.tech[method](arg);
- } catch(e) {
- _V_.log(e);
- }
- }
- },
-
- // Get calls can't wait for the tech, and sometimes don't need to.
- techGet: function(method){
-
- // Make sure tech is ready
- if (this.tech.isReady) {
-
- // Flash likes to die and reload when you hide or reposition it.
- // In these cases the object methods go away and we get errors.
- // When that happens we'll catch the errors and inform tech that it's not ready any more.
- try {
- return this.tech[method]();
- } catch(e) {
-
- // When building additional tech libs, an expected method may not be defined yet
- if (this.tech[method] === undefined) {
- _V_.log("Video.js: " + method + " method not defined for "+this.techName+" playback technology.", e);
-
- } else {
-
- // When a method isn't available on the object it throws a TypeError
- if (e.name == "TypeError") {
- _V_.log("Video.js: " + method + " unavailable on "+this.techName+" playback technology element.", e);
- this.tech.isReady = false;
-
- } else {
- _V_.log(e);
- }
- }
- }
- }
-
- return;
- },
-
- // Method for calling methods on the current playback technology
- // techCall: function(method, arg){
- //
- // // if (this.isReady) {
- // //
- // // } else {
- // // _V_.log("The playback technology API is not ready yet. Use player.ready(myFunction)."+" ["+method+"]", arguments.callee.caller.arguments.callee.caller.arguments.callee.caller)
- // // return false;
- // // // throw new Error("The playback technology API is not ready yet. Use player.ready(myFunction)."+" ["+method+"]");
- // // }
- // },
-
- // http://dev.w3.org/html5/spec/video.html#dom-media-play
- play: function(){
- this.techCall("play");
- return this;
- },
-
- // http://dev.w3.org/html5/spec/video.html#dom-media-pause
- pause: function(){
- this.techCall("pause");
- return this;
- },
-
- // http://dev.w3.org/html5/spec/video.html#dom-media-paused
- // The initial state of paused should be true (in Safari it's actually false)
- paused: function(){
- return (this.techGet("paused") === false) ? false : true;
- },
-
- // http://dev.w3.org/html5/spec/video.html#dom-media-currenttime
- currentTime: function(seconds){
- if (seconds !== undefined) {
-
- // Cache the last set value for smoother scrubbing.
- this.values.lastSetCurrentTime = seconds;
-
- this.techCall("setCurrentTime", seconds);
-
- // Improve the accuracy of manual timeupdates
- if (this.manualTimeUpdates) { this.trigger("timeupdate"); }
-
- return this;
- }
-
- // Cache last currentTime and return
- // Default to 0 seconds
- return this.values.currentTime = (this.techGet("currentTime") || 0);
- },
-
- // http://dev.w3.org/html5/spec/video.html#dom-media-duration
- // Duration should return NaN if not available. ParseFloat will turn false-ish values to NaN.
- duration: function(){
- return parseFloat(this.techGet("duration"));
- },
-
- // Calculates how much time is left. Not in spec, but useful.
- remainingTime: function(){
- return this.duration() - this.currentTime();
- },
-
- // http://dev.w3.org/html5/spec/video.html#dom-media-buffered
- // Buffered returns a timerange object. Kind of like an array of portions of the video that have been downloaded.
- // So far no browsers return more than one range (portion)
- buffered: function(){
- var buffered = this.techGet("buffered"),
- start = 0,
- end = this.values.bufferEnd = this.values.bufferEnd || 0, // Default end to 0 and store in values
- timeRange;
-
- if (buffered && buffered.length > 0 && buffered.end(0) !== end) {
- end = buffered.end(0);
- // Storing values allows them be overridden by setBufferedFromProgress
- this.values.bufferEnd = end;
- }
-
- return _V_.createTimeRange(start, end);
- },
-
- // Calculates amount of buffer is full. Not in spec but useful.
- bufferedPercent: function(){
- return (this.duration()) ? this.buffered().end(0) / this.duration() : 0;
- },
-
- // http://dev.w3.org/html5/spec/video.html#dom-media-volume
- volume: function(percentAsDecimal){
- var vol;
-
- if (percentAsDecimal !== undefined) {
- vol = Math.max(0, Math.min(1, parseFloat(percentAsDecimal))); // Force value to between 0 and 1
- this.values.volume = vol;
- this.techCall("setVolume", vol);
- _V_.setLocalStorage("volume", vol);
- return this;
- }
-
- // Default to 1 when returning current volume.
- vol = parseFloat(this.techGet("volume"));
- return (isNaN(vol)) ? 1 : vol;
- },
-
- // http://dev.w3.org/html5/spec/video.html#attr-media-muted
- muted: function(muted){
- if (muted !== undefined) {
- this.techCall("setMuted", muted);
- return this;
- }
- return this.techGet("muted") || false; // Default to false
- },
-
- // http://dev.w3.org/html5/spec/dimension-attributes.html#attr-dim-height
- // Video tag width/height only work in pixels. No percents.
- // We could potentially allow percents but won't for now until we can do testing around it.
- width: function(width, skipListeners){
- if (width !== undefined) {
- this.el.width = width;
- this.el.style.width = width+"px";
-
- // skipListeners allows us to avoid triggering the resize event when setting both width and height
- if (!skipListeners) { this.trigger("resize"); }
- return this;
- }
- return parseInt(this.el.getAttribute("width"));
- },
- height: function(height){
- if (height !== undefined) {
- this.el.height = height;
- this.el.style.height = height+"px";
- this.trigger("resize");
- return this;
- }
- return parseInt(this.el.getAttribute("height"));
- },
- // Set both width and height at the same time.
- size: function(width, height){
- // Skip resize listeners on width for optimization
- return this.width(width, true).height(height);
- },
-
- // Check if current tech can support native fullscreen (e.g. with built in controls lik iOS, so not our flash swf)
- supportsFullScreen: function(){ return this.techGet("supportsFullScreen") || false; },
-
- // Turn on fullscreen (or window) mode
- requestFullScreen: function(){
- var requestFullScreen = _V_.support.requestFullScreen;
-
- this.isFullScreen = true;
-
- // Check for browser element fullscreen support
- if (requestFullScreen) {
-
- // Trigger fullscreenchange event after change
- _V_.on(document, requestFullScreen.eventName, this.proxy(function(){
- this.isFullScreen = document[requestFullScreen.isFullScreen];
-
- // If cancelling fullscreen, remove event listener.
- if (this.isFullScreen == false) {
- _V_.removeEvent(document, requestFullScreen.eventName, arguments.callee);
- }
-
- this.trigger("fullscreenchange");
- }));
-
- // Flash and other plugins get reloaded when you take their parent to fullscreen.
- // To fix that we'll remove the tech, and reload it after the resize has finished.
- if (this.tech.support.fullscreenResize === false && this.options.flash.iFrameMode != true) {
-
- this.pause();
- this.unloadTech();
-
- _V_.on(document, requestFullScreen.eventName, this.proxy(function(){
- _V_.removeEvent(document, requestFullScreen.eventName, arguments.callee);
- this.loadTech(this.techName, { src: this.values.src });
- }));
-
- this.el[requestFullScreen.requestFn]();
-
- } else {
- this.el[requestFullScreen.requestFn]();
- }
-
- } else if (this.tech.supportsFullScreen()) {
- this.trigger("fullscreenchange");
- this.techCall("enterFullScreen");
-
- } else {
- this.trigger("fullscreenchange");
- this.enterFullWindow();
- }
-
- return this;
- },
-
- cancelFullScreen: function(){
- var requestFullScreen = _V_.support.requestFullScreen;
-
- this.isFullScreen = false;
-
- // Check for browser element fullscreen support
- if (requestFullScreen) {
-
- // Flash and other plugins get reloaded when you take their parent to fullscreen.
- // To fix that we'll remove the tech, and reload it after the resize has finished.
- if (this.tech.support.fullscreenResize === false && this.options.flash.iFrameMode != true) {
-
- this.pause();
- this.unloadTech();
-
- _V_.on(document, requestFullScreen.eventName, this.proxy(function(){
- _V_.removeEvent(document, requestFullScreen.eventName, arguments.callee);
- this.loadTech(this.techName, { src: this.values.src })
- }));
-
- document[requestFullScreen.cancelFn]();
-
- } else {
- document[requestFullScreen.cancelFn]();
- }
-
- } else if (this.tech.supportsFullScreen()) {
- this.techCall("exitFullScreen");
- this.trigger("fullscreenchange");
-
- } else {
- this.exitFullWindow();
- this.trigger("fullscreenchange");
- }
-
- return this;
- },
-
- // When fullscreen isn't supported we can stretch the video container to as wide as the browser will let us.
- enterFullWindow: function(){
- this.isFullWindow = true;
-
- // Storing original doc overflow value to return to when fullscreen is off
- this.docOrigOverflow = document.documentElement.style.overflow;
-
- // Add listener for esc key to exit fullscreen
- _V_.on(document, "keydown", _V_.proxy(this, this.fullWindowOnEscKey));
-
- // Hide any scroll bars
- document.documentElement.style.overflow = 'hidden';
-
- // Apply fullscreen styles
- _V_.addClass(document.body, "vjs-full-window");
- _V_.addClass(this.el, "vjs-fullscreen");
-
- this.trigger("enterFullWindow");
- },
- fullWindowOnEscKey: function(event){
- if (event.keyCode == 27) {
- if (this.isFullScreen == true) {
- this.cancelFullScreen();
- } else {
- this.exitFullWindow();
- }
- }
- },
-
- exitFullWindow: function(){
- this.isFullWindow = false;
- _V_.removeEvent(document, "keydown", this.fullWindowOnEscKey);
-
- // Unhide scroll bars.
- document.documentElement.style.overflow = this.docOrigOverflow;
-
- // Remove fullscreen styles
- _V_.removeClass(document.body, "vjs-full-window");
- _V_.removeClass(this.el, "vjs-fullscreen");
-
- // Resize the box, controller, and poster to original sizes
- // this.positionAll();
- this.trigger("exitFullWindow");
- },
-
- selectSource: function(sources){
-
- // Loop through each playback technology in the options order
- for (var i=0,j=this.options.techOrder;i<j.length;i++) {
- var techName = j[i],
- tech = _V_[techName];
- // tech = _V_.tech[techName];
-
- // Check if the browser supports this technology
- if (tech.isSupported()) {
-
- // Loop through each source object
- for (var a=0,b=sources;a<b.length;a++) {
- var source = b[a];
-
- // Check if source can be played with this technology
- if (tech.canPlaySource.call(this, source)) {
-
- return { source: source, tech: techName };
-
- }
- }
- }
- }
-
- return false;
- },
-
- // src is a pretty powerful function
- // If you pass it an array of source objects, it will find the best source to play and use that object.src
- // If the new source requires a new playback technology, it will switch to that.
- // If you pass it an object, it will set the source to object.src
- // If you pass it anything else (url string) it will set the video source to that
- src: function(source){
- // Case: Array of source objects to choose from and pick the best to play
- if (source instanceof Array) {
-
- var sourceTech = this.selectSource(source),
- source,
- techName;
-
- if (sourceTech) {
- source = sourceTech.source;
- techName = sourceTech.tech;
-
- // If this technology is already loaded, set source
- if (techName == this.techName) {
- this.src(source); // Passing the source object
-
- // Otherwise load this technology with chosen source
- } else {
- this.loadTech(techName, source);
- }
- } else {
- _V_.log("No compatible source and playback technology were found.")
- }
-
- // Case: Source object { src: "", type: "" ... }
- } else if (source instanceof Object) {
-
- if (_V_[this.techName].canPlaySource(source)) {
- this.src(source.src);
- } else {
- // Send through tech loop to check for a compatible technology.
- this.src([source]);
- }
-
- // Case: URL String (http://myvideo...)
- } else {
- // Cache for getting last set source
- this.values.src = source;
-
- if (!this.isReady) {
- this.ready(function(){
- this.src(source);
- });
- } else {
- this.techCall("src", source);
- if (this.options.preload == "auto") {
- this.load();
- }
- if (this.options.autoplay) {
- this.play();
- }
- }
- }
- return this;
- },
-
- // Begin loading the src data
- // http://dev.w3.org/html5/spec/video.html#dom-media-load
- load: function(){
- this.techCall("load");
- return this;
- },
-
- // http://dev.w3.org/html5/spec/video.html#dom-media-currentsrc
- currentSrc: function(){
- return this.techGet("currentSrc") || this.values.src || "";
- },
-
- // Attributes/Options
- preload: function(value){
- if (value !== undefined) {
- this.techCall("setPreload", value);
- this.options.preload = value;
- return this;
- }
- return this.techGet("preload");
- },
- autoplay: function(value){
- if (value !== undefined) {
- this.techCall("setAutoplay", value);
- this.options.autoplay = value;
- return this;
- }
- return this.techGet("autoplay", value);
- },
- loop: function(value){
- if (value !== undefined) {
- this.techCall("setLoop", value);
- this.options.loop = value;
- return this;
- }
- return this.techGet("loop");
- },
-
- controls: function(){ return this.options.controls; },
- poster: function(){ return this.techGet("poster"); },
- error: function(){ return this.techGet("error"); },
- ended: function(){ return this.techGet("ended"); }
-
- // Methods to add support for
- // networkState: function(){ return this.techCall("networkState"); },
- // readyState: function(){ return this.techCall("readyState"); },
- // seeking: function(){ return this.techCall("seeking"); },
- // initialTime: function(){ return this.techCall("initialTime"); },
- // startOffsetTime: function(){ return this.techCall("startOffsetTime"); },
- // played: function(){ return this.techCall("played"); },
- // seekable: function(){ return this.techCall("seekable"); },
- // videoTracks: function(){ return this.techCall("videoTracks"); },
- // audioTracks: function(){ return this.techCall("audioTracks"); },
- // videoWidth: function(){ return this.techCall("videoWidth"); },
- // videoHeight: function(){ return this.techCall("videoHeight"); },
- // defaultPlaybackRate: function(){ return this.techCall("defaultPlaybackRate"); },
- // playbackRate: function(){ return this.techCall("playbackRate"); },
- // mediaGroup: function(){ return this.techCall("mediaGroup"); },
- // controller: function(){ return this.techCall("controller"); },
- // defaultMuted: function(){ return this.techCall("defaultMuted"); }
-});
-
-// RequestFullscreen API
-(function(){
- var requestFn,
- cancelFn,
- eventName,
- isFullScreen,
- playerProto = _V_.Player.prototype;
-
- // Current W3C Spec
- // http://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#api
- // Mozilla Draft: https://wiki.mozilla.org/Gecko:FullScreenAPI#fullscreenchange_event
- if (document.cancelFullscreen !== undefined) {
- requestFn = "requestFullscreen";
- cancelFn = "exitFullscreen";
- eventName = "fullscreenchange";
- isFullScreen = "fullScreen";
-
- // Webkit (Chrome/Safari) and Mozilla (Firefox) have working implementaitons
- // that use prefixes and vary slightly from the new W3C spec. Specifically, using 'exit' instead of 'cancel',
- // and lowercasing the 'S' in Fullscreen.
- // Other browsers don't have any hints of which version they might follow yet, so not going to try to predict by loopeing through all prefixes.
- } else {
-
- _V_.each(["moz", "webkit"], function(prefix){
-
- // https://github.com/zencoder/video-js/pull/128
- if ((prefix != "moz" || document.mozFullScreenEnabled) && document[prefix + "CancelFullScreen"] !== undefined) {
- requestFn = prefix + "RequestFullScreen";
- cancelFn = prefix + "CancelFullScreen";
- eventName = prefix + "fullscreenchange";
-
- if (prefix == "webkit") {
- isFullScreen = prefix + "IsFullScreen";
- } else {
- isFullScreen = prefix + "FullScreen";
- }
- }
-
- });
-
- }
-
- if (requestFn) {
- _V_.support.requestFullScreen = {
- requestFn: requestFn,
- cancelFn: cancelFn,
- eventName: eventName,
- isFullScreen: isFullScreen
- };
- }
-
-})();/* Playback Technology - Base class for playback technologies
-================================================================================ */
-_V_.PlaybackTech = _V_.Component.extend({
- init: function(player, options){
- // this._super(player, options);
-
- // Make playback element clickable
- // _V_.addEvent(this.el, "click", _V_.proxy(this, _V_.PlayToggle.prototype.onClick));
-
- // this.addEvent("click", this.proxy(this.onClick));
-
- // player.triggerEvent("techready");
- },
- // destroy: function(){},
- // createElement: function(){},
- onClick: function(){
- if (this.player.options.controls) {
- _V_.PlayToggle.prototype.onClick.call(this);
- }
- }
-});
-
-// Create placeholder methods for each that warn when a method isn't supported by the current playback technology
-_V_.apiMethods = "play,pause,paused,currentTime,setCurrentTime,duration,buffered,volume,setVolume,muted,setMuted,width,height,supportsFullScreen,enterFullScreen,src,load,currentSrc,preload,setPreload,autoplay,setAutoplay,loop,setLoop,error,networkState,readyState,seeking,initialTime,startOffsetTime,played,seekable,ended,videoTracks,audioTracks,videoWidth,videoHeight,textTracks,defaultPlaybackRate,playbackRate,mediaGroup,controller,controls,defaultMuted".split(",");
-_V_.each(_V_.apiMethods, function(methodName){
- _V_.PlaybackTech.prototype[methodName] = function(){
- throw new Error("The '"+methodName+"' method is not available on the playback technology's API");
- }
-});
-
-/* HTML5 Playback Technology - Wrapper for HTML5 Media API
-================================================================================ */
-_V_.html5 = _V_.PlaybackTech.extend({
-
- init: function(player, options, ready){
- this.player = player;
- this.el = this.createElement();
- this.ready(ready);
-
- this.addEvent("click", this.proxy(this.onClick));
-
- var source = options.source;
-
- // If the element source is already set, we may have missed the loadstart event, and want to trigger it.
- // We don't want to set the source again and interrupt playback.
- if (source && this.el.currentSrc == source.src) {
- player.triggerEvent("loadstart");
-
- // Otherwise set the source if one was provided.
- } else if (source) {
- this.el.src = source.src;
- }
-
- // Chrome and Safari both have issues with autoplay.
- // In Safari (5.1.1), when we move the video element into the container div, autoplay doesn't work.
- // In Chrome (15), if you have autoplay + a poster + no controls, the video gets hidden (but audio plays)
- // This fixes both issues. Need to wait for API, so it updates displays correctly
- player.ready(function(){
- if (this.options.autoplay && this.paused()) {
- this.tag.poster = null; // Chrome Fix. Fixed in Chrome v16.
- this.play();
- }
- });
-
- this.setupTriggers();
-
- this.triggerReady();
- },
-
- destroy: function(){
- this.player.tag = false;
- this.removeTriggers();
- this.el.parentNode.removeChild(this.el);
- },
-
- createElement: function(){
- var html5 = _V_.html5,
- player = this.player,
-
- // If possible, reuse original tag for HTML5 playback technology element
- el = player.tag,
- newEl;
-
- // Check if this browser supports moving the element into the box.
- // On the iPhone video will break if you move the element,
- // So we have to create a brand new element.
- if (!el || this.support.movingElementInDOM === false) {
-
- // If the original tag is still there, remove it.
- if (el) {
- player.el.removeChild(el);
- }
-
- newEl = _V_.createElement("video", {
- id: el.id || player.el.id + "_html5_api",
- className: el.className || "vjs-tech"
- });
-
- el = newEl;
- _V_.insertFirst(el, player.el);
- }
-
- // Update tag settings, in case they were overridden
- _V_.each(["autoplay","preload","loop","muted"], function(attr){ // ,"poster"
- if (player.options[attr] !== null) {
- el[attr] = player.options[attr];
- }
- }, this);
-
- return el;
- },
-
- // Make video events trigger player events
- // May seem verbose here, but makes other APIs possible.
- setupTriggers: function(){
- _V_.each.call(this, _V_.html5.events, function(type){
- _V_.addEvent(this.el, type, _V_.proxy(this.player, this.eventHandler));
- });
- },
- removeTriggers: function(){
- _V_.each.call(this, _V_.html5.events, function(type){
- _V_.removeEvent(this.el, type, _V_.proxy(this.player, this.eventHandler));
- });
- },
- eventHandler: function(e){
- e.stopPropagation();
- this.triggerEvent(e);
- },
-
- play: function(){ this.el.play(); },
- pause: function(){ this.el.pause(); },
- paused: function(){ return this.el.paused; },
-
- currentTime: function(){ return this.el.currentTime; },
- setCurrentTime: function(seconds){
- try {
- this.el.currentTime = seconds;
- } catch(e) {
- _V_.log(e, "Video isn't ready. (VideoJS)");
- // this.warning(VideoJS.warnings.videoNotReady);
- }
- },
-
- duration: function(){ return this.el.duration || 0; },
- buffered: function(){ return this.el.buffered; },
-
- volume: function(){ return this.el.volume; },
- setVolume: function(percentAsDecimal){ this.el.volume = percentAsDecimal; },
- muted: function(){ return this.el.muted; },
- setMuted: function(muted){ this.el.muted = muted },
-
- width: function(){ return this.el.offsetWidth; },
- height: function(){ return this.el.offsetHeight; },
-
- supportsFullScreen: function(){
- if (typeof this.el.webkitEnterFullScreen == 'function') {
-
- // Seems to be broken in Chromium/Chrome && Safari in Leopard
- if (!navigator.userAgent.match("Chrome") && !navigator.userAgent.match("Mac OS X 10.5")) {
- return true;
- }
- }
- return false;
- },
-
- enterFullScreen: function(){
- try {
- this.el.webkitEnterFullScreen();
- } catch (e) {
- if (e.code == 11) {
- // this.warning(VideoJS.warnings.videoNotReady);
- _V_.log("VideoJS: Video not ready.")
- }
- }
- },
- exitFullScreen: function(){
- try {
- this.el.webkitExitFullScreen();
- } catch (e) {
- if (e.code == 11) {
- // this.warning(VideoJS.warnings.videoNotReady);
- _V_.log("VideoJS: Video not ready.")
- }
- }
- },
- src: function(src){ this.el.src = src; },
- load: function(){ this.el.load(); },
- currentSrc: function(){ return this.el.currentSrc; },
-
- preload: function(){ return this.el.preload; },
- setPreload: function(val){ this.el.preload = val; },
- autoplay: function(){ return this.el.autoplay; },
- setAutoplay: function(val){ this.el.autoplay = val; },
- loop: function(){ return this.el.loop; },
- setLoop: function(val){ this.el.loop = val; },
-
- error: function(){ return this.el.error; },
- // networkState: function(){ return this.el.networkState; },
- // readyState: function(){ return this.el.readyState; },
- seeking: function(){ return this.el.seeking; },
- // initialTime: function(){ return this.el.initialTime; },
- // startOffsetTime: function(){ return this.el.startOffsetTime; },
- // played: function(){ return this.el.played; },
- // seekable: function(){ return this.el.seekable; },
- ended: function(){ return this.el.ended; },
- // videoTracks: function(){ return this.el.videoTracks; },
- // audioTracks: function(){ return this.el.audioTracks; },
- // videoWidth: function(){ return this.el.videoWidth; },
- // videoHeight: function(){ return this.el.videoHeight; },
- // textTracks: function(){ return this.el.textTracks; },
- // defaultPlaybackRate: function(){ return this.el.defaultPlaybackRate; },
- // playbackRate: function(){ return this.el.playbackRate; },
- // mediaGroup: function(){ return this.el.mediaGroup; },
- // controller: function(){ return this.el.controller; },
- controls: function(){ return this.player.options.controls; },
- defaultMuted: function(){ return this.el.defaultMuted; }
-});
-
-/* HTML5 Support Testing -------------------------------------------------------- */
-
-_V_.html5.isSupported = function(){
- return !!document.createElement("video").canPlayType;
-};
-
-_V_.html5.canPlaySource = function(srcObj){
- return !!document.createElement("video").canPlayType(srcObj.type);
- // TODO: Check Type
- // If no Type, check ext
- // Check Media Type
-};
-
-// List of all HTML5 events (various uses).
-_V_.html5.events = "loadstart,suspend,abort,error,emptied,stalled,loadedmetadata,loadeddata,canplay,canplaythrough,playing,waiting,seeking,seeked,ended,durationchange,timeupdate,progress,play,pause,ratechange,volumechange".split(",");
-
-/* HTML5 Device Fixes ---------------------------------------------------------- */
-
-_V_.html5.prototype.support = {
-
- // Support for tech specific full screen. (webkitEnterFullScreen, not requestFullscreen)
- // http://developer.apple.com/library/safari/#documentation/AudioVideo/Reference/HTMLVideoElementClassReference/HTMLVideoElement/HTMLVideoElement.html
- // Seems to be broken in Chromium/Chrome && Safari in Leopard
- fullscreen: (typeof _V_.testVid.webkitEnterFullScreen !== undefined) ? (!_V_.ua.match("Chrome") && !_V_.ua.match("Mac OS X 10.5") ? true : false) : false,
-
- // In iOS, if you move a video element in the DOM, it breaks video playback.
- movingElementInDOM: !_V_.isIOS()
-
-};
-
-// Android
-if (_V_.isAndroid()) {
-
- // Override Android 2.2 and less canPlayType method which is broken
- if (_V_.androidVersion() < 3) {
- document.createElement("video").constructor.prototype.canPlayType = function(type){
- return (type && type.toLowerCase().indexOf("video/mp4") != -1) ? "maybe" : "";
- };
- }
-}
-
-
-/* VideoJS-SWF - Custom Flash Player with HTML5-ish API - https://github.com/zencoder/video-js-swf
-================================================================================ */
-_V_.flash = _V_.PlaybackTech.extend({
-
- init: function(player, options){
- this.player = player;
-
- var source = options.source,
-
- // Which element to embed in
- parentEl = options.parentEl,
-
- // Create a temporary element to be replaced by swf object
- placeHolder = this.el = _V_.createElement("div", { id: parentEl.id + "_temp_flash" }),
-
- // Generate ID for swf object
- objId = player.el.id+"_flash_api",
-
- // Store player options in local var for optimization
- playerOptions = player.options,
-
- // Merge default flashvars with ones passed in to init
- flashVars = _V_.merge({
-
- // SWF Callback Functions
- readyFunction: "_V_.flash.onReady",
- eventProxyFunction: "_V_.flash.onEvent",
- errorEventProxyFunction: "_V_.flash.onError",
-
- // Player Settings
- autoplay: playerOptions.autoplay,
- preload: playerOptions.preload,
- loop: playerOptions.loop,
- muted: playerOptions.muted
-
- }, options.flashVars),
-
- // Merge default parames with ones passed in
- params = _V_.merge({
- wmode: "opaque", // Opaque is needed to overlay controls, but can affect playback performance
- bgcolor: "#000000" // Using bgcolor prevents a white flash when the object is loading
- }, options.params),
-
- // Merge default attributes with ones passed in
- attributes = _V_.merge({
- id: objId,
- name: objId, // Both ID and Name needed or swf to identifty itself
- 'class': 'vjs-tech'
- }, options.attributes)
- ;
-
- // If source was supplied pass as a flash var.
- if (source) {
- flashVars.src = encodeURIComponent(_V_.getAbsoluteURL(source.src));
- }
-
- // Add placeholder to player div
- _V_.insertFirst(placeHolder, parentEl);
-
- // Having issues with Flash reloading on certain page actions (hide/resize/fullscreen) in certain browsers
- // This allows resetting the playhead when we catch the reload
- if (options.startTime) {
- this.ready(function(){
- this.load();
- this.play();
- this.currentTime(options.startTime);
- });
- }
-
- // Flash iFrame Mode
- // In web browsers there are multiple instances where changing the parent element or visibility of a plugin causes the plugin to reload.
- // - Firefox just about always. https://bugzilla.mozilla.org/show_bug.cgi?id=90268 (might be fixed by version 13)
- // - Webkit when hiding the plugin
- // - Webkit and Firefox when using requestFullScreen on a parent element
- // Loading the flash plugin into a dynamically generated iFrame gets around most of these issues.
- // Issues that remain include hiding the element and requestFullScreen in Firefox specifically
-
- // There's on particularly annoying issue with this method which is that Firefox throws a security error on an offsite Flash object loaded into a dynamically created iFrame.
- // Even though the iframe was inserted into a page on the web, Firefox + Flash considers it a local app trying to access an internet file.
- // I tried mulitple ways of setting the iframe src attribute but couldn't find a src that worked well. Tried a real/fake source, in/out of domain.
- // Also tried a method from stackoverflow that caused a security error in all browsers. http://stackoverflow.com/questions/2486901/how-to-set-document-domain-for-a-dynamically-generated-iframe
- // In the end the solution I found to work was setting the iframe window.location.href right before doing a document.write of the Flash object.
- // The only downside of this it seems to trigger another http request to the original page (no matter what's put in the href). Not sure why that is.
-
- // NOTE (2012-01-29): Cannot get Firefox to load the remote hosted SWF into a dynamically created iFrame
- // Firefox 9 throws a security error, unleess you call location.href right before doc.write.
- // Not sure why that even works, but it causes the browser to look like it's continuously trying to load the page.
- // Firefox 3.6 keeps calling the iframe onload function anytime I write to it, causing an endless loop.
-
- if (options.iFrameMode == true && !_V_.isFF) {
-
- // Create iFrame with vjs-tech class so it's 100% width/height
- var iFrm = _V_.createElement("iframe", {
- id: objId + "_iframe",
- name: objId + "_iframe",
- className: "vjs-tech",
- scrolling: "no",
- marginWidth: 0,
- marginHeight: 0,
- frameBorder: 0
- });
-
- // Update ready function names in flash vars for iframe window
- flashVars.readyFunction = "ready";
- flashVars.eventProxyFunction = "events";
- flashVars.errorEventProxyFunction = "errors";
-
- // Tried multiple methods to get this to work in all browsers
-
- // Tried embedding the flash object in the page first, and then adding a place holder to the iframe, then replacing the placeholder with the page object.
- // The goal here was to try to load the swf URL in the parent page first and hope that got around the firefox security error
- // var newObj = _V_.flash.embed(options.swf, placeHolder, flashVars, params, attributes);
- // (in onload)
- // var temp = _V_.createElement("a", { id:"asdf", innerHTML: "asdf" } );
- // iDoc.body.appendChild(temp);
-
- // Tried embedding the flash object through javascript in the iframe source.
- // This works in webkit but still triggers the firefox security error
- // iFrm.src = "javascript: document.write('"+_V_.flash.getEmbedCode(options.swf, flashVars, params, attributes)+"');";
-
- // Tried an actual local iframe just to make sure that works, but it kills the easiness of the CDN version if you require the user to host an iframe
- // We should add an option to host the iframe locally though, because it could help a lot of issues.
- // iFrm.src = "iframe.html";
-
- // Wait until iFrame has loaded to write into it.
- _V_.addEvent(iFrm, "load", _V_.proxy(this, function(){
-
- var iDoc, objTag, swfLoc,
- iWin = iFrm.contentWindow,
- varString = "";
-
-
- // The one working method I found was to use the iframe's document.write() to create the swf object
- // This got around the security issue in all browsers except firefox.
- // I did find a hack where if I call the iframe's window.location.href="", it would get around the security error
- // However, the main page would look like it was loading indefinitely (URL bar loading spinner would never stop)
- // Plus Firefox 3.6 didn't work no matter what I tried.
- // if (_V_.ua.match("Firefox")) {
- // iWin.location.href = "";
- // }
-
- // Get the iFrame's document depending on what the browser supports
- iDoc = iFrm.contentDocument ? iFrm.contentDocument : iFrm.contentWindow.document;
-
- // Tried ensuring both document domains were the same, but they already were, so that wasn't the issue.
- // Even tried adding /. that was mentioned in a browser security writeup
- // document.domain = document.domain+"/.";
- // iDoc.domain = document.domain+"/.";
-
- // Tried adding the object to the iframe doc's innerHTML. Security error in all browsers.
- // iDoc.body.innerHTML = swfObjectHTML;
-
- // Tried appending the object to the iframe doc's body. Security error in all browsers.
- // iDoc.body.appendChild(swfObject);
-
- // Using document.write actually got around the security error that browsers were throwing.
- // Again, it's a dynamically generated (same domain) iframe, loading an external Flash swf.
- // Not sure why that's a security issue, but apparently it is.
- iDoc.write(_V_.flash.getEmbedCode(options.swf, flashVars, params, attributes));
-
- // Setting variables on the window needs to come after the doc write because otherwise they can get reset in some browsers
- // So far no issues with swf ready event being called before it's set on the window.
- iWin.player = this.player;
-
- // Create swf ready function for iFrame window
- iWin.ready = _V_.proxy(this.player, function(currSwf){
- var el = iDoc.getElementById(currSwf),
- player = this,
- tech = player.tech;
-
- // Update reference to playback technology element
- tech.el = el;
-
- // Now that the element is ready, make a click on the swf play the video
- _V_.addEvent(el, "click", tech.proxy(tech.onClick));
-
- // Make sure swf is actually ready. Sometimes the API isn't actually yet.
- _V_.flash.checkReady(tech);
- });
-
- // Create event listener for all swf events
- iWin.events = _V_.proxy(this.player, function(swfID, eventName, other){
- var player = this;
- if (player && player.techName == "flash") {
- player.triggerEvent(eventName);
- }
- });
-
- // Create error listener for all swf errors
- iWin.errors = _V_.proxy(this.player, function(swfID, eventName){
- _V_.log("Flash Error", eventName);
- });
-
- }));
-
- // Replace placeholder with iFrame (it will load now)
- placeHolder.parentNode.replaceChild(iFrm, placeHolder);
-
- // If not using iFrame mode, embed as normal object
- } else {
- _V_.flash.embed(options.swf, placeHolder, flashVars, params, attributes);
- }
- },
-
- destroy: function(){
- this.el.parentNode.removeChild(this.el);
- },
-
- // setupTriggers: function(){}, // Using global onEvent func to distribute events
-
- play: function(){ this.el.vjs_play(); },
- pause: function(){ this.el.vjs_pause(); },
- src: function(src){
- // Make sure source URL is abosolute.
- src = _V_.getAbsoluteURL(src);
-
- this.el.vjs_src(src);
-
- // Currently the SWF doesn't autoplay if you load a source later.
- // e.g. Load player w/ no source, wait 2s, set src.
- if (this.player.autoplay()) {
- var tech = this;
- setTimeout(function(){ tech.play(); }, 0);
- }
- },
- load: function(){ this.el.vjs_load(); },
- poster: function(){ this.el.vjs_getProperty("poster"); },
-
- buffered: function(){
- return _V_.createTimeRange(0, this.el.vjs_getProperty("buffered"));
- },
-
- supportsFullScreen: function(){
- return false; // Flash does not allow fullscreen through javascript
- },
- enterFullScreen: function(){
- return false;
- }
-});
-
-// Create setters and getters for attributes
-(function(){
-
- var api = _V_.flash.prototype,
- readWrite = "preload,currentTime,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted".split(","),
- readOnly = "error,currentSrc,networkState,readyState,seeking,initialTime,duration,startOffsetTime,paused,played,seekable,ended,videoTracks,audioTracks,videoWidth,videoHeight,textTracks".split(","),
- callOnly = "load,play,pause".split(",");
- // Overridden: buffered
-
- createSetter = function(attr){
- var attrUpper = attr.charAt(0).toUpperCase() + attr.slice(1);
- api["set"+attrUpper] = function(val){ return this.el.vjs_setProperty(attr, val); };
- },
-
- createGetter = function(attr){
- api[attr] = function(){ return this.el.vjs_getProperty(attr); };
- }
- ;
-
- // Create getter and setters for all read/write attributes
- _V_.each(readWrite, function(attr){
- createGetter(attr);
- createSetter(attr);
- });
-
- // Create getters for read-only attributes
- _V_.each(readOnly, function(attr){
- createGetter(attr);
- });
-
-})();
-
-/* Flash Support Testing -------------------------------------------------------- */
-
-_V_.flash.isSupported = function(){
- return _V_.flash.version()[0] >= 10;
- // return swfobject.hasFlashPlayerVersion("10");
-};
-
-_V_.flash.canPlaySource = function(srcObj){
- if (srcObj.type in _V_.flash.prototype.support.formats) { return "maybe"; }
-};
-
-_V_.flash.prototype.support = {
- formats: {
- "video/flv": "FLV",
- "video/x-flv": "FLV",
- "video/mp4": "MP4",
- "video/m4v": "MP4"
- },
-
- // Optional events that we can manually mimic with timers
- progressEvent: false,
- timeupdateEvent: false,
-
- // Resizing plugins using request fullscreen reloads the plugin
- fullscreenResize: false,
-
- // Resizing plugins in Firefox always reloads the plugin (e.g. full window mode)
- parentResize: !(_V_.ua.match("Firefox"))
-};
-
-_V_.flash.onReady = function(currSwf){
-
- var el = _V_.el(currSwf);
-
- // Get player from box
- // On firefox reloads, el might already have a player
- var player = el.player || el.parentNode.player,
- tech = player.tech;
-
- // Reference player on tech element
- el.player = player;
-
- // Update reference to playback technology element
- tech.el = el;
-
- // Now that the element is ready, make a click on the swf play the video
- tech.addEvent("click", tech.onClick);
-
- _V_.flash.checkReady(tech);
-};
-
-// The SWF isn't alwasy ready when it says it is. Sometimes the API functions still need to be added to the object.
-// If it's not ready, we set a timeout to check again shortly.
-_V_.flash.checkReady = function(tech){
-
- // Check if API property exists
- if (tech.el.vjs_getProperty) {
-
- // If so, tell tech it's ready
- tech.triggerReady();
-
- // Otherwise wait longer.
- } else {
-
- setTimeout(function(){
- _V_.flash.checkReady(tech);
- }, 50);
-
- }
-};
-
-// Trigger events from the swf on the player
-_V_.flash.onEvent = function(swfID, eventName){
- var player = _V_.el(swfID).player;
- player.triggerEvent(eventName);
-};
-
-// Log errors from the swf
-_V_.flash.onError = function(swfID, err){
- var player = _V_.el(swfID).player;
- player.triggerEvent("error");
- _V_.log("Flash Error", err, swfID);
-};
-
-// Flash Version Check
-_V_.flash.version = function(){
- var version = '0,0,0'
-
- // IE
- try {
- version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
-
- // other browsers
- } catch(e) {
- try {
- if (navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin){
- version = (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]).description.replace(/\D+/g, ",").match(/^,?(.+),?$/)[1];
- }
- } catch(e) {}
- }
- return version.split(",");
-}
-
-// Flash embedding method. Only used in non-iframe mode
-_V_.flash.embed = function(swf, placeHolder, flashVars, params, attributes){
- var code = _V_.flash.getEmbedCode(swf, flashVars, params, attributes),
-
- // Get element by embedding code and retrieving created element
- obj = _V_.createElement("div", { innerHTML: code }).childNodes[0],
-
- par = placeHolder.parentNode
- ;
-
- placeHolder.parentNode.replaceChild(obj, placeHolder);
-
- // IE6 seems to have an issue where it won't initialize the swf object after injecting it.
- // This is a dumb temporary fix
- if (_V_.isIE()) {
- var newObj = par.childNodes[0];
- setTimeout(function(){
- newObj.style.display = "block";
- }, 1000);
- }
-
- return obj;
-
-};
-
-_V_.flash.getEmbedCode = function(swf, flashVars, params, attributes){
-
- var objTag = '<object type="application/x-shockwave-flash"',
- flashVarsString = '',
- paramsString = ''
- attrsString = '';
-
- // Convert flash vars to string
- if (flashVars) {
- _V_.eachProp(flashVars, function(key, val){
- flashVarsString += (key + "=" + val + "&");
- });
- }
-
- // Add swf, flashVars, and other default params
- params = _V_.merge({
- movie: swf,
- flashvars: flashVarsString,
- allowScriptAccess: "always", // Required to talk to swf
- allowNetworking: "all" // All should be default, but having security issues.
- }, params);
-
- // Create param tags string
- _V_.eachProp(params, function(key, val){
- paramsString += '<param name="'+key+'" value="'+val+'" />';
- });
-
- attributes = _V_.merge({
- // Add swf to attributes (need both for IE and Others to work)
- data: swf,
-
- // Default to 100% width/height
- width: "100%",
- height: "100%"
-
- }, attributes);
-
- // Create Attributes string
- _V_.eachProp(attributes, function(key, val){
- attrsString += (key + '="' + val + '" ');
- });
-
- return objTag + attrsString + '>' + paramsString + '</object>';
-}
-/* Control - Base class for all control elements
-================================================================================ */
-_V_.Control = _V_.Component.extend({
-
- buildCSSClass: function(){
- return "vjs-control " + this._super();
- }
-
-});
-
-/* Control Bar
-================================================================================ */
-_V_.ControlBar = _V_.Component.extend({
-
- options: {
- loadEvent: "play",
- components: {
- "playToggle": {},
- "fullscreenToggle": {},
- "currentTimeDisplay": {},
- "timeDivider": {},
- "durationDisplay": {},
- "remainingTimeDisplay": {},
- "progressControl": {},
- "volumeControl": {},
- "muteToggle": {}
- }
- },
-
- init: function(player, options){
- this._super(player, options);
-
- player.on("play", this.proxy(function(){
- this.fadeIn();
- this.player.on("mouseover", this.proxy(this.fadeIn));
- this.player.on("mouseout", this.proxy(this.fadeOut));
- }));
-
- },
-
- createElement: function(){
- return _V_.createElement("div", {
- className: "vjs-controls"
- });
- },
-
- fadeIn: function(){
- this._super();
- this.player.trigger("controlsvisible");
- },
-
- fadeOut: function(){
- this._super();
- this.player.trigger("controlshidden");
- },
-
- lockShowing: function(){
- this.el.style.opacity = "1";
- }
-
-});
-
-/* Button - Base class for all buttons
-================================================================================ */
-_V_.Button = _V_.Control.extend({
-
- init: function(player, options){
- this._super(player, options);
-
- this.on("click", this.onClick);
- this.on("focus", this.onFocus);
- this.on("blur", this.onBlur);
- },
-
- createElement: function(type, attrs){
- // Add standard Aria and Tabindex info
- attrs = _V_.merge({
- className: this.buildCSSClass(),
- innerHTML: '<div><span class="vjs-control-text">' + (this.buttonText || "Need Text") + '</span></div>',
- role: "button",
- tabIndex: 0
- }, attrs);
-
- return this._super(type, attrs);
- },
-
- // Click - Override with specific functionality for button
- onClick: function(){},
-
- // Focus - Add keyboard functionality to element
- onFocus: function(){
- _V_.on(document, "keyup", _V_.proxy(this, this.onKeyPress));
- },
-
- // KeyPress (document level) - Trigger click when keys are pressed
- onKeyPress: function(event){
- // Check for space bar (32) or enter (13) keys
- if (event.which == 32 || event.which == 13) {
- event.preventDefault();
- this.onClick();
- }
- },
-
- // Blur - Remove keyboard triggers
- onBlur: function(){
- _V_.off(document, "keyup", _V_.proxy(this, this.onKeyPress));
- }
-
-});
-
-/* Play Button
-================================================================================ */
-_V_.PlayButton = _V_.Button.extend({
-
- buttonText: "Play",
-
- buildCSSClass: function(){
- return "vjs-play-button " + this._super();
- },
-
- onClick: function(){
- this.player.play();
- }
-
-});
-
-/* Pause Button
-================================================================================ */
-_V_.PauseButton = _V_.Button.extend({
-
- buttonText: "Pause",
-
- buildCSSClass: function(){
- return "vjs-pause-button " + this._super();
- },
-
- onClick: function(){
- this.player.pause();
- }
-
-});
-
-/* Play Toggle - Play or Pause Media
-================================================================================ */
-_V_.PlayToggle = _V_.Button.extend({
-
- buttonText: "Play",
-
- init: function(player, options){
- this._super(player, options);
-
- player.on("play", _V_.proxy(this, this.onPlay));
- player.on("pause", _V_.proxy(this, this.onPause));
- },
-
- buildCSSClass: function(){
- return "vjs-play-control " + this._super();
- },
-
- // OnClick - Toggle between play and pause
- onClick: function(){
- if (this.player.paused()) {
- this.player.play();
- } else {
- this.player.pause();
- }
- },
-
- // OnPlay - Add the vjs-playing class to the element so it can change appearance
- onPlay: function(){
- _V_.removeClass(this.el, "vjs-paused");
- _V_.addClass(this.el, "vjs-playing");
- },
-
- // OnPause - Add the vjs-paused class to the element so it can change appearance
- onPause: function(){
- _V_.removeClass(this.el, "vjs-playing");
- _V_.addClass(this.el, "vjs-paused");
- }
-
-});
-
-
-/* Fullscreen Toggle Behaviors
-================================================================================ */
-_V_.FullscreenToggle = _V_.Button.extend({
-
- buttonText: "Fullscreen",
-
- buildCSSClass: function(){
- return "vjs-fullscreen-control " + this._super();
- },
-
- onClick: function(){
- if (!this.player.isFullScreen) {
- this.player.requestFullScreen();
- } else {
- this.player.cancelFullScreen();
- }
- }
-
-});
-
-/* Big Play Button
-================================================================================ */
-_V_.BigPlayButton = _V_.Button.extend({
- init: function(player, options){
- this._super(player, options);
-
- player.on("play", _V_.proxy(this, this.hide));
- player.on("ended", _V_.proxy(this, this.show));
- },
-
- createElement: function(){
- return this._super("div", {
- className: "vjs-big-play-button",
- innerHTML: "<span></span>"
- });
- },
-
- onClick: function(){
- // Go back to the beginning if big play button is showing at the end.
- // Have to check for current time otherwise it might throw a 'not ready' error.
- if(this.player.currentTime()) {
- this.player.currentTime(0);
- }
- this.player.play();
- }
-});
-
-/* Loading Spinner
-================================================================================ */
-_V_.LoadingSpinner = _V_.Component.extend({
- init: function(player, options){
- this._super(player, options);
-
- player.on("canplay", _V_.proxy(this, this.hide));
- player.on("canplaythrough", _V_.proxy(this, this.hide));
- player.on("playing", _V_.proxy(this, this.hide));
-
- player.on("seeking", _V_.proxy(this, this.show));
- player.on("error", _V_.proxy(this, this.show));
-
- // Not showing spinner on stalled any more. Browsers may stall and then not trigger any events that would remove the spinner.
- // Checked in Chrome 16 and Safari 5.1.2. http://help.videojs.com/discussions/problems/883-why-is-the-download-progress-showing
- // player.on("stalled", _V_.proxy(this, this.show));
-
- player.on("waiting", _V_.proxy(this, this.show));
- },
-
- createElement: function(){
-
- var classNameSpinner, innerHtmlSpinner;
-
- if ( typeof this.player.el.style.WebkitBorderRadius == "string"
- || typeof this.player.el.style.MozBorderRadius == "string"
- || typeof this.player.el.style.KhtmlBorderRadius == "string"
- || typeof this.player.el.style.borderRadius == "string")
- {
- classNameSpinner = "vjs-loading-spinner";
- innerHtmlSpinner = "<div class='ball1'></div><div class='ball2'></div><div class='ball3'></div><div class='ball4'></div><div class='ball5'></div><div class='ball6'></div><div class='ball7'></div><div class='ball8'></div>";
- } else {
- classNameSpinner = "vjs-loading-spinner-fallback";
- innerHtmlSpinner = "";
- }
-
- return this._super("div", {
- className: classNameSpinner,
- innerHTML: innerHtmlSpinner
- });
- }
-});
-
-/* Time
-================================================================================ */
-_V_.CurrentTimeDisplay = _V_.Component.extend({
-
- init: function(player, options){
- this._super(player, options);
-
- player.on("timeupdate", _V_.proxy(this, this.updateContent));
- },
-
- createElement: function(){
- var el = this._super("div", {
- className: "vjs-current-time vjs-time-controls vjs-control"
- });
-
- this.content = _V_.createElement("div", {
- className: "vjs-current-time-display",
- innerHTML: '0:00'
- });
-
- el.appendChild(_V_.createElement("div").appendChild(this.content));
- return el;
- },
-
- updateContent: function(){
- // Allows for smooth scrubbing, when player can't keep up.
- var time = (this.player.scrubbing) ? this.player.values.currentTime : this.player.currentTime();
- this.content.innerHTML = _V_.formatTime(time, this.player.duration());
- }
-
-});
-
-_V_.DurationDisplay = _V_.Component.extend({
-
- init: function(player, options){
- this._super(player, options);
-
- player.on("timeupdate", _V_.proxy(this, this.updateContent));
- },
-
- createElement: function(){
- var el = this._super("div", {
- className: "vjs-duration vjs-time-controls vjs-control"
- });
-
- this.content = _V_.createElement("div", {
- className: "vjs-duration-display",
- innerHTML: '0:00'
- });
-
- el.appendChild(_V_.createElement("div").appendChild(this.content));
- return el;
- },
-
- updateContent: function(){
- if (this.player.duration()) { this.content.innerHTML = _V_.formatTime(this.player.duration()); }
- }
-
-});
-
-// Time Separator (Not used in main skin, but still available, and could be used as a 'spare element')
-_V_.TimeDivider = _V_.Component.extend({
-
- createElement: function(){
- return this._super("div", {
- className: "vjs-time-divider",
- innerHTML: '<div><span>/</span></div>'
- });
- }
-
-});
-
-_V_.RemainingTimeDisplay = _V_.Component.extend({
-
- init: function(player, options){
- this._super(player, options);
-
- player.on("timeupdate", _V_.proxy(this, this.updateContent));
- },
-
- createElement: function(){
- var el = this._super("div", {
- className: "vjs-remaining-time vjs-time-controls vjs-control"
- });
-
- this.content = _V_.createElement("div", {
- className: "vjs-remaining-time-display",
- innerHTML: '-0:00'
- });
-
- el.appendChild(_V_.createElement("div").appendChild(this.content));
- return el;
- },
-
- updateContent: function(){
- if (this.player.duration()) { this.content.innerHTML = "-"+_V_.formatTime(this.player.remainingTime()); }
-
- // Allows for smooth scrubbing, when player can't keep up.
- // var time = (this.player.scrubbing) ? this.player.values.currentTime : this.player.currentTime();
- // this.content.innerHTML = _V_.formatTime(time, this.player.duration());
- }
-
-});
-
-/* Slider - Parent for seek bar and volume slider
-================================================================================ */
-_V_.Slider = _V_.Component.extend({
-
- init: function(player, options){
- this._super(player, options);
-
- player.on(this.playerEvent, _V_.proxy(this, this.update));
-
- this.on("mousedown", this.onMouseDown);
- this.on("focus", this.onFocus);
- this.on("blur", this.onBlur);
-
- this.player.on("controlsvisible", this.proxy(this.update));
-
- // This is actually to fix the volume handle position. http://twitter.com/#!/gerritvanaaken/status/159046254519787520
- // this.player.one("timeupdate", this.proxy(this.update));
-
- this.update();
- },
-
- createElement: function(type, attrs) {
- attrs = _V_.merge({
- role: "slider",
- "aria-valuenow": 0,
- "aria-valuemin": 0,
- "aria-valuemax": 100,
- tabIndex: 0
- }, attrs);
-
- return this._super(type, attrs);
- },
-
- onMouseDown: function(event){
- event.preventDefault();
- _V_.blockTextSelection();
-
- _V_.on(document, "mousemove", _V_.proxy(this, this.onMouseMove));
- _V_.on(document, "mouseup", _V_.proxy(this, this.onMouseUp));
-
- this.onMouseMove(event);
- },
-
- onMouseUp: function(event) {
- _V_.unblockTextSelection();
- _V_.off(document, "mousemove", this.onMouseMove, false);
- _V_.off(document, "mouseup", this.onMouseUp, false);
-
- this.update();
- },
-
- update: function(){
- // If scrubbing, we could use a cached value to make the handle keep up with the user's mouse.
- // On HTML5 browsers scrubbing is really smooth, but some flash players are slow, so we might want to utilize this later.
- // var progress = (this.player.scrubbing) ? this.player.values.currentTime / this.player.duration() : this.player.currentTime() / this.player.duration();
-
- var barProgress,
- progress = this.getPercent();
- handle = this.handle,
- bar = this.bar;
-
- // Protect against no duration and other division issues
- if (isNaN(progress)) { progress = 0; }
-
- barProgress = progress;
-
- // If there is a handle, we need to account for the handle in our calculation for progress bar
- // so that it doesn't fall short of or extend past the handle.
- if (handle) {
-
- var box = this.el,
- boxWidth = box.offsetWidth,
-
- handleWidth = handle.el.offsetWidth,
-
- // The width of the handle in percent of the containing box
- // In IE, widths may not be ready yet causing NaN
- handlePercent = (handleWidth) ? handleWidth / boxWidth : 0,
-
- // Get the adjusted size of the box, considering that the handle's center never touches the left or right side.
- // There is a margin of half the handle's width on both sides.
- boxAdjustedPercent = 1 - handlePercent;
-
- // Adjust the progress that we'll use to set widths to the new adjusted box width
- adjustedProgress = progress * boxAdjustedPercent,
-
- // The bar does reach the left side, so we need to account for this in the bar's width
- barProgress = adjustedProgress + (handlePercent / 2);
-
- // Move the handle from the left based on the adjected progress
- handle.el.style.left = _V_.round(adjustedProgress * 100, 2) + "%";
- }
-
- // Set the new bar width
- bar.el.style.width = _V_.round(barProgress * 100, 2) + "%";
- },
-
- calculateDistance: function(event){
- var box = this.el,
- boxX = _V_.findPosX(box),
- boxW = box.offsetWidth,
- handle = this.handle;
-
- if (handle) {
- var handleW = handle.el.offsetWidth;
-
- // Adjusted X and Width, so handle doesn't go outside the bar
- boxX = boxX + (handleW / 2);
- boxW = boxW - handleW;
- }
-
- // Percent that the click is through the adjusted area
- return Math.max(0, Math.min(1, (event.pageX - boxX) / boxW));
- },
-
- onFocus: function(event){
- _V_.on(document, "keyup", _V_.proxy(this, this.onKeyPress));
- },
-
- onKeyPress: function(event){
- if (event.which == 37) { // Left Arrow
- event.preventDefault();
- this.stepBack();
- } else if (event.which == 39) { // Right Arrow
- event.preventDefault();
- this.stepForward();
- }
- },
-
- onBlur: function(event){
- _V_.off(document, "keyup", _V_.proxy(this, this.onKeyPress));
- }
-});
-
-
-/* Progress
-================================================================================ */
-
-// Progress Control: Seek, Load Progress, and Play Progress
-_V_.ProgressControl = _V_.Component.extend({
-
- options: {
- components: {
- "seekBar": {}
- }
- },
-
- createElement: function(){
- return this._super("div", {
- className: "vjs-progress-control vjs-control"
- });
- }
-
-});
-
-// Seek Bar and holder for the progress bars
-_V_.SeekBar = _V_.Slider.extend({
-
- options: {
- components: {
- "loadProgressBar": {},
-
- // Set property names to bar and handle to match with the parent Slider class is looking for
- "bar": { componentClass: "PlayProgressBar" },
- "handle": { componentClass: "SeekHandle" }
- }
- },
-
- playerEvent: "timeupdate",
-
- init: function(player, options){
- this._super(player, options);
- },
-
- createElement: function(){
- return this._super("div", {
- className: "vjs-progress-holder"
- });
- },
-
- getPercent: function(){
- return this.player.currentTime() / this.player.duration();
- },
-
- onMouseDown: function(event){
- this._super(event);
-
- this.player.scrubbing = true;
-
- this.videoWasPlaying = !this.player.paused();
- this.player.pause();
- },
-
- onMouseMove: function(event){
- var newTime = this.calculateDistance(event) * this.player.duration();
-
- // Don't let video end while scrubbing.
- if (newTime == this.player.duration()) { newTime = newTime - 0.1; }
-
- // Set new time (tell player to seek to new time)
- this.player.currentTime(newTime);
- },
-
- onMouseUp: function(event){
- this._super(event);
-
- this.player.scrubbing = false;
- if (this.videoWasPlaying) {
- this.player.play();
- }
- },
-
- stepForward: function(){
- this.player.currentTime(this.player.currentTime() + 1);
- },
-
- stepBack: function(){
- this.player.currentTime(this.player.currentTime() - 1);
- }
-
-});
-
-// Load Progress Bar
-_V_.LoadProgressBar = _V_.Component.extend({
-
- init: function(player, options){
- this._super(player, options);
- player.on("progress", _V_.proxy(this, this.update));
- },
-
- createElement: function(){
- return this._super("div", {
- className: "vjs-load-progress",
- innerHTML: '<span class="vjs-control-text">Loaded: 0%</span>'
- });
- },
-
- update: function(){
- if (this.el.style) { this.el.style.width = _V_.round(this.player.bufferedPercent() * 100, 2) + "%"; }
- }
-
-});
-
-// Play Progress Bar
-_V_.PlayProgressBar = _V_.Component.extend({
-
- createElement: function(){
- return this._super("div", {
- className: "vjs-play-progress",
- innerHTML: '<span class="vjs-control-text">Progress: 0%</span>'
- });
- }
-
-});
-
-// Seek Handle
-// SeekBar Behavior includes play progress bar, and seek handle
-// Needed so it can determine seek position based on handle position/size
-_V_.SeekHandle = _V_.Component.extend({
-
- createElement: function(){
- return this._super("div", {
- className: "vjs-seek-handle",
- innerHTML: '<span class="vjs-control-text">00:00</span>'
- });
- }
-
-});
-
-/* Volume Scrubber
-================================================================================ */
-// Progress Control: Seek, Load Progress, and Play Progress
-_V_.VolumeControl = _V_.Component.extend({
-
- options: {
- components: {
- "volumeBar": {}
- }
- },
-
- createElement: function(){
- return this._super("div", {
- className: "vjs-volume-control vjs-control"
- });
- }
-
-});
-
-_V_.VolumeBar = _V_.Slider.extend({
-
- options: {
- components: {
- "bar": { componentClass: "VolumeLevel" },
- "handle": { componentClass: "VolumeHandle" }
- }
- },
-
- playerEvent: "volumechange",
-
- createElement: function(){
- return this._super("div", {
- className: "vjs-volume-bar"
- });
- },
-
- onMouseMove: function(event) {
- this.player.volume(this.calculateDistance(event));
- },
-
- getPercent: function(){
- return this.player.volume();
- },
-
- stepForward: function(){
- this.player.volume(this.player.volume() + 0.1);
- },
-
- stepBack: function(){
- this.player.volume(this.player.volume() - 0.1);
- }
-});
-
-_V_.VolumeLevel = _V_.Component.extend({
-
- createElement: function(){
- return this._super("div", {
- className: "vjs-volume-level",
- innerHTML: '<span class="vjs-control-text"></span>'
- });
- }
-
-});
-
-_V_.VolumeHandle = _V_.Component.extend({
-
- createElement: function(){
- return this._super("div", {
- className: "vjs-volume-handle",
- innerHTML: '<span class="vjs-control-text"></span>'
- // tabindex: 0,
- // role: "slider", "aria-valuenow": 0, "aria-valuemin": 0, "aria-valuemax": 100
- });
- }
-
-});
-
-_V_.MuteToggle = _V_.Button.extend({
-
- init: function(player, options){
- this._super(player, options);
-
- player.on("volumechange", _V_.proxy(this, this.update));
- },
-
- createElement: function(){
- return this._super("div", {
- className: "vjs-mute-control vjs-control",
- innerHTML: '<div><span class="vjs-control-text">Mute</span></div>'
- });
- },
-
- onClick: function(event){
- this.player.muted( this.player.muted() ? false : true );
- },
-
- update: function(event){
- var vol = this.player.volume(),
- level = 3;
-
- if (vol == 0 || this.player.muted()) {
- level = 0;
- } else if (vol < 0.33) {
- level = 1;
- } else if (vol < 0.67) {
- level = 2;
- }
-
- /* TODO improve muted icon classes */
- _V_.each.call(this, [0,1,2,3], function(i){
- _V_.removeClass(this.el, "vjs-vol-"+i);
- });
- _V_.addClass(this.el, "vjs-vol-"+level);
- }
-
-});
-
-
-/* Poster Image
-================================================================================ */
-_V_.PosterImage = _V_.Button.extend({
- init: function(player, options){
- this._super(player, options);
-
- if (!this.player.options.poster) {
- this.hide();
- }
-
- player.on("play", _V_.proxy(this, this.hide));
- },
-
- createElement: function(){
- return _V_.createElement("img", {
- className: "vjs-poster",
- src: this.player.options.poster,
-
- // Don't want poster to be tabbable.
- tabIndex: -1
- });
- },
-
- onClick: function(){
- this.player.play();
- }
-});
-
-/* Menu
-================================================================================ */
-// The base for text track and settings menu buttons.
-_V_.Menu = _V_.Component.extend({
-
- init: function(player, options){
- this._super(player, options);
- },
-
- addItem: function(component){
- this.addComponent(component);
- component.on("click", this.proxy(function(){
- this.unlockShowing();
- }));
- },
-
- createElement: function(){
- return this._super("ul", {
- className: "vjs-menu"
- });
- }
-
-});
-
-_V_.MenuItem = _V_.Button.extend({
-
- init: function(player, options){
- this._super(player, options);
-
- if (options.selected) {
- this.addClass("vjs-selected");
- }
- },
-
- createElement: function(type, attrs){
- return this._super("li", _V_.merge({
- className: "vjs-menu-item",
- innerHTML: this.options.label
- }, attrs));
- },
-
- onClick: function(){
- this.selected(true);
- },
-
- selected: function(selected){
- if (selected) {
- this.addClass("vjs-selected");
- } else {
- this.removeClass("vjs-selected")
- }
- }
-
-});// TEXT TRACKS
-// Text tracks are tracks of timed text events.
-// Captions - text displayed over the video for the hearing impared
-// Subtitles - text displayed over the video for those who don't understand langauge in the video
-// Chapters - text displayed in a menu allowing the user to jump to particular points (chapters) in the video
-// Descriptions (not supported yet) - audio descriptions that are read back to the user by a screen reading device
-
-// Player Track Functions - Functions add to the player object for easier access to tracks
-_V_.merge(_V_.Player.prototype, {
-
- // Add an array of text tracks. captions, subtitles, chapters, descriptions
- // Track objects will be stored in the player.textTracks array
- addTextTracks: function(trackObjects){
- var tracks = this.textTracks = (this.textTracks) ? this.textTracks : [],
- i = 0, j = trackObjects.length, track, Kind;
-
- for (;i<j;i++) {
- // HTML5 Spec says default to subtitles.
- // Uppercase (uc) first letter to match class names
- Kind = _V_.uc(trackObjects[i].kind || "subtitles");
-
- // Create correct texttrack class. CaptionsTrack, etc.
- track = new _V_[Kind + "Track"](this, trackObjects[i]);
-
- tracks.push(track);
-
- // If track.default is set, start showing immediately
- // TODO: Add a process to deterime the best track to show for the specific kind
- // Incase there are mulitple defaulted tracks of the same kind
- // Or the user has a set preference of a specific language that should override the default
- if (track['default']) {
- this.ready(_V_.proxy(track, track.show));
- }
- }
-
- // Return the track so it can be appended to the display component
- return this;
- },
-
- // Show a text track
- // disableSameKind: disable all other tracks of the same kind. Value should be a track kind (captions, etc.)
- showTextTrack: function(id, disableSameKind){
- var tracks = this.textTracks,
- i = 0,
- j = tracks.length,
- track, showTrack, kind;
-
- // Find Track with same ID
- for (;i<j;i++) {
- track = tracks[i];
- if (track.id === id) {
- track.show();
- showTrack = track;
-
- // Disable tracks of the same kind
- } else if (disableSameKind && track.kind == disableSameKind && track.mode > 0) {
- track.disable();
- }
- }
-
- // Get track kind from shown track or disableSameKind
- kind = (showTrack) ? showTrack.kind : ((disableSameKind) ? disableSameKind : false);
-
- // Trigger trackchange event, captionstrackchange, subtitlestrackchange, etc.
- if (kind) {
- this.trigger(kind+"trackchange");
- }
-
- return this;
- }
-
-});
-
-// Track Class
-// Contains track methods for loading, showing, parsing cues of tracks
-_V_.Track = _V_.Component.extend({
-
- init: function(player, options){
- this._super(player, options);
-
- // Apply track info to track object
- // Options will often be a track element
- _V_.merge(this, {
- // Build ID if one doesn't exist
- id: options.id || ("vjs_" + options.kind + "_" + options.language + "_" + _V_.guid++),
-
- src: options.src,
-
- // If default is used, subtitles/captions to start showing
- "default": options["default"], // 'default' is reserved-ish
- title: options.title,
-
- // Language - two letter string to represent track language, e.g. "en" for English
- // readonly attribute DOMString language;
- language: options.srclang,
-
- // Track label e.g. "English"
- // readonly attribute DOMString label;
- label: options.label,
-
- // All cues of the track. Cues have a startTime, endTime, text, and other properties.
- // readonly attribute TextTrackCueList cues;
- cues: [],
-
- // ActiveCues is all cues that are currently showing
- // readonly attribute TextTrackCueList activeCues;
- activeCues: [],
-
- // ReadyState describes if the text file has been loaded
- // const unsigned short NONE = 0;
- // const unsigned short LOADING = 1;
- // const unsigned short LOADED = 2;
- // const unsigned short ERROR = 3;
- // readonly attribute unsigned short readyState;
- readyState: 0,
-
- // Mode describes if the track is showing, hidden, or disabled
- // const unsigned short OFF = 0;
- // const unsigned short HIDDEN = 1; (still triggering cuechange events, but not visible)
- // const unsigned short SHOWING = 2;
- // attribute unsigned short mode;
- mode: 0
- });
- },
-
- // Create basic div to hold cue text
- createElement: function(){
- return this._super("div", {
- className: "vjs-" + this.kind + " vjs-text-track"
- });
- },
-
- // Show: Mode Showing (2)
- // Indicates that the text track is active. If no attempt has yet been made to obtain the track's cues, the user agent will perform such an attempt momentarily.
- // The user agent is maintaining a list of which cues are active, and events are being fired accordingly.
- // In addition, for text tracks whose kind is subtitles or captions, the cues are being displayed over the video as appropriate;
- // for text tracks whose kind is descriptions, the user agent is making the cues available to the user in a non-visual fashion;
- // and for text tracks whose kind is chapters, the user agent is making available to the user a mechanism by which the user can navigate to any point in the media resource by selecting a cue.
- // The showing by default state is used in conjunction with the default attribute on track elements to indicate that the text track was enabled due to that attribute.
- // This allows the user agent to override the state if a later track is discovered that is more appropriate per the user's preferences.
- show: function(){
- this.activate();
-
- this.mode = 2;
-
- // Show element.
- this._super();
- },
-
- // Hide: Mode Hidden (1)
- // Indicates that the text track is active, but that the user agent is not actively displaying the cues.
- // If no attempt has yet been made to obtain the track's cues, the user agent will perform such an attempt momentarily.
- // The user agent is maintaining a list of which cues are active, and events are being fired accordingly.
- hide: function(){
- // When hidden, cues are still triggered. Disable to stop triggering.
- this.activate();
-
- this.mode = 1;
-
- // Hide element.
- this._super();
- },
-
- // Disable: Mode Off/Disable (0)
- // Indicates that the text track is not active. Other than for the purposes of exposing the track in the DOM, the user agent is ignoring the text track.
- // No cues are active, no events are fired, and the user agent will not attempt to obtain the track's cues.
- disable: function(){
- // If showing, hide.
- if (this.mode == 2) { this.hide(); }
-
- // Stop triggering cues
- this.deactivate();
-
- // Switch Mode to Off
- this.mode = 0;
- },
-
- // Turn on cue tracking. Tracks that are showing OR hidden are active.
- activate: function(){
- // Load text file if it hasn't been yet.
- if (this.readyState == 0) { this.load(); }
-
- // Only activate if not already active.
- if (this.mode == 0) {
- // Update current cue on timeupdate
- // Using unique ID for proxy function so other tracks don't remove listener
- this.player.on("timeupdate", this.proxy(this.update, this.id));
-
- // Reset cue time on media end
- this.player.on("ended", this.proxy(this.reset, this.id));
-
- // Add to display
- if (this.kind == "captions" || this.kind == "subtitles") {
- this.player.textTrackDisplay.addComponent(this);
- }
- }
- },
-
- // Turn off cue tracking.
- deactivate: function(){
- // Using unique ID for proxy function so other tracks don't remove listener
- this.player.off("timeupdate", this.proxy(this.update, this.id));
- this.player.off("ended", this.proxy(this.reset, this.id));
- this.reset(); // Reset
-
- // Remove from display
- this.player.textTrackDisplay.removeComponent(this);
- },
-
- // A readiness state
- // One of the following:
- //
- // Not loaded
- // Indicates that the text track is known to exist (e.g. it has been declared with a track element), but its cues have not been obtained.
- //
- // Loading
- // Indicates that the text track is loading and there have been no fatal errors encountered so far. Further cues might still be added to the track.
- //
- // Loaded
- // Indicates that the text track has been loaded with no fatal errors. No new cues will be added to the track except if the text track corresponds to a MutableTextTrack object.
- //
- // Failed to load
- // Indicates that the text track was enabled, but when the user agent attempted to obtain it, this failed in some way (e.g. URL could not be resolved, network error, unknown text track format). Some or all of the cues are likely missing and will not be obtained.
- load: function(){
-
- // Only load if not loaded yet.
- if (this.readyState == 0) {
- this.readyState = 1;
- _V_.get(this.src, this.proxy(this.parseCues), this.proxy(this.onError));
- }
-
- },
-
- onError: function(err){
- this.error = err;
- this.readyState = 3;
- this.trigger("error");
- },
-
- // Parse the WebVTT text format for cue times.
- // TODO: Separate parser into own class so alternative timed text formats can be used. (TTML, DFXP)
- parseCues: function(srcContent) {
- var cue, time, text,
- lines = srcContent.split("\n"),
- line = "", id;
-
- for (var i=1, j=lines.length; i<j; i++) {
- // Line 0 should be 'WEBVTT', so skipping i=0
-
- line = _V_.trim(lines[i]); // Trim whitespace and linebreaks
-
- if (line) { // Loop until a line with content
-
- // First line could be an optional cue ID
- // Check if line has the time separator
- if (line.indexOf("-->") == -1) {
- id = line;
- // Advance to next line for timing.
- line = _V_.trim(lines[++i]);
- } else {
- id = this.cues.length;
- }
-
- // First line - Number
- cue = {
- id: id, // Cue Number
- index: this.cues.length // Position in Array
- };
-
- // Timing line
- time = line.split(" --> ");
- cue.startTime = this.parseCueTime(time[0]);
- cue.endTime = this.parseCueTime(time[1]);
-
- // Additional lines - Cue Text
- text = [];
-
- // Loop until a blank line or end of lines
- // Assumeing trim("") returns false for blank lines
- while (lines[++i] && (line = _V_.trim(lines[i]))) {
- text.push(line);
- }
-
- cue.text = text.join('<br/>');
-
- // Add this cue
- this.cues.push(cue);
- }
- }
-
- this.readyState = 2;
- this.trigger("loaded");
- },
-
- parseCueTime: function(timeText) {
- var parts = timeText.split(':'),
- time = 0,
- hours, minutes, other, seconds, ms, flags;
-
- // Check if optional hours place is included
- // 00:00:00.000 vs. 00:00.000
- if (parts.length == 3) {
- hours = parts[0];
- minutes = parts[1];
- other = parts[2];
- } else {
- hours = 0;
- minutes = parts[0];
- other = parts[1];
- }
-
- // Break other (seconds, milliseconds, and flags) by spaces
- // TODO: Make additional cue layout settings work with flags
- other = other.split(/\s+/)
- // Remove seconds. Seconds is the first part before any spaces.
- seconds = other.splice(0,1)[0];
- // Could use either . or , for decimal
- seconds = seconds.split(/\.|,/);
- // Get milliseconds
- ms = parseFloat(seconds[1]);
- seconds = seconds[0];
-
- // hours => seconds
- time += parseFloat(hours) * 3600;
- // minutes => seconds
- time += parseFloat(minutes) * 60;
- // Add seconds
- time += parseFloat(seconds);
- // Add milliseconds
- if (ms) { time += ms/1000; }
-
- return time;
- },
-
- // Update active cues whenever timeupdate events are triggered on the player.
- update: function(){
- if (this.cues.length > 0) {
-
- // Get curent player time
- var time = this.player.currentTime();
-
- // Check if the new time is outside the time box created by the the last update.
- if (this.prevChange === undefined || time < this.prevChange || this.nextChange <= time) {
- var cues = this.cues,
-
- // Create a new time box for this state.
- newNextChange = this.player.duration(), // Start at beginning of the timeline
- newPrevChange = 0, // Start at end
-
- reverse = false, // Set the direction of the loop through the cues. Optimized the cue check.
- newCues = [], // Store new active cues.
-
- // Store where in the loop the current active cues are, to provide a smart starting point for the next loop.
- firstActiveIndex, lastActiveIndex,
-
- html = "", // Create cue text HTML to add to the display
- cue, i, j; // Loop vars
-
- // Check if time is going forwards or backwards (scrubbing/rewinding)
- // If we know the direction we can optimize the starting position and direction of the loop through the cues array.
- if (time >= this.nextChange || this.nextChange === undefined) { // NextChange should happen
- // Forwards, so start at the index of the first active cue and loop forward
- i = (this.firstActiveIndex !== undefined) ? this.firstActiveIndex : 0;
- } else {
- // Backwards, so start at the index of the last active cue and loop backward
- reverse = true;
- i = (this.lastActiveIndex !== undefined) ? this.lastActiveIndex : cues.length - 1;
- }
-
- while (true) { // Loop until broken
- cue = cues[i];
-
- // Cue ended at this point
- if (cue.endTime <= time) {
- newPrevChange = Math.max(newPrevChange, cue.endTime);
-
- if (cue.active) {
- cue.active = false;
- }
-
- // No earlier cues should have an active start time.
- // Nevermind. Assume first cue could have a duration the same as the video.
- // In that case we need to loop all the way back to the beginning.
- // if (reverse && cue.startTime) { break; }
-
- // Cue hasn't started
- } else if (time < cue.startTime) {
- newNextChange = Math.min(newNextChange, cue.startTime);
-
- if (cue.active) {
- cue.active = false;
- }
-
- // No later cues should have an active start time.
- if (!reverse) { break; }
-
- // Cue is current
- } else {
-
- if (reverse) {
- // Add cue to front of array to keep in time order
- newCues.splice(0,0,cue);
-
- // If in reverse, the first current cue is our lastActiveCue
- if (lastActiveIndex === undefined) { lastActiveIndex = i; }
- firstActiveIndex = i;
- } else {
- // Add cue to end of array
- newCues.push(cue);
-
- // If forward, the first current cue is our firstActiveIndex
- if (firstActiveIndex === undefined) { firstActiveIndex = i; }
- lastActiveIndex = i;
- }
-
- newNextChange = Math.min(newNextChange, cue.endTime);
- newPrevChange = Math.max(newPrevChange, cue.startTime);
-
- cue.active = true;
- }
-
- if (reverse) {
- // Reverse down the array of cues, break if at first
- if (i === 0) { break; } else { i--; }
- } else {
- // Walk up the array fo cues, break if at last
- if (i === cues.length - 1) { break; } else { i++; }
- }
-
- }
-
- this.activeCues = newCues;
- this.nextChange = newNextChange;
- this.prevChange = newPrevChange;
- this.firstActiveIndex = firstActiveIndex;
- this.lastActiveIndex = lastActiveIndex;
-
- this.updateDisplay();
-
- this.trigger("cuechange");
- }
- }
- },
-
- // Add cue HTML to display
- updateDisplay: function(){
- var cues = this.activeCues,
- html = "",
- i=0,j=cues.length;
-
- for (;i<j;i++) {
- html += "<span class='vjs-tt-cue'>"+cues[i].text+"</span>";
- }
-
- this.el.innerHTML = html;
- },
-
- // Set all loop helper values back
- reset: function(){
- this.nextChange = 0;
- this.prevChange = this.player.duration();
- this.firstActiveIndex = 0;
- this.lastActiveIndex = 0;
- }
-
-});
-
-// Create specific track types
-_V_.CaptionsTrack = _V_.Track.extend({
- kind: "captions"
-});
-
-_V_.SubtitlesTrack = _V_.Track.extend({
- kind: "subtitles"
-});
-
-_V_.ChaptersTrack = _V_.Track.extend({
- kind: "chapters"
-});
-
-
-/* Text Track Display
-================================================================================ */
-// Global container for both subtitle and captions text. Simple div container.
-_V_.TextTrackDisplay = _V_.Component.extend({
-
- createElement: function(){
- return this._super("div", {
- className: "vjs-text-track-display"
- });
- }
-
-});
-
-/* Text Track Menu Items
-================================================================================ */
-_V_.TextTrackMenuItem = _V_.MenuItem.extend({
-
- init: function(player, options){
- var track = this.track = options.track;
-
- // Modify options for parent MenuItem class's init.
- options.label = track.label;
- options.selected = track["default"];
- this._super(player, options);
-
- this.player.on(track.kind + "trackchange", _V_.proxy(this, this.update));
- },
-
- onClick: function(){
- this._super();
- this.player.showTextTrack(this.track.id, this.track.kind);
- },
-
- update: function(){
- if (this.track.mode == 2) {
- this.selected(true);
- } else {
- this.selected(false);
- }
- }
-
-});
-
-_V_.OffTextTrackMenuItem = _V_.TextTrackMenuItem.extend({
-
- init: function(player, options){
- // Create pseudo track info
- // Requires options.kind
- options.track = { kind: options.kind, player: player, label: "Off" }
- this._super(player, options);
- },
-
- onClick: function(){
- this._super();
- this.player.showTextTrack(this.track.id, this.track.kind);
- },
-
- update: function(){
- var tracks = this.player.textTracks,
- i=0, j=tracks.length, track,
- off = true;
-
- for (;i<j;i++) {
- track = tracks[i];
- if (track.kind == this.track.kind && track.mode == 2) {
- off = false;
- }
- }
-
- if (off) {
- this.selected(true);
- } else {
- this.selected(false);
- }
- }
-
-});
-
-/* Captions Button
-================================================================================ */
-_V_.TextTrackButton = _V_.Button.extend({
-
- init: function(player, options){
- this._super(player, options);
-
- this.menu = this.createMenu();
-
- if (this.items.length === 0) {
- this.hide();
- }
- },
-
- createMenu: function(){
- var menu = new _V_.Menu(this.player);
-
- // Add a title list item to the top
- menu.el.appendChild(_V_.createElement("li", {
- className: "vjs-menu-title",
- innerHTML: _V_.uc(this.kind)
- }));
-
- // Add an OFF menu item to turn all tracks off
- menu.addItem(new _V_.OffTextTrackMenuItem(this.player, { kind: this.kind }))
-
- this.items = this.createItems();
-
- // Add menu items to the menu
- this.each(this.items, function(item){
- menu.addItem(item);
- });
-
- // Add list to element
- this.addComponent(menu);
-
- return menu;
- },
-
- // Create a menu item for each text track
- createItems: function(){
- var items = [];
- this.each(this.player.textTracks, function(track){
- if (track.kind === this.kind) {
- items.push(new _V_.TextTrackMenuItem(this.player, {
- track: track
- }));
- }
- });
- return items;
- },
-
- buildCSSClass: function(){
- return this.className + " vjs-menu-button " + this._super();
- },
-
- // Focus - Add keyboard functionality to element
- onFocus: function(){
- // Show the menu, and keep showing when the menu items are in focus
- this.menu.lockShowing();
- // this.menu.el.style.display = "block";
-
- // When tabbing through, the menu should hide when focus goes from the last menu item to the next tabbed element.
- _V_.one(this.menu.el.childNodes[this.menu.el.childNodes.length - 1], "blur", this.proxy(function(){
- this.menu.unlockShowing();
- }));
- },
- // Can't turn off list display that we turned on with focus, because list would go away.
- onBlur: function(){},
-
- onClick: function(){
- // When you click the button it adds focus, which will show the menu indefinitely.
- // So we'll remove focus when the mouse leaves the button.
- // Focus is needed for tab navigation.
- this.one("mouseout", this.proxy(function(){
- this.menu.unlockShowing();
- this.el.blur();
- }));
- }
-
-});
-
-_V_.CaptionsButton = _V_.TextTrackButton.extend({
- kind: "captions",
- buttonText: "Captions",
- className: "vjs-captions-button"
-});
-
-_V_.SubtitlesButton = _V_.TextTrackButton.extend({
- kind: "subtitles",
- buttonText: "Subtitles",
- className: "vjs-subtitles-button"
-});
-
-// Chapters act much differently than other text tracks
-// Cues are navigation vs. other tracks of alternative languages
-_V_.ChaptersButton = _V_.TextTrackButton.extend({
- kind: "chapters",
- buttonText: "Chapters",
- className: "vjs-chapters-button",
-
- // Create a menu item for each text track
- createItems: function(chaptersTrack){
- var items = [];
-
- this.each(this.player.textTracks, function(track){
- if (track.kind === this.kind) {
- items.push(new _V_.TextTrackMenuItem(this.player, {
- track: track
- }));
- }
- });
-
- return items;
- },
-
- createMenu: function(){
- var tracks = this.player.textTracks,
- i = 0,
- j = tracks.length,
- track, chaptersTrack,
- items = this.items = [];
-
- for (;i<j;i++) {
- track = tracks[i];
- if (track.kind == this.kind && track["default"]) {
- if (track.readyState < 2) {
- this.chaptersTrack = track;
- track.on("loaded", this.proxy(this.createMenu));
- return;
- } else {
- chaptersTrack = track;
- break;
- }
- }
- }
-
- var menu = this.menu = new _V_.Menu(this.player);
-
- menu.el.appendChild(_V_.createElement("li", {
- className: "vjs-menu-title",
- innerHTML: _V_.uc(this.kind)
- }));
-
- if (chaptersTrack) {
- var cues = chaptersTrack.cues,
- i = 0, j = cues.length, cue, mi;
-
- for (;i<j;i++) {
- cue = cues[i];
-
- mi = new _V_.ChaptersTrackMenuItem(this.player, {
- track: chaptersTrack,
- cue: cue
- });
-
- items.push(mi);
-
- menu.addComponent(mi);
- }
- }
-
- // Add list to element
- this.addComponent(menu);
-
- if (this.items.length > 0) {
- this.show();
- }
-
- return menu;
- }
-
-});
-
-_V_.ChaptersTrackMenuItem = _V_.MenuItem.extend({
-
- init: function(player, options){
- var track = this.track = options.track,
- cue = this.cue = options.cue,
- currentTime = player.currentTime();
-
- // Modify options for parent MenuItem class's init.
- options.label = cue.text;
- options.selected = (cue.startTime <= currentTime && currentTime < cue.endTime);
- this._super(player, options);
-
- track.on("cuechange", _V_.proxy(this, this.update));
- },
-
- onClick: function(){
- this._super();
- this.player.currentTime(this.cue.startTime);
- this.update(this.cue.startTime);
- },
-
- update: function(time){
- var cue = this.cue,
- currentTime = this.player.currentTime();
-
- // _V_.log(currentTime, cue.startTime);
- if (cue.startTime <= currentTime && currentTime < cue.endTime) {
- this.selected(true);
- } else {
- this.selected(false);
- }
- }
-
-});
-
-// Add Buttons to controlBar
-_V_.merge(_V_.ControlBar.prototype.options.components, {
- "subtitlesButton": {},
- "captionsButton": {},
- "chaptersButton": {}
-});
-
-// _V_.Cue = _V_.Component.extend({
-// init: function(player, options){
-// this._super(player, options);
-// }
-// });// Automatically set up any tags that have a data-setup attribute
-_V_.autoSetup = function(){
- var options, vid, player,
- vids = document.getElementsByTagName("video");
-
- // Check if any media elements exist
- if (vids && vids.length > 0) {
-
- for (var i=0,j=vids.length; i<j; i++) {
- vid = vids[i];
-
- // Check if element exists, has getAttribute func.
- // IE seems to consider typeof el.getAttribute == "object" instead of "function" like expected, at least when loading the player immediately.
- if (vid && vid.getAttribute) {
-
- // Make sure this player hasn't already been set up.
- if (vid.player === undefined) {
- options = vid.getAttribute("data-setup");
-
- // Check if data-setup attr exists.
- // We only auto-setup if they've added the data-setup attr.
- if (options !== null) {
-
- // Parse options JSON
- // If empty string, make it a parsable json object.
- options = JSON.parse(options || "{}");
-
- // Create new video.js instance.
- player = _V_(vid, options);
- }
- }
-
- // If getAttribute isn't defined, we need to wait for the DOM.
- } else {
- _V_.autoSetupTimeout(1);
- break;
- }
- }
-
- // No videos were found, so keep looping unless page is finisehd loading.
- } else if (!_V_.windowLoaded) {
- _V_.autoSetupTimeout(1);
- }
-};
-
-// Pause to let the DOM keep processing
-_V_.autoSetupTimeout = function(wait){
- setTimeout(_V_.autoSetup, wait);
-};
-
-_V_.addEvent(window, "load", function(){
- _V_.windowLoaded = true;
-});
-
-// Run Auto-load players
-_V_.autoSetup();
-// Expose to global
-window.VideoJS = window._V_ = VideoJS;
-
-// End self-executing function
-})(window);
\ No newline at end of file
+++ /dev/null
-/*!
-Video.js - HTML5 Video Player
-Version GENERATED_AT_BUILD
-
-LGPL v3 LICENSE INFO
-This file is part of Video.js. Copyright 2011 Zencoder, Inc.
-
-Video.js is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-Video.js is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with Video.js. If not, see <http://www.gnu.org/licenses/>.
-*/
-(function(window,undefined){var document=window.document;document.createElement("video");document.createElement("audio");var VideoJS=function(id,addOptions,ready){var tag;if(typeof id=="string"){if(id.indexOf("#")===0){id=id.slice(1)}if(_V_.players[id]){return _V_.players[id]}else{tag=_V_.el(id)}}else{tag=id}if(!tag||!tag.nodeName){throw new TypeError("The element or ID supplied is not valid. (VideoJS)")}return tag.player||new _V_.Player(tag,addOptions,ready)},_V_=VideoJS,CDN_VERSION="GENERATED_CDN_VSN";VideoJS.players={};VideoJS.options={techOrder:["html5","flash"],html5:{},flash:{swf:"http://vjs.zencdn.net/c/video-js.swf"},width:300,height:150,defaultVolume:0,components:{posterImage:{},textTrackDisplay:{},loadingSpinner:{},bigPlayButton:{},controlBar:{}}};if(CDN_VERSION!="GENERATED_CDN_VSN"){_V_.options.flash.swf="http://vjs.zencdn.net/"+CDN_VERSION+"/video-js.swf"}_V_.merge=function(obj1,obj2,safe){if(!obj2){obj2={}}for(var attrname in obj2){if(obj2.hasOwnProperty(attrname)&&(!safe||!obj1.hasOwnProperty(attrname))){obj1[attrname]=obj2[attrname]}}return obj1};_V_.extend=function(obj){this.merge(this,obj,true)};_V_.extend({tech:{},controlSets:{},isIE:function(){return !+"\v1"},isFF:function(){return !!_V_.ua.match("Firefox")},isIPad:function(){return navigator.userAgent.match(/iPad/i)!==null},isIPhone:function(){return navigator.userAgent.match(/iPhone/i)!==null},isIOS:function(){return VideoJS.isIPhone()||VideoJS.isIPad()},iOSVersion:function(){var match=navigator.userAgent.match(/OS (\d+)_/i);if(match&&match[1]){return match[1]}},isAndroid:function(){return navigator.userAgent.match(/Android.*AppleWebKit/i)!==null},androidVersion:function(){var match=navigator.userAgent.match(/Android (\d+)\./i);if(match&&match[1]){return match[1]}},testVid:document.createElement("video"),ua:navigator.userAgent,support:{},each:function(arr,fn){if(!arr||arr.length===0){return}for(var i=0,j=arr.length;i<j;i++){fn.call(this,arr[i],i)}},eachProp:function(obj,fn){if(!obj){return}for(var name in obj){if(obj.hasOwnProperty(name)){fn.call(this,name,obj[name])}}},el:function(id){return document.getElementById(id)},createElement:function(tagName,attributes){var el=document.createElement(tagName),attrname;for(attrname in attributes){if(attributes.hasOwnProperty(attrname)){if(attrname.indexOf("-")!==-1){el.setAttribute(attrname,attributes[attrname])}else{el[attrname]=attributes[attrname]}}}return el},insertFirst:function(node,parent){if(parent.firstChild){parent.insertBefore(node,parent.firstChild)}else{parent.appendChild(node)}},addClass:function(element,classToAdd){if((" "+element.className+" ").indexOf(" "+classToAdd+" ")==-1){element.className=element.className===""?classToAdd:element.className+" "+classToAdd}},removeClass:function(element,classToRemove){if(element.className.indexOf(classToRemove)==-1){return}var classNames=element.className.split(" ");classNames.splice(classNames.indexOf(classToRemove),1);element.className=classNames.join(" ")},blockTextSelection:function(){document.body.focus();document.onselectstart=function(){return false}},unblockTextSelection:function(){document.onselectstart=function(){return true}},formatTime:function(seconds,guide){guide=guide||seconds;var s=Math.floor(seconds%60),m=Math.floor(seconds/60%60),h=Math.floor(seconds/3600),gm=Math.floor(guide/60%60),gh=Math.floor(guide/3600);h=(h>0||gh>0)?h+":":"";m=(((h||gm>=10)&&m<10)?"0"+m:m)+":";s=(s<10)?"0"+s:s;return h+m+s},uc:function(string){return string.charAt(0).toUpperCase()+string.slice(1)},getRelativePosition:function(x,relativeElement){return Math.max(0,Math.min(1,(x-_V_.findPosX(relativeElement))/relativeElement.offsetWidth))},getComputedStyleValue:function(element,style){return window.getComputedStyle(element,null).getPropertyValue(style)},trim:function(string){return string.toString().replace(/^\s+/,"").replace(/\s+$/,"")},round:function(num,dec){if(!dec){dec=0}return Math.round(num*Math.pow(10,dec))/Math.pow(10,dec)},isEmpty:function(object){for(var prop in object){return false}return true},createTimeRange:function(start,end){return{length:1,start:function(){return start},end:function(){return end}}},cache:{},guid:1,expando:"vdata"+(new Date).getTime(),getData:function(elem){var id=elem[_V_.expando];if(!id){id=elem[_V_.expando]=_V_.guid++;_V_.cache[id]={}}return _V_.cache[id]},removeData:function(elem){var id=elem[_V_.expando];if(!id){return}delete _V_.cache[id];try{delete elem[_V_.expando]}catch(e){if(elem.removeAttribute){elem.removeAttribute(_V_.expando)}else{elem[_V_.expando]=null}}},proxy:function(context,fn,uid){if(!fn.guid){fn.guid=_V_.guid++}var ret=function(){return fn.apply(context,arguments)};ret.guid=(uid)?uid+"_"+fn.guid:fn.guid;return ret},get:function(url,onSuccess,onError){var local=(url.indexOf("file:")==0||(window.location.href.indexOf("file:")==0&&url.indexOf("http:")==-1));if(typeof XMLHttpRequest=="undefined"){XMLHttpRequest=function(){try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(f){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(g){}throw new Error("This browser does not support XMLHttpRequest.")}}var request=new XMLHttpRequest();try{request.open("GET",url)}catch(e){_V_.log("VideoJS XMLHttpRequest (open)",e);return false}request.onreadystatechange=_V_.proxy(this,function(){if(request.readyState==4){if(request.status==200||local&&request.status==0){onSuccess(request.responseText)}else{if(onError){onError()}}}});try{request.send()}catch(e){_V_.log("VideoJS XMLHttpRequest (send)",e);if(onError){onError(e)}}},setLocalStorage:function(key,value){var localStorage=window.localStorage||false;if(!localStorage){return}try{localStorage[key]=value}catch(e){if(e.code==22||e.code==1014){_V_.log("LocalStorage Full (VideoJS)",e)}else{_V_.log("LocalStorage Error (VideoJS)",e)}}},getAbsoluteURL:function(url){if(!url.match(/^https?:\/\//)){url=_V_.createElement("div",{innerHTML:'<a href="'+url+'">x</a>'}).firstChild.href}return url}});_V_.log=function(){_V_.log.history=_V_.log.history||[];_V_.log.history.push(arguments);if(window.console){arguments.callee=arguments.callee.caller;var newarr=[].slice.call(arguments);(typeof console.log==="object"?_V_.log.apply.call(console.log,console,newarr):console.log.apply(console,newarr))}};(function(b){function c(){}for(var d="assert,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,timeStamp,profile,profileEnd,time,timeEnd,trace,warn".split(","),a;a=d.pop();){b[a]=b[a]||c}})((function(){try{console.log();return window.console}catch(err){return window.console={}}})());if("getBoundingClientRect" in document.documentElement){_V_.findPosX=function(el){var box;try{box=el.getBoundingClientRect()}catch(e){}if(!box){return 0}var docEl=document.documentElement,body=document.body,clientLeft=docEl.clientLeft||body.clientLeft||0,scrollLeft=window.pageXOffset||body.scrollLeft,left=box.left+scrollLeft-clientLeft;return left}}else{_V_.findPosX=function(el){var curleft=el.offsetLeft;while(el=obj.offsetParent){if(el.className.indexOf("video-js")==-1){}else{}curleft+=el.offsetLeft}return curleft}}var JSON;if(!JSON){JSON={}}(function(){var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;if(typeof JSON.parse!=="function"){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==="object"){for(k in value){if(Object.prototype.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v}else{delete value[k]}}}}return reviver.call(holder,key,value)}text=String(text);cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})}if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))){j=eval("("+text+")");return typeof reviver==="function"?walk({"":j},""):j}throw new SyntaxError("JSON.parse")}}}());_V_.extend({on:function(elem,type,fn){var data=_V_.getData(elem),handlers;if(data&&!data.handler){data.handler=function(event){event=_V_.fixEvent(event);var handlers=_V_.getData(elem).events[event.type];if(handlers){var handlersCopy=[];_V_.each(handlers,function(handler,i){handlersCopy[i]=handler});for(var i=0,l=handlersCopy.length;i<l;i++){handlersCopy[i].call(elem,event)}}}}if(!data.events){data.events={}}handlers=data.events[type];if(!handlers){handlers=data.events[type]=[];if(document.addEventListener){elem.addEventListener(type,data.handler,false)}else{if(document.attachEvent){elem.attachEvent("on"+type,data.handler)}}}if(!fn.guid){fn.guid=_V_.guid++}handlers.push(fn)},addEvent:function(){return _V_.on.apply(this,arguments)},off:function(elem,type,fn){var data=_V_.getData(elem),handlers;if(!data.events){return}if(!type){for(type in data.events){_V_.cleanUpEvents(elem,type)}return}handlers=data.events[type];if(!handlers){return}if(fn&&fn.guid){for(var i=0;i<handlers.length;i++){if(handlers[i].guid===fn.guid){handlers.splice(i--,1)}}}_V_.cleanUpEvents(elem,type)},removeEvent:function(){return _V_.off.apply(this,arguments)},cleanUpEvents:function(elem,type){var data=_V_.getData(elem);if(data.events[type].length===0){delete data.events[type];if(document.removeEventListener){elem.removeEventListener(type,data.handler,false)}else{if(document.detachEvent){elem.detachEvent("on"+type,data.handler)}}}if(_V_.isEmpty(data.events)){delete data.events;delete data.handler}if(_V_.isEmpty(data)){_V_.removeData(elem)}},fixEvent:function(event){if(event[_V_.expando]){return event}var originalEvent=event;event=new _V_.Event(originalEvent);for(var i=_V_.Event.props.length,prop;i;){prop=_V_.Event.props[--i];event[prop]=originalEvent[prop]}if(!event.target){event.target=event.srcElement||document}if(event.target.nodeType===3){event.target=event.target.parentNode}if(!event.relatedTarget&&event.fromElement){event.relatedTarget=event.fromElement===event.target?event.toElement:event.fromElement}if(event.pageX==null&&event.clientX!=null){var eventDocument=event.target.ownerDocument||document,doc=eventDocument.documentElement,body=eventDocument.body;event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc&&doc.clientLeft||body&&body.clientLeft||0);event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc&&doc.clientTop||body&&body.clientTop||0)}if(event.which==null&&(event.charCode!=null||event.keyCode!=null)){event.which=event.charCode!=null?event.charCode:event.keyCode}if(!event.metaKey&&event.ctrlKey){event.metaKey=event.ctrlKey}if(!event.which&&event.button!==undefined){event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)))}return event},trigger:function(elem,event){var data=_V_.getData(elem),parent=elem.parentNode||elem.ownerDocument,type=event.type||event,handler;if(data){handler=data.handler}event=typeof event==="object"?event[_V_.expando]?event:new _V_.Event(type,event):new _V_.Event(type);event.type=type;if(handler){handler.call(elem,event)}event.result=undefined;event.target=elem},triggerEvent:function(){return _V_.trigger.apply(this,arguments)},one:function(elem,type,fn){_V_.on(elem,type,function(){_V_.off(elem,type,arguments.callee);fn.apply(this,arguments)})}});_V_.Event=function(src,props){if(src&&src.type){this.originalEvent=src;this.type=src.type;this.isDefaultPrevented=(src.defaultPrevented||src.returnValue===false||src.getPreventDefault&&src.getPreventDefault())?returnTrue:returnFalse}else{this.type=src}if(props){_V_.merge(this,props)}this.timeStamp=(new Date).getTime();this[_V_.expando]=true};_V_.Event.prototype={preventDefault:function(){this.isDefaultPrevented=returnTrue;var e=this.originalEvent;if(!e){return}if(e.preventDefault){e.preventDefault()}else{e.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=returnTrue;var e=this.originalEvent;if(!e){return}if(e.stopPropagation){e.stopPropagation()}e.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=returnTrue;this.stopPropagation()},isDefaultPrevented:returnFalse,isPropagationStopped:returnFalse,isImmediatePropagationStopped:returnFalse};_V_.Event.props="altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" ");function returnTrue(){return true}function returnFalse(){return false}(function(){var initializing=false,fnTest=/xyz/.test(function(){xyz})?/\b_super\b/:/.*/;_V_.Class=function(){};_V_.Class.extend=function(prop){var _super=this.prototype;initializing=true;var prototype=new this();initializing=false;for(var name in prop){prototype[name]=typeof prop[name]=="function"&&typeof _super[name]=="function"&&fnTest.test(prop[name])?(function(name,fn){return function(){var tmp=this._super;this._super=_super[name];var ret=fn.apply(this,arguments);this._super=tmp;return ret}})(name,prop[name]):prop[name]}function Class(){if(!initializing&&this.init){return this.init.apply(this,arguments)}else{if(!initializing){return arguments.callee.prototype.init()}}}Class.prototype=prototype;Class.constructor=Class;Class.extend=arguments.callee;return Class}})();_V_.Component=_V_.Class.extend({init:function(player,options){this.player=player;options=this.options=_V_.merge(this.options||{},options);if(options.el){this.el=options.el}else{this.el=this.createElement()}this.initComponents()},destroy:function(){},createElement:function(type,attrs){return _V_.createElement(type||"div",attrs)},buildCSSClass:function(){return""},initComponents:function(){var options=this.options;if(options&&options.components){this.eachProp(options.components,function(name,opts){var tempAdd=this.proxy(function(){this[name]=this.addComponent(name,opts)});if(opts.loadEvent){this.one(opts.loadEvent,tempAdd)}else{tempAdd()}})}},addComponent:function(name,options){var component,componentClass;if(typeof name=="string"){options=options||{};componentClass=options.componentClass||_V_.uc(name);component=new _V_[componentClass](this.player||this,options)}else{component=name}this.el.appendChild(component.el);return component},removeComponent:function(component){this.el.removeChild(component.el)},show:function(){this.el.style.display="block"},hide:function(){this.el.style.display="none"},fadeIn:function(){this.removeClass("vjs-fade-out");this.addClass("vjs-fade-in")},fadeOut:function(){this.removeClass("vjs-fade-in");this.addClass("vjs-fade-out")},lockShowing:function(){var style=this.el.style;style.display="block";style.opacity=1;style.visiblity="visible"},unlockShowing:function(){var style=this.el.style;style.display="";style.opacity="";style.visiblity=""},addClass:function(classToAdd){_V_.addClass(this.el,classToAdd)},removeClass:function(classToRemove){_V_.removeClass(this.el,classToRemove)},on:function(type,fn,uid){return _V_.on(this.el,type,_V_.proxy(this,fn))},addEvent:function(){return this.on.apply(this,arguments)},off:function(type,fn){return _V_.off(this.el,type,fn)},removeEvent:function(){return this.off.apply(this,arguments)},trigger:function(type,e){return _V_.trigger(this.el,type,e)},triggerEvent:function(){return this.trigger.apply(this,arguments)},one:function(type,fn){_V_.one(this.el,type,_V_.proxy(this,fn))},ready:function(fn){if(!fn){return this}if(this.isReady){fn.call(this)}else{if(this.readyQueue===undefined){this.readyQueue=[]}this.readyQueue.push(fn)}return this},triggerReady:function(){this.isReady=true;if(this.readyQueue&&this.readyQueue.length>0){this.each(this.readyQueue,function(fn){fn.call(this)});this.readyQueue=[];this.trigger("ready")}},each:function(arr,fn){_V_.each.call(this,arr,fn)},eachProp:function(obj,fn){_V_.eachProp.call(this,obj,fn)},extend:function(obj){_V_.merge(this,obj)},proxy:function(fn,uid){return _V_.proxy(this,fn,uid)}});_V_.Player=_V_.Component.extend({init:function(tag,addOptions,ready){this.tag=tag;var el=this.el=_V_.createElement("div"),options=this.options={};_V_.merge(options,_V_.options);_V_.merge(options,this.getVideoTagSettings());_V_.merge(options,addOptions);this.ready(ready);tag.removeAttribute("controls");tag.removeAttribute("poster");tag.player=el.player=this;tag.id=tag.id||"vjs_video_"+_V_.guid++;this.id=el.id=tag.id;el.className=tag.className;_V_.players[el.id]=this;el.setAttribute("width",options.width);el.setAttribute("height",options.height);el.style.width=options.width+"px";el.style.height=options.height+"px";tag.id+="_html5_api";tag.className="vjs-tech";tag.removeAttribute("width");tag.removeAttribute("height");tag.parentNode.insertBefore(el,tag);el.appendChild(tag);if(tag.hasChildNodes()){var nrOfChildNodes=tag.childNodes.length;for(var i=0,j=tag.childNodes;i<nrOfChildNodes;i++){if(j[0].nodeName.toLowerCase()=="source"||j[0].nodeName.toLowerCase()=="track"){tag.removeChild(j[0])}}}this.values={};this.addClass("vjs-paused");this.on("ended",this.onEnded);this.on("play",this.onPlay);this.on("pause",this.onPause);this.on("progress",this.onProgress);this.on("error",this.onError);if(options.controls){this.ready(function(){this.initComponents()})}this.textTracks=[];if(options.tracks&&options.tracks.length>0){this.addTextTracks(options.tracks)}if(!options.sources||options.sources.length==0){for(var i=0,j=options.techOrder;i<j.length;i++){var techName=j[i],tech=_V_[techName];if(tech.isSupported()){this.loadTech(techName);break}}}else{this.src(options.sources)}},destroy:function(){this.stopTrackingProgress();this.stopTrackingCurrentTime();_V_.players[this.id]=null;delete _V_.players[this.id];this.tech.destroy();this.el.parentNode.removeChild(this.el)},createElement:function(type,options){},getVideoTagSettings:function(){var options={sources:[],tracks:[]},tag=this.tag,getAttribute="getAttribute";options.src=tag[getAttribute]("src");options.controls=tag[getAttribute]("controls")!==null;options.poster=tag[getAttribute]("poster");options.preload=tag[getAttribute]("preload");options.autoplay=tag[getAttribute]("autoplay")!==null;options.loop=tag[getAttribute]("loop")!==null;options.muted=tag[getAttribute]("muted")!==null;options.width=tag[getAttribute]("width");options.height=tag[getAttribute]("height");if(this.tag.hasChildNodes()){for(var c,i=0,j=this.tag.childNodes;i<j.length;i++){c=j[i];if(c.nodeName.toLowerCase()=="source"){options.sources.push({src:c[getAttribute]("src"),type:c[getAttribute]("type"),media:c[getAttribute]("media"),title:c[getAttribute]("title")})}if(c.nodeName.toLowerCase()=="track"){options.tracks.push({src:c[getAttribute]("src"),kind:c[getAttribute]("kind"),srclang:c[getAttribute]("srclang"),label:c[getAttribute]("label"),"default":c[getAttribute]("default")!==null,title:c[getAttribute]("title")})}}}return options},loadTech:function(techName,source){if(this.tech){this.unloadTech()}else{if(techName!="html5"&&this.tag){this.el.removeChild(this.tag);this.tag=false}}this.techName=techName;this.isReady=false;var techReady=function(){this.player.triggerReady();if(!this.support.progressEvent){this.player.manualProgressOn()}if(!this.support.timeupdateEvent){this.player.manualTimeUpdatesOn()}};var techOptions=_V_.merge({source:source,parentEl:this.el},this.options[techName]);if(source){if(source.src==this.values.src&&this.values.currentTime>0){techOptions.startTime=this.values.currentTime}this.values.src=source.src}this.tech=new _V_[techName](this,techOptions);this.tech.ready(techReady)},unloadTech:function(){this.tech.destroy();if(this.manualProgress){this.manualProgressOff()}if(this.manualTimeUpdates){this.manualTimeUpdatesOff()}this.tech=false},manualProgressOn:function(){this.manualProgress=true;this.trackProgress();this.tech.on("progress",function(){this.removeEvent("progress",arguments.callee);this.support.progressEvent=true;this.player.manualProgressOff()})},manualProgressOff:function(){this.manualProgress=false;this.stopTrackingProgress()},trackProgress:function(){this.progressInterval=setInterval(_V_.proxy(this,function(){if(this.values.bufferEnd<this.buffered().end(0)){this.trigger("progress")}else{if(this.bufferedPercent()==1){this.stopTrackingProgress();this.trigger("progress")}}}),500)},stopTrackingProgress:function(){clearInterval(this.progressInterval)},manualTimeUpdatesOn:function(){this.manualTimeUpdates=true;this.on("play",this.trackCurrentTime);this.on("pause",this.stopTrackingCurrentTime);this.tech.on("timeupdate",function(){this.removeEvent("timeupdate",arguments.callee);this.support.timeupdateEvent=true;this.player.manualTimeUpdatesOff()})},manualTimeUpdatesOff:function(){this.manualTimeUpdates=false;this.stopTrackingCurrentTime();this.removeEvent("play",this.trackCurrentTime);this.removeEvent("pause",this.stopTrackingCurrentTime)},trackCurrentTime:function(){if(this.currentTimeInterval){this.stopTrackingCurrentTime()}this.currentTimeInterval=setInterval(_V_.proxy(this,function(){this.trigger("timeupdate")}),250)},stopTrackingCurrentTime:function(){clearInterval(this.currentTimeInterval)},onEnded:function(){if(this.options.loop){this.currentTime(0);this.play()}else{this.pause();this.currentTime(0);this.pause()}},onPlay:function(){_V_.removeClass(this.el,"vjs-paused");_V_.addClass(this.el,"vjs-playing")},onPause:function(){_V_.removeClass(this.el,"vjs-playing");_V_.addClass(this.el,"vjs-paused")},onProgress:function(){if(this.bufferedPercent()==1){this.trigger("loadedalldata")}},onError:function(e){_V_.log("Video Error",e)},techCall:function(method,arg){if(!this.tech.isReady){this.tech.ready(function(){this[method](arg)})}else{try{this.tech[method](arg)}catch(e){_V_.log(e)}}},techGet:function(method){if(this.tech.isReady){try{return this.tech[method]()}catch(e){if(this.tech[method]===undefined){_V_.log("Video.js: "+method+" method not defined for "+this.techName+" playback technology.",e)}else{if(e.name=="TypeError"){_V_.log("Video.js: "+method+" unavailable on "+this.techName+" playback technology element.",e);this.tech.isReady=false}else{_V_.log(e)}}}}return},play:function(){this.techCall("play");return this},pause:function(){this.techCall("pause");return this},paused:function(){return(this.techGet("paused")===false)?false:true},currentTime:function(seconds){if(seconds!==undefined){this.values.lastSetCurrentTime=seconds;this.techCall("setCurrentTime",seconds);if(this.manualTimeUpdates){this.trigger("timeupdate")}return this}return this.values.currentTime=(this.techGet("currentTime")||0)},duration:function(){return parseFloat(this.techGet("duration"))},remainingTime:function(){return this.duration()-this.currentTime()},buffered:function(){var buffered=this.techGet("buffered"),start=0,end=this.values.bufferEnd=this.values.bufferEnd||0,timeRange;if(buffered&&buffered.length>0&&buffered.end(0)!==end){end=buffered.end(0);this.values.bufferEnd=end}return _V_.createTimeRange(start,end)},bufferedPercent:function(){return(this.duration())?this.buffered().end(0)/this.duration():0},volume:function(percentAsDecimal){var vol;if(percentAsDecimal!==undefined){vol=Math.max(0,Math.min(1,parseFloat(percentAsDecimal)));this.values.volume=vol;this.techCall("setVolume",vol);_V_.setLocalStorage("volume",vol);return this}vol=parseFloat(this.techGet("volume"));return(isNaN(vol))?1:vol},muted:function(muted){if(muted!==undefined){this.techCall("setMuted",muted);return this}return this.techGet("muted")||false},width:function(width,skipListeners){if(width!==undefined){this.el.width=width;this.el.style.width=width+"px";if(!skipListeners){this.trigger("resize")}return this}return parseInt(this.el.getAttribute("width"))},height:function(height){if(height!==undefined){this.el.height=height;this.el.style.height=height+"px";this.trigger("resize");return this}return parseInt(this.el.getAttribute("height"))},size:function(width,height){return this.width(width,true).height(height)},supportsFullScreen:function(){return this.techGet("supportsFullScreen")||false},requestFullScreen:function(){var requestFullScreen=_V_.support.requestFullScreen;this.isFullScreen=true;if(requestFullScreen){_V_.on(document,requestFullScreen.eventName,this.proxy(function(){this.isFullScreen=document[requestFullScreen.isFullScreen];if(this.isFullScreen==false){_V_.removeEvent(document,requestFullScreen.eventName,arguments.callee)}this.trigger("fullscreenchange")}));if(this.tech.support.fullscreenResize===false&&this.options.flash.iFrameMode!=true){this.pause();this.unloadTech();_V_.on(document,requestFullScreen.eventName,this.proxy(function(){_V_.removeEvent(document,requestFullScreen.eventName,arguments.callee);this.loadTech(this.techName,{src:this.values.src})}));this.el[requestFullScreen.requestFn]()}else{this.el[requestFullScreen.requestFn]()}}else{if(this.tech.supportsFullScreen()){this.trigger("fullscreenchange");this.techCall("enterFullScreen")}else{this.trigger("fullscreenchange");this.enterFullWindow()}}return this},cancelFullScreen:function(){var requestFullScreen=_V_.support.requestFullScreen;this.isFullScreen=false;if(requestFullScreen){if(this.tech.support.fullscreenResize===false&&this.options.flash.iFrameMode!=true){this.pause();this.unloadTech();_V_.on(document,requestFullScreen.eventName,this.proxy(function(){_V_.removeEvent(document,requestFullScreen.eventName,arguments.callee);this.loadTech(this.techName,{src:this.values.src})}));document[requestFullScreen.cancelFn]()}else{document[requestFullScreen.cancelFn]()}}else{if(this.tech.supportsFullScreen()){this.techCall("exitFullScreen");this.trigger("fullscreenchange")}else{this.exitFullWindow();this.trigger("fullscreenchange")}}return this},enterFullWindow:function(){this.isFullWindow=true;this.docOrigOverflow=document.documentElement.style.overflow;_V_.on(document,"keydown",_V_.proxy(this,this.fullWindowOnEscKey));document.documentElement.style.overflow="hidden";_V_.addClass(document.body,"vjs-full-window");_V_.addClass(this.el,"vjs-fullscreen");this.trigger("enterFullWindow")},fullWindowOnEscKey:function(event){if(event.keyCode==27){if(this.isFullScreen==true){this.cancelFullScreen()}else{this.exitFullWindow()}}},exitFullWindow:function(){this.isFullWindow=false;_V_.removeEvent(document,"keydown",this.fullWindowOnEscKey);document.documentElement.style.overflow=this.docOrigOverflow;_V_.removeClass(document.body,"vjs-full-window");_V_.removeClass(this.el,"vjs-fullscreen");this.trigger("exitFullWindow")},selectSource:function(sources){for(var i=0,j=this.options.techOrder;i<j.length;i++){var techName=j[i],tech=_V_[techName];if(tech.isSupported()){for(var a=0,b=sources;a<b.length;a++){var source=b[a];if(tech.canPlaySource.call(this,source)){return{source:source,tech:techName}}}}}return false},src:function(source){if(source instanceof Array){var sourceTech=this.selectSource(source),source,techName;if(sourceTech){source=sourceTech.source;techName=sourceTech.tech;if(techName==this.techName){this.src(source)}else{this.loadTech(techName,source)}}else{_V_.log("No compatible source and playback technology were found.")}}else{if(source instanceof Object){if(_V_[this.techName].canPlaySource(source)){this.src(source.src)}else{this.src([source])}}else{this.values.src=source;if(!this.isReady){this.ready(function(){this.src(source)})}else{this.techCall("src",source);if(this.options.preload=="auto"){this.load()}if(this.options.autoplay){this.play()}}}}return this},load:function(){this.techCall("load");return this},currentSrc:function(){return this.techGet("currentSrc")||this.values.src||""},preload:function(value){if(value!==undefined){this.techCall("setPreload",value);this.options.preload=value;return this}return this.techGet("preload")},autoplay:function(value){if(value!==undefined){this.techCall("setAutoplay",value);this.options.autoplay=value;return this}return this.techGet("autoplay",value)},loop:function(value){if(value!==undefined){this.techCall("setLoop",value);this.options.loop=value;return this}return this.techGet("loop")},controls:function(){return this.options.controls},poster:function(){return this.techGet("poster")},error:function(){return this.techGet("error")},ended:function(){return this.techGet("ended")}});(function(){var requestFn,cancelFn,eventName,isFullScreen,playerProto=_V_.Player.prototype;if(document.cancelFullscreen!==undefined){requestFn="requestFullscreen";cancelFn="exitFullscreen";eventName="fullscreenchange";isFullScreen="fullScreen"}else{_V_.each(["moz","webkit"],function(prefix){if((prefix!="moz"||document.mozFullScreenEnabled)&&document[prefix+"CancelFullScreen"]!==undefined){requestFn=prefix+"RequestFullScreen";cancelFn=prefix+"CancelFullScreen";eventName=prefix+"fullscreenchange";if(prefix=="webkit"){isFullScreen=prefix+"IsFullScreen"}else{isFullScreen=prefix+"FullScreen"}}})}if(requestFn){_V_.support.requestFullScreen={requestFn:requestFn,cancelFn:cancelFn,eventName:eventName,isFullScreen:isFullScreen}}})();_V_.PlaybackTech=_V_.Component.extend({init:function(player,options){},onClick:function(){if(this.player.options.controls){_V_.PlayToggle.prototype.onClick.call(this)}}});_V_.apiMethods="play,pause,paused,currentTime,setCurrentTime,duration,buffered,volume,setVolume,muted,setMuted,width,height,supportsFullScreen,enterFullScreen,src,load,currentSrc,preload,setPreload,autoplay,setAutoplay,loop,setLoop,error,networkState,readyState,seeking,initialTime,startOffsetTime,played,seekable,ended,videoTracks,audioTracks,videoWidth,videoHeight,textTracks,defaultPlaybackRate,playbackRate,mediaGroup,controller,controls,defaultMuted".split(",");_V_.each(_V_.apiMethods,function(methodName){_V_.PlaybackTech.prototype[methodName]=function(){throw new Error("The '"+methodName+"' method is not available on the playback technology's API")}});_V_.html5=_V_.PlaybackTech.extend({init:function(player,options,ready){this.player=player;this.el=this.createElement();this.ready(ready);this.addEvent("click",this.proxy(this.onClick));var source=options.source;if(source&&this.el.currentSrc==source.src){player.triggerEvent("loadstart")}else{if(source){this.el.src=source.src}}player.ready(function(){if(this.options.autoplay&&this.paused()){this.tag.poster=null;this.play()}});this.setupTriggers();this.triggerReady()},destroy:function(){this.player.tag=false;this.removeTriggers();this.el.parentNode.removeChild(this.el)},createElement:function(){var html5=_V_.html5,player=this.player,el=player.tag,newEl;if(!el||this.support.movingElementInDOM===false){if(el){player.el.removeChild(el)}newEl=_V_.createElement("video",{id:el.id||player.el.id+"_html5_api",className:el.className||"vjs-tech"});el=newEl;_V_.insertFirst(el,player.el)}_V_.each(["autoplay","preload","loop","muted"],function(attr){if(player.options[attr]!==null){el[attr]=player.options[attr]}},this);return el},setupTriggers:function(){_V_.each.call(this,_V_.html5.events,function(type){_V_.addEvent(this.el,type,_V_.proxy(this.player,this.eventHandler))})},removeTriggers:function(){_V_.each.call(this,_V_.html5.events,function(type){_V_.removeEvent(this.el,type,_V_.proxy(this.player,this.eventHandler))})},eventHandler:function(e){e.stopPropagation();this.triggerEvent(e)},play:function(){this.el.play()},pause:function(){this.el.pause()},paused:function(){return this.el.paused},currentTime:function(){return this.el.currentTime},setCurrentTime:function(seconds){try{this.el.currentTime=seconds}catch(e){_V_.log(e,"Video isn't ready. (VideoJS)")}},duration:function(){return this.el.duration||0},buffered:function(){return this.el.buffered},volume:function(){return this.el.volume},setVolume:function(percentAsDecimal){this.el.volume=percentAsDecimal},muted:function(){return this.el.muted},setMuted:function(muted){this.el.muted=muted},width:function(){return this.el.offsetWidth},height:function(){return this.el.offsetHeight},supportsFullScreen:function(){if(typeof this.el.webkitEnterFullScreen=="function"){if(!navigator.userAgent.match("Chrome")&&!navigator.userAgent.match("Mac OS X 10.5")){return true}}return false},enterFullScreen:function(){try{this.el.webkitEnterFullScreen()}catch(e){if(e.code==11){_V_.log("VideoJS: Video not ready.")}}},exitFullScreen:function(){try{this.el.webkitExitFullScreen()}catch(e){if(e.code==11){_V_.log("VideoJS: Video not ready.")}}},src:function(src){this.el.src=src},load:function(){this.el.load()},currentSrc:function(){return this.el.currentSrc},preload:function(){return this.el.preload},setPreload:function(val){this.el.preload=val},autoplay:function(){return this.el.autoplay},setAutoplay:function(val){this.el.autoplay=val},loop:function(){return this.el.loop},setLoop:function(val){this.el.loop=val},error:function(){return this.el.error},seeking:function(){return this.el.seeking},ended:function(){return this.el.ended},controls:function(){return this.player.options.controls},defaultMuted:function(){return this.el.defaultMuted}});_V_.html5.isSupported=function(){return !!document.createElement("video").canPlayType};_V_.html5.canPlaySource=function(srcObj){return !!document.createElement("video").canPlayType(srcObj.type)};_V_.html5.events="loadstart,suspend,abort,error,emptied,stalled,loadedmetadata,loadeddata,canplay,canplaythrough,playing,waiting,seeking,seeked,ended,durationchange,timeupdate,progress,play,pause,ratechange,volumechange".split(",");_V_.html5.prototype.support={fullscreen:(typeof _V_.testVid.webkitEnterFullScreen!==undefined)?(!_V_.ua.match("Chrome")&&!_V_.ua.match("Mac OS X 10.5")?true:false):false,movingElementInDOM:!_V_.isIOS()};if(_V_.isAndroid()){if(_V_.androidVersion()<3){document.createElement("video").constructor.prototype.canPlayType=function(type){return(type&&type.toLowerCase().indexOf("video/mp4")!=-1)?"maybe":""}}}_V_.flash=_V_.PlaybackTech.extend({init:function(player,options){this.player=player;var source=options.source,parentEl=options.parentEl,placeHolder=this.el=_V_.createElement("div",{id:parentEl.id+"_temp_flash"}),objId=player.el.id+"_flash_api",playerOptions=player.options,flashVars=_V_.merge({readyFunction:"_V_.flash.onReady",eventProxyFunction:"_V_.flash.onEvent",errorEventProxyFunction:"_V_.flash.onError",autoplay:playerOptions.autoplay,preload:playerOptions.preload,loop:playerOptions.loop,muted:playerOptions.muted},options.flashVars),params=_V_.merge({wmode:"opaque",bgcolor:"#000000"},options.params),attributes=_V_.merge({id:objId,name:objId,"class":"vjs-tech"},options.attributes);if(source){flashVars.src=encodeURIComponent(_V_.getAbsoluteURL(source.src))}_V_.insertFirst(placeHolder,parentEl);if(options.startTime){this.ready(function(){this.load();this.play();this.currentTime(options.startTime)})}if(options.iFrameMode==true&&!_V_.isFF){var iFrm=_V_.createElement("iframe",{id:objId+"_iframe",name:objId+"_iframe",className:"vjs-tech",scrolling:"no",marginWidth:0,marginHeight:0,frameBorder:0});flashVars.readyFunction="ready";flashVars.eventProxyFunction="events";flashVars.errorEventProxyFunction="errors";_V_.addEvent(iFrm,"load",_V_.proxy(this,function(){var iDoc,objTag,swfLoc,iWin=iFrm.contentWindow,varString="";iDoc=iFrm.contentDocument?iFrm.contentDocument:iFrm.contentWindow.document;iDoc.write(_V_.flash.getEmbedCode(options.swf,flashVars,params,attributes));iWin.player=this.player;iWin.ready=_V_.proxy(this.player,function(currSwf){var el=iDoc.getElementById(currSwf),player=this,tech=player.tech;tech.el=el;_V_.addEvent(el,"click",tech.proxy(tech.onClick));_V_.flash.checkReady(tech)});iWin.events=_V_.proxy(this.player,function(swfID,eventName,other){var player=this;if(player&&player.techName=="flash"){player.triggerEvent(eventName)}});iWin.errors=_V_.proxy(this.player,function(swfID,eventName){_V_.log("Flash Error",eventName)})}));placeHolder.parentNode.replaceChild(iFrm,placeHolder)}else{_V_.flash.embed(options.swf,placeHolder,flashVars,params,attributes)}},destroy:function(){this.el.parentNode.removeChild(this.el)},play:function(){this.el.vjs_play()},pause:function(){this.el.vjs_pause()},src:function(src){src=_V_.getAbsoluteURL(src);this.el.vjs_src(src);if(this.player.autoplay()){var tech=this;setTimeout(function(){tech.play()},0)}},load:function(){this.el.vjs_load()},poster:function(){this.el.vjs_getProperty("poster")},buffered:function(){return _V_.createTimeRange(0,this.el.vjs_getProperty("buffered"))},supportsFullScreen:function(){return false},enterFullScreen:function(){return false}});(function(){var api=_V_.flash.prototype,readWrite="preload,currentTime,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted".split(","),readOnly="error,currentSrc,networkState,readyState,seeking,initialTime,duration,startOffsetTime,paused,played,seekable,ended,videoTracks,audioTracks,videoWidth,videoHeight,textTracks".split(","),callOnly="load,play,pause".split(",");createSetter=function(attr){var attrUpper=attr.charAt(0).toUpperCase()+attr.slice(1);api["set"+attrUpper]=function(val){return this.el.vjs_setProperty(attr,val)}},createGetter=function(attr){api[attr]=function(){return this.el.vjs_getProperty(attr)}};_V_.each(readWrite,function(attr){createGetter(attr);createSetter(attr)});_V_.each(readOnly,function(attr){createGetter(attr)})})();_V_.flash.isSupported=function(){return _V_.flash.version()[0]>=10};_V_.flash.canPlaySource=function(srcObj){if(srcObj.type in _V_.flash.prototype.support.formats){return"maybe"}};_V_.flash.prototype.support={formats:{"video/flv":"FLV","video/x-flv":"FLV","video/mp4":"MP4","video/m4v":"MP4"},progressEvent:false,timeupdateEvent:false,fullscreenResize:false,parentResize:!(_V_.ua.match("Firefox"))};_V_.flash.onReady=function(currSwf){var el=_V_.el(currSwf);var player=el.player||el.parentNode.player,tech=player.tech;el.player=player;tech.el=el;tech.addEvent("click",tech.onClick);_V_.flash.checkReady(tech)};_V_.flash.checkReady=function(tech){if(tech.el.vjs_getProperty){tech.triggerReady()}else{setTimeout(function(){_V_.flash.checkReady(tech)},50)}};_V_.flash.onEvent=function(swfID,eventName){var player=_V_.el(swfID).player;player.triggerEvent(eventName)};_V_.flash.onError=function(swfID,err){var player=_V_.el(swfID).player;player.triggerEvent("error");_V_.log("Flash Error",err,swfID)};_V_.flash.version=function(){var version="0,0,0";try{version=new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version").replace(/\D+/g,",").match(/^,?(.+),?$/)[1]}catch(e){try{if(navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin){version=(navigator.plugins["Shockwave Flash 2.0"]||navigator.plugins["Shockwave Flash"]).description.replace(/\D+/g,",").match(/^,?(.+),?$/)[1]}}catch(e){}}return version.split(",")};_V_.flash.embed=function(swf,placeHolder,flashVars,params,attributes){var code=_V_.flash.getEmbedCode(swf,flashVars,params,attributes),obj=_V_.createElement("div",{innerHTML:code}).childNodes[0],par=placeHolder.parentNode;placeHolder.parentNode.replaceChild(obj,placeHolder);if(_V_.isIE()){var newObj=par.childNodes[0];setTimeout(function(){newObj.style.display="block"},1000)}return obj};_V_.flash.getEmbedCode=function(swf,flashVars,params,attributes){var objTag='<object type="application/x-shockwave-flash"',flashVarsString="",paramsString="";attrsString="";if(flashVars){_V_.eachProp(flashVars,function(key,val){flashVarsString+=(key+"="+val+"&")})}params=_V_.merge({movie:swf,flashvars:flashVarsString,allowScriptAccess:"always",allowNetworking:"all"},params);_V_.eachProp(params,function(key,val){paramsString+='<param name="'+key+'" value="'+val+'" />'});attributes=_V_.merge({data:swf,width:"100%",height:"100%"},attributes);_V_.eachProp(attributes,function(key,val){attrsString+=(key+'="'+val+'" ')});return objTag+attrsString+">"+paramsString+"</object>"};_V_.Control=_V_.Component.extend({buildCSSClass:function(){return"vjs-control "+this._super()}});_V_.ControlBar=_V_.Component.extend({options:{loadEvent:"play",components:{playToggle:{},fullscreenToggle:{},currentTimeDisplay:{},timeDivider:{},durationDisplay:{},remainingTimeDisplay:{},progressControl:{},volumeControl:{},muteToggle:{}}},init:function(player,options){this._super(player,options);player.on("play",this.proxy(function(){this.fadeIn();this.player.on("mouseover",this.proxy(this.fadeIn));this.player.on("mouseout",this.proxy(this.fadeOut))}))},createElement:function(){return _V_.createElement("div",{className:"vjs-controls"})},fadeIn:function(){this._super();this.player.trigger("controlsvisible")},fadeOut:function(){this._super();this.player.trigger("controlshidden")},lockShowing:function(){this.el.style.opacity="1"}});_V_.Button=_V_.Control.extend({init:function(player,options){this._super(player,options);this.on("click",this.onClick);this.on("focus",this.onFocus);this.on("blur",this.onBlur)},createElement:function(type,attrs){attrs=_V_.merge({className:this.buildCSSClass(),innerHTML:'<div><span class="vjs-control-text">'+(this.buttonText||"Need Text")+"</span></div>",role:"button",tabIndex:0},attrs);return this._super(type,attrs)},onClick:function(){},onFocus:function(){_V_.on(document,"keyup",_V_.proxy(this,this.onKeyPress))},onKeyPress:function(event){if(event.which==32||event.which==13){event.preventDefault();this.onClick()}},onBlur:function(){_V_.off(document,"keyup",_V_.proxy(this,this.onKeyPress))}});_V_.PlayButton=_V_.Button.extend({buttonText:"Play",buildCSSClass:function(){return"vjs-play-button "+this._super()},onClick:function(){this.player.play()}});_V_.PauseButton=_V_.Button.extend({buttonText:"Pause",buildCSSClass:function(){return"vjs-pause-button "+this._super()},onClick:function(){this.player.pause()}});_V_.PlayToggle=_V_.Button.extend({buttonText:"Play",init:function(player,options){this._super(player,options);player.on("play",_V_.proxy(this,this.onPlay));player.on("pause",_V_.proxy(this,this.onPause))},buildCSSClass:function(){return"vjs-play-control "+this._super()},onClick:function(){if(this.player.paused()){this.player.play()}else{this.player.pause()}},onPlay:function(){_V_.removeClass(this.el,"vjs-paused");_V_.addClass(this.el,"vjs-playing")},onPause:function(){_V_.removeClass(this.el,"vjs-playing");_V_.addClass(this.el,"vjs-paused")}});_V_.FullscreenToggle=_V_.Button.extend({buttonText:"Fullscreen",buildCSSClass:function(){return"vjs-fullscreen-control "+this._super()},onClick:function(){if(!this.player.isFullScreen){this.player.requestFullScreen()}else{this.player.cancelFullScreen()}}});_V_.BigPlayButton=_V_.Button.extend({init:function(player,options){this._super(player,options);player.on("play",_V_.proxy(this,this.hide));player.on("ended",_V_.proxy(this,this.show))},createElement:function(){return this._super("div",{className:"vjs-big-play-button",innerHTML:"<span></span>"})},onClick:function(){if(this.player.currentTime()){this.player.currentTime(0)}this.player.play()}});_V_.LoadingSpinner=_V_.Component.extend({init:function(player,options){this._super(player,options);player.on("canplay",_V_.proxy(this,this.hide));player.on("canplaythrough",_V_.proxy(this,this.hide));player.on("playing",_V_.proxy(this,this.hide));player.on("seeking",_V_.proxy(this,this.show));player.on("error",_V_.proxy(this,this.show));player.on("waiting",_V_.proxy(this,this.show))},createElement:function(){var classNameSpinner,innerHtmlSpinner;if(typeof this.player.el.style.WebkitBorderRadius=="string"||typeof this.player.el.style.MozBorderRadius=="string"||typeof this.player.el.style.KhtmlBorderRadius=="string"||typeof this.player.el.style.borderRadius=="string"){classNameSpinner="vjs-loading-spinner";innerHtmlSpinner="<div class='ball1'></div><div class='ball2'></div><div class='ball3'></div><div class='ball4'></div><div class='ball5'></div><div class='ball6'></div><div class='ball7'></div><div class='ball8'></div>"}else{classNameSpinner="vjs-loading-spinner-fallback";innerHtmlSpinner=""}return this._super("div",{className:classNameSpinner,innerHTML:innerHtmlSpinner})}});_V_.CurrentTimeDisplay=_V_.Component.extend({init:function(player,options){this._super(player,options);player.on("timeupdate",_V_.proxy(this,this.updateContent))},createElement:function(){var el=this._super("div",{className:"vjs-current-time vjs-time-controls vjs-control"});this.content=_V_.createElement("div",{className:"vjs-current-time-display",innerHTML:"0:00"});el.appendChild(_V_.createElement("div").appendChild(this.content));return el},updateContent:function(){var time=(this.player.scrubbing)?this.player.values.currentTime:this.player.currentTime();this.content.innerHTML=_V_.formatTime(time,this.player.duration())}});_V_.DurationDisplay=_V_.Component.extend({init:function(player,options){this._super(player,options);player.on("timeupdate",_V_.proxy(this,this.updateContent))},createElement:function(){var el=this._super("div",{className:"vjs-duration vjs-time-controls vjs-control"});this.content=_V_.createElement("div",{className:"vjs-duration-display",innerHTML:"0:00"});el.appendChild(_V_.createElement("div").appendChild(this.content));return el},updateContent:function(){if(this.player.duration()){this.content.innerHTML=_V_.formatTime(this.player.duration())}}});_V_.TimeDivider=_V_.Component.extend({createElement:function(){return this._super("div",{className:"vjs-time-divider",innerHTML:"<div><span>/</span></div>"})}});_V_.RemainingTimeDisplay=_V_.Component.extend({init:function(player,options){this._super(player,options);player.on("timeupdate",_V_.proxy(this,this.updateContent))},createElement:function(){var el=this._super("div",{className:"vjs-remaining-time vjs-time-controls vjs-control"});this.content=_V_.createElement("div",{className:"vjs-remaining-time-display",innerHTML:"-0:00"});el.appendChild(_V_.createElement("div").appendChild(this.content));return el},updateContent:function(){if(this.player.duration()){this.content.innerHTML="-"+_V_.formatTime(this.player.remainingTime())}}});_V_.Slider=_V_.Component.extend({init:function(player,options){this._super(player,options);player.on(this.playerEvent,_V_.proxy(this,this.update));this.on("mousedown",this.onMouseDown);this.on("focus",this.onFocus);this.on("blur",this.onBlur);this.player.on("controlsvisible",this.proxy(this.update));this.update()},createElement:function(type,attrs){attrs=_V_.merge({role:"slider","aria-valuenow":0,"aria-valuemin":0,"aria-valuemax":100,tabIndex:0},attrs);return this._super(type,attrs)},onMouseDown:function(event){event.preventDefault();_V_.blockTextSelection();_V_.on(document,"mousemove",_V_.proxy(this,this.onMouseMove));_V_.on(document,"mouseup",_V_.proxy(this,this.onMouseUp));this.onMouseMove(event)},onMouseUp:function(event){_V_.unblockTextSelection();_V_.off(document,"mousemove",this.onMouseMove,false);_V_.off(document,"mouseup",this.onMouseUp,false);this.update()},update:function(){var barProgress,progress=this.getPercent();handle=this.handle,bar=this.bar;if(isNaN(progress)){progress=0}barProgress=progress;if(handle){var box=this.el,boxWidth=box.offsetWidth,handleWidth=handle.el.offsetWidth,handlePercent=(handleWidth)?handleWidth/boxWidth:0,boxAdjustedPercent=1-handlePercent;adjustedProgress=progress*boxAdjustedPercent,barProgress=adjustedProgress+(handlePercent/2);handle.el.style.left=_V_.round(adjustedProgress*100,2)+"%"}bar.el.style.width=_V_.round(barProgress*100,2)+"%"},calculateDistance:function(event){var box=this.el,boxX=_V_.findPosX(box),boxW=box.offsetWidth,handle=this.handle;if(handle){var handleW=handle.el.offsetWidth;boxX=boxX+(handleW/2);boxW=boxW-handleW}return Math.max(0,Math.min(1,(event.pageX-boxX)/boxW))},onFocus:function(event){_V_.on(document,"keyup",_V_.proxy(this,this.onKeyPress))},onKeyPress:function(event){if(event.which==37){event.preventDefault();this.stepBack()}else{if(event.which==39){event.preventDefault();this.stepForward()}}},onBlur:function(event){_V_.off(document,"keyup",_V_.proxy(this,this.onKeyPress))}});_V_.ProgressControl=_V_.Component.extend({options:{components:{seekBar:{}}},createElement:function(){return this._super("div",{className:"vjs-progress-control vjs-control"})}});_V_.SeekBar=_V_.Slider.extend({options:{components:{loadProgressBar:{},bar:{componentClass:"PlayProgressBar"},handle:{componentClass:"SeekHandle"}}},playerEvent:"timeupdate",init:function(player,options){this._super(player,options)},createElement:function(){return this._super("div",{className:"vjs-progress-holder"})},getPercent:function(){return this.player.currentTime()/this.player.duration()},onMouseDown:function(event){this._super(event);this.player.scrubbing=true;this.videoWasPlaying=!this.player.paused();this.player.pause()},onMouseMove:function(event){var newTime=this.calculateDistance(event)*this.player.duration();if(newTime==this.player.duration()){newTime=newTime-0.1}this.player.currentTime(newTime)},onMouseUp:function(event){this._super(event);this.player.scrubbing=false;if(this.videoWasPlaying){this.player.play()}},stepForward:function(){this.player.currentTime(this.player.currentTime()+1)},stepBack:function(){this.player.currentTime(this.player.currentTime()-1)}});_V_.LoadProgressBar=_V_.Component.extend({init:function(player,options){this._super(player,options);player.on("progress",_V_.proxy(this,this.update))},createElement:function(){return this._super("div",{className:"vjs-load-progress",innerHTML:'<span class="vjs-control-text">Loaded: 0%</span>'})},update:function(){if(this.el.style){this.el.style.width=_V_.round(this.player.bufferedPercent()*100,2)+"%"}}});_V_.PlayProgressBar=_V_.Component.extend({createElement:function(){return this._super("div",{className:"vjs-play-progress",innerHTML:'<span class="vjs-control-text">Progress: 0%</span>'})}});_V_.SeekHandle=_V_.Component.extend({createElement:function(){return this._super("div",{className:"vjs-seek-handle",innerHTML:'<span class="vjs-control-text">00:00</span>'})}});_V_.VolumeControl=_V_.Component.extend({options:{components:{volumeBar:{}}},createElement:function(){return this._super("div",{className:"vjs-volume-control vjs-control"})}});_V_.VolumeBar=_V_.Slider.extend({options:{components:{bar:{componentClass:"VolumeLevel"},handle:{componentClass:"VolumeHandle"}}},playerEvent:"volumechange",createElement:function(){return this._super("div",{className:"vjs-volume-bar"})},onMouseMove:function(event){this.player.volume(this.calculateDistance(event))},getPercent:function(){return this.player.volume()},stepForward:function(){this.player.volume(this.player.volume()+0.1)},stepBack:function(){this.player.volume(this.player.volume()-0.1)}});_V_.VolumeLevel=_V_.Component.extend({createElement:function(){return this._super("div",{className:"vjs-volume-level",innerHTML:'<span class="vjs-control-text"></span>'})}});_V_.VolumeHandle=_V_.Component.extend({createElement:function(){return this._super("div",{className:"vjs-volume-handle",innerHTML:'<span class="vjs-control-text"></span>'})}});_V_.MuteToggle=_V_.Button.extend({init:function(player,options){this._super(player,options);player.on("volumechange",_V_.proxy(this,this.update))},createElement:function(){return this._super("div",{className:"vjs-mute-control vjs-control",innerHTML:'<div><span class="vjs-control-text">Mute</span></div>'})},onClick:function(event){this.player.muted(this.player.muted()?false:true)},update:function(event){var vol=this.player.volume(),level=3;if(vol==0||this.player.muted()){level=0}else{if(vol<0.33){level=1}else{if(vol<0.67){level=2}}}_V_.each.call(this,[0,1,2,3],function(i){_V_.removeClass(this.el,"vjs-vol-"+i)});_V_.addClass(this.el,"vjs-vol-"+level)}});_V_.PosterImage=_V_.Button.extend({init:function(player,options){this._super(player,options);if(!this.player.options.poster){this.hide()}player.on("play",_V_.proxy(this,this.hide))},createElement:function(){return _V_.createElement("img",{className:"vjs-poster",src:this.player.options.poster,tabIndex:-1})},onClick:function(){this.player.play()}});_V_.Menu=_V_.Component.extend({init:function(player,options){this._super(player,options)},addItem:function(component){this.addComponent(component);component.on("click",this.proxy(function(){this.unlockShowing()}))},createElement:function(){return this._super("ul",{className:"vjs-menu"})}});_V_.MenuItem=_V_.Button.extend({init:function(player,options){this._super(player,options);if(options.selected){this.addClass("vjs-selected")}},createElement:function(type,attrs){return this._super("li",_V_.merge({className:"vjs-menu-item",innerHTML:this.options.label},attrs))},onClick:function(){this.selected(true)},selected:function(selected){if(selected){this.addClass("vjs-selected")}else{this.removeClass("vjs-selected")}}});_V_.merge(_V_.Player.prototype,{addTextTracks:function(trackObjects){var tracks=this.textTracks=(this.textTracks)?this.textTracks:[],i=0,j=trackObjects.length,track,Kind;for(;i<j;i++){Kind=_V_.uc(trackObjects[i].kind||"subtitles");track=new _V_[Kind+"Track"](this,trackObjects[i]);tracks.push(track);if(track["default"]){this.ready(_V_.proxy(track,track.show))}}return this},showTextTrack:function(id,disableSameKind){var tracks=this.textTracks,i=0,j=tracks.length,track,showTrack,kind;for(;i<j;i++){track=tracks[i];if(track.id===id){track.show();showTrack=track}else{if(disableSameKind&&track.kind==disableSameKind&&track.mode>0){track.disable()}}}kind=(showTrack)?showTrack.kind:((disableSameKind)?disableSameKind:false);if(kind){this.trigger(kind+"trackchange")}return this}});_V_.Track=_V_.Component.extend({init:function(player,options){this._super(player,options);_V_.merge(this,{id:options.id||("vjs_"+options.kind+"_"+options.language+"_"+_V_.guid++),src:options.src,"default":options["default"],title:options.title,language:options.srclang,label:options.label,cues:[],activeCues:[],readyState:0,mode:0})},createElement:function(){return this._super("div",{className:"vjs-"+this.kind+" vjs-text-track"})},show:function(){this.activate();this.mode=2;this._super()},hide:function(){this.activate();this.mode=1;this._super()},disable:function(){if(this.mode==2){this.hide()}this.deactivate();this.mode=0},activate:function(){if(this.readyState==0){this.load()}if(this.mode==0){this.player.on("timeupdate",this.proxy(this.update,this.id));this.player.on("ended",this.proxy(this.reset,this.id));if(this.kind=="captions"||this.kind=="subtitles"){this.player.textTrackDisplay.addComponent(this)}}},deactivate:function(){this.player.off("timeupdate",this.proxy(this.update,this.id));this.player.off("ended",this.proxy(this.reset,this.id));this.reset();this.player.textTrackDisplay.removeComponent(this)},load:function(){if(this.readyState==0){this.readyState=1;_V_.get(this.src,this.proxy(this.parseCues),this.proxy(this.onError))}},onError:function(err){this.error=err;this.readyState=3;this.trigger("error")},parseCues:function(srcContent){var cue,time,text,lines=srcContent.split("\n"),line="",id;for(var i=1,j=lines.length;i<j;i++){line=_V_.trim(lines[i]);if(line){if(line.indexOf("-->")==-1){id=line;line=_V_.trim(lines[++i])}else{id=this.cues.length}cue={id:id,index:this.cues.length};time=line.split(" --> ");cue.startTime=this.parseCueTime(time[0]);cue.endTime=this.parseCueTime(time[1]);text=[];while(lines[++i]&&(line=_V_.trim(lines[i]))){text.push(line)}cue.text=text.join("<br/>");this.cues.push(cue)}}this.readyState=2;this.trigger("loaded")},parseCueTime:function(timeText){var parts=timeText.split(":"),time=0,hours,minutes,other,seconds,ms,flags;if(parts.length==3){hours=parts[0];minutes=parts[1];other=parts[2]}else{hours=0;minutes=parts[0];other=parts[1]}other=other.split(/\s+/);seconds=other.splice(0,1)[0];seconds=seconds.split(/\.|,/);ms=parseFloat(seconds[1]);seconds=seconds[0];time+=parseFloat(hours)*3600;time+=parseFloat(minutes)*60;time+=parseFloat(seconds);if(ms){time+=ms/1000}return time},update:function(){if(this.cues.length>0){var time=this.player.currentTime();if(this.prevChange===undefined||time<this.prevChange||this.nextChange<=time){var cues=this.cues,newNextChange=this.player.duration(),newPrevChange=0,reverse=false,newCues=[],firstActiveIndex,lastActiveIndex,html="",cue,i,j;if(time>=this.nextChange||this.nextChange===undefined){i=(this.firstActiveIndex!==undefined)?this.firstActiveIndex:0}else{reverse=true;i=(this.lastActiveIndex!==undefined)?this.lastActiveIndex:cues.length-1}while(true){cue=cues[i];if(cue.endTime<=time){newPrevChange=Math.max(newPrevChange,cue.endTime);if(cue.active){cue.active=false}}else{if(time<cue.startTime){newNextChange=Math.min(newNextChange,cue.startTime);if(cue.active){cue.active=false}if(!reverse){break}}else{if(reverse){newCues.splice(0,0,cue);if(lastActiveIndex===undefined){lastActiveIndex=i}firstActiveIndex=i}else{newCues.push(cue);if(firstActiveIndex===undefined){firstActiveIndex=i}lastActiveIndex=i}newNextChange=Math.min(newNextChange,cue.endTime);newPrevChange=Math.max(newPrevChange,cue.startTime);cue.active=true}}if(reverse){if(i===0){break}else{i--}}else{if(i===cues.length-1){break}else{i++}}}this.activeCues=newCues;this.nextChange=newNextChange;this.prevChange=newPrevChange;this.firstActiveIndex=firstActiveIndex;this.lastActiveIndex=lastActiveIndex;this.updateDisplay();this.trigger("cuechange")}}},updateDisplay:function(){var cues=this.activeCues,html="",i=0,j=cues.length;for(;i<j;i++){html+="<span class='vjs-tt-cue'>"+cues[i].text+"</span>"}this.el.innerHTML=html},reset:function(){this.nextChange=0;this.prevChange=this.player.duration();this.firstActiveIndex=0;this.lastActiveIndex=0}});_V_.CaptionsTrack=_V_.Track.extend({kind:"captions"});_V_.SubtitlesTrack=_V_.Track.extend({kind:"subtitles"});_V_.ChaptersTrack=_V_.Track.extend({kind:"chapters"});_V_.TextTrackDisplay=_V_.Component.extend({createElement:function(){return this._super("div",{className:"vjs-text-track-display"})}});_V_.TextTrackMenuItem=_V_.MenuItem.extend({init:function(player,options){var track=this.track=options.track;options.label=track.label;options.selected=track["default"];this._super(player,options);this.player.on(track.kind+"trackchange",_V_.proxy(this,this.update))},onClick:function(){this._super();this.player.showTextTrack(this.track.id,this.track.kind)},update:function(){if(this.track.mode==2){this.selected(true)}else{this.selected(false)}}});_V_.OffTextTrackMenuItem=_V_.TextTrackMenuItem.extend({init:function(player,options){options.track={kind:options.kind,player:player,label:"Off"};this._super(player,options)},onClick:function(){this._super();this.player.showTextTrack(this.track.id,this.track.kind)},update:function(){var tracks=this.player.textTracks,i=0,j=tracks.length,track,off=true;for(;i<j;i++){track=tracks[i];if(track.kind==this.track.kind&&track.mode==2){off=false}}if(off){this.selected(true)}else{this.selected(false)}}});_V_.TextTrackButton=_V_.Button.extend({init:function(player,options){this._super(player,options);this.menu=this.createMenu();if(this.items.length===0){this.hide()}},createMenu:function(){var menu=new _V_.Menu(this.player);menu.el.appendChild(_V_.createElement("li",{className:"vjs-menu-title",innerHTML:_V_.uc(this.kind)}));menu.addItem(new _V_.OffTextTrackMenuItem(this.player,{kind:this.kind}));this.items=this.createItems();this.each(this.items,function(item){menu.addItem(item)});this.addComponent(menu);return menu},createItems:function(){var items=[];this.each(this.player.textTracks,function(track){if(track.kind===this.kind){items.push(new _V_.TextTrackMenuItem(this.player,{track:track}))}});return items},buildCSSClass:function(){return this.className+" vjs-menu-button "+this._super()},onFocus:function(){this.menu.lockShowing();_V_.one(this.menu.el.childNodes[this.menu.el.childNodes.length-1],"blur",this.proxy(function(){this.menu.unlockShowing()}))},onBlur:function(){},onClick:function(){this.one("mouseout",this.proxy(function(){this.menu.unlockShowing();this.el.blur()}))}});_V_.CaptionsButton=_V_.TextTrackButton.extend({kind:"captions",buttonText:"Captions",className:"vjs-captions-button"});_V_.SubtitlesButton=_V_.TextTrackButton.extend({kind:"subtitles",buttonText:"Subtitles",className:"vjs-subtitles-button"});_V_.ChaptersButton=_V_.TextTrackButton.extend({kind:"chapters",buttonText:"Chapters",className:"vjs-chapters-button",createItems:function(chaptersTrack){var items=[];this.each(this.player.textTracks,function(track){if(track.kind===this.kind){items.push(new _V_.TextTrackMenuItem(this.player,{track:track}))}});return items},createMenu:function(){var tracks=this.player.textTracks,i=0,j=tracks.length,track,chaptersTrack,items=this.items=[];for(;i<j;i++){track=tracks[i];if(track.kind==this.kind&&track["default"]){if(track.readyState<2){this.chaptersTrack=track;track.on("loaded",this.proxy(this.createMenu));return}else{chaptersTrack=track;break}}}var menu=this.menu=new _V_.Menu(this.player);menu.el.appendChild(_V_.createElement("li",{className:"vjs-menu-title",innerHTML:_V_.uc(this.kind)}));if(chaptersTrack){var cues=chaptersTrack.cues,i=0,j=cues.length,cue,mi;for(;i<j;i++){cue=cues[i];mi=new _V_.ChaptersTrackMenuItem(this.player,{track:chaptersTrack,cue:cue});items.push(mi);menu.addComponent(mi)}}this.addComponent(menu);if(this.items.length>0){this.show()}return menu}});_V_.ChaptersTrackMenuItem=_V_.MenuItem.extend({init:function(player,options){var track=this.track=options.track,cue=this.cue=options.cue,currentTime=player.currentTime();options.label=cue.text;options.selected=(cue.startTime<=currentTime&¤tTime<cue.endTime);this._super(player,options);track.on("cuechange",_V_.proxy(this,this.update))},onClick:function(){this._super();this.player.currentTime(this.cue.startTime);this.update(this.cue.startTime)},update:function(time){var cue=this.cue,currentTime=this.player.currentTime();if(cue.startTime<=currentTime&¤tTime<cue.endTime){this.selected(true)}else{this.selected(false)}}});_V_.merge(_V_.ControlBar.prototype.options.components,{subtitlesButton:{},captionsButton:{},chaptersButton:{}});_V_.autoSetup=function(){var options,vid,player,vids=document.getElementsByTagName("video");if(vids&&vids.length>0){for(var i=0,j=vids.length;i<j;i++){vid=vids[i];if(vid&&vid.getAttribute){if(vid.player===undefined){options=vid.getAttribute("data-setup");if(options!==null){options=JSON.parse(options||"{}");player=_V_(vid,options)}}}else{_V_.autoSetupTimeout(1);break}}}else{if(!_V_.windowLoaded){_V_.autoSetupTimeout(1)}}};_V_.autoSetupTimeout=function(wait){setTimeout(_V_.autoSetup,wait)};_V_.addEvent(window,"load",function(){_V_.windowLoaded=true});_V_.autoSetup();window.VideoJS=window._V_=VideoJS})(window);
\ No newline at end of file
--- /dev/null
+===============================
+TimeSide - Web Audio Components
+===============================
+
+TimeSide UI Dependencies
+========================
+
+* SoundManager 2 >= 2.91 : http://www.schillmania.com/projects/soundmanager2
+* jQuery => 1.2.6 : http://www.jquery.com
+* jsGraphics => 3.03 http://www.walterzorn.com/jsgraphics/jsgraphics_e.htm
+
+Licensing
+=========
+
+Copyright (c) 2008-2009 Samalyse
+Author: Olivier Guilyardi <olivier samalyse com>
+
+TimeSide is released under the terms of the GNU General Public License
+version 2. Please see the LICENSE file for details.
+
--- /dev/null
+/*!
+ * jQuery JavaScript Library v1.6
+ * http://jquery.com/
+ *
+ * Copyright 2011, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2011, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Mon May 2 13:50:00 2011 -0400
+ */
+(function(a,b){function cw(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function ct(a){if(!ch[a]){var b=f("<"+a+">").appendTo("body"),d=b.css("display");b.remove();if(d==="none"||d===""){ci||(ci=c.createElement("iframe"),ci.frameBorder=ci.width=ci.height=0),c.body.appendChild(ci);if(!cj||!ci.createElement)cj=(ci.contentWindow||ci.contentDocument).document,cj.write("<!doctype><html><body></body></html>");b=cj.createElement(a),cj.body.appendChild(b),d=f.css(b,"display"),c.body.removeChild(ci)}ch[a]=d}return ch[a]}function cs(a,b){var c={};f.each(cn.concat.apply([],cn.slice(0,b)),function(){c[this]=a});return c}function cr(){co=b}function cq(){setTimeout(cr,0);return co=f.now()}function cg(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function cf(){try{return new a.XMLHttpRequest}catch(b){}}function b_(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function b$(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function bZ(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bD.test(a)?d(a,e):bZ(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)bZ(a+"["+e+"]",b[e],c,d);else d(a,b)}function bY(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bS,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=bY(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bY(a,c,d,e,"*",g));return l}function bX(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bO),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bB(a,b,c){var d=b==="width"?bv:bw,e=b==="width"?a.offsetWidth:a.offsetHeight;if(c==="border")return e;f.each(d,function(){c||(e-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?e+=parseFloat(f.css(a,"margin"+this))||0:e-=parseFloat(f.css(a,"border"+this+"Width"))||0});return e}function bl(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval(b.text||b.textContent||b.innerHTML||""),b.parentNode&&b.parentNode.removeChild(b)}function bk(a){f.nodeName(a,"input")?bj(a):a.getElementsByTagName&&f.grep(a.getElementsByTagName("input"),bj)}function bj(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bi(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function bh(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bg(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c=f.expando,d=f.data(a),e=f.data(b,d);if(d=d[c]){var g=d.events;e=e[c]=f.extend({},d);if(g){delete e.handle,e.events={};for(var h in g)for(var i=0,j=g[h].length;i<j;i++)f.event.add(b,h+(g[h][i].namespace?".":"")+g[h][i].namespace,g[h][i],g[h][i].data)}}}}function bf(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function W(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(R.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function V(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function N(a,b){return(a&&a!=="*"?a+".":"")+b.replace(z,"`").replace(A,"&")}function M(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;i<s.length;i++)g=s[i],g.origType.replace(x,"")===a.type?q.push(g.selector):s.splice(i--,1);e=f(a.target).closest(q,a.currentTarget);for(j=0,k=e.length;j<k;j++){m=e[j];for(i=0;i<s.length;i++){g=s[i];if(m.selector===g.selector&&(!n||n.test(g.namespace))&&!m.elem.disabled){h=m.elem,d=null;if(g.preType==="mouseenter"||g.preType==="mouseleave")a.type=g.preType,d=f(a.relatedTarget).closest(g.selector)[0],d&&f.contains(h,d)&&(d=h);(!d||d!==h)&&p.push({elem:h,handleObj:g,level:m.level})}}}for(j=0,k=p.length;j<k;j++){e=p[j];if(c&&e.level>c)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function K(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function E(){return!0}function D(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){name="data-"+c.replace(j,"$1-$2").toLowerCase(),d=a.getAttribute(name);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(e){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function H(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(H,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=d.userAgent,x,y,z,A=Object.prototype.toString,B=Object.prototype.hasOwnProperty,C=Array.prototype.push,D=Array.prototype.slice,E=String.prototype.trim,F=Array.prototype.indexOf,G={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)==="<"&&a.charAt(a.length-1)===">"&&a.length>=3?g=[null,a,null]:g=i.exec(a);if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6",length:0,size:function(){return this.length},toArray:function(){return D.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?C.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),y.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(D.apply(this,arguments),"slice",D.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:C,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;y.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!y){y=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",z,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",z),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&H()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):G[A.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;if(a.constructor&&!B.call(a,"constructor")&&!B.call(a.constructor.prototype,"isPrototypeOf"))return!1;var c;for(c in a);return c===b||B.call(a,c)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(b,c,d){a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b)),d=c.documentElement,(!d||!d.nodeName||d.nodeName==="parsererror")&&e.error("Invalid XML: "+b);return c},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:E?function(a){return a==null?"":E.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?C.call(c,a):e.merge(c,a)}return c},inArray:function(a,b){if(F)return F.call(b,a);for(var c=0,d=b.length;c<d;c++)if(b[c]===a)return c;return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=D.call(arguments,2),g=function(){return a.apply(c,f.concat(D.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=s.exec(a)||t.exec(a)||u.exec(a)||a.indexOf("compatible")<0&&v.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(c,d){d&&d instanceof e&&!(d instanceof a)&&(d=a(d));return e.fn.init.call(this,c,d,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){G["[object "+b+"]"]=b.toLowerCase()}),x=e.uaMatch(w),x.browser&&(e.browser[x.browser]=!0,e.browser.version=x.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?z=function(){c.removeEventListener("DOMContentLoaded",z,!1),e.ready()}:c.attachEvent&&(z=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",z),e.ready())});return e}(),g="done fail isResolved isRejected promise then always pipe".split(" "),h=[].slice;f.extend({_Deferred:function(){var a=[],b,c,d,e={done:function(){if(!d){var c=arguments,g,h,i,j,k;b&&(k=b,b=0);for(g=0,h=c.length;g<h;g++)i=c[g],j=f.type(i),j==="array"?e.done.apply(e,i):j==="function"&&a.push(i);k&&e.resolveWith(k[0],k[1])}return this},resolveWith:function(e,f){if(!d&&!b&&!c){f=f||[],c=1;try{while(a[0])a.shift().apply(e,f)}finally{b=[e,f],c=0}}return this},resolve:function(){e.resolveWith(this,arguments);return this},isResolved:function(){return!!c||!!b},cancel:function(){d=1,a=[];return this}};return e},Deferred:function(a){var b=f._Deferred(),c=f._Deferred(),d;f.extend(b,{then:function(a,c){b.done(a).fail(c);return this},always:function(){return b.done.apply(b,arguments).fail.apply(this,arguments)},fail:c.done,rejectWith:c.resolveWith,reject:c.resolve,isRejected:c.isResolved,pipe:function(a,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[c,"reject"]},function(a,c){var e=c[0],g=c[1],h;f.isFunction(e)?b[a](function(){h=e.apply(this,arguments),f.isFunction(h.promise)?h.promise().then(d.resolve,d.reject):d[g](h)}):b[a](d[g])})}).promise()},promise:function(a){if(a==null){if(d)return d;d=a={}}var c=g.length;while(c--)a[g[c]]=b[g[c]];return a}}),b.done(c.cancel).fail(b.cancel),delete b.cancel,a&&a.call(b,b);return b},when:function(a){function i(a){return function(c){b[a]=arguments.length>1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c<d;c++)b[c]&&f.isFunction(b[c].promise)?b[c].promise().then(i(c),g.reject):--e;e||g.resolveWith(g,b)}else g!==a&&g.resolveWith(g,d?[a]:[]);return g.promise()}}),f.support=function(){var a=c.createElement("div"),b,d,e,f,g,h,i,j,k,l,m,n,o,p,q;a.setAttribute("className","t"),a.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",b=a.getElementsByTagName("*"),d=a.getElementsByTagName("a")[0];if(!b||!b.length||!d)return{};e=c.createElement("select"),f=e.appendChild(c.createElement("option")),g=a.getElementsByTagName("input")[0],i={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(d.getAttribute("style")),hrefNormalized:d.getAttribute("href")==="/a",opacity:/^0.55$/.test(d.style.opacity),cssFloat:!!d.style.cssFloat,checkOn:g.value==="on",optSelected:f.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},g.checked=!0,i.noCloneChecked=g.cloneNode(!0).checked,e.disabled=!0,i.optDisabled=!f.disabled;try{delete a.test}catch(r){i.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function click(){i.noCloneEvent=!1,a.detachEvent("onclick",click)}),a.cloneNode(!0).fireEvent("onclick")),g=c.createElement("input"),g.value="t",g.setAttribute("type","radio"),i.radioValue=g.value==="t",g.setAttribute("checked","checked"),a.appendChild(g),j=c.createDocumentFragment(),j.appendChild(a.firstChild),i.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",k=c.createElement("body"),l={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"};for(p in l)k.style[p]=l[p];k.appendChild(a),c.documentElement.appendChild(k),i.appendChecked=g.checked,i.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,i.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="<div style='width:4px;'></div>",i.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",m=a.getElementsByTagName("td"),q=m[0].offsetHeight===0,m[0].style.display="",m[1].style.display="none",i.reliableHiddenOffsets=q&&m[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(h=c.createElement("div"),h.style.width="0",h.style.marginRight="0",a.appendChild(h),i.reliableMarginRight=(parseInt(c.defaultView.getComputedStyle(h,null).marginRight,10)||0)===0),k.innerHTML="",c.documentElement.removeChild(k);if(a.attachEvent)for(p in{submit:1,change:1,focusin:1})o="on"+p,q=o in a,q||(a.setAttribute(o,"return;"),q=typeof a[o]=="function"),i[p+"Bubbles"]=q;return i}(),f.boxModel=f.support.boxModel;var i=/^(?:\{.*\}|\[.*\])$/,j=/([a-z])([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!l(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g=f.expando,h=typeof c=="string",i,j=a.nodeType,k=j?f.cache:a,l=j?a[f.expando]:a[f.expando]&&f.expando;if((!l||e&&l&&!k[l][g])&&h&&d===b)return;l||(j?a[f.expando]=l=++f.uuid:l=f.expando),k[l]||(k[l]={},j||(k[l].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?k[l][g]=f.extend(k[l][g],c):k[l]=f.extend(k[l],c);i=k[l],e&&(i[g]||(i[g]={}),i=i[g]),d!==b&&(i[c]=d);if(c==="events"&&!i[c])return i[g]&&i[g].events;return h?i[c]:i}},removeData:function(b,c,d){if(!!f.acceptData(b)){var e=f.expando,g=b.nodeType,h=g?f.cache:b,i=g?b[f.expando]:f.expando;if(!h[i])return;if(c){var j=d?h[i][e]:h[i];if(j){delete j[c];if(!l(j))return}}if(d){delete h[i][e];if(!l(h[i]))return}var k=h[i][e];f.support.deleteExpando||h!=a?delete h[i]:h[i]=null,k?(h[i]={},g||(h[i].toJSON=f.noop),h[i][e]=k):g&&(f.support.deleteExpando?delete b[f.expando]:b.removeAttribute?b.removeAttribute(f.expando):b[f.expando]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d=null;if(typeof a=="undefined"){if(this.length){d=f.data(this[0]);if(this[0].nodeType===1){var e=this[0].attributes,g;for(var h=0,i=e.length;h<i;h++)g=e[h].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),k(this[0],g,d[g]))}}return d}if(typeof a=="object")return this.each(function(){f.data(this,a)});var j=a.split(".");j[1]=j[1]?"."+j[1]:"";if(c===b){d=this.triggerHandler("getData"+j[1]+"!",[j[0]]),d===b&&this.length&&(d=f.data(this[0],a),d=k(this[0],a,d));return d===b&&j[1]?this.data(j[0]):d}return this.each(function(){var b=f(this),d=[j[0],c];b.triggerHandler("setData"+j[1]+"!",d),f.data(this,a,c),b.triggerHandler("changeData"+j[1]+"!",d)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,c){a&&(c=(c||"fx")+"mark",f.data(a,c,(f.data(a,c,b,!0)||0)+1,!0))},_unmark:function(a,c,d){a!==!0&&(d=c,c=a,a=!1);if(c){d=d||"fx";var e=d+"mark",g=a?0:(f.data(c,e,b,!0)||1)-1;g?f.data(c,e,g,!0):(f.removeData(c,e,!0),m(c,d,"mark"))}},queue:function(a,c,d){if(a){c=(c||"fx")+"queue";var e=f.data(a,c,b,!0);d&&(!e||f.isArray(d)?e=f.data(a,c,f.makeArray(d),!0):e.push(d));return e||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e;d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),d.call(a,function(){f.dequeue(a,b)})),c.length||(f.removeData(a,b+"queue",!0),m(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(){var c=this;setTimeout(function(){f.dequeue(c,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function l(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark";while(g--)if(tmp=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f._Deferred(),!0))h++,tmp.done(l);l();return d.promise()}});var n=/[\n\t\r]/g,o=/\s+/,p=/\r/g,q=/^(?:button|input)$/i,r=/^(?:button|input|object|select|textarea)$/i,s=/^a(?:rea)?$/i,t=/^(?:data-|aria-)/,u=/\:/,v;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.addClass(a.call(this,b,c.attr("class")||""))});if(a&&typeof a=="string"){var b=(a||"").split(o);for(var c=0,d=this.length;c<d;c++){var e=this[c];if(e.nodeType===1)if(!e.className)e.className=a;else{var g=" "+e.className+" ",h=e.className;for(var i=0,j=b.length;i<j;i++)g.indexOf(" "+b[i]+" ")<0&&(h+=" "+b[i]);e.className=f.trim(h)}}}return this},removeClass:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.removeClass(a.call(this,b,c.attr("class")))});if(a&&typeof a=="string"||a===b){var c=(a||"").split(o);for(var d=0,e=this.length;d<e;d++){var g=this[d];if(g.nodeType===1&&g.className)if(a){var h=(" "+g.className+" ").replace(n," ");for(var i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){var d=f(this);d.toggleClass(a.call(this,c,d.attr("class"),b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(o);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ";for(var c=0,d=this.length;c<d;c++)if((" "+this[c].className+" ").replace(n," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e=this[0];if(!arguments.length){if(e){c=f.valHooks[e.nodeName.toLowerCase()]||f.valHooks[e.type];if(c&&"get"in c&&(d=c.get(e,"value"))!==b)return d;return(e.value||"").replace(p,"")}return b}var g=f.isFunction(a);return this.each(function(d){var e=f(this),h;if(this.nodeType===1){g?h=a.call(this,d,e.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||"set"in c&&c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b=a.selectedIndex,c=[],d=a.options,e=a.type==="select-one";if(b<0)return null;for(var g=e?b:0,h=e?b+1:d.length;g<h;g++){var i=d[g];if(i.selected&&(f.support.optDisabled?!i.disabled:i.getAttribute("disabled")===null)&&(!i.parentNode.disabled||!f.nodeName(i.parentNode,"optgroup"))){value=f(i).val();if(e)return value;c.push(value)}}if(e&&!c.length&&d.length)return f(d[b]).val();return c},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attrFix:{tabindex:"tabIndex",readonly:"readOnly"},attr:function(a,c,d,e){var g=a.nodeType;if(!a||g===3||g===8||g===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);var h,i,j=g!==1||!f.isXMLDoc(a);c=j&&f.attrFix[c]||c,i=f.attrHooks[c]||(v&&(f.nodeName(a,"form")||u.test(c))?v:b);if(d!==b){if(d===null||d===!1&&!t.test(c)){f.removeAttr(a,c);return b}if(i&&"set"in i&&j&&(h=i.set(a,d,c))!==b)return h;d===!0&&!t.test(c)&&(d=c),a.setAttribute(c,""+d);return d}if(i&&"get"in i&&j)return i.get(a,c);h=a.getAttribute(c);return h===null?b:h},removeAttr:function(a,b){a.nodeType===1&&(b=f.attrFix[b]||b,f.support.getSetAttribute?a.removeAttribute(b):(f.attr(a,b,""),a.removeAttributeNode(a.getAttributeNode(b))))},attrHooks:{type:{set:function(a,b){if(q.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.getAttribute("value");a.setAttribute("type",b),c&&(a.value=c);return b}}},tabIndex:{get:function(a){var c=a.getAttributeNode("tabIndex");return c&&c.specified?parseInt(c.value,10):r.test(a.nodeName)||s.test(a.nodeName)&&a.href?0:b}}},propFix:{},prop:function(a,c,d){var e=a.nodeType;if(!a||e===3||e===8||e===2)return b;var g,h,i=e!==1||!f.isXMLDoc(a);c=i&&f.propFix[c]||c,h=f.propHooks[c];return d!==b?h&&"set"in h&&(g=h.set(a,d,c))!==b?g:a[c]=d:h&&"get"in h&&(g=h.get(a,c))!==b?g:a[c]},propHooks:{}}),f.support.getSetAttribute||(f.attrFix=f.extend(f.attrFix,{"for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder"}),v=f.attrHooks.name=f.attrHooks.value=f.valHooks.button={get:function(a,c){var d;if(c==="value"&&!f.nodeName(a,"button"))return a.getAttribute(c);d=a.getAttributeNode(c);return d&&d.specified?d.nodeValue:b},set:function(a,b,c){var d=a.getAttributeNode(c);if(d){d.nodeValue=b;return b}}},f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})})),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}})),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var w=Object.prototype.hasOwnProperty,x=/\.(.*)$/,y=/^(?:textarea|input|select)$/i,z=/\./g,A=/ /g,B=/[^\w\s.|`]/g,C=function(a){return a.replace(B,"\\$&")};f.event={add:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){if(d===!1)d=D;else if(!d)return;var g,h;d.handler&&(g=d,d=g.handler),d.guid||(d.guid=f.guid++);var i=f._data(a);if(!i)return;var j=i.events,k=i.handle;j||(i.events=j={}),k||(i.handle=k=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.handle.apply(k.elem,arguments):b}),k.elem=a,c=c.split(" ");var l,m=0,n;while(l=c[m++]){h=g?f.extend({},g):{handler:d,data:e},l.indexOf(".")>-1?(n=l.split("."),l=n.shift(),h.namespace=n.slice(0).sort().join(".")):(n=[],h.namespace=""),h.type=l,h.guid||(h.guid=d.guid);var o=j[l],p=f.event.special[l]||{};if(!o){o=j[l]=[];if(!p.setup||p.setup.call(a,e,n,k)===!1)a.addEventListener?a.addEventListener(l,k,!1):a.attachEvent&&a.attachEvent("on"+l,k)}p.add&&(p.add.call(a,h),h.handler.guid||(h.handler.guid=d.guid)),o.push(h),f.event.global[l]=!0}a=null}},global:{},remove:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){d===!1&&(d=D);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=f.hasData(a)&&f._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(d=c.handler,c=c.type);if(!c||typeof c=="string"&&c.charAt(0)==="."){c=c||"";for(h in t)f.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+f.map(m.slice(0).sort(),C).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!d){for(j=0;j<p.length;j++){q=p[j];if(l||n.test(q.namespace))f.event.remove(a,r,q.handler,j),p.splice(j--,1)}continue}o=f.event.special[h]||{};for(j=e||0;j<p.length;j++){q=p[j];if(d.guid===q.guid){if(l||n.test(q.namespace))e==null&&p.splice(j--,1),o.remove&&o.remove.call(a,q);if(e!=null)break}}if(p.length===0||e!=null&&p.length===1)(!o.teardown||o.teardown.call(a,m)===!1)&&f.removeEvent(a,h,s.handle),g=null,delete t[h]}if(f.isEmptyObject(t)){var u=s.handle;u&&(u.elem=null),delete s.events,delete s.handle,f.isEmptyObject(s)&&f.removeData(a,b,!0)}}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){var h=c.type||c,i=[],j;h.indexOf("!")>=0&&(h=h.slice(0,-1),j=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if(!!e&&!f.event.customEvent[h]||!!f.event.global[h]){c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.exclusive=j,c.namespace=i.join("."),c.namespace_re=new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)");if(g||!e)c.preventDefault(),c.stopPropagation();if(!e){f.each(f.cache,function(){var a=f.expando,b=this[a];b&&b.events&&b.events[h]&&f.event.trigger(c,d,b.handle.elem)});return}if(e.nodeType===3||e.nodeType===8)return;c.result=b,c.target=e,d=d?f.makeArray(d):[],d.unshift(c);var k=e,l=h.indexOf(":")<0?"on"+h:"";do{var m=f._data(k,"handle");c.currentTarget=k,m&&m.apply(k,d),l&&f.acceptData(k)&&k[l]&&k[l].apply(k,d)===!1&&(c.result=!1,c.preventDefault()),k=k.parentNode||k.ownerDocument||k===c.target.ownerDocument&&a}while(k&&!c.isPropagationStopped());if(!c.isDefaultPrevented()){var n,o=f.event.special[h]||{};if((!o._default||o._default.call(e.ownerDocument,c)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)){try{l&&e[h]&&(n=e[l],n&&(e[l]=null),f.event.triggered=h,e[h]())}catch(p){}n&&(e[l]=n),f.event.triggered=b}}return c.result}},handle:function(c){c=f.event.fix(c||a.event);var d=((f._data(this,"events")||{})[c.type]||[]).slice(0),e=!c.exclusive&&!c.namespace,g=Array.prototype.slice.call(arguments,0);g[0]=c,c.currentTarget=this;for(var h=0,i=d.length;h<i;h++){var j=d[h];if(e||c.namespace_re.test(j.namespace)){c.handler=j.handler,c.data=j.data,c.handleObj=j;var k=j.handler.apply(this,g);k!==b&&(c.result=k,k===!1&&(c.preventDefault(),c.stopPropagation()));if(c.isImmediatePropagationStopped())break}}return c.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(a){if(a[f.expando])return a;var d=a;a=f.Event(d);for(var e=this.props.length,g;e;)g=this.props[--e],a[g]=d[g];a.target||(a.target=a.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),!a.relatedTarget&&a.fromElement&&(a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement);if(a.pageX==null&&a.clientX!=null){var h=a.target.ownerDocument||c,i=h.documentElement,j=h.body;a.pageX=a.clientX+(i&&i.scrollLeft||j&&j.scrollLeft||0)-(i&&i.clientLeft||j&&j.clientLeft||0),a.pageY=a.clientY+(i&&i.scrollTop||j&&j.scrollTop||0)-(i&&i.clientTop||j&&j.clientTop||0)}a.which==null&&(a.charCode!=null||a.keyCode!=null)&&(a.which=a.charCode!=null?a.charCode:a.keyCode),!a.metaKey&&a.ctrlKey&&(a.metaKey=a.ctrlKey),!a.which&&a.button!==b&&(a.which=a.button&1?1:a.button&2?3:a.button&4?2:0);return a},guid:1e8,proxy:f.proxy,special:{ready:{setup:f.bindReady,teardown:f.noop},live:{add:function(a){f.event.add(this,N(a.origType,a.selector),f.extend({},a,{handler:M,guid:a.handler.guid}))},remove:function(a){f.event.remove(this,N(a.origType,a.selector),a)}},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}}},f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!this.preventDefault)return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?E:D):this.type=a,b&&f.extend(this,b),this.timeStamp=f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=E;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=E;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=E,this.stopPropagation()},isDefaultPrevented:D,isPropagationStopped:D,isImmediatePropagationStopped:D};var F=function(a){var b=a.relatedTarget;try{if(b&&b!==c&&!b.parentNode)return;while(b&&b!==this)b=b.parentNode;b!==this&&(a.type=a.data,f.event.handle.apply(this,arguments))}catch(d){}},G=function(a){a.type=a.data,f.event.handle.apply(this,arguments)};f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={setup:function(c){f.event.add(this,b,c&&c.selector?G:F,a)},teardown:function(a){f.event.remove(this,b,a&&a.selector?G:F)}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(a,b){if(!f.nodeName(this,"form"))f.event.add(this,"click.specialSubmit",function(a){var b=a.target,c=b.type;(c==="submit"||c==="image")&&f(b).closest("form").length&&K("submit",this,arguments)}),f.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,c=b.type;(c==="text"||c==="password")&&f(b).closest("form").length&&a.keyCode===13&&K("submit",this,arguments)});else return!1},teardown:function(a){f.event.remove(this,".specialSubmit")}});if(!f.support.changeBubbles){var H,I=function(a){var b=a.type,c=a.value;b==="radio"||b==="checkbox"?c=a.checked:b==="select-multiple"?c=a.selectedIndex>-1?f.map(a.options,function(a){return a.selected}).join("-"):"":f.nodeName(a,"select")&&(c=a.selectedIndex);return c},J=function J(a){var c=a.target,d,e;if(!!y.test(c.nodeName)&&!c.readOnly){d=f._data(c,"_change_data"),e=I(c),(a.type!=="focusout"||c.type!=="radio")&&f._data(c,"_change_data",e);if(d===b||e===d)return;if(d!=null||e)a.type="change",a.liveFired=b,f.event.trigger(a,arguments[1],c)}};f.event.special.change={filters:{focusout:J,beforedeactivate:J,click:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(c==="radio"||c==="checkbox"||f.nodeName(b,"select"))&&J.call(this,a)},keydown:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(a.keyCode===13&&!f.nodeName(b,"textarea")||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&J.call(this,a)},beforeactivate:function(a){var b=a.target;f._data(b,"_change_data",I(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in H)f.event.add(this,c+".specialChange",H[c]);return y.test(this.nodeName)},teardown:function(a){f.event.remove(this,".specialChange");return y.test(this.nodeName)}},H=f.event.special.change.filters,H.focus=H.beforeactivate}f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){function e(a){var c=f.event.fix(a);c.type=b,c.originalEvent={},f.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var d=0;f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.each(["bind","one"],function(a,c){f.fn[c]=function(a,d,e){var g;if(typeof a=="object"){for(var h in a)this[c](h,d,a[h],e);return this}if(arguments.length===2||d===!1)e=d,d=b;c==="one"?(g=function(a){f(this).unbind(a,g);return e.apply(this,arguments)},g.guid=e.guid||f.guid++):g=e;if(a==="unload"&&c!=="one")this.one(a,d,e);else for(var i=0,j=this.length;i<j;i++)f.event.add(this[i],a,g,d);return this}}),f.fn.extend({unbind:function(a,b){if(typeof a=="object"&&!a.preventDefault)for(var c in a)this.unbind(c,a[c]);else for(var d=0,e=this.length;d<e;d++)f.event.remove(this[d],a,b);return this},delegate:function(a,b,c,d){return this.live(b,c,d,a)},undelegate:function(a,b,c){return arguments.length===0?this.unbind("live"):this.die(b,null,c,a)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f.data(this,"lastToggle"+a.guid)||0)%d;f.data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var L={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};f.each(["live","die"],function(a,c){f.fn[c]=function(a,d,e,g){var h,i=0,j,k,l,m=g||this.selector,n=g?this:f(this.context);if(typeof a=="object"&&!a.preventDefault){for(var o in a)n[c](o,d,a[o],m);return this}if(c==="die"&&!a&&g&&g.charAt(0)==="."){n.unbind(g);return this}if(d===!1||f.isFunction(d))e=d||D,d=b;a=(a||"").split(" ");while((h=a[i++])!=null){j=x.exec(h),k="",j&&(k=j[0],h=h.replace(x,""));if(h==="hover"){a.push("mouseenter"+k,"mouseleave"+k);continue}l=h,L[h]?(a.push(L[h]+k),h=h+k):h=(L[h]||h)+k;if(c==="live")for(var p=0,q=n.length;p<q;p++)f.event.add(n[p],"live."+N(h,m),{data:d,selector:m,handler:e,origType:h,origHandler:e,preType:l});else n.unbind("live."+N(h,m),e)}return this}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}if(i.nodeType===1){f||(i.sizcache=c,i.sizset=g);if(typeof b!="string"){if(i===b){j=!0;break}}else if(k.filter(b,[i]).length>0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}i.nodeType===1&&!f&&(i.sizcache=c,i.sizset=g);if(i.nodeName.toLowerCase()===b){j=i;break}i=i[a]}d[g]=j}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d=0,e=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,f,g){f=f||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return f;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(e.call(n)==="[object Array]")if(!u)f.push.apply(f,n);else if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&f.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&f.push(j[t]);else p(n,f);o&&(k(o,h,f,g),k.uniqueSort(f));return f};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},k.matches=function(a,b){return k(a,null,null,b)},k.matchesSelector=function(a,b){return k(b,null,null,[a]).length>0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e<f;e++){var g,h=l.order[e];if(g=l.leftMatch[h].exec(a)){var j=g[1];g.splice(1,1);if(j.substr(j.length-1)!=="\\"){g[1]=(g[1]||"").replace(i,""),d=l.find[h](g,b,c);if(d!=null){a=a.replace(l.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},k.filter=function(a,c,d,e){var f,g,h=a,i=[],j=c,m=c&&c[0]&&k.isXML(c[0]);while(a&&c.length){for(var n in l.filter)if((f=l.leftMatch[n].exec(a))!=null&&f[2]){var o,p,q=l.filter[n],r=f[1];g=!1,f.splice(1,1);if(r.substr(r.length-1)==="\\")continue;j===i&&(i=[]);if(l.preFilter[n]){f=l.preFilter[n](f,j,d,i,e,m);if(!f)g=o=!0;else if(f===!0)continue}if(f)for(var s=0;(p=j[s])!=null;s++)if(p){o=q(p,f,s,j);var t=e^!!o;d&&o!=null?t?g=!0:j[s]=!1:t&&(i.push(p),g=!0)}if(o!==b){d||(j=i),a=a.replace(l.match[n],"");if(!g)return[];break}}if(a===h)if(g==null)k.error(a);else break;h=a}return j},k.error=function(a){throw"Syntax error, unrecognized expression: "+a};var l=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!j.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&k.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&k.filter(b,a,!0)}},"":function(a,b,c){var e,f=d++,g=u;typeof b=="string"&&!j.test(b)&&(b=b.toLowerCase(),e=b,g=t),g("parentNode",b,f,a,e,c)},"~":function(a,b,c){var e,f=d++,g=u;typeof b=="string"&&!j.test(b)&&(b=b.toLowerCase(),e=b,g=t),g("previousSibling",b,f,a,e,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(i,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);a[0]=d++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){return a.nodeName.toLowerCase()==="input"&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}k.error(e)},CHILD:function(a,b){var c=b[1],d=a;switch(c){case"only":case"first":while(d=d.previousSibling)if(d.nodeType===1)return!1;if(c==="first")return!0;d=a;case"last":while(d=d.nextSibling)if(d.nodeType===1)return!1;return!0;case"nth":var e=b[2],f=b[3];if(e===1&&f===0)return!0;var g=b[0],h=a.parentNode;if(h&&(h.sizcache!==g||!a.nodeIndex)){var i=0;for(d=h.firstChild;d;d=d.nextSibling)d.nodeType===1&&(d.nodeIndex=++i);h.sizcache=g}var j=a.nodeIndex-f;return e===0?j===0:j%e===0&&j/e>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(e.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var f=a.length;c<f;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var r,s;c.documentElement.compareDocumentPosition?r=function(a,b){if(a===b){g=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(r=function(a,b){var c,d,e=[],f=[],h=a.parentNode,i=b.parentNode,j=h;if(a===b){g=!0;return 0}if(h===i)return s(a,b);if(!h)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return s(e[k],f[k]);return k===c?s(a,f[k],-1):s(e[k],b,1)},s=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),k.getText=function(a){var b="",c;for(var d=0;a[d];d++)c=a[d],c.nodeType===3||c.nodeType===4?b+=c.nodeValue:c.nodeType!==8&&(b+=k.getText(c.childNodes));return b},function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g<h;g++)k(a,f[g],d);return k.filter(e,d)};f.find=k,f.expr=k.selectors,f.expr[":"]=f.expr.filters,f.unique=k.uniqueSort,f.text=k.getText,f.isXMLDoc=k.isXML,f.contains=k.contains}();var O=/Until$/,P=/^(?:parents|prevUntil|prevAll)/,Q=/,/,R=/^.[^:#\[\.,]*$/,S=Array.prototype.slice,T=f.expr.match.POS,U={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(W(this,a,!1),"not",a)},filter:function(a){return this.pushStack(W(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(d=0,e=a.length;d<e;d++)i=a[d],j[i]||(j[i]=T.test(i)?f(i,b||this.context):i);while(g&&g.ownerDocument&&g!==b){for(i in j)h=j[i],(h.jquery?h.index(g)>-1:f(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=T.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(l?l.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a||typeof a=="string")return f.inArray(this[0],a?f(a):this.parent().children());return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(V(c[0])||V(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=S.call(arguments);O.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!U[a]?f.unique(e):e,(this.length>1||Q.test(d))&&P.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var X=/ jQuery\d+="(?:\d+|null)"/g,Y=/^\s+/,Z=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,$=/<([\w:]+)/,_=/<tbody/i,ba=/<|&#?\w+;/,bb=/<(?:script|object|embed|option|style)/i,bc=/checked\s*(?:[^=]|=\s*.checked.)/i,bd=/\/(java|ecma)script/i,be={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};be.optgroup=be.option,be.tbody=be.tfoot=be.colgroup=be.caption=be.thead,be.th=be.td,f.support.htmlSerialize||(be._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(X,""):null;if(typeof a=="string"&&!bb.test(a)&&(f.support.leadingWhitespace||!Y.test(a))&&!be[($.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Z,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bc.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bf(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bl)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i=b&&b[0]?b[0].ownerDocument||b[0]:c;a.length===1&&typeof a[0]=="string"&&a[0].length<512&&i===c&&a[0].charAt(0)==="<"&&!bb.test(a[0])&&(f.support.checkClone||!bc.test(a[0]))&&(g=!0,h=f.fragments[a[0]],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[a[0]]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bh(a,d),e=bi(a),g=bi(d);for(h=0;e[h];++h)bh(e[h],g[h])}if(b){bg(a,d);if(c){e=bi(a),g=bi(d);for(h=0;e[h];++h)bg(e[h],g[h])}}return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[];for(var i=0,j;(j=a[i])!=null;i++){typeof j=="number"&&(j+="");if(!j)continue;if(typeof j=="string")if(!ba.test(j))j=b.createTextNode(j);else{j=j.replace(Z,"<$1></$2>");var k=($.exec(j)||["",""])[1].toLowerCase(),l=be[k]||be._default,m=l[0],n=b.createElement("div");n.innerHTML=l[1]+j+l[2];while(m--)n=n.lastChild;if(!f.support.tbody){var o=_.test(j),p=k==="table"&&!o?n.firstChild&&n.firstChild.childNodes:l[1]==="<table>"&&!o?n.childNodes:[];for(var q=p.length-1;q>=0;--q)f.nodeName(p[q],"tbody")&&!p[q].childNodes.length&&p[q].parentNode.removeChild(p[q])}!f.support.leadingWhitespace&&Y.test(j)&&n.insertBefore(b.createTextNode(Y.exec(j)[0]),n.firstChild),j=n.childNodes}var r;if(!f.support.appendChecked)if(j[0]&&typeof (r=j.length)=="number")for(i=0;i<r;i++)bk(j[i]);else bk(j);j.nodeType?h.push(j):h=f.merge(h,j)}if(d){g=function(a){return!a.type||bd.test(a.type)};for(i=0;h[i];i++)if(e&&f.nodeName(h[i],"script")&&(!h[i].type||h[i].type.toLowerCase()==="text/javascript"))e.push(h[i].parentNode?h[i].parentNode.removeChild(h[i]):h[i]);else{if(h[i].nodeType===1){var s=f.grep(h[i].getElementsByTagName("script"),g);h.splice.apply(h,[i+1,0].concat(s))}d.appendChild(h[i])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.expando,g=f.event.special,h=f.support.deleteExpando;for(var i=0,j;(j=a[i])!=null;i++){if(j.nodeName&&f.noData[j.nodeName.toLowerCase()])continue;c=j[f.expando];if(c){b=d[c]&&d[c][e];if(b&&b.events){for(var k in b.events)g[k]?f.event.remove(j,k):f.removeEvent(j,k,b.handle);b.handle&&(b.handle.elem=null)}h?delete j[f.expando]:j.removeAttribute&&j.removeAttribute(f.expando),delete d[c]}}}});var bm=/alpha\([^)]*\)/i,bn=/opacity=([^)]*)/,bo=/-([a-z])/ig,bp=/([A-Z]|^ms)/g,bq=/^-?\d+(?:px)?$/i,br=/^-?\d/,bs=/^[+\-]=/,bt=/[^+\-\.\de]+/g,bu={position:"absolute",visibility:"hidden",display:"block"},bv=["Left","Right"],bw=["Top","Bottom"],bx,by,bz,bA=function(a,b){return b.toUpperCase()};f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bx(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{zIndex:!0,fontWeight:!0,opacity:!0,zoom:!0,lineHeight:!0,widows:!0,orphans:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d;if(h==="number"&&isNaN(d)||d==null)return;h==="string"&&bs.test(d)&&(d=+d.replace(bt,"")+parseFloat(f.css(a,c))),h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bx)return bx(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]},camelCase:function(a){return a.replace(bo,bA)}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){a.offsetWidth!==0?e=bB(a,b,d):f.swap(a,bu,function(){e=bB(a,b,d)});if(e<=0){e=bx(a,b,b),e==="0px"&&bz&&(e=bz(a,b,b));if(e!=null)return e===""||e==="auto"?"0px":e}if(e<0||e==null){e=a.style[b];return e===""||e==="auto"?"0px":e}return typeof e=="string"?e:e+"px"}},set:function(a,b){if(!bq.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bn.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle;c.zoom=1;var e=f.isNaN(b)?"":"alpha(opacity="+b*100+")",g=d&&d.filter||c.filter||"";c.filter=bm.test(g)?g.replace(bm,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bx(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(by=function(a,c){var d,e,g;c=c.replace(bp,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bz=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bq.test(d)&&br.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bx=by||bz,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bC=/%20/g,bD=/\[\]$/,bE=/\r?\n/g,bF=/#.*$/,bG=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bH=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bI=/^(?:about|app|app\-storage|.+\-extension|file|widget):$/,bJ=/^(?:GET|HEAD)$/,bK=/^\/\//,bL=/\?/,bM=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bN=/^(?:select|textarea)/i,bO=/\s+/,bP=/([?&])_=[^&]*/,bQ=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bR=f.fn.load,bS={},bT={},bU,bV;try{bU=e.href}catch(bW){bU=c.createElement("a"),bU.href="",bU=bU.href}bV=bQ.exec(bU.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bR)return bR.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bM,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bN.test(this.nodeName)||bH.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bE,"\r\n")}}):{name:b.name,value:c.replace(bE,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?f.extend(!0,a,f.ajaxSettings,b):(b=a,a=f.extend(!0,f.ajaxSettings,b));for(var c in{context:1,url:1})c in b?a[c]=b[c]:c in f.ajaxSettings&&(a[c]=f.ajaxSettings[c]);return a},ajaxSettings:{url:bU,isLocal:bI.test(bV[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":"*/*"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML}},ajaxPrefilter:bX(bS),ajaxTransport:bX(bT),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a?4:0;var o,r,u,w=l?b$(d,v,l):b,x,y;if(a>=200&&a<300||a===304){if(d.ifModified){if(x=v.getResponseHeader("Last-Modified"))f.lastModified[k]=x;if(y=v.getResponseHeader("Etag"))f.etag[k]=y}if(a===304)c="notmodified",o=!0;else try{r=b_(d,w),c="success",o=!0}catch(z){c="parsererror",u=z}}else{u=c;if(!c||a)c="error",a<0&&(a=0)}v.status=a,v.statusText=c,o?h.resolveWith(e,[r,c,v]):h.rejectWith(e,[v,c,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.resolveWith(e,[v,c]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f._Deferred(),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.done,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bF,"").replace(bK,bV[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bO),d.crossDomain==null&&(r=bQ.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bV[1]&&r[2]==bV[2]&&(r[3]||(r[1]==="http:"?80:443))==(bV[3]||(bV[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bY(bS,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bJ.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bL.test(d.url)?"&":"?")+d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bP,"$1_="+x);d.url=y+(y===d.url?(bL.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", */*; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bY(bT,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){status<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)bZ(g,a[g],c,e);return d.join("&").replace(bC,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var ca=f.now(),cb=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+ca++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cb.test(b.url)||e&&cb.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cb,l),b.url===j&&(e&&(k=k.replace(cb,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cc=a.ActiveXObject?function(){for(var a in ce)ce[a](0,1)}:!1,cd=0,ce;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&cf()||cg()}:cf,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cc&&delete ce[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cd,cc&&(ce||(ce={},f(a).unload(cc)),ce[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ch={},ci,cj,ck=/^(?:toggle|show|hide)$/,cl=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cm,cn=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],co,cp=a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cs("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",ct(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cs("hide",3),a,b,c);for(var d=0,e=this.length;d<e;d++)if(this[d].style){var g=f.css(this[d],"display");g!=="none"&&!f._data(this[d],"olddisplay")&&f._data(this[d],"olddisplay",g)}for(d=0;d<e;d++)this[d].style&&(this[d].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cs("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);return this[e.queue===!1?"each":"queue"](function(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g];if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(f.support.inlineBlockNeedsLayout?(j=ct(this.nodeName),j==="inline"?this.style.display="inline-block":(this.style.display="inline",this.style.zoom=1)):this.style.display="inline-block")),b.animatedProperties[g]=f.isArray(h)?h[1]:b.specialEasing&&b.specialEasing[g]||b.easing||"swing"}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)k=new f.fx(this,b,i),h=a[i],ck.test(h)?k[h==="toggle"?d?"show":"hide":h]():(l=cl.exec(h),m=k.cur(),l?(n=parseFloat(l[2]),o=l[3]||(f.cssNumber[g]?"":"px"),o!=="px"&&(f.style(this,i,(n||1)+o),m=(n||1)/k.cur()*m,f.style(this,i,m+o)),l[1]&&(n=(l[1]==="-="?-1:1)*n+m),k.custom(m,n,o)):k.custom(m,h,""));return!0})},stop:function(a,b){a&&this.queue([]),this.each(function(){var a=f.timers,c=a.length;b||f._unmark(!0,this);while(c--)a[c].elem===this&&(b&&a[c](!0),a.splice(c,1))}),b||this.dequeue();return this}}),f.each({slideDown:cs("show",1),slideUp:cs("hide",1),slideToggle:cs("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default,d.old=d.complete,d.complete=function(a){d.queue!==!1?f.dequeue(this):a!==!1&&f._unmark(this),f.isFunction(d.old)&&d.old.call(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,b,c){function h(a){return d.step(a)}var d=this,e=f.fx,g;this.startTime=co||cq(),this.start=a,this.end=b,this.unit=c||this.unit||(f.cssNumber[this.prop]?"":"px"),this.now=this.start,this.pos=this.state=0,h.elem=this.elem,h()&&f.timers.push(h)&&!cm&&(cp?(cm=1,g=function(){cm&&(cp(g),e.tick())},cp(g)):cm=setInterval(e.tick,e.interval))},show:function(){this.options.orig[this.prop]=f.style(this.elem,this.prop),this.options.show=!0,this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b=co||cq(),c=!0,d=this.elem,e=this.options,g,h;if(a||b>=e.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),e.animatedProperties[this.prop]=!0;for(g in e.animatedProperties)e.animatedProperties[g]!==!0&&(c=!1);if(c){e.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){d.style["overflow"+b]=e.overflow[a]}),e.hide&&f(d).hide();if(e.hide||e.show)for(var i in e.animatedProperties)f.style(d,i,e.orig[i]);e.complete.call(d)}return!1}e.duration==Infinity?this.now=b:(h=b-this.startTime,this.state=h/e.duration,this.pos=f.easing[e.animatedProperties[this.prop]](this.state,h,0,1,e.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a=f.timers,b=a.length;while(b--)a[b]()||a.splice(b,1);a.length||f.fx.stop()},interval:13,stop:function(){clearInterval(cm),cm=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit:a.elem[a.prop]=a.now}}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cu=/^t(?:able|d|h)$/i,cv=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cw(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);f.offset.initialize();var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.offset.supportsFixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.offset.doesNotAddBorder&&(!f.offset.doesAddBorderForTableAndCells||!cu.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.offset.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.offset.supportsFixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={initialize:function(){var a=c.body,b=c.createElement("div"),d,e,g,h,i=parseFloat(f.css(a,"marginTop"))||0,j="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";f.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),d=b.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,this.doesNotAddBorder=e.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,e.style.position="fixed",e.style.top="20px",this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),f.offset.initialize=f.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.offset.initialize(),f.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cv.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cv.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cw(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cw(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){return this[0]?parseFloat(f.css(this[0],d,"padding")):null},f.fn["outer"+c]=function(a){return this[0]?parseFloat(f.css(this[0],d,a?"margin":"border")):null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c];return e.document.compatMode==="CSS1Compat"&&g||e.document.body["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var h=f.css(e,d),i=parseFloat(h);return f.isNaN(i)?h:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window);
\ No newline at end of file
--- /dev/null
+/*
+ * Raphael 1.5.2 - JavaScript Vector Library
+ *
+ * Copyright (c) 2010 Dmitry Baranovskiy (http://raphaeljs.com)
+ * Licensed under the MIT (http://raphaeljs.com/license.html) license.
+ */
+(function(){function a(){if(a.is(arguments[0],G)){var b=arguments[0],d=bV[m](a,b.splice(0,3+a.is(b[0],E))),e=d.set();for(var g=0,h=b[w];g<h;g++){var i=b[g]||{};c[f](i.type)&&e[L](d[i.type]().attr(i))}return e}return bV[m](a,arguments)}a.version="1.5.2";var b=/[, ]+/,c={circle:1,rect:1,path:1,ellipse:1,text:1,image:1},d=/\{(\d+)\}/g,e="prototype",f="hasOwnProperty",g=document,h=window,i={was:Object[e][f].call(h,"Raphael"),is:h.Raphael},j=function(){this.customAttributes={}},k,l="appendChild",m="apply",n="concat",o="createTouch"in g,p="",q=" ",r=String,s="split",t="click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend orientationchange touchcancel gesturestart gesturechange gestureend"[s](q),u={mousedown:"touchstart",mousemove:"touchmove",mouseup:"touchend"},v="join",w="length",x=r[e].toLowerCase,y=Math,z=y.max,A=y.min,B=y.abs,C=y.pow,D=y.PI,E="number",F="string",G="array",H="toString",I="fill",J=Object[e][H],K={},L="push",M=/^url\(['"]?([^\)]+?)['"]?\)$/i,N=/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\))\s*$/i,O={"NaN":1,Infinity:1,"-Infinity":1},P=/^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,Q=y.round,R="setAttribute",S=parseFloat,T=parseInt,U=" progid:DXImageTransform.Microsoft",V=r[e].toUpperCase,W={blur:0,"clip-rect":"0 0 1e9 1e9",cursor:"default",cx:0,cy:0,fill:"#fff","fill-opacity":1,font:"10px \"Arial\"","font-family":"\"Arial\"","font-size":"10","font-style":"normal","font-weight":400,gradient:0,height:0,href:"http://raphaeljs.com/",opacity:1,path:"M0,0",r:0,rotation:0,rx:0,ry:0,scale:"1 1",src:"",stroke:"#000","stroke-dasharray":"","stroke-linecap":"butt","stroke-linejoin":"butt","stroke-miterlimit":0,"stroke-opacity":1,"stroke-width":1,target:"_blank","text-anchor":"middle",title:"Raphael",translation:"0 0",width:0,x:0,y:0},X={along:"along",blur:E,"clip-rect":"csv",cx:E,cy:E,fill:"colour","fill-opacity":E,"font-size":E,height:E,opacity:E,path:"path",r:E,rotation:"csv",rx:E,ry:E,scale:"csv",stroke:"colour","stroke-opacity":E,"stroke-width":E,translation:"csv",width:E,x:E,y:E},Y="replace",Z=/^(from|to|\d+%?)$/,$=/\s*,\s*/,_={hs:1,rg:1},ba=/,?([achlmqrstvxz]),?/gi,bb=/([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig,bc=/(-?\d*\.?\d*(?:e[-+]?\d+)?)\s*,?\s*/ig,bd=/^r(?:\(([^,]+?)\s*,\s*([^\)]+?)\))?/,be=function(a,b){return a.key-b.key};a.type=h.SVGAngle||g.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")?"SVG":"VML";if(a.type=="VML"){var bf=g.createElement("div"),bg;bf.innerHTML="<v:shape adj=\"1\"/>";bg=bf.firstChild;bg.style.behavior="url(#default#VML)";if(!(bg&&typeof bg.adj=="object"))return a.type=null;bf=null}a.svg=!(a.vml=a.type=="VML");j[e]=a[e];k=j[e];a._id=0;a._oid=0;a.fn={};a.is=function(a,b){b=x.call(b);if(b=="finite")return!O[f](+a);return b=="null"&&a===null||b==typeof a||b=="object"&&a===Object(a)||b=="array"&&Array.isArray&&Array.isArray(a)||J.call(a).slice(8,-1).toLowerCase()==b};a.angle=function(b,c,d,e,f,g){{if(f==null){var h=b-d,i=c-e;if(!h&&!i)return 0;return((h<0)*180+y.atan(-i/-h)*180/D+360)%360}return a.angle(b,c,f,g)-a.angle(d,e,f,g)}};a.rad=function(a){return a%360*D/180};a.deg=function(a){return a*180/D%360};a.snapTo=function(b,c,d){d=a.is(d,"finite")?d:10;if(a.is(b,G)){var e=b.length;while(e--)if(B(b[e]-c)<=d)return b[e]}else{b=+b;var f=c%b;if(f<d)return c-f;if(f>b-d)return c-f+b}return c};function bh(){var a=[],b=0;for(;b<32;b++)a[b]=(~(~(y.random()*16)))[H](16);a[12]=4;a[16]=(a[16]&3|8)[H](16);return"r-"+a[v]("")}a.setWindow=function(a){h=a;g=h.document};var bi=function(b){if(a.vml){var c=/^\s+|\s+$/g,d;try{var e=new ActiveXObject("htmlfile");e.write("<body>");e.close();d=e.body}catch(a){d=createPopup().document.body}var f=d.createTextRange();bi=bm(function(a){try{d.style.color=r(a)[Y](c,p);var b=f.queryCommandValue("ForeColor");b=(b&255)<<16|b&65280|(b&16711680)>>>16;return"#"+("000000"+b[H](16)).slice(-6)}catch(a){return"none"}})}else{var h=g.createElement("i");h.title="Raphaël Colour Picker";h.style.display="none";g.body[l](h);bi=bm(function(a){h.style.color=a;return g.defaultView.getComputedStyle(h,p).getPropertyValue("color")})}return bi(b)},bj=function(){return"hsb("+[this.h,this.s,this.b]+")"},bk=function(){return"hsl("+[this.h,this.s,this.l]+")"},bl=function(){return this.hex};a.hsb2rgb=function(b,c,d,e){if(a.is(b,"object")&&"h"in b&&"s"in b&&"b"in b){d=b.b;c=b.s;b=b.h;e=b.o}return a.hsl2rgb(b,c,d/2,e)};a.hsl2rgb=function(b,c,d,e){if(a.is(b,"object")&&"h"in b&&"s"in b&&"l"in b){d=b.l;c=b.s;b=b.h}if(b>1||c>1||d>1){b/=360;c/=100;d/=100}var f={},g=["r","g","b"],h,i,j,k,l,m;if(c){d<0.5?h=d*(1+c):h=d+c-d*c;i=2*d-h;for(var n=0;n<3;n++){j=b+1/3*-(n-1);j<0&&j++;j>1&&j--;j*6<1?f[g[n]]=i+(h-i)*6*j:j*2<1?f[g[n]]=h:j*3<2?f[g[n]]=i+(h-i)*(2/3-j)*6:f[g[n]]=i}}else f={r:d,g:d,b:d};f.r*=255;f.g*=255;f.b*=255;f.hex="#"+(16777216|f.b|f.g<<8|f.r<<16).toString(16).slice(1);a.is(e,"finite")&&(f.opacity=e);f.toString=bl;return f};a.rgb2hsb=function(b,c,d){if(c==null&&a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b){d=b.b;c=b.g;b=b.r}if(c==null&&a.is(b,F)){var e=a.getRGB(b);b=e.r;c=e.g;d=e.b}if(b>1||c>1||d>1){b/=255;c/=255;d/=255}var f=z(b,c,d),g=A(b,c,d),h,i,j=f;{if(g==f)return{h:0,s:0,b:f,toString:bj};var k=f-g;i=k/f;b==f?h=(c-d)/k:c==f?h=2+(d-b)/k:h=4+(b-c)/k;h/=6;h<0&&h++;h>1&&h--}return{h:h,s:i,b:j,toString:bj}};a.rgb2hsl=function(b,c,d){if(c==null&&a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b){d=b.b;c=b.g;b=b.r}if(c==null&&a.is(b,F)){var e=a.getRGB(b);b=e.r;c=e.g;d=e.b}if(b>1||c>1||d>1){b/=255;c/=255;d/=255}var f=z(b,c,d),g=A(b,c,d),h,i,j=(f+g)/2,k;if(g==f)k={h:0,s:0,l:j};else{var l=f-g;i=j<0.5?l/(f+g):l/(2-f-g);b==f?h=(c-d)/l:c==f?h=2+(d-b)/l:h=4+(b-c)/l;h/=6;h<0&&h++;h>1&&h--;k={h:h,s:i,l:j}}k.toString=bk;return k};a._path2string=function(){return this.join(",")[Y](ba,"$1")};function bm(a,b,c){function d(){var g=Array[e].slice.call(arguments,0),h=g[v]("►"),i=d.cache=d.cache||{},j=d.count=d.count||[];if(i[f](h))return c?c(i[h]):i[h];j[w]>=1000&&delete i[j.shift()];j[L](h);i[h]=a[m](b,g);return c?c(i[h]):i[h]}return d}a.getRGB=bm(function(b){if(!b||!(!((b=r(b)).indexOf("-")+1)))return{r:-1,g:-1,b:-1,hex:"none",error:1};if(b=="none")return{r:-1,g:-1,b:-1,hex:"none"};!(_[f](b.toLowerCase().substring(0,2))||b.charAt()=="#")&&(b=bi(b));var c,d,e,g,h,i,j,k=b.match(N);if(k){if(k[2]){g=T(k[2].substring(5),16);e=T(k[2].substring(3,5),16);d=T(k[2].substring(1,3),16)}if(k[3]){g=T((i=k[3].charAt(3))+i,16);e=T((i=k[3].charAt(2))+i,16);d=T((i=k[3].charAt(1))+i,16)}if(k[4]){j=k[4][s]($);d=S(j[0]);j[0].slice(-1)=="%"&&(d*=2.55);e=S(j[1]);j[1].slice(-1)=="%"&&(e*=2.55);g=S(j[2]);j[2].slice(-1)=="%"&&(g*=2.55);k[1].toLowerCase().slice(0,4)=="rgba"&&(h=S(j[3]));j[3]&&j[3].slice(-1)=="%"&&(h/=100)}if(k[5]){j=k[5][s]($);d=S(j[0]);j[0].slice(-1)=="%"&&(d*=2.55);e=S(j[1]);j[1].slice(-1)=="%"&&(e*=2.55);g=S(j[2]);j[2].slice(-1)=="%"&&(g*=2.55);(j[0].slice(-3)=="deg"||j[0].slice(-1)=="°")&&(d/=360);k[1].toLowerCase().slice(0,4)=="hsba"&&(h=S(j[3]));j[3]&&j[3].slice(-1)=="%"&&(h/=100);return a.hsb2rgb(d,e,g,h)}if(k[6]){j=k[6][s]($);d=S(j[0]);j[0].slice(-1)=="%"&&(d*=2.55);e=S(j[1]);j[1].slice(-1)=="%"&&(e*=2.55);g=S(j[2]);j[2].slice(-1)=="%"&&(g*=2.55);(j[0].slice(-3)=="deg"||j[0].slice(-1)=="°")&&(d/=360);k[1].toLowerCase().slice(0,4)=="hsla"&&(h=S(j[3]));j[3]&&j[3].slice(-1)=="%"&&(h/=100);return a.hsl2rgb(d,e,g,h)}k={r:d,g:e,b:g};k.hex="#"+(16777216|g|e<<8|d<<16).toString(16).slice(1);a.is(h,"finite")&&(k.opacity=h);return k}return{r:-1,g:-1,b:-1,hex:"none",error:1}},a);a.getColor=function(a){var b=this.getColor.start=this.getColor.start||{h:0,s:1,b:a||0.75},c=this.hsb2rgb(b.h,b.s,b.b);b.h+=0.075;if(b.h>1){b.h=0;b.s-=0.2;b.s<=0&&(this.getColor.start={h:0,s:1,b:b.b})}return c.hex};a.getColor.reset=function(){delete this.start};a.parsePathString=bm(function(b){if(!b)return null;var c={a:7,c:6,h:1,l:2,m:2,q:4,s:4,t:2,v:1,z:0},d=[];a.is(b,G)&&a.is(b[0],G)&&(d=bo(b));d[w]||r(b)[Y](bb,function(a,b,e){var f=[],g=x.call(b);e[Y](bc,function(a,b){b&&f[L](+b)});if(g=="m"&&f[w]>2){d[L]([b][n](f.splice(0,2)));g="l";b=b=="m"?"l":"L"}while(f[w]>=c[g]){d[L]([b][n](f.splice(0,c[g])));if(!c[g])break}});d[H]=a._path2string;return d});a.findDotsAtSegment=function(a,b,c,d,e,f,g,h,i){var j=1-i,k=C(j,3)*a+C(j,2)*3*i*c+j*3*i*i*e+C(i,3)*g,l=C(j,3)*b+C(j,2)*3*i*d+j*3*i*i*f+C(i,3)*h,m=a+2*i*(c-a)+i*i*(e-2*c+a),n=b+2*i*(d-b)+i*i*(f-2*d+b),o=c+2*i*(e-c)+i*i*(g-2*e+c),p=d+2*i*(f-d)+i*i*(h-2*f+d),q=(1-i)*a+i*c,r=(1-i)*b+i*d,s=(1-i)*e+i*g,t=(1-i)*f+i*h,u=90-y.atan((m-o)/(n-p))*180/D;(m>o||n<p)&&(u+=180);return{x:k,y:l,m:{x:m,y:n},n:{x:o,y:p},start:{x:q,y:r},end:{x:s,y:t},alpha:u}};var bn=bm(function(a){if(!a)return{x:0,y:0,width:0,height:0};a=bw(a);var b=0,c=0,d=[],e=[],f;for(var g=0,h=a[w];g<h;g++){f=a[g];if(f[0]=="M"){b=f[1];c=f[2];d[L](b);e[L](c)}else{var i=bv(b,c,f[1],f[2],f[3],f[4],f[5],f[6]);d=d[n](i.min.x,i.max.x);e=e[n](i.min.y,i.max.y);b=f[5];c=f[6]}}var j=A[m](0,d),k=A[m](0,e);return{x:j,y:k,width:z[m](0,d)-j,height:z[m](0,e)-k}}),bo=function(b){var c=[];if(!a.is(b,G)||!a.is(b&&b[0],G))b=a.parsePathString(b);for(var d=0,e=b[w];d<e;d++){c[d]=[];for(var f=0,g=b[d][w];f<g;f++)c[d][f]=b[d][f]}c[H]=a._path2string;return c},bp=bm(function(b){if(!a.is(b,G)||!a.is(b&&b[0],G))b=a.parsePathString(b);var c=[],d=0,e=0,f=0,g=0,h=0;if(b[0][0]=="M"){d=b[0][1];e=b[0][2];f=d;g=e;h++;c[L](["M",d,e])}for(var i=h,j=b[w];i<j;i++){var k=c[i]=[],l=b[i];if(l[0]!=x.call(l[0])){k[0]=x.call(l[0]);switch(k[0]){case"a":k[1]=l[1];k[2]=l[2];k[3]=l[3];k[4]=l[4];k[5]=l[5];k[6]=+(l[6]-d).toFixed(3);k[7]=+(l[7]-e).toFixed(3);break;case"v":k[1]=+(l[1]-e).toFixed(3);break;case"m":f=l[1];g=l[2];default:for(var m=1,n=l[w];m<n;m++)k[m]=+(l[m]-(m%2?d:e)).toFixed(3)}}else{k=c[i]=[];if(l[0]=="m"){f=l[1]+d;g=l[2]+e}for(var o=0,p=l[w];o<p;o++)c[i][o]=l[o]}var q=c[i][w];switch(c[i][0]){case"z":d=f;e=g;break;case"h":d+=+c[i][q-1];break;case"v":e+=+c[i][q-1];break;default:d+=+c[i][q-2];e+=+c[i][q-1]}}c[H]=a._path2string;return c},0,bo),bq=bm(function(b){if(!a.is(b,G)||!a.is(b&&b[0],G))b=a.parsePathString(b);var c=[],d=0,e=0,f=0,g=0,h=0;if(b[0][0]=="M"){d=+b[0][1];e=+b[0][2];f=d;g=e;h++;c[0]=["M",d,e]}for(var i=h,j=b[w];i<j;i++){var k=c[i]=[],l=b[i];if(l[0]!=V.call(l[0])){k[0]=V.call(l[0]);switch(k[0]){case"A":k[1]=l[1];k[2]=l[2];k[3]=l[3];k[4]=l[4];k[5]=l[5];k[6]=+(l[6]+d);k[7]=+(l[7]+e);break;case"V":k[1]=+l[1]+e;break;case"H":k[1]=+l[1]+d;break;case"M":f=+l[1]+d;g=+l[2]+e;default:for(var m=1,n=l[w];m<n;m++)k[m]=+l[m]+(m%2?d:e)}}else for(var o=0,p=l[w];o<p;o++)c[i][o]=l[o];switch(k[0]){case"Z":d=f;e=g;break;case"H":d=k[1];break;case"V":e=k[1];break;case"M":f=c[i][c[i][w]-2];g=c[i][c[i][w]-1];default:d=c[i][c[i][w]-2];e=c[i][c[i][w]-1]}}c[H]=a._path2string;return c},null,bo),br=function(a,b,c,d){return[a,b,c,d,c,d]},bs=function(a,b,c,d,e,f){var g=1/3,h=2/3;return[g*a+h*c,g*b+h*d,g*e+h*c,g*f+h*d,e,f]},bt=function(a,b,c,d,e,f,g,h,i,j){var k=D*120/180,l=D/180*(+e||0),m=[],o,p=bm(function(a,b,c){var d=a*y.cos(c)-b*y.sin(c),e=a*y.sin(c)+b*y.cos(c);return{x:d,y:e}});if(j){G=j[0];H=j[1];E=j[2];F=j[3]}else{o=p(a,b,-l);a=o.x;b=o.y;o=p(h,i,-l);h=o.x;i=o.y;var q=y.cos(D/180*e),r=y.sin(D/180*e),t=(a-h)/2,u=(b-i)/2,x=t*t/(c*c)+u*u/(d*d);if(x>1){x=y.sqrt(x);c=x*c;d=x*d}var z=c*c,A=d*d,C=(f==g?-1:1)*y.sqrt(B((z*A-z*u*u-A*t*t)/(z*u*u+A*t*t))),E=C*c*u/d+(a+h)/2,F=C*-d*t/c+(b+i)/2,G=y.asin(((b-F)/d).toFixed(9)),H=y.asin(((i-F)/d).toFixed(9));G=a<E?D-G:G;H=h<E?D-H:H;G<0&&(G=D*2+G);H<0&&(H=D*2+H);g&&G>H&&(G=G-D*2);!g&&H>G&&(H=H-D*2)}var I=H-G;if(B(I)>k){var J=H,K=h,L=i;H=G+k*(g&&H>G?1:-1);h=E+c*y.cos(H);i=F+d*y.sin(H);m=bt(h,i,c,d,e,0,g,K,L,[H,J,E,F])}I=H-G;var M=y.cos(G),N=y.sin(G),O=y.cos(H),P=y.sin(H),Q=y.tan(I/4),R=4/3*c*Q,S=4/3*d*Q,T=[a,b],U=[a+R*N,b-S*M],V=[h+R*P,i-S*O],W=[h,i];U[0]=2*T[0]-U[0];U[1]=2*T[1]-U[1];{if(j)return[U,V,W][n](m);m=[U,V,W][n](m)[v]()[s](",");var X=[];for(var Y=0,Z=m[w];Y<Z;Y++)X[Y]=Y%2?p(m[Y-1],m[Y],l).y:p(m[Y],m[Y+1],l).x;return X}},bu=function(a,b,c,d,e,f,g,h,i){var j=1-i;return{x:C(j,3)*a+C(j,2)*3*i*c+j*3*i*i*e+C(i,3)*g,y:C(j,3)*b+C(j,2)*3*i*d+j*3*i*i*f+C(i,3)*h}},bv=bm(function(a,b,c,d,e,f,g,h){var i=e-2*c+a-(g-2*e+c),j=2*(c-a)-2*(e-c),k=a-c,l=(-j+y.sqrt(j*j-4*i*k))/2/i,n=(-j-y.sqrt(j*j-4*i*k))/2/i,o=[b,h],p=[a,g],q;B(l)>"1e12"&&(l=0.5);B(n)>"1e12"&&(n=0.5);if(l>0&&l<1){q=bu(a,b,c,d,e,f,g,h,l);p[L](q.x);o[L](q.y)}if(n>0&&n<1){q=bu(a,b,c,d,e,f,g,h,n);p[L](q.x);o[L](q.y)}i=f-2*d+b-(h-2*f+d);j=2*(d-b)-2*(f-d);k=b-d;l=(-j+y.sqrt(j*j-4*i*k))/2/i;n=(-j-y.sqrt(j*j-4*i*k))/2/i;B(l)>"1e12"&&(l=0.5);B(n)>"1e12"&&(n=0.5);if(l>0&&l<1){q=bu(a,b,c,d,e,f,g,h,l);p[L](q.x);o[L](q.y)}if(n>0&&n<1){q=bu(a,b,c,d,e,f,g,h,n);p[L](q.x);o[L](q.y)}return{min:{x:A[m](0,p),y:A[m](0,o)},max:{x:z[m](0,p),y:z[m](0,o)}}}),bw=bm(function(a,b){var c=bq(a),d=b&&bq(b),e={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},f={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},g=function(a,b){var c,d;if(!a)return["C",b.x,b.y,b.x,b.y,b.x,b.y];!(a[0]in{T:1,Q:1})&&(b.qx=b.qy=null);switch(a[0]){case"M":b.X=a[1];b.Y=a[2];break;case"A":a=["C"][n](bt[m](0,[b.x,b.y][n](a.slice(1))));break;case"S":c=b.x+(b.x-(b.bx||b.x));d=b.y+(b.y-(b.by||b.y));a=["C",c,d][n](a.slice(1));break;case"T":b.qx=b.x+(b.x-(b.qx||b.x));b.qy=b.y+(b.y-(b.qy||b.y));a=["C"][n](bs(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1];b.qy=a[2];a=["C"][n](bs(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"][n](br(b.x,b.y,a[1],a[2]));break;case"H":a=["C"][n](br(b.x,b.y,a[1],b.y));break;case"V":a=["C"][n](br(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"][n](br(b.x,b.y,b.X,b.Y));break}return a},h=function(a,b){if(a[b][w]>7){a[b].shift();var e=a[b];while(e[w])a.splice(b++,0,["C"][n](e.splice(0,6)));a.splice(b,1);k=z(c[w],d&&d[w]||0)}},i=function(a,b,e,f,g){if(a&&b&&a[g][0]=="M"&&b[g][0]!="M"){b.splice(g,0,["M",f.x,f.y]);e.bx=0;e.by=0;e.x=a[g][1];e.y=a[g][2];k=z(c[w],d&&d[w]||0)}};for(var j=0,k=z(c[w],d&&d[w]||0);j<k;j++){c[j]=g(c[j],e);h(c,j);d&&(d[j]=g(d[j],f));d&&h(d,j);i(c,d,e,f,j);i(d,c,f,e,j);var l=c[j],o=d&&d[j],p=l[w],q=d&&o[w];e.x=l[p-2];e.y=l[p-1];e.bx=S(l[p-4])||e.x;e.by=S(l[p-3])||e.y;f.bx=d&&(S(o[q-4])||f.x);f.by=d&&(S(o[q-3])||f.y);f.x=d&&o[q-2];f.y=d&&o[q-1]}return d?[c,d]:c},null,bo),bx=bm(function(b){var c=[];for(var d=0,e=b[w];d<e;d++){var f={},g=b[d].match(/^([^:]*):?([\d\.]*)/);f.color=a.getRGB(g[1]);if(f.color.error)return null;f.color=f.color.hex;g[2]&&(f.offset=g[2]+"%");c[L](f)}for(d=1,e=c[w]-1;d<e;d++){if(!c[d].offset){var h=S(c[d-1].offset||0),i=0;for(var j=d+1;j<e;j++){if(c[j].offset){i=c[j].offset;break}}if(!i){i=100;j=e}i=S(i);var k=(i-h)/(j-d+1);for(;d<j;d++){h+=k;c[d].offset=h+"%"}}}return c}),by=function(b,c,d,e){var f;if(a.is(b,F)||a.is(b,"object")){f=a.is(b,F)?g.getElementById(b):b;if(f.tagName)return c==null?{container:f,width:f.style.pixelWidth||f.offsetWidth,height:f.style.pixelHeight||f.offsetHeight}:{container:f,width:c,height:d}}else return{container:1,x:b,y:c,width:d,height:e}},bz=function(a,b){var c=this;for(var d in b){if(b[f](d)&&!(d in a))switch(typeof b[d]){case"function":(function(b){a[d]=a===c?b:function(){return b[m](c,arguments)}})(b[d]);break;case"object":a[d]=a[d]||{};bz.call(this,a[d],b[d]);break;default:a[d]=b[d];break}}},bA=function(a,b){a==b.top&&(b.top=a.prev);a==b.bottom&&(b.bottom=a.next);a.next&&(a.next.prev=a.prev);a.prev&&(a.prev.next=a.next)},bB=function(a,b){if(b.top===a)return;bA(a,b);a.next=null;a.prev=b.top;b.top.next=a;b.top=a},bC=function(a,b){if(b.bottom===a)return;bA(a,b);a.next=b.bottom;a.prev=null;b.bottom.prev=a;b.bottom=a},bD=function(a,b,c){bA(a,c);b==c.top&&(c.top=a);b.next&&(b.next.prev=a);a.next=b.next;a.prev=b;b.next=a},bE=function(a,b,c){bA(a,c);b==c.bottom&&(c.bottom=a);b.prev&&(b.prev.next=a);a.prev=b.prev;b.prev=a;a.next=b},bF=function(a){return function(){throw new Error("Raphaël: you are calling to method “"+a+"” of removed object")}};a.pathToRelative=bp;if(a.svg){k.svgns="http://www.w3.org/2000/svg";k.xlink="http://www.w3.org/1999/xlink";Q=function(a){return+a+(~(~a)===a)*0.5};var bG=function(a,b){if(b)for(var c in b)b[f](c)&&a[R](c,r(b[c]));else{a=g.createElementNS(k.svgns,a);a.style.webkitTapHighlightColor="rgba(0,0,0,0)";return a}};a[H]=function(){return"Your browser supports SVG.\nYou are running Raphaël "+this.version};var bH=function(a,b){var c=bG("path");b.canvas&&b.canvas[l](c);var d=new bN(c,b);d.type="path";bK(d,{fill:"none",stroke:"#000",path:a});return d},bI=function(a,b,c){var d="linear",e=0.5,f=0.5,h=a.style;b=r(b)[Y](bd,function(a,b,c){d="radial";if(b&&c){e=S(b);f=S(c);var g=(f>0.5)*2-1;C(e-0.5,2)+C(f-0.5,2)>0.25&&(f=y.sqrt(0.25-C(e-0.5,2))*g+0.5)&&f!=0.5&&(f=f.toFixed(5)-0.00001*g)}return p});b=b[s](/\s*\-\s*/);if(d=="linear"){var i=b.shift();i=-S(i);if(isNaN(i))return null;var j=[0,0,y.cos(i*D/180),y.sin(i*D/180)],k=1/(z(B(j[2]),B(j[3]))||1);j[2]*=k;j[3]*=k;if(j[2]<0){j[0]=-j[2];j[2]=0}if(j[3]<0){j[1]=-j[3];j[3]=0}}var m=bx(b);if(!m)return null;var n=a.getAttribute(I);n=n.match(/^url\(#(.*)\)$/);n&&c.defs.removeChild(g.getElementById(n[1]));var o=bG(d+"Gradient");o.id=bh();bG(o,d=="radial"?{fx:e,fy:f}:{x1:j[0],y1:j[1],x2:j[2],y2:j[3]});c.defs[l](o);for(var q=0,t=m[w];q<t;q++){var u=bG("stop");bG(u,{offset:m[q].offset?m[q].offset:q?"100%":"0%","stop-color":m[q].color||"#fff"});o[l](u)}bG(a,{fill:"url(#"+o.id+")",opacity:1,"fill-opacity":1});h.fill=p;h.opacity=1;h.fillOpacity=1;return 1},bJ=function(b){var c=b.getBBox();bG(b.pattern,{patternTransform:a.format("translate({0},{1})",c.x,c.y)})},bK=function(c,d){var e={"":[0],none:[0],"-":[3,1],".":[1,1],"-.":[3,1,1,1],"-..":[3,1,1,1,1,1],". ":[1,3],"- ":[4,3],"--":[8,3],"- .":[4,3,1,3],"--.":[8,3,1,3],"--..":[8,3,1,3,1,3]},h=c.node,i=c.attrs,j=c.rotate(),k=function(a,b){b=e[x.call(b)];if(b){var c=a.attrs["stroke-width"]||"1",f=({round:c,square:c,butt:0})[a.attrs["stroke-linecap"]||d["stroke-linecap"]]||0,g=[],i=b[w];while(i--)g[i]=b[i]*c+(i%2?1:-1)*f;bG(h,{"stroke-dasharray":g[v](",")})}};d[f]("rotation")&&(j=d.rotation);var m=r(j)[s](b);if(m.length-1){m[1]=+m[1];m[2]=+m[2]}else m=null;S(j)&&c.rotate(0,true);for(var n in d){if(d[f](n)){if(!W[f](n))continue;var o=d[n];i[n]=o;switch(n){case"blur":c.blur(o);break;case"rotation":c.rotate(o,true);break;case"href":case"title":case"target":var t=h.parentNode;if(x.call(t.tagName)!="a"){var u=bG("a");t.insertBefore(u,h);u[l](h);t=u}n=="target"&&o=="blank"?t.setAttributeNS(c.paper.xlink,"show","new"):t.setAttributeNS(c.paper.xlink,n,o);break;case"cursor":h.style.cursor=o;break;case"clip-rect":var y=r(o)[s](b);if(y[w]==4){c.clip&&c.clip.parentNode.parentNode.removeChild(c.clip.parentNode);var z=bG("clipPath"),A=bG("rect");z.id=bh();bG(A,{x:y[0],y:y[1],width:y[2],height:y[3]});z[l](A);c.paper.defs[l](z);bG(h,{"clip-path":"url(#"+z.id+")"});c.clip=A}if(!o){var B=g.getElementById(h.getAttribute("clip-path")[Y](/(^url\(#|\)$)/g,p));B&&B.parentNode.removeChild(B);bG(h,{"clip-path":p});delete c.clip}break;case"path":c.type=="path"&&bG(h,{d:o?i.path=bq(o):"M0,0"});break;case"width":h[R](n,o);if(i.fx){n="x";o=i.x}else break;case"x":i.fx&&(o=-i.x-(i.width||0));case"rx":if(n=="rx"&&c.type=="rect")break;case"cx":m&&(n=="x"||n=="cx")&&(m[1]+=o-i[n]);h[R](n,o);c.pattern&&bJ(c);break;case"height":h[R](n,o);if(i.fy){n="y";o=i.y}else break;case"y":i.fy&&(o=-i.y-(i.height||0));case"ry":if(n=="ry"&&c.type=="rect")break;case"cy":m&&(n=="y"||n=="cy")&&(m[2]+=o-i[n]);h[R](n,o);c.pattern&&bJ(c);break;case"r":c.type=="rect"?bG(h,{rx:o,ry:o}):h[R](n,o);break;case"src":c.type=="image"&&h.setAttributeNS(c.paper.xlink,"href",o);break;case"stroke-width":h.style.strokeWidth=o;h[R](n,o);i["stroke-dasharray"]&&k(c,i["stroke-dasharray"]);break;case"stroke-dasharray":k(c,o);break;case"translation":var C=r(o)[s](b);C[0]=+C[0]||0;C[1]=+C[1]||0;if(m){m[1]+=C[0];m[2]+=C[1]}cz.call(c,C[0],C[1]);break;case"scale":C=r(o)[s](b);c.scale(+C[0]||1,+C[1]||+C[0]||1,isNaN(S(C[2]))?null:+C[2],isNaN(S(C[3]))?null:+C[3]);break;case I:var D=r(o).match(M);if(D){z=bG("pattern");var E=bG("image");z.id=bh();bG(z,{x:0,y:0,patternUnits:"userSpaceOnUse",height:1,width:1});bG(E,{x:0,y:0});E.setAttributeNS(c.paper.xlink,"href",D[1]);z[l](E);var F=g.createElement("img");F.style.cssText="position:absolute;left:-9999em;top-9999em";F.onload=function(){bG(z,{width:this.offsetWidth,height:this.offsetHeight});bG(E,{width:this.offsetWidth,height:this.offsetHeight});g.body.removeChild(this);c.paper.safari()};g.body[l](F);F.src=D[1];c.paper.defs[l](z);h.style.fill="url(#"+z.id+")";bG(h,{fill:"url(#"+z.id+")"});c.pattern=z;c.pattern&&bJ(c);break}var G=a.getRGB(o);if(G.error)if((({circle:1,ellipse:1})[f](c.type)||r(o).charAt()!="r")&&bI(h,o,c.paper)){i.gradient=o;i.fill="none";break}else{delete d.gradient;delete i.gradient;!a.is(i.opacity,"undefined")&&a.is(d.opacity,"undefined")&&bG(h,{opacity:i.opacity});!a.is(i["fill-opacity"],"undefined")&&a.is(d["fill-opacity"],"undefined")&&bG(h,{"fill-opacity":i["fill-opacity"]})}G[f]("opacity")&&bG(h,{"fill-opacity":G.opacity>1?G.opacity/100:G.opacity});case"stroke":G=a.getRGB(o);h[R](n,G.hex);n=="stroke"&&G[f]("opacity")&&bG(h,{"stroke-opacity":G.opacity>1?G.opacity/100:G.opacity});break;case"gradient":(({circle:1,ellipse:1})[f](c.type)||r(o).charAt()!="r")&&bI(h,o,c.paper);break;case"opacity":i.gradient&&!i[f]("stroke-opacity")&&bG(h,{"stroke-opacity":o>1?o/100:o});case"fill-opacity":if(i.gradient){var H=g.getElementById(h.getAttribute(I)[Y](/^url\(#|\)$/g,p));if(H){var J=H.getElementsByTagName("stop");J[J[w]-1][R]("stop-opacity",o)}break}default:n=="font-size"&&(o=T(o,10)+"px");var K=n[Y](/(\-.)/g,function(a){return V.call(a.substring(1))});h.style[K]=o;h[R](n,o);break}}}bM(c,d);m?c.rotate(m.join(q)):S(j)&&c.rotate(j,true)},bL=1.2,bM=function(b,c){if(b.type!="text"||!(c[f]("text")||c[f]("font")||c[f]("font-size")||c[f]("x")||c[f]("y")))return;var d=b.attrs,e=b.node,h=e.firstChild?T(g.defaultView.getComputedStyle(e.firstChild,p).getPropertyValue("font-size"),10):10;if(c[f]("text")){d.text=c.text;while(e.firstChild)e.removeChild(e.firstChild);var i=r(c.text)[s]("\n");for(var j=0,k=i[w];j<k;j++)if(i[j]){var m=bG("tspan");j&&bG(m,{dy:h*bL,x:d.x});m[l](g.createTextNode(i[j]));e[l](m)}}else{i=e.getElementsByTagName("tspan");for(j=0,k=i[w];j<k;j++)j&&bG(i[j],{dy:h*bL,x:d.x})}bG(e,{y:d.y});var n=b.getBBox(),o=d.y-(n.y+n.height/2);o&&a.is(o,"finite")&&bG(e,{y:d.y+o})},bN=function(b,c){var d=0,e=0;this[0]=b;this.id=a._oid++;this.node=b;b.raphael=this;this.paper=c;this.attrs=this.attrs||{};this.transformations=[];this._={tx:0,ty:0,rt:{deg:0,cx:0,cy:0},sx:1,sy:1};!c.bottom&&(c.bottom=this);this.prev=c.top;c.top&&(c.top.next=this);c.top=this;this.next=null},bO=bN[e];bN[e].rotate=function(c,d,e){if(this.removed)return this;if(c==null){if(this._.rt.cx)return[this._.rt.deg,this._.rt.cx,this._.rt.cy][v](q);return this._.rt.deg}var f=this.getBBox();c=r(c)[s](b);if(c[w]-1){d=S(c[1]);e=S(c[2])}c=S(c[0]);d!=null&&d!==false?this._.rt.deg=c:this._.rt.deg+=c;e==null&&(d=null);this._.rt.cx=d;this._.rt.cy=e;d=d==null?f.x+f.width/2:d;e=e==null?f.y+f.height/2:e;if(this._.rt.deg){this.transformations[0]=a.format("rotate({0} {1} {2})",this._.rt.deg,d,e);this.clip&&bG(this.clip,{transform:a.format("rotate({0} {1} {2})",-this._.rt.deg,d,e)})}else{this.transformations[0]=p;this.clip&&bG(this.clip,{transform:p})}bG(this.node,{transform:this.transformations[v](q)});return this};bN[e].hide=function(){!this.removed&&(this.node.style.display="none");return this};bN[e].show=function(){!this.removed&&(this.node.style.display="");return this};bN[e].remove=function(){if(this.removed)return;bA(this,this.paper);this.node.parentNode.removeChild(this.node);for(var a in this)delete this[a];this.removed=true};bN[e].getBBox=function(){if(this.removed)return this;if(this.type=="path")return bn(this.attrs.path);if(this.node.style.display=="none"){this.show();var a=true}var b={};try{b=this.node.getBBox()}catch(a){}finally{b=b||{}}if(this.type=="text"){b={x:b.x,y:Infinity,width:0,height:0};for(var c=0,d=this.node.getNumberOfChars();c<d;c++){var e=this.node.getExtentOfChar(c);e.y<b.y&&(b.y=e.y);e.y+e.height-b.y>b.height&&(b.height=e.y+e.height-b.y);e.x+e.width-b.x>b.width&&(b.width=e.x+e.width-b.x)}}a&&this.hide();return b};bN[e].attr=function(b,c){if(this.removed)return this;if(b==null){var d={};for(var e in this.attrs)this.attrs[f](e)&&(d[e]=this.attrs[e]);this._.rt.deg&&(d.rotation=this.rotate());(this._.sx!=1||this._.sy!=1)&&(d.scale=this.scale());d.gradient&&d.fill=="none"&&(d.fill=d.gradient)&&delete d.gradient;return d}if(c==null&&a.is(b,F)){if(b=="translation")return cz.call(this);if(b=="rotation")return this.rotate();if(b=="scale")return this.scale();if(b==I&&this.attrs.fill=="none"&&this.attrs.gradient)return this.attrs.gradient;return this.attrs[b]}if(c==null&&a.is(b,G)){var g={};for(var h=0,i=b.length;h<i;h++)g[b[h]]=this.attr(b[h]);return g}if(c!=null){var j={};j[b]=c}else b!=null&&a.is(b,"object")&&(j=b);for(var k in this.paper.customAttributes)if(this.paper.customAttributes[f](k)&&j[f](k)&&a.is(this.paper.customAttributes[k],"function")){var l=this.paper.customAttributes[k].apply(this,[][n](j[k]));this.attrs[k]=j[k];for(var m in l)l[f](m)&&(j[m]=l[m])}bK(this,j);return this};bN[e].toFront=function(){if(this.removed)return this;this.node.parentNode[l](this.node);var a=this.paper;a.top!=this&&bB(this,a);return this};bN[e].toBack=function(){if(this.removed)return this;if(this.node.parentNode.firstChild!=this.node){this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild);bC(this,this.paper);var a=this.paper}return this};bN[e].insertAfter=function(a){if(this.removed)return this;var b=a.node||a[a.length-1].node;b.nextSibling?b.parentNode.insertBefore(this.node,b.nextSibling):b.parentNode[l](this.node);bD(this,a,this.paper);return this};bN[e].insertBefore=function(a){if(this.removed)return this;var b=a.node||a[0].node;b.parentNode.insertBefore(this.node,b);bE(this,a,this.paper);return this};bN[e].blur=function(a){var b=this;if(+a!==0){var c=bG("filter"),d=bG("feGaussianBlur");b.attrs.blur=a;c.id=bh();bG(d,{stdDeviation:+a||1.5});c.appendChild(d);b.paper.defs.appendChild(c);b._blur=c;bG(b.node,{filter:"url(#"+c.id+")"})}else{if(b._blur){b._blur.parentNode.removeChild(b._blur);delete b._blur;delete b.attrs.blur}b.node.removeAttribute("filter")}};var bP=function(a,b,c,d){var e=bG("circle");a.canvas&&a.canvas[l](e);var f=new bN(e,a);f.attrs={cx:b,cy:c,r:d,fill:"none",stroke:"#000"};f.type="circle";bG(e,f.attrs);return f},bQ=function(a,b,c,d,e,f){var g=bG("rect");a.canvas&&a.canvas[l](g);var h=new bN(g,a);h.attrs={x:b,y:c,width:d,height:e,r:f||0,rx:f||0,ry:f||0,fill:"none",stroke:"#000"};h.type="rect";bG(g,h.attrs);return h},bR=function(a,b,c,d,e){var f=bG("ellipse");a.canvas&&a.canvas[l](f);var g=new bN(f,a);g.attrs={cx:b,cy:c,rx:d,ry:e,fill:"none",stroke:"#000"};g.type="ellipse";bG(f,g.attrs);return g},bS=function(a,b,c,d,e,f){var g=bG("image");bG(g,{x:c,y:d,width:e,height:f,preserveAspectRatio:"none"});g.setAttributeNS(a.xlink,"href",b);a.canvas&&a.canvas[l](g);var h=new bN(g,a);h.attrs={x:c,y:d,width:e,height:f,src:b};h.type="image";return h},bT=function(a,b,c,d){var e=bG("text");bG(e,{x:b,y:c,"text-anchor":"middle"});a.canvas&&a.canvas[l](e);var f=new bN(e,a);f.attrs={x:b,y:c,"text-anchor":"middle",text:d,font:W.font,stroke:"none",fill:"#000"};f.type="text";bK(f,f.attrs);return f},bU=function(a,b){this.width=a||this.width;this.height=b||this.height;this.canvas[R]("width",this.width);this.canvas[R]("height",this.height);return this},bV=function(){var b=by[m](0,arguments),c=b&&b.container,d=b.x,e=b.y,f=b.width,h=b.height;if(!c)throw new Error("SVG container not found.");var i=bG("svg");d=d||0;e=e||0;f=f||512;h=h||342;bG(i,{xmlns:"http://www.w3.org/2000/svg",version:1.1,width:f,height:h});if(c==1){i.style.cssText="position:absolute;left:"+d+"px;top:"+e+"px";g.body[l](i)}else c.firstChild?c.insertBefore(i,c.firstChild):c[l](i);c=new j;c.width=f;c.height=h;c.canvas=i;bz.call(c,c,a.fn);c.clear();return c};k.clear=function(){var a=this.canvas;while(a.firstChild)a.removeChild(a.firstChild);this.bottom=this.top=null;(this.desc=bG("desc"))[l](g.createTextNode("Created with Raphaël"));a[l](this.desc);a[l](this.defs=bG("defs"))};k.remove=function(){this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);for(var a in this)this[a]=bF(a)}}if(a.vml){var bW={M:"m",L:"l",C:"c",Z:"x",m:"t",l:"r",c:"v",z:"x"},bX=/([clmz]),?([^clmz]*)/gi,bY=/ progid:\S+Blur\([^\)]+\)/g,bZ=/-?[^,\s-]+/g,b$=1000+q+1000,b_=10,ca={path:1,rect:1},cb=function(a){var b=/[ahqstv]/ig,c=bq;r(a).match(b)&&(c=bw);b=/[clmz]/g;if(c==bq&&!r(a).match(b)){var d=r(a)[Y](bX,function(a,b,c){var d=[],e=x.call(b)=="m",f=bW[b];c[Y](bZ,function(a){if(e&&d[w]==2){f+=d+bW[b=="m"?"l":"L"];d=[]}d[L](Q(a*b_))});return f+d});return d}var e=c(a),f,g;d=[];for(var h=0,i=e[w];h<i;h++){f=e[h];g=x.call(e[h][0]);g=="z"&&(g="x");for(var j=1,k=f[w];j<k;j++)g+=Q(f[j]*b_)+(j!=k-1?",":p);d[L](g)}return d[v](q)};a[H]=function(){return"Your browser doesn’t support SVG. Falling down to VML.\nYou are running Raphaël "+this.version};bH=function(a,b){var c=cd("group");c.style.cssText="position:absolute;left:0;top:0;width:"+b.width+"px;height:"+b.height+"px";c.coordsize=b.coordsize;c.coordorigin=b.coordorigin;var d=cd("shape"),e=d.style;e.width=b.width+"px";e.height=b.height+"px";d.coordsize=b$;d.coordorigin=b.coordorigin;c[l](d);var f=new bN(d,c,b),g={fill:"none",stroke:"#000"};a&&(g.path=a);f.type="path";f.path=[];f.Path=p;bK(f,g);b.canvas[l](c);return f};bK=function(c,d){c.attrs=c.attrs||{};var e=c.node,h=c.attrs,i=e.style,j,k=(d.x!=h.x||d.y!=h.y||d.width!=h.width||d.height!=h.height||d.r!=h.r)&&c.type=="rect",m=c;for(var n in d)d[f](n)&&(h[n]=d[n]);if(k){h.path=cc(h.x,h.y,h.width,h.height,h.r);c.X=h.x;c.Y=h.y;c.W=h.width;c.H=h.height}d.href&&(e.href=d.href);d.title&&(e.title=d.title);d.target&&(e.target=d.target);d.cursor&&(i.cursor=d.cursor);"blur"in d&&c.blur(d.blur);if(d.path&&c.type=="path"||k)e.path=cb(h.path);d.rotation!=null&&c.rotate(d.rotation,true);if(d.translation){j=r(d.translation)[s](b);cz.call(c,j[0],j[1]);if(c._.rt.cx!=null){c._.rt.cx+=+j[0];c._.rt.cy+=+j[1];c.setBox(c.attrs,j[0],j[1])}}if(d.scale){j=r(d.scale)[s](b);c.scale(+j[0]||1,+j[1]||+j[0]||1,+j[2]||null,+j[3]||null)}if("clip-rect"in d){var o=r(d["clip-rect"])[s](b);if(o[w]==4){o[2]=+o[2]+ +o[0];o[3]=+o[3]+ +o[1];var q=e.clipRect||g.createElement("div"),t=q.style,u=e.parentNode;t.clip=a.format("rect({1}px {2}px {3}px {0}px)",o);if(!e.clipRect){t.position="absolute";t.top=0;t.left=0;t.width=c.paper.width+"px";t.height=c.paper.height+"px";u.parentNode.insertBefore(q,u);q[l](u);e.clipRect=q}}d["clip-rect"]||e.clipRect&&(e.clipRect.style.clip=p)}c.type=="image"&&d.src&&(e.src=d.src);if(c.type=="image"&&d.opacity){e.filterOpacity=U+".Alpha(opacity="+d.opacity*100+")";i.filter=(e.filterMatrix||p)+(e.filterOpacity||p)}d.font&&(i.font=d.font);d["font-family"]&&(i.fontFamily="\""+d["font-family"][s](",")[0][Y](/^['"]+|['"]+$/g,p)+"\"");d["font-size"]&&(i.fontSize=d["font-size"]);d["font-weight"]&&(i.fontWeight=d["font-weight"]);d["font-style"]&&(i.fontStyle=d["font-style"]);if(d.opacity!=null||d["stroke-width"]!=null||d.fill!=null||d.stroke!=null||d["stroke-width"]!=null||d["stroke-opacity"]!=null||d["fill-opacity"]!=null||d["stroke-dasharray"]!=null||d["stroke-miterlimit"]!=null||d["stroke-linejoin"]!=null||d["stroke-linecap"]!=null){e=c.shape||e;var v=e.getElementsByTagName(I)&&e.getElementsByTagName(I)[0],x=false;!v&&(x=v=cd(I));if("fill-opacity"in d||"opacity"in d){var y=((+h["fill-opacity"]+1||2)-1)*((+h.opacity+1||2)-1)*((+a.getRGB(d.fill).o+1||2)-1);y=A(z(y,0),1);v.opacity=y}d.fill&&(v.on=true);if(v.on==null||d.fill=="none")v.on=false;if(v.on&&d.fill){var B=d.fill.match(M);if(B){v.src=B[1];v.type="tile"}else{v.color=a.getRGB(d.fill).hex;v.src=p;v.type="solid";if(a.getRGB(d.fill).error&&(m.type in{circle:1,ellipse:1}||r(d.fill).charAt()!="r")&&bI(m,d.fill)){h.fill="none";h.gradient=d.fill}}}x&&e[l](v);var C=e.getElementsByTagName("stroke")&&e.getElementsByTagName("stroke")[0],D=false;!C&&(D=C=cd("stroke"));if(d.stroke&&d.stroke!="none"||d["stroke-width"]||d["stroke-opacity"]!=null||d["stroke-dasharray"]||d["stroke-miterlimit"]||d["stroke-linejoin"]||d["stroke-linecap"])C.on=true;(d.stroke=="none"||C.on==null||d.stroke==0||d["stroke-width"]==0)&&(C.on=false);var E=a.getRGB(d.stroke);C.on&&d.stroke&&(C.color=E.hex);y=((+h["stroke-opacity"]+1||2)-1)*((+h.opacity+1||2)-1)*((+E.o+1||2)-1);var F=(S(d["stroke-width"])||1)*0.75;y=A(z(y,0),1);d["stroke-width"]==null&&(F=h["stroke-width"]);d["stroke-width"]&&(C.weight=F);F&&F<1&&(y*=F)&&(C.weight=1);C.opacity=y;d["stroke-linejoin"]&&(C.joinstyle=d["stroke-linejoin"]||"miter");C.miterlimit=d["stroke-miterlimit"]||8;d["stroke-linecap"]&&(C.endcap=d["stroke-linecap"]=="butt"?"flat":d["stroke-linecap"]=="square"?"square":"round");if(d["stroke-dasharray"]){var G={"-":"shortdash",".":"shortdot","-.":"shortdashdot","-..":"shortdashdotdot",". ":"dot","- ":"dash","--":"longdash","- .":"dashdot","--.":"longdashdot","--..":"longdashdotdot"};C.dashstyle=G[f](d["stroke-dasharray"])?G[d["stroke-dasharray"]]:p}D&&e[l](C)}if(m.type=="text"){i=m.paper.span.style;h.font&&(i.font=h.font);h["font-family"]&&(i.fontFamily=h["font-family"]);h["font-size"]&&(i.fontSize=h["font-size"]);h["font-weight"]&&(i.fontWeight=h["font-weight"]);h["font-style"]&&(i.fontStyle=h["font-style"]);m.node.string&&(m.paper.span.innerHTML=r(m.node.string)[Y](/</g,"<")[Y](/&/g,"&")[Y](/\n/g,"<br>"));m.W=h.w=m.paper.span.offsetWidth;m.H=h.h=m.paper.span.offsetHeight;m.X=h.x;m.Y=h.y+Q(m.H/2);switch(h["text-anchor"]){case"start":m.node.style["v-text-align"]="left";m.bbx=Q(m.W/2);break;case"end":m.node.style["v-text-align"]="right";m.bbx=-Q(m.W/2);break;default:m.node.style["v-text-align"]="center";break}}};bI=function(a,b){a.attrs=a.attrs||{};var c=a.attrs,d,e="linear",f=".5 .5";a.attrs.gradient=b;b=r(b)[Y](bd,function(a,b,c){e="radial";if(b&&c){b=S(b);c=S(c);C(b-0.5,2)+C(c-0.5,2)>0.25&&(c=y.sqrt(0.25-C(b-0.5,2))*((c>0.5)*2-1)+0.5);f=b+q+c}return p});b=b[s](/\s*\-\s*/);if(e=="linear"){var g=b.shift();g=-S(g);if(isNaN(g))return null}var h=bx(b);if(!h)return null;a=a.shape||a.node;d=a.getElementsByTagName(I)[0]||cd(I);!d.parentNode&&a.appendChild(d);if(h[w]){d.on=true;d.method="none";d.color=h[0].color;d.color2=h[h[w]-1].color;var i=[];for(var j=0,k=h[w];j<k;j++)h[j].offset&&i[L](h[j].offset+q+h[j].color);d.colors&&(d.colors.value=i[w]?i[v]():"0% "+d.color);if(e=="radial"){d.type="gradientradial";d.focus="100%";d.focussize=f;d.focusposition=f}else{d.type="gradient";d.angle=(270-g)%360}}return 1};bN=function(b,c,d){var e=0,f=0,g=0,h=1;this[0]=b;this.id=a._oid++;this.node=b;b.raphael=this;this.X=0;this.Y=0;this.attrs={};this.Group=c;this.paper=d;this._={tx:0,ty:0,rt:{deg:0},sx:1,sy:1};!d.bottom&&(d.bottom=this);this.prev=d.top;d.top&&(d.top.next=this);d.top=this;this.next=null};bO=bN[e];bO.rotate=function(a,c,d){if(this.removed)return this;if(a==null){if(this._.rt.cx)return[this._.rt.deg,this._.rt.cx,this._.rt.cy][v](q);return this._.rt.deg}a=r(a)[s](b);if(a[w]-1){c=S(a[1]);d=S(a[2])}a=S(a[0]);c!=null?this._.rt.deg=a:this._.rt.deg+=a;d==null&&(c=null);this._.rt.cx=c;this._.rt.cy=d;this.setBox(this.attrs,c,d);this.Group.style.rotation=this._.rt.deg;return this};bO.setBox=function(a,b,c){if(this.removed)return this;var d=this.Group.style,e=this.shape&&this.shape.style||this.node.style;a=a||{};for(var g in a)a[f](g)&&(this.attrs[g]=a[g]);b=b||this._.rt.cx;c=c||this._.rt.cy;var h=this.attrs,i,j,k,l;switch(this.type){case"circle":i=h.cx-h.r;j=h.cy-h.r;k=l=h.r*2;break;case"ellipse":i=h.cx-h.rx;j=h.cy-h.ry;k=h.rx*2;l=h.ry*2;break;case"image":i=+h.x;j=+h.y;k=h.width||0;l=h.height||0;break;case"text":this.textpath.v=["m",Q(h.x),", ",Q(h.y-2),"l",Q(h.x)+1,", ",Q(h.y-2)][v](p);i=h.x-Q(this.W/2);j=h.y-this.H/2;k=this.W;l=this.H;break;case"rect":case"path":if(this.attrs.path){var m=bn(this.attrs.path);i=m.x;j=m.y;k=m.width;l=m.height}else{i=0;j=0;k=this.paper.width;l=this.paper.height}break;default:i=0;j=0;k=this.paper.width;l=this.paper.height;break}b=b==null?i+k/2:b;c=c==null?j+l/2:c;var n=b-this.paper.width/2,o=c-this.paper.height/2,q;d.left!=(q=n+"px")&&(d.left=q);d.top!=(q=o+"px")&&(d.top=q);this.X=ca[f](this.type)?-n:i;this.Y=ca[f](this.type)?-o:j;this.W=k;this.H=l;if(ca[f](this.type)){e.left!=(q=-n*b_+"px")&&(e.left=q);e.top!=(q=-o*b_+"px")&&(e.top=q)}else if(this.type=="text"){e.left!=(q=-n+"px")&&(e.left=q);e.top!=(q=-o+"px")&&(e.top=q)}else{d.width!=(q=this.paper.width+"px")&&(d.width=q);d.height!=(q=this.paper.height+"px")&&(d.height=q);e.left!=(q=i-n+"px")&&(e.left=q);e.top!=(q=j-o+"px")&&(e.top=q);e.width!=(q=k+"px")&&(e.width=q);e.height!=(q=l+"px")&&(e.height=q)}};bO.hide=function(){!this.removed&&(this.Group.style.display="none");return this};bO.show=function(){!this.removed&&(this.Group.style.display="block");return this};bO.getBBox=function(){if(this.removed)return this;if(ca[f](this.type))return bn(this.attrs.path);return{x:this.X+(this.bbx||0),y:this.Y,width:this.W,height:this.H}};bO.remove=function(){if(this.removed)return;bA(this,this.paper);this.node.parentNode.removeChild(this.node);this.Group.parentNode.removeChild(this.Group);this.shape&&this.shape.parentNode.removeChild(this.shape);for(var a in this)delete this[a];this.removed=true};bO.attr=function(b,c){if(this.removed)return this;if(b==null){var d={};for(var e in this.attrs)this.attrs[f](e)&&(d[e]=this.attrs[e]);this._.rt.deg&&(d.rotation=this.rotate());(this._.sx!=1||this._.sy!=1)&&(d.scale=this.scale());d.gradient&&d.fill=="none"&&(d.fill=d.gradient)&&delete d.gradient;return d}if(c==null&&a.is(b,"string")){if(b=="translation")return cz.call(this);if(b=="rotation")return this.rotate();if(b=="scale")return this.scale();if(b==I&&this.attrs.fill=="none"&&this.attrs.gradient)return this.attrs.gradient;return this.attrs[b]}if(this.attrs&&c==null&&a.is(b,G)){var g,h={};for(e=0,g=b[w];e<g;e++)h[b[e]]=this.attr(b[e]);return h}var i;if(c!=null){i={};i[b]=c}c==null&&a.is(b,"object")&&(i=b);if(i){for(var j in this.paper.customAttributes)if(this.paper.customAttributes[f](j)&&i[f](j)&&a.is(this.paper.customAttributes[j],"function")){var k=this.paper.customAttributes[j].apply(this,[][n](i[j]));this.attrs[j]=i[j];for(var l in k)k[f](l)&&(i[l]=k[l])}i.text&&this.type=="text"&&(this.node.string=i.text);bK(this,i);i.gradient&&(({circle:1,ellipse:1})[f](this.type)||r(i.gradient).charAt()!="r")&&bI(this,i.gradient);(!ca[f](this.type)||this._.rt.deg)&&this.setBox(this.attrs)}return this};bO.toFront=function(){!this.removed&&this.Group.parentNode[l](this.Group);this.paper.top!=this&&bB(this,this.paper);return this};bO.toBack=function(){if(this.removed)return this;if(this.Group.parentNode.firstChild!=this.Group){this.Group.parentNode.insertBefore(this.Group,this.Group.parentNode.firstChild);bC(this,this.paper)}return this};bO.insertAfter=function(a){if(this.removed)return this;a.constructor==cC&&(a=a[a.length-1]);a.Group.nextSibling?a.Group.parentNode.insertBefore(this.Group,a.Group.nextSibling):a.Group.parentNode[l](this.Group);bD(this,a,this.paper);return this};bO.insertBefore=function(a){if(this.removed)return this;a.constructor==cC&&(a=a[0]);a.Group.parentNode.insertBefore(this.Group,a.Group);bE(this,a,this.paper);return this};bO.blur=function(b){var c=this.node.runtimeStyle,d=c.filter;d=d.replace(bY,p);if(+b!==0){this.attrs.blur=b;c.filter=d+q+U+".Blur(pixelradius="+(+b||1.5)+")";c.margin=a.format("-{0}px 0 0 -{0}px",Q(+b||1.5))}else{c.filter=d;c.margin=0;delete this.attrs.blur}};bP=function(a,b,c,d){var e=cd("group"),f=cd("oval"),g=f.style;e.style.cssText="position:absolute;left:0;top:0;width:"+a.width+"px;height:"+a.height+"px";e.coordsize=b$;e.coordorigin=a.coordorigin;e[l](f);var h=new bN(f,e,a);h.type="circle";bK(h,{stroke:"#000",fill:"none"});h.attrs.cx=b;h.attrs.cy=c;h.attrs.r=d;h.setBox({x:b-d,y:c-d,width:d*2,height:d*2});a.canvas[l](e);return h};function cc(b,c,d,e,f){return f?a.format("M{0},{1}l{2},0a{3},{3},0,0,1,{3},{3}l0,{5}a{3},{3},0,0,1,{4},{3}l{6},0a{3},{3},0,0,1,{4},{4}l0,{7}a{3},{3},0,0,1,{3},{4}z",b+f,c,d-f*2,f,-f,e-f*2,f*2-d,f*2-e):a.format("M{0},{1}l{2},0,0,{3},{4},0z",b,c,d,e,-d)}bQ=function(a,b,c,d,e,f){var g=cc(b,c,d,e,f),h=a.path(g),i=h.attrs;h.X=i.x=b;h.Y=i.y=c;h.W=i.width=d;h.H=i.height=e;i.r=f;i.path=g;h.type="rect";return h};bR=function(a,b,c,d,e){var f=cd("group"),g=cd("oval"),h=g.style;f.style.cssText="position:absolute;left:0;top:0;width:"+a.width+"px;height:"+a.height+"px";f.coordsize=b$;f.coordorigin=a.coordorigin;f[l](g);var i=new bN(g,f,a);i.type="ellipse";bK(i,{stroke:"#000"});i.attrs.cx=b;i.attrs.cy=c;i.attrs.rx=d;i.attrs.ry=e;i.setBox({x:b-d,y:c-e,width:d*2,height:e*2});a.canvas[l](f);return i};bS=function(a,b,c,d,e,f){var g=cd("group"),h=cd("image");g.style.cssText="position:absolute;left:0;top:0;width:"+a.width+"px;height:"+a.height+"px";g.coordsize=b$;g.coordorigin=a.coordorigin;h.src=b;g[l](h);var i=new bN(h,g,a);i.type="image";i.attrs.src=b;i.attrs.x=c;i.attrs.y=d;i.attrs.w=e;i.attrs.h=f;i.setBox({x:c,y:d,width:e,height:f});a.canvas[l](g);return i};bT=function(b,c,d,e){var f=cd("group"),g=cd("shape"),h=g.style,i=cd("path"),j=i.style,k=cd("textpath");f.style.cssText="position:absolute;left:0;top:0;width:"+b.width+"px;height:"+b.height+"px";f.coordsize=b$;f.coordorigin=b.coordorigin;i.v=a.format("m{0},{1}l{2},{1}",Q(c*10),Q(d*10),Q(c*10)+1);i.textpathok=true;h.width=b.width;h.height=b.height;k.string=r(e);k.on=true;g[l](k);g[l](i);f[l](g);var m=new bN(k,f,b);m.shape=g;m.textpath=i;m.type="text";m.attrs.text=e;m.attrs.x=c;m.attrs.y=d;m.attrs.w=1;m.attrs.h=1;bK(m,{font:W.font,stroke:"none",fill:"#000"});m.setBox();b.canvas[l](f);return m};bU=function(a,b){var c=this.canvas.style;a==+a&&(a+="px");b==+b&&(b+="px");c.width=a;c.height=b;c.clip="rect(0 "+a+" "+b+" 0)";return this};var cd;g.createStyleSheet().addRule(".rvml","behavior:url(#default#VML)");try{!g.namespaces.rvml&&g.namespaces.add("rvml","urn:schemas-microsoft-com:vml");cd=function(a){return g.createElement("<rvml:"+a+" class=\"rvml\">")}}catch(a){cd=function(a){return g.createElement("<"+a+" xmlns=\"urn:schemas-microsoft.com:vml\" class=\"rvml\">")}}bV=function(){var b=by[m](0,arguments),c=b.container,d=b.height,e,f=b.width,h=b.x,i=b.y;if(!c)throw new Error("VML container not found.");var k=new j,n=k.canvas=g.createElement("div"),o=n.style;h=h||0;i=i||0;f=f||512;d=d||342;f==+f&&(f+="px");d==+d&&(d+="px");k.width=1000;k.height=1000;k.coordsize=b_*1000+q+b_*1000;k.coordorigin="0 0";k.span=g.createElement("span");k.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";n[l](k.span);o.cssText=a.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",f,d);if(c==1){g.body[l](n);o.left=h+"px";o.top=i+"px";o.position="absolute"}else c.firstChild?c.insertBefore(n,c.firstChild):c[l](n);bz.call(k,k,a.fn);return k};k.clear=function(){this.canvas.innerHTML=p;this.span=g.createElement("span");this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";this.canvas[l](this.span);this.bottom=this.top=null};k.remove=function(){this.canvas.parentNode.removeChild(this.canvas);for(var a in this)this[a]=bF(a);return true}}var ce=navigator.userAgent.match(/Version\\x2f(.*?)\s/);navigator.vendor=="Apple Computer, Inc."&&(ce&&ce[1]<4||navigator.platform.slice(0,2)=="iP")?k.safari=function(){var a=this.rect(-99,-99,this.width+99,this.height+99).attr({stroke:"none"});h.setTimeout(function(){a.remove()})}:k.safari=function(){};var cf=function(){this.returnValue=false},cg=function(){return this.originalEvent.preventDefault()},ch=function(){this.cancelBubble=true},ci=function(){return this.originalEvent.stopPropagation()},cj=(function(){{if(g.addEventListener)return function(a,b,c,d){var e=o&&u[b]?u[b]:b,g=function(e){if(o&&u[f](b))for(var g=0,h=e.targetTouches&&e.targetTouches.length;g<h;g++){if(e.targetTouches[g].target==a){var i=e;e=e.targetTouches[g];e.originalEvent=i;e.preventDefault=cg;e.stopPropagation=ci;break}}return c.call(d,e)};a.addEventListener(e,g,false);return function(){a.removeEventListener(e,g,false);return true}};if(g.attachEvent)return function(a,b,c,d){var e=function(a){a=a||h.event;a.preventDefault=a.preventDefault||cf;a.stopPropagation=a.stopPropagation||ch;return c.call(d,a)};a.attachEvent("on"+b,e);var f=function(){a.detachEvent("on"+b,e);return true};return f}}})(),ck=[],cl=function(a){var b=a.clientX,c=a.clientY,d=g.documentElement.scrollTop||g.body.scrollTop,e=g.documentElement.scrollLeft||g.body.scrollLeft,f,h=ck.length;while(h--){f=ck[h];if(o){var i=a.touches.length,j;while(i--){j=a.touches[i];if(j.identifier==f.el._drag.id){b=j.clientX;c=j.clientY;(a.originalEvent?a.originalEvent:a).preventDefault();break}}}else a.preventDefault();b+=e;c+=d;f.move&&f.move.call(f.move_scope||f.el,b-f.el._drag.x,c-f.el._drag.y,b,c,a)}},cm=function(b){a.unmousemove(cl).unmouseup(cm);var c=ck.length,d;while(c--){d=ck[c];d.el._drag={};d.end&&d.end.call(d.end_scope||d.start_scope||d.move_scope||d.el,b)}ck=[]};for(var cn=t[w];cn--;)(function(b){a[b]=bN[e][b]=function(c,d){if(a.is(c,"function")){this.events=this.events||[];this.events.push({name:b,f:c,unbind:cj(this.shape||this.node||g,b,c,d||this)})}return this};a["un"+b]=bN[e]["un"+b]=function(a){var c=this.events,d=c[w];while(d--)if(c[d].name==b&&c[d].f==a){c[d].unbind();c.splice(d,1);!c.length&&delete this.events;return this}return this}})(t[cn]);bO.hover=function(a,b,c,d){return this.mouseover(a,c).mouseout(b,d||c)};bO.unhover=function(a,b){return this.unmouseover(a).unmouseout(b)};bO.drag=function(b,c,d,e,f,h){this._drag={};this.mousedown(function(i){(i.originalEvent||i).preventDefault();var j=g.documentElement.scrollTop||g.body.scrollTop,k=g.documentElement.scrollLeft||g.body.scrollLeft;this._drag.x=i.clientX+k;this._drag.y=i.clientY+j;this._drag.id=i.identifier;c&&c.call(f||e||this,i.clientX+k,i.clientY+j,i);!ck.length&&a.mousemove(cl).mouseup(cm);ck.push({el:this,move:b,end:d,move_scope:e,start_scope:f,end_scope:h})});return this};bO.undrag=function(b,c,d){var e=ck.length;while(e--)ck[e].el==this&&(ck[e].move==b&&ck[e].end==d)&&ck.splice(e++,1);!ck.length&&a.unmousemove(cl).unmouseup(cm)};k.circle=function(a,b,c){return bP(this,a||0,b||0,c||0)};k.rect=function(a,b,c,d,e){return bQ(this,a||0,b||0,c||0,d||0,e||0)};k.ellipse=function(a,b,c,d){return bR(this,a||0,b||0,c||0,d||0)};k.path=function(b){b&&!a.is(b,F)&&!a.is(b[0],G)&&(b+=p);return bH(a.format[m](a,arguments),this)};k.image=function(a,b,c,d,e){return bS(this,a||"about:blank",b||0,c||0,d||0,e||0)};k.text=function(a,b,c){return bT(this,a||0,b||0,r(c))};k.set=function(a){arguments[w]>1&&(a=Array[e].splice.call(arguments,0,arguments[w]));return new cC(a)};k.setSize=bU;k.top=k.bottom=null;k.raphael=a;function co(){return this.x+q+this.y}bO.resetScale=function(){if(this.removed)return this;this._.sx=1;this._.sy=1;this.attrs.scale="1 1"};bO.scale=function(a,b,c,d){if(this.removed)return this;if(a==null&&b==null)return{x:this._.sx,y:this._.sy,toString:co};b=b||a;!(+b)&&(b=a);var e,f,g,h,i=this.attrs;if(a!=0){var j=this.getBBox(),k=j.x+j.width/2,l=j.y+j.height/2,m=B(a/this._.sx),o=B(b/this._.sy);c=+c||c==0?c:k;d=+d||d==0?d:l;var r=this._.sx>0,s=this._.sy>0,t=~(~(a/B(a))),u=~(~(b/B(b))),x=m*t,y=o*u,z=this.node.style,A=c+B(k-c)*x*(k>c==r?1:-1),C=d+B(l-d)*y*(l>d==s?1:-1),D=a*t>b*u?o:m;switch(this.type){case"rect":case"image":var E=i.width*m,F=i.height*o;this.attr({height:F,r:i.r*D,width:E,x:A-E/2,y:C-F/2});break;case"circle":case"ellipse":this.attr({rx:i.rx*m,ry:i.ry*o,r:i.r*D,cx:A,cy:C});break;case"text":this.attr({x:A,y:C});break;case"path":var G=bp(i.path),H=true,I=r?x:m,J=s?y:o;for(var K=0,L=G[w];K<L;K++){var M=G[K],N=V.call(M[0]);{if(N=="M"&&H)continue;H=false}if(N=="A"){M[G[K][w]-2]*=I;M[G[K][w]-1]*=J;M[1]*=m;M[2]*=o;M[5]=+(t+u?!(!(+M[5])):!(+M[5]))}else if(N=="H")for(var O=1,P=M[w];O<P;O++)M[O]*=I;else if(N=="V")for(O=1,P=M[w];O<P;O++)M[O]*=J;else for(O=1,P=M[w];O<P;O++)M[O]*=O%2?I:J}var Q=bn(G);e=A-Q.x-Q.width/2;f=C-Q.y-Q.height/2;G[0][1]+=e;G[0][2]+=f;this.attr({path:G});break}if(this.type in{text:1,image:1}&&(t!=1||u!=1))if(this.transformations){this.transformations[2]="scale("[n](t,",",u,")");this.node[R]("transform",this.transformations[v](q));e=t==-1?-i.x-(E||0):i.x;f=u==-1?-i.y-(F||0):i.y;this.attr({x:e,y:f});i.fx=t-1;i.fy=u-1}else{this.node.filterMatrix=U+".Matrix(M11="[n](t,", M12=0, M21=0, M22=",u,", Dx=0, Dy=0, sizingmethod='auto expand', filtertype='bilinear')");z.filter=(this.node.filterMatrix||p)+(this.node.filterOpacity||p)}else if(this.transformations){this.transformations[2]=p;this.node[R]("transform",this.transformations[v](q));i.fx=0;i.fy=0}else{this.node.filterMatrix=p;z.filter=(this.node.filterMatrix||p)+(this.node.filterOpacity||p)}i.scale=[a,b,c,d][v](q);this._.sx=a;this._.sy=b}return this};bO.clone=function(){if(this.removed)return null;var a=this.attr();delete a.scale;delete a.translation;return this.paper[this.type]().attr(a)};var cp={},cq=function(b,c,d,e,f,g,h,i,j){var k=0,l=100,m=[b,c,d,e,f,g,h,i].join(),n=cp[m],o,p;!n&&(cp[m]=n={data:[]});n.timer&&clearTimeout(n.timer);n.timer=setTimeout(function(){delete cp[m]},2000);if(j!=null){var q=cq(b,c,d,e,f,g,h,i);l=~(~q)*10}for(var r=0;r<l+1;r++){if(n.data[j]>r)p=n.data[r*l];else{p=a.findDotsAtSegment(b,c,d,e,f,g,h,i,r/l);n.data[r]=p}r&&(k+=C(C(o.x-p.x,2)+C(o.y-p.y,2),0.5));if(j!=null&&k>=j)return p;o=p}if(j==null)return k},cr=function(b,c){return function(d,e,f){d=bw(d);var g,h,i,j,k="",l={},m,n=0;for(var o=0,p=d.length;o<p;o++){i=d[o];if(i[0]=="M"){g=+i[1];h=+i[2]}else{j=cq(g,h,i[1],i[2],i[3],i[4],i[5],i[6]);if(n+j>e){if(c&&!l.start){m=cq(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n);k+=["C",m.start.x,m.start.y,m.m.x,m.m.y,m.x,m.y];if(f)return k;l.start=k;k=["M",m.x,m.y+"C",m.n.x,m.n.y,m.end.x,m.end.y,i[5],i[6]][v]();n+=j;g=+i[5];h=+i[6];continue}if(!b&&!c){m=cq(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n);return{x:m.x,y:m.y,alpha:m.alpha}}}n+=j;g=+i[5];h=+i[6]}k+=i}l.end=k;m=b?n:c?l:a.findDotsAtSegment(g,h,i[1],i[2],i[3],i[4],i[5],i[6],1);m.alpha&&(m={x:m.x,y:m.y,alpha:m.alpha});return m}},cs=cr(1),ct=cr(),cu=cr(0,1);bO.getTotalLength=function(){if(this.type!="path")return;if(this.node.getTotalLength)return this.node.getTotalLength();return cs(this.attrs.path)};bO.getPointAtLength=function(a){if(this.type!="path")return;return ct(this.attrs.path,a)};bO.getSubpath=function(a,b){if(this.type!="path")return;if(B(this.getTotalLength()-b)<"1e-6")return cu(this.attrs.path,a).end;var c=cu(this.attrs.path,b,1);return a?cu(c,a).end:c};a.easing_formulas={linear:function(a){return a},"<":function(a){return C(a,3)},">":function(a){return C(a-1,3)+1},"<>":function(a){a=a*2;if(a<1)return C(a,3)/2;a-=2;return(C(a,3)+2)/2},backIn:function(a){var b=1.70158;return a*a*((b+1)*a-b)},backOut:function(a){a=a-1;var b=1.70158;return a*a*((b+1)*a+b)+1},elastic:function(a){if(a==0||a==1)return a;var b=0.3,c=b/4;return C(2,-10*a)*y.sin((a-c)*(2*D)/b)+1},bounce:function(a){var b=7.5625,c=2.75,d;if(a<1/c)d=b*a*a;else if(a<2/c){a-=1.5/c;d=b*a*a+0.75}else if(a<2.5/c){a-=2.25/c;d=b*a*a+0.9375}else{a-=2.625/c;d=b*a*a+0.984375}return d}};var cv=[],cw=function(){var b=+(new Date);for(var c=0;c<cv[w];c++){var d=cv[c];if(d.stop||d.el.removed)continue;var e=b-d.start,g=d.ms,h=d.easing,i=d.from,j=d.diff,k=d.to,l=d.t,m=d.el,n={},o;if(e<g){var r=h(e/g);for(var s in i)if(i[f](s)){switch(X[s]){case"along":o=r*g*j[s];k.back&&(o=k.len-o);var t=ct(k[s],o);m.translate(j.sx-j.x||0,j.sy-j.y||0);j.x=t.x;j.y=t.y;m.translate(t.x-j.sx,t.y-j.sy);k.rot&&m.rotate(j.r+t.alpha,t.x,t.y);break;case E:o=+i[s]+r*g*j[s];break;case"colour":o="rgb("+[cy(Q(i[s].r+r*g*j[s].r)),cy(Q(i[s].g+r*g*j[s].g)),cy(Q(i[s].b+r*g*j[s].b))][v](",")+")";break;case"path":o=[];for(var u=0,x=i[s][w];u<x;u++){o[u]=[i[s][u][0]];for(var y=1,z=i[s][u][w];y<z;y++)o[u][y]=+i[s][u][y]+r*g*j[s][u][y];o[u]=o[u][v](q)}o=o[v](q);break;case"csv":switch(s){case"translation":var A=r*g*j[s][0]-l.x,B=r*g*j[s][1]-l.y;l.x+=A;l.y+=B;o=A+q+B;break;case"rotation":o=+i[s][0]+r*g*j[s][0];i[s][1]&&(o+=","+i[s][1]+","+i[s][2]);break;case"scale":o=[+i[s][0]+r*g*j[s][0],+i[s][1]+r*g*j[s][1],2 in k[s]?k[s][2]:p,3 in k[s]?k[s][3]:p][v](q);break;case"clip-rect":o=[];u=4;while(u--)o[u]=+i[s][u]+r*g*j[s][u];break}break;default:var C=[].concat(i[s]);o=[];u=m.paper.customAttributes[s].length;while(u--)o[u]=+C[u]+r*g*j[s][u];break}n[s]=o}m.attr(n);m._run&&m._run.call(m)}else{if(k.along){t=ct(k.along,k.len*!k.back);m.translate(j.sx-(j.x||0)+t.x-j.sx,j.sy-(j.y||0)+t.y-j.sy);k.rot&&m.rotate(j.r+t.alpha,t.x,t.y)}(l.x||l.y)&&m.translate(-l.x,-l.y);k.scale&&(k.scale+=p);m.attr(k);cv.splice(c--,1)}}a.svg&&m&&m.paper&&m.paper.safari();cv[w]&&setTimeout(cw)},cx=function(b,c,d,e,f){var g=d-e;c.timeouts.push(setTimeout(function(){a.is(f,"function")&&f.call(c);c.animate(b,g,b.easing)},e))},cy=function(a){return z(A(a,255),0)},cz=function(a,b){if(a==null)return{x:this._.tx,y:this._.ty,toString:co};this._.tx+=+a;this._.ty+=+b;switch(this.type){case"circle":case"ellipse":this.attr({cx:+a+this.attrs.cx,cy:+b+this.attrs.cy});break;case"rect":case"image":case"text":this.attr({x:+a+this.attrs.x,y:+b+this.attrs.y});break;case"path":var c=bp(this.attrs.path);c[0][1]+=+a;c[0][2]+=+b;this.attr({path:c});break}return this};bO.animateWith=function(a,b,c,d,e){for(var f=0,g=cv.length;f<g;f++)cv[f].el.id==a.id&&(b.start=cv[f].start);return this.animate(b,c,d,e)};bO.animateAlong=cA();bO.animateAlongBack=cA(1);function cA(b){return function(c,d,e,f){var g={back:b};a.is(e,"function")?f=e:g.rot=e;c&&c.constructor==bN&&(c=c.attrs.path);c&&(g.along=c);return this.animate(g,d,f)}}function cB(a,b,c,d,e,f){var g=3*b,h=3*(d-b)-g,i=1-g-h,j=3*c,k=3*(e-c)-j,l=1-j-k;function m(a){return((i*a+h)*a+g)*a}function n(a,b){var c=o(a,b);return((l*c+k)*c+j)*c}function o(a,b){var c,d,e,f,j,k;for(e=a,k=0;k<8;k++){f=m(e)-a;if(B(f)<b)return e;j=(3*i*e+2*h)*e+g;if(B(j)<0.000001)break;e=e-f/j}c=0;d=1;e=a;if(e<c)return c;if(e>d)return d;while(c<d){f=m(e);if(B(f-a)<b)return e;a>f?c=e:d=e;e=(d-c)/2+c}return e}return n(a,1/(200*f))}bO.onAnimation=function(a){this._run=a||0;return this};bO.animate=function(c,d,e,g){var h=this;h.timeouts=h.timeouts||[];if(a.is(e,"function")||!e)g=e||null;if(h.removed){g&&g.call(h);return h}var i={},j={},k=false,l={};for(var m in c)if(c[f](m)){if(X[f](m)||h.paper.customAttributes[f](m)){k=true;i[m]=h.attr(m);i[m]==null&&(i[m]=W[m]);j[m]=c[m];switch(X[m]){case"along":var n=cs(c[m]),o=ct(c[m],n*!(!c.back)),p=h.getBBox();l[m]=n/d;l.tx=p.x;l.ty=p.y;l.sx=o.x;l.sy=o.y;j.rot=c.rot;j.back=c.back;j.len=n;c.rot&&(l.r=S(h.rotate())||0);break;case E:l[m]=(j[m]-i[m])/d;break;case"colour":i[m]=a.getRGB(i[m]);var q=a.getRGB(j[m]);l[m]={r:(q.r-i[m].r)/d,g:(q.g-i[m].g)/d,b:(q.b-i[m].b)/d};break;case"path":var t=bw(i[m],j[m]);i[m]=t[0];var u=t[1];l[m]=[];for(var v=0,x=i[m][w];v<x;v++){l[m][v]=[0];for(var y=1,z=i[m][v][w];y<z;y++)l[m][v][y]=(u[v][y]-i[m][v][y])/d}break;case"csv":var A=r(c[m])[s](b),B=r(i[m])[s](b);switch(m){case"translation":i[m]=[0,0];l[m]=[A[0]/d,A[1]/d];break;case"rotation":i[m]=B[1]==A[1]&&B[2]==A[2]?B:[0,A[1],A[2]];l[m]=[(A[0]-i[m][0])/d,0,0];break;case"scale":c[m]=A;i[m]=r(i[m])[s](b);l[m]=[(A[0]-i[m][0])/d,(A[1]-i[m][1])/d,0,0];break;case"clip-rect":i[m]=r(i[m])[s](b);l[m]=[];v=4;while(v--)l[m][v]=(A[v]-i[m][v])/d;break}j[m]=A;break;default:A=[].concat(c[m]);B=[].concat(i[m]);l[m]=[];v=h.paper.customAttributes[m][w];while(v--)l[m][v]=((A[v]||0)-(B[v]||0))/d;break}}}if(k){var G=a.easing_formulas[e];if(!G){G=r(e).match(P);if(G&&G[w]==5){var H=G;G=function(a){return cB(a,+H[1],+H[2],+H[3],+H[4],d)}}else G=function(a){return a}}cv.push({start:c.start||+(new Date),ms:d,easing:G,from:i,diff:l,to:j,el:h,t:{x:0,y:0}});a.is(g,"function")&&(h._ac=setTimeout(function(){g.call(h)},d));cv[w]==1&&setTimeout(cw)}else{var C=[],D;for(var F in c)if(c[f](F)&&Z.test(F)){m={value:c[F]};F=="from"&&(F=0);F=="to"&&(F=100);m.key=T(F,10);C.push(m)}C.sort(be);C[0].key&&C.unshift({key:0,value:h.attrs});for(v=0,x=C[w];v<x;v++)cx(C[v].value,h,d/100*C[v].key,d/100*(C[v-1]&&C[v-1].key||0),C[v-1]&&C[v-1].value.callback);D=C[C[w]-1].value.callback;D&&h.timeouts.push(setTimeout(function(){D.call(h)},d))}return this};bO.stop=function(){for(var a=0;a<cv.length;a++)cv[a].el.id==this.id&&cv.splice(a--,1);for(a=0,ii=this.timeouts&&this.timeouts.length;a<ii;a++)clearTimeout(this.timeouts[a]);this.timeouts=[];clearTimeout(this._ac);delete this._ac;return this};bO.translate=function(a,b){return this.attr({translation:a+" "+b})};bO[H]=function(){return"Raphaël’s object"};a.ae=cv;var cC=function(a){this.items=[];this[w]=0;this.type="set";if(a)for(var b=0,c=a[w];b<c;b++){if(a[b]&&(a[b].constructor==bN||a[b].constructor==cC)){this[this.items[w]]=this.items[this.items[w]]=a[b];this[w]++}}};cC[e][L]=function(){var a,b;for(var c=0,d=arguments[w];c<d;c++){a=arguments[c];if(a&&(a.constructor==bN||a.constructor==cC)){b=this.items[w];this[b]=this.items[b]=a;this[w]++}}return this};cC[e].pop=function(){delete this[this[w]--];return this.items.pop()};for(var cD in bO)bO[f](cD)&&(cC[e][cD]=(function(a){return function(){for(var b=0,c=this.items[w];b<c;b++)this.items[b][a][m](this.items[b],arguments);return this}})(cD));cC[e].attr=function(b,c){if(b&&a.is(b,G)&&a.is(b[0],"object"))for(var d=0,e=b[w];d<e;d++)this.items[d].attr(b[d]);else for(var f=0,g=this.items[w];f<g;f++)this.items[f].attr(b,c);return this};cC[e].animate=function(b,c,d,e){(a.is(d,"function")||!d)&&(e=d||null);var f=this.items[w],g=f,h,i=this,j;e&&(j=function(){!(--f)&&e.call(i)});d=a.is(d,F)?d:j;h=this.items[--g].animate(b,c,d,j);while(g--)this.items[g]&&!this.items[g].removed&&this.items[g].animateWith(h,b,c,d,j);return this};cC[e].insertAfter=function(a){var b=this.items[w];while(b--)this.items[b].insertAfter(a);return this};cC[e].getBBox=function(){var a=[],b=[],c=[],d=[];for(var e=this.items[w];e--;){var f=this.items[e].getBBox();a[L](f.x);b[L](f.y);c[L](f.x+f.width);d[L](f.y+f.height)}a=A[m](0,a);b=A[m](0,b);return{x:a,y:b,width:z[m](0,c)-a,height:z[m](0,d)-b}};cC[e].clone=function(a){a=new cC;for(var b=0,c=this.items[w];b<c;b++)a[L](this.items[b].clone());return a};a.registerFont=function(a){if(!a.face)return a;this.fonts=this.fonts||{};var b={w:a.w,face:{},glyphs:{}},c=a.face["font-family"];for(var d in a.face)a.face[f](d)&&(b.face[d]=a.face[d]);this.fonts[c]?this.fonts[c][L](b):this.fonts[c]=[b];if(!a.svg){b.face["units-per-em"]=T(a.face["units-per-em"],10);for(var e in a.glyphs)if(a.glyphs[f](e)){var g=a.glyphs[e];b.glyphs[e]={w:g.w,k:{},d:g.d&&"M"+g.d[Y](/[mlcxtrv]/g,function(a){return({l:"L",c:"C",x:"z",t:"m",r:"l",v:"c"})[a]||"M"})+"z"};if(g.k)for(var h in g.k)g[f](h)&&(b.glyphs[e].k[h]=g.k[h])}}return a};k.getFont=function(b,c,d,e){e=e||"normal";d=d||"normal";c=+c||({normal:400,bold:700,lighter:300,bolder:800})[c]||400;if(!a.fonts)return;var g=a.fonts[b];if(!g){var h=new RegExp("(^|\\s)"+b[Y](/[^\w\d\s+!~.:_-]/g,p)+"(\\s|$)","i");for(var i in a.fonts)if(a.fonts[f](i)){if(h.test(i)){g=a.fonts[i];break}}}var j;if(g)for(var k=0,l=g[w];k<l;k++){j=g[k];if(j.face["font-weight"]==c&&(j.face["font-style"]==d||!j.face["font-style"])&&j.face["font-stretch"]==e)break}return j};k.print=function(c,d,e,f,g,h,i){h=h||"middle";i=z(A(i||0,1),-1);var j=this.set(),k=r(e)[s](p),l=0,m=p,n;a.is(f,e)&&(f=this.getFont(f));if(f){n=(g||16)/f.face["units-per-em"];var o=f.face.bbox.split(b),q=+o[0],t=+o[1]+(h=="baseline"?o[3]-o[1]+ +f.face.descent:(o[3]-o[1])/2);for(var u=0,v=k[w];u<v;u++){var x=u&&f.glyphs[k[u-1]]||{},y=f.glyphs[k[u]];l+=u?(x.w||f.w)+(x.k&&x.k[k[u]]||0)+f.w*i:0;y&&y.d&&j[L](this.path(y.d).attr({fill:"#000",stroke:"none",translation:[l,0]}))}j.scale(n,n,q,t).translate(c-q,d-t)}return j};a.format=function(b,c){var e=a.is(c,G)?[0][n](c):arguments;b&&a.is(b,F)&&e[w]-1&&(b=b[Y](d,function(a,b){return e[++b]==null?p:e[b]}));return b||p};a.ninja=function(){i.was?h.Raphael=i.is:delete Raphael;return a};a.el=bO;a.st=cC[e];i.was?h.Raphael=a:Raphael=a})()
\ No newline at end of file
--- /dev/null
+/** @license
+
+
+ SoundManager 2: JavaScript Sound for the Web
+ ----------------------------------------------
+ http://schillmania.com/projects/soundmanager2/
+
+ Copyright (c) 2007, Scott Schiller. All rights reserved.
+ Code provided under the BSD License:
+ http://schillmania.com/projects/soundmanager2/license.txt
+
+ V2.97a.20111030
+*/
+(function(S){function T(T,fa){function k(b){return function(a){return!this._t||!this._t._a?(this._t&&this._t.sID?c._wD(h+"ignoring "+a.type+": "+this._t.sID):c._wD(h+"ignoring "+a.type),null):b.call(this,a)}}this.flashVersion=8;this.debugMode=true;this.debugFlash=false;this.useConsole=true;this.waitForWindowLoad=this.consoleOnly=false;this.bgColor="#ffffff";this.useHighPerformance=false;this.flashPollingInterval=null;this.flashLoadTimeout=1E3;this.wmode=null;this.allowScriptAccess="always";this.useFlashBlock=
+false;this.useHTML5Audio=true;this.html5Test=/^(probably|maybe)$/i;this.preferFlash=true;this.noSWFCache=false;this.audioFormats={mp3:{type:['audio/mpeg; codecs="mp3"',"audio/mpeg","audio/mp3","audio/MPA","audio/mpa-robust"],required:true},mp4:{related:["aac","m4a"],type:['audio/mp4; codecs="mp4a.40.2"',"audio/aac","audio/x-m4a","audio/MP4A-LATM","audio/mpeg4-generic"],required:false},ogg:{type:["audio/ogg; codecs=vorbis"],required:false},wav:{type:['audio/wav; codecs="1"',"audio/wav","audio/wave",
+"audio/x-wav"],required:false}};this.defaultOptions={autoLoad:false,stream:true,autoPlay:false,loops:1,onid3:null,onload:null,whileloading:null,onplay:null,onpause:null,onresume:null,whileplaying:null,onstop:null,onfailure:null,onfinish:null,multiShot:true,multiShotEvents:false,position:null,pan:0,type:null,usePolicyFile:false,volume:100};this.flash9Options={isMovieStar:null,usePeakData:false,useWaveformData:false,useEQData:false,onbufferchange:null,ondataerror:null};this.movieStarOptions={bufferTime:3,
+serverURL:null,onconnect:null,duration:null};this.movieID="sm2-container";this.id=fa||"sm2movie";this.swfCSS={swfBox:"sm2-object-box",swfDefault:"movieContainer",swfError:"swf_error",swfTimedout:"swf_timedout",swfLoaded:"swf_loaded",swfUnblocked:"swf_unblocked",sm2Debug:"sm2_debug",highPerf:"high_performance",flashDebug:"flash_debug"};this.debugID="soundmanager-debug";this.debugURLParam=/([#?&])debug=1/i;this.versionNumber="V2.97a.20111030";this.movieURL=this.version=null;this.url=T||null;this.altURL=
+null;this.enabled=this.swfLoaded=false;this.oMC=this.o=null;this.sounds={};this.soundIDs=[];this.didFlashBlock=this.specialWmodeCase=this.muted=false;this.filePattern=null;this.filePatterns={flash8:/\.mp3(\?.*)?$/i,flash9:/\.mp3(\?.*)?$/i};this.features={buffering:false,peakData:false,waveformData:false,eqData:false,movieStar:false};this.sandbox={type:null,types:{remote:"remote (domain-based) rules",localWithFile:"local with file access (no internet access)",localWithNetwork:"local with network (internet access only, no local access)",
+localTrusted:"local, trusted (local+internet access)"},description:null,noRemote:null,noLocal:null};var J;try{J=typeof Audio!=="undefined"&&typeof(new Audio).canPlayType!=="undefined"}catch(Xa){J=false}this.hasHTML5=J;this.html5={usingFlash:null};this.flash={};this.ignoreFlash=this.html5Only=false;var ya,c=this,h="HTML5::",u,q=navigator.userAgent,i=S,K=i.location.href.toString(),g=document,ga,U,j,y=[],ha=true,r,L=false,M=false,m=false,v=false,ia=false,l,Qa=0,N,s,ja,C,D,V,za,ka,B,W,X,E,la,Y,Z,F,Aa,
+ma,Ra=["log","info","warn","error"],Ba,$,Ca,O=null,na=null,n,oa,G,Da,aa,ba,pa,o,ca=false,qa=false,Ea,Fa,w=null,Ga,da,P,z,ra,sa,Ha,p,Ia=Array.prototype.slice,Q=false,t,ea,Ja,x,Ka,ta=q.match(/(ipad|iphone|ipod)/i),Sa=q.match(/firefox/i),Ta=q.match(/droid/i),A=q.match(/msie/i),Ua=q.match(/webkit/i),R=q.match(/safari/i)&&!q.match(/chrome/i),Va=q.match(/opera/i);J=q.match(/(mobile|pre\/|xoom)/i)||ta;var ua=!K.match(/usehtml5audio/i)&&!K.match(/sm2\-ignorebadua/i)&&R&&q.match(/OS X 10_6_([3-7])/i),va=typeof console!==
+"undefined"&&typeof console.log!=="undefined",wa=typeof g.hasFocus!=="undefined"?g.hasFocus():null,H=R&&typeof g.hasFocus==="undefined",La=!H,Ma=/(mp3|mp4|mpa)/i,I=g.location?g.location.protocol.match(/http/i):null,Na=!I?"http://":"",Oa=/^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|mp4v|3gp|3g2)\s*(?:$|;)/i,Pa="mpeg4,aac,flv,mov,mp4,m4v,f4v,m4a,mp4v,3gp,3g2".split(","),Wa=RegExp("\\.("+Pa.join("|")+")(\\?.*)?$","i");this.mimePattern=/^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i;this.useAltURL=
+!I;this._global_a=null;if(J&&(c.useHTML5Audio=true,c.preferFlash=false,ta))Q=c.ignoreFlash=true;this.supported=this.ok=function(){return w?m&&!v:c.useHTML5Audio&&c.hasHTML5};this.getMovie=function(c){return u(c)||g[c]||i[c]};this.createSound=function(b){function a(){e=aa(e);c.sounds[d.id]=new ya(d);c.soundIDs.push(d.id);return c.sounds[d.id]}var e=null,f=null,d=null;if(!m||!c.ok())return pa("soundManager.createSound(): "+n(!m?"notReady":"notOK")),false;arguments.length===2&&(b={id:arguments[0],url:arguments[1]});
+d=e=s(b);d.id.toString().charAt(0).match(/^[0-9]$/)&&c._wD("soundManager.createSound(): "+n("badID",d.id),2);c._wD("soundManager.createSound(): "+d.id+" ("+d.url+")",1);if(o(d.id,true))return c._wD("soundManager.createSound(): "+d.id+" exists",1),c.sounds[d.id];if(da(d))f=a(),c._wD("Loading sound "+d.id+" via HTML5"),f._setup_html5(d);else{if(j>8){if(d.isMovieStar===null)d.isMovieStar=d.serverURL||(d.type?d.type.match(Oa):false)||d.url.match(Wa);d.isMovieStar&&c._wD("soundManager.createSound(): using MovieStar handling");
+if(d.isMovieStar){if(d.usePeakData)l("noPeak"),d.usePeakData=false;d.loops>1&&l("noNSLoop")}}d=ba(d,"soundManager.createSound(): ");f=a();if(j===8)c.o._createSound(d.id,d.loops||1,d.usePolicyFile);else if(c.o._createSound(d.id,d.url,d.usePeakData,d.useWaveformData,d.useEQData,d.isMovieStar,d.isMovieStar?d.bufferTime:false,d.loops||1,d.serverURL,d.duration||null,d.autoPlay,true,d.autoLoad,d.usePolicyFile),!d.serverURL)f.connected=true,d.onconnect&&d.onconnect.apply(f);!d.serverURL&&(d.autoLoad||d.autoPlay)&&
+f.load(d)}!d.serverURL&&d.autoPlay&&f.play();return f};this.destroySound=function(b,a){if(!o(b))return false;var e=c.sounds[b],f;e._iO={};e.stop();e.unload();for(f=0;f<c.soundIDs.length;f++)if(c.soundIDs[f]===b){c.soundIDs.splice(f,1);break}a||e.destruct(true);delete c.sounds[b];return true};this.load=function(b,a){return!o(b)?false:c.sounds[b].load(a)};this.unload=function(b){return!o(b)?false:c.sounds[b].unload()};this.onposition=function(b,a,e,f){return!o(b)?false:c.sounds[b].onposition(a,e,f)};
+this.start=this.play=function(b,a){if(!m||!c.ok())return pa("soundManager.play(): "+n(!m?"notReady":"notOK")),false;return!o(b)?(a instanceof Object||(a={url:a}),a&&a.url?(c._wD('soundManager.play(): attempting to create "'+b+'"',1),a.id=b,c.createSound(a).play()):false):c.sounds[b].play(a)};this.setPosition=function(b,a){return!o(b)?false:c.sounds[b].setPosition(a)};this.stop=function(b){if(!o(b))return false;c._wD("soundManager.stop("+b+")",1);return c.sounds[b].stop()};this.stopAll=function(){var b;
+c._wD("soundManager.stopAll()",1);for(b in c.sounds)c.sounds.hasOwnProperty(b)&&c.sounds[b].stop()};this.pause=function(b){return!o(b)?false:c.sounds[b].pause()};this.pauseAll=function(){var b;for(b=c.soundIDs.length;b--;)c.sounds[c.soundIDs[b]].pause()};this.resume=function(b){return!o(b)?false:c.sounds[b].resume()};this.resumeAll=function(){var b;for(b=c.soundIDs.length;b--;)c.sounds[c.soundIDs[b]].resume()};this.togglePause=function(b){return!o(b)?false:c.sounds[b].togglePause()};this.setPan=function(b,
+a){return!o(b)?false:c.sounds[b].setPan(a)};this.setVolume=function(b,a){return!o(b)?false:c.sounds[b].setVolume(a)};this.mute=function(b){var a=0;typeof b!=="string"&&(b=null);if(b){if(!o(b))return false;c._wD('soundManager.mute(): Muting "'+b+'"');return c.sounds[b].mute()}else{c._wD("soundManager.mute(): Muting all sounds");for(a=c.soundIDs.length;a--;)c.sounds[c.soundIDs[a]].mute();c.muted=true}return true};this.muteAll=function(){c.mute()};this.unmute=function(b){typeof b!=="string"&&(b=null);
+if(b){if(!o(b))return false;c._wD('soundManager.unmute(): Unmuting "'+b+'"');return c.sounds[b].unmute()}else{c._wD("soundManager.unmute(): Unmuting all sounds");for(b=c.soundIDs.length;b--;)c.sounds[c.soundIDs[b]].unmute();c.muted=false}return true};this.unmuteAll=function(){c.unmute()};this.toggleMute=function(b){return!o(b)?false:c.sounds[b].toggleMute()};this.getMemoryUse=function(){var b=0;c.o&&j!==8&&(b=parseInt(c.o._getMemoryUse(),10));return b};this.disable=function(b){var a;typeof b==="undefined"&&
+(b=false);if(v)return false;v=true;l("shutdown",1);for(a=c.soundIDs.length;a--;)Ba(c.sounds[c.soundIDs[a]]);N(b);p.remove(i,"load",D);return true};this.canPlayMIME=function(b){var a;c.hasHTML5&&(a=P({type:b}));return!w||a?a:b?!!(j>8&&b.match(Oa)||b.match(c.mimePattern)):null};this.canPlayURL=function(b){var a;c.hasHTML5&&(a=P({url:b}));return!w||a?a:b?!!b.match(c.filePattern):null};this.canPlayLink=function(b){return typeof b.type!=="undefined"&&b.type&&c.canPlayMIME(b.type)?true:c.canPlayURL(b.href)};
+this.getSoundById=function(b,a){if(!b)throw Error("soundManager.getSoundById(): sID is null/undefined");var e=c.sounds[b];!e&&!a&&c._wD('"'+b+'" is an invalid sound ID.',2);return e};this.onready=function(b,a){if(b&&b instanceof Function)return m&&c._wD(n("queue","onready")),a||(a=i),ja("onready",b,a),C(),true;else throw n("needFunction","onready");};this.ontimeout=function(b,a){if(b&&b instanceof Function)return m&&c._wD(n("queue","ontimeout")),a||(a=i),ja("ontimeout",b,a),C({type:"ontimeout"}),
+true;else throw n("needFunction","ontimeout");};this._wD=this._writeDebug=function(b,a,e){var f,d;if(!c.debugMode)return false;typeof e!=="undefined"&&e&&(b=b+" | "+(new Date).getTime());if(va&&c.useConsole){e=Ra[a];if(typeof console[e]!=="undefined")console[e](b);else console.log(b);if(c.useConsoleOnly)return true}try{f=u("soundmanager-debug");if(!f)return false;d=g.createElement("div");if(++Qa%2===0)d.className="sm2-alt";a=typeof a==="undefined"?0:parseInt(a,10);d.appendChild(g.createTextNode(b));
+if(a){if(a>=2)d.style.fontWeight="bold";if(a===3)d.style.color="#ff3333"}f.insertBefore(d,f.firstChild)}catch(Ya){}return true};this._debug=function(){var b,a;l("currentObj",1);for(b=0,a=c.soundIDs.length;b<a;b++)c.sounds[c.soundIDs[b]]._debug()};this.reboot=function(){c._wD("soundManager.reboot()");c.soundIDs.length&&c._wD("Destroying "+c.soundIDs.length+" SMSound objects...");var b,a;for(b=c.soundIDs.length;b--;)c.sounds[c.soundIDs[b]].destruct();try{if(A)na=c.o.innerHTML;O=c.o.parentNode.removeChild(c.o);
+c._wD("Flash movie removed.")}catch(e){l("badRemove",2)}na=O=w=null;c.enabled=la=m=ca=qa=L=M=v=c.swfLoaded=false;c.soundIDs=c.sounds=[];c.o=null;for(b in y)if(y.hasOwnProperty(b))for(a=y[b].length;a--;)y[b][a].fired=false;c._wD("soundManager: Rebooting...");i.setTimeout(c.beginDelayedInit,20)};this.getMoviePercent=function(){return c.o&&typeof c.o.PercentLoaded!=="undefined"?c.o.PercentLoaded():null};this.beginDelayedInit=function(){ia=true;E();setTimeout(function(){if(qa)return false;Z();X();return qa=
+true},20);V()};this.destruct=function(){c._wD("soundManager.destruct()");c.disable(true)};ya=function(b){var a=this,e,f,d;this.sID=b.id;this.url=b.url;this._iO=this.instanceOptions=this.options=s(b);this.pan=this.options.pan;this.volume=this.options.volume;this._lastURL=null;this.isHTML5=false;this._a=null;this.id3={};this._debug=function(){if(c.debugMode){var b=null,d=[],e,f;for(b in a.options)a.options[b]!==null&&(a.options[b]instanceof Function?(e=a.options[b].toString(),e=e.replace(/\s\s+/g," "),
+f=e.indexOf("{"),d.push(" "+b+": {"+e.substr(f+1,Math.min(Math.max(e.indexOf("\n")-1,64),64)).replace(/\n/g,"")+"... }")):d.push(" "+b+": "+a.options[b]));c._wD("SMSound() merged options: {\n"+d.join(", \n")+"\n}")}};this._debug();this.load=function(b){var d=null;if(typeof b!=="undefined")a._iO=s(b,a.options),a.instanceOptions=a._iO;else if(b=a.options,a._iO=b,a.instanceOptions=a._iO,a._lastURL&&a._lastURL!==a.url)l("manURL"),a._iO.url=a.url,a.url=null;if(!a._iO.url)a._iO.url=a.url;c._wD("SMSound.load(): "+
+a._iO.url,1);if(a._iO.url===a.url&&a.readyState!==0&&a.readyState!==2)return l("onURL",1),a;a._lastURL=a.url;a.loaded=false;a.readyState=1;a.playState=0;if(da(a._iO))d=a._setup_html5(a._iO),d._called_load?c._wD(h+"ignoring request to load again: "+a.sID):(c._wD(h+"load: "+a.sID),a._html5_canplay=false,d.load(),d._called_load=true,a._iO.autoPlay&&a.play());else try{a.isHTML5=false,a._iO=ba(aa(a._iO)),j===8?c.o._load(a.sID,a._iO.url,a._iO.stream,a._iO.autoPlay,a._iO.whileloading?1:0,a._iO.loops||1,
+a._iO.usePolicyFile):c.o._load(a.sID,a._iO.url,!!a._iO.stream,!!a._iO.autoPlay,a._iO.loops||1,!!a._iO.autoLoad,a._iO.usePolicyFile)}catch(e){l("smError",2),r("onload",false),F({type:"SMSOUND_LOAD_JS_EXCEPTION",fatal:true})}return a};this.unload=function(){a.readyState!==0&&(c._wD('SMSound.unload(): "'+a.sID+'"'),a.isHTML5?(f(),a._a&&(a._a.pause(),ra(a._a))):j===8?c.o._unload(a.sID,"about:blank"):c.o._unload(a.sID),e());return a};this.destruct=function(b){c._wD('SMSound.destruct(): "'+a.sID+'"');if(a.isHTML5){if(f(),
+a._a)a._a.pause(),ra(a._a),Q||a._remove_html5_events(),a._a._t=null,a._a=null}else a._iO.onfailure=null,c.o._destroySound(a.sID);b||c.destroySound(a.sID,true)};this.start=this.play=function(b,e){var f,e=e===void 0?true:e;b||(b={});a._iO=s(b,a._iO);a._iO=s(a._iO,a.options);a.instanceOptions=a._iO;if(a._iO.serverURL&&!a.connected)return a.getAutoPlay()||(c._wD("SMSound.play(): Netstream not connected yet - setting autoPlay"),a.setAutoPlay(true)),a;da(a._iO)&&(a._setup_html5(a._iO),d());if(a.playState===
+1&&!a.paused)if(f=a._iO.multiShot)c._wD('SMSound.play(): "'+a.sID+'" already playing (multi-shot)',1);else return c._wD('SMSound.play(): "'+a.sID+'" already playing (one-shot)',1),a;if(a.loaded)c._wD('SMSound.play(): "'+a.sID+'"');else if(a.readyState===0){c._wD('SMSound.play(): Attempting to load "'+a.sID+'"',1);if(!a.isHTML5)a._iO.autoPlay=true;a.load(a._iO)}else if(a.readyState===2)return c._wD('SMSound.play(): Could not load "'+a.sID+'" - exiting',2),a;else c._wD('SMSound.play(): "'+a.sID+'" is loading - attempting to play..',
+1);if(!a.isHTML5&&j===9&&a.position>0&&a.position===a.duration)c._wD('SMSound.play(): "'+a.sID+'": Sound at end, resetting to position:0'),a._iO.position=0;if(a.paused&&a.position&&a.position>0)c._wD('SMSound.play(): "'+a.sID+'" is resuming from paused state',1),a.resume();else{c._wD('SMSound.play(): "'+a.sID+'" is starting to play');a.playState=1;a.paused=false;(!a.instanceCount||a._iO.multiShotEvents||!a.isHTML5&&j>8&&!a.getAutoPlay())&&a.instanceCount++;a.position=typeof a._iO.position!=="undefined"&&
+!isNaN(a._iO.position)?a._iO.position:0;if(!a.isHTML5)a._iO=ba(aa(a._iO));if(a._iO.onplay&&e)a._iO.onplay.apply(a),a._onplay_called=true;a.setVolume(a._iO.volume,true);a.setPan(a._iO.pan,true);a.isHTML5?(d(),f=a._setup_html5(),a.setPosition(a._iO.position),f.play()):c.o._start(a.sID,a._iO.loops||1,j===9?a._iO.position:a._iO.position/1E3)}return a};this.stop=function(b){if(a.playState===1){a._onbufferchange(0);a.resetOnPosition(0);a.paused=false;if(!a.isHTML5)a.playState=0;a._iO.onstop&&a._iO.onstop.apply(a);
+if(a.isHTML5){if(a._a)a.setPosition(0),a._a.pause(),a.playState=0,a._onTimer(),f()}else c.o._stop(a.sID,b),a._iO.serverURL&&a.unload();a.instanceCount=0;a._iO={}}return a};this.setAutoPlay=function(b){c._wD("sound "+a.sID+" turned autoplay "+(b?"on":"off"));a._iO.autoPlay=b;a.isHTML5||(c.o._setAutoPlay(a.sID,b),b&&!a.instanceCount&&a.readyState===1&&(a.instanceCount++,c._wD("sound "+a.sID+" incremented instance count to "+a.instanceCount)))};this.getAutoPlay=function(){return a._iO.autoPlay};this.setPosition=
+function(b){b===void 0&&(b=0);var d=a.isHTML5?Math.max(b,0):Math.min(a.duration||a._iO.duration,Math.max(b,0));a.position=d;b=a.position/1E3;a.resetOnPosition(a.position);a._iO.position=d;if(a.isHTML5){if(a._a)if(a._html5_canplay){if(a._a.currentTime!==b){c._wD("setPosition("+b+"): setting position");try{a._a.currentTime=b,(a.playState===0||a.paused)&&a._a.pause()}catch(e){c._wD("setPosition("+b+"): setting position failed: "+e.message,2)}}}else c._wD("setPosition("+b+"): delaying, sound not ready")}else b=
+j===9?a.position:b,a.readyState&&a.readyState!==2&&c.o._setPosition(a.sID,b,a.paused||!a.playState);a.isHTML5&&a.paused&&a._onTimer(true);return a};this.pause=function(b){if(a.paused||a.playState===0&&a.readyState!==1)return a;c._wD("SMSound.pause()");a.paused=true;a.isHTML5?(a._setup_html5().pause(),f()):(b||b===void 0)&&c.o._pause(a.sID);a._iO.onpause&&a._iO.onpause.apply(a);return a};this.resume=function(){if(!a.paused)return a;c._wD("SMSound.resume()");a.paused=false;a.playState=1;a.isHTML5?(a._setup_html5().play(),
+d()):(a._iO.isMovieStar&&a.setPosition(a.position),c.o._pause(a.sID));!a._onplay_called&&a._iO.onplay?(a._iO.onplay.apply(a),a._onplay_called=true):a._iO.onresume&&a._iO.onresume.apply(a);return a};this.togglePause=function(){c._wD("SMSound.togglePause()");if(a.playState===0)return a.play({position:j===9&&!a.isHTML5?a.position:a.position/1E3}),a;a.paused?a.resume():a.pause();return a};this.setPan=function(b,d){typeof b==="undefined"&&(b=0);typeof d==="undefined"&&(d=false);a.isHTML5||c.o._setPan(a.sID,
+b);a._iO.pan=b;if(!d)a.pan=b,a.options.pan=b;return a};this.setVolume=function(b,d){typeof b==="undefined"&&(b=100);typeof d==="undefined"&&(d=false);if(a.isHTML5){if(a._a)a._a.volume=Math.max(0,Math.min(1,b/100))}else c.o._setVolume(a.sID,c.muted&&!a.muted||a.muted?0:b);a._iO.volume=b;if(!d)a.volume=b,a.options.volume=b;return a};this.mute=function(){a.muted=true;if(a.isHTML5){if(a._a)a._a.muted=true}else c.o._setVolume(a.sID,0);return a};this.unmute=function(){a.muted=false;var b=typeof a._iO.volume!==
+"undefined";if(a.isHTML5){if(a._a)a._a.muted=false}else c.o._setVolume(a.sID,b?a._iO.volume:a.options.volume);return a};this.toggleMute=function(){return a.muted?a.unmute():a.mute()};this.onposition=function(c,b,d){a._onPositionItems.push({position:c,method:b,scope:typeof d!=="undefined"?d:a,fired:false});return a};this.processOnPosition=function(){var b,d;b=a._onPositionItems.length;if(!b||!a.playState||a._onPositionFired>=b)return false;for(;b--;)if(d=a._onPositionItems[b],!d.fired&&a.position>=
+d.position)d.fired=true,c._onPositionFired++,d.method.apply(d.scope,[d.position]);return true};this.resetOnPosition=function(b){var d,e;d=a._onPositionItems.length;if(!d)return false;for(;d--;)if(e=a._onPositionItems[d],e.fired&&b<=e.position)e.fired=false,c._onPositionFired--;return true};d=function(){a.isHTML5&&Ea(a)};f=function(){a.isHTML5&&Fa(a)};e=function(){a._onPositionItems=[];a._onPositionFired=0;a._hasTimer=null;a._onplay_called=false;a._a=null;a._html5_canplay=false;a.bytesLoaded=null;
+a.bytesTotal=null;a.position=null;a.duration=a._iO&&a._iO.duration?a._iO.duration:null;a.durationEstimate=null;a.failures=0;a.loaded=false;a.playState=0;a.paused=false;a.readyState=0;a.muted=false;a.isBuffering=false;a.instanceOptions={};a.instanceCount=0;a.peakData={left:0,right:0};a.waveformData={left:[],right:[]};a.eqData=[];a.eqData.left=[];a.eqData.right=[]};e();this._onTimer=function(b){var d={};if(a._hasTimer||b)return a._a&&(b||(a.playState>0||a.readyState===1)&&!a.paused)?(a.duration=a._get_html5_duration(),
+a.durationEstimate=a.duration,b=a._a.currentTime?a._a.currentTime*1E3:0,a._whileplaying(b,d,d,d,d),true):(c._wD('_onTimer: Warn for "'+a.sID+'": '+(!a._a?"Could not find element. ":"")+(a.playState===0?"playState bad, 0?":"playState = "+a.playState+", OK")),false)};this._get_html5_duration=function(){var c=a._a?a._a.duration*1E3:a._iO?a._iO.duration:void 0;return c&&!isNaN(c)&&c!==Infinity?c:a._iO?a._iO.duration:null};this._setup_html5=function(b){var b=s(a._iO,b),d=Q?c._global_a:a._a,f=decodeURI(b.url),
+g=d&&d._t?d._t.instanceOptions:null;if(d){if(d._t&&g.url===b.url&&(!a._lastURL||a._lastURL===g.url))return d;c._wD("setting new URL on existing object: "+f+(a._lastURL?", old URL: "+a._lastURL:""));Q&&d._t&&d._t.playState&&b.url!==g.url&&d._t.stop();e();d.src=b.url;a.url=b.url;a._lastURL=b.url;d._called_load=false}else{c._wD("creating HTML5 Audio() element with URL: "+f);d=new Audio(b.url);d._called_load=false;if(Ta)d._called_load=true;if(Q)c._global_a=d}a.isHTML5=true;a._a=d;d._t=a;a._add_html5_events();
+d.loop=b.loops>1?"loop":"";b.autoLoad||b.autoPlay?(d.autobuffer="auto",d.preload="auto",a.load(),d._called_load=true):(d.autobuffer=false,d.preload="none");d.loop=b.loops>1?"loop":"";return d};this._add_html5_events=function(){if(a._a._added_events)return false;var b;c._wD(h+"adding event listeners: "+a.sID);a._a._added_events=true;for(b in x)x.hasOwnProperty(b)&&a._a&&a._a.addEventListener(b,x[b],false);return true};this._remove_html5_events=function(){var b;c._wD(h+"removing event listeners: "+
+a.sID);a._a._added_events=false;for(b in x)x.hasOwnProperty(b)&&a._a&&a._a.removeEventListener(b,x[b],false)};this._onload=function(b){b=!!b;c._wD('SMSound._onload(): "'+a.sID+'"'+(b?" loaded.":" failed to load? - "+a.url),b?1:2);!b&&!a.isHTML5&&(c.sandbox.noRemote===true&&c._wD("SMSound._onload(): "+n("noNet"),1),c.sandbox.noLocal===true&&c._wD("SMSound._onload(): "+n("noLocal"),1));a.loaded=b;a.readyState=b?3:2;a._onbufferchange(0);a._iO.onload&&a._iO.onload.apply(a,[b]);return true};this._onbufferchange=
+function(b){if(a.playState===0)return false;if(b&&a.isBuffering||!b&&!a.isBuffering)return false;a.isBuffering=b===1;a._iO.onbufferchange&&(c._wD("SMSound._onbufferchange(): "+b),a._iO.onbufferchange.apply(a));return true};this._onsuspend=function(){a._iO.onsuspend&&(c._wD("SMSound._onsuspend()"),a._iO.onsuspend.apply(a));return true};this._onfailure=function(b,d,e){a.failures++;c._wD('SMSound._onfailure(): "'+a.sID+'" count '+a.failures);if(a._iO.onfailure&&a.failures===1)a._iO.onfailure(a,b,d,e);
+else c._wD("SMSound._onfailure(): ignoring")};this._onfinish=function(){var b=a._iO.onfinish;a._onbufferchange(0);a.resetOnPosition(0);if(a.instanceCount){a.instanceCount--;if(!a.instanceCount)a.playState=0,a.paused=false,a.instanceCount=0,a.instanceOptions={},a._iO={},f();if((!a.instanceCount||a._iO.multiShotEvents)&&b)c._wD('SMSound._onfinish(): "'+a.sID+'"'),b.apply(a)}};this._whileloading=function(c,b,d,e){a.bytesLoaded=c;a.bytesTotal=b;a.duration=Math.floor(d);a.bufferLength=e;if(a._iO.isMovieStar)a.durationEstimate=
+a.duration;else if(a.durationEstimate=a._iO.duration?a.duration>a._iO.duration?a.duration:a._iO.duration:parseInt(a.bytesTotal/a.bytesLoaded*a.duration,10),a.durationEstimate===void 0)a.durationEstimate=a.duration;a.readyState!==3&&a._iO.whileloading&&a._iO.whileloading.apply(a)};this._whileplaying=function(c,b,d,e,f){if(isNaN(c)||c===null)return false;a.position=c;a.processOnPosition();if(!a.isHTML5&&j>8){if(a._iO.usePeakData&&typeof b!=="undefined"&&b)a.peakData={left:b.leftPeak,right:b.rightPeak};
+if(a._iO.useWaveformData&&typeof d!=="undefined"&&d)a.waveformData={left:d.split(","),right:e.split(",")};if(a._iO.useEQData&&typeof f!=="undefined"&&f&&f.leftEQ&&(c=f.leftEQ.split(","),a.eqData=c,a.eqData.left=c,typeof f.rightEQ!=="undefined"&&f.rightEQ))a.eqData.right=f.rightEQ.split(",")}a.playState===1&&(!a.isHTML5&&j===8&&!a.position&&a.isBuffering&&a._onbufferchange(0),a._iO.whileplaying&&a._iO.whileplaying.apply(a));return true};this._onid3=function(b,d){c._wD('SMSound._onid3(): "'+this.sID+
+'" ID3 data received.');var e=[],f,g;for(f=0,g=b.length;f<g;f++)e[b[f]]=d[f];a.id3=s(a.id3,e);a._iO.onid3&&a._iO.onid3.apply(a)};this._onconnect=function(b){b=b===1;c._wD('SMSound._onconnect(): "'+a.sID+'"'+(b?" connected.":" failed to connect? - "+a.url),b?1:2);if(a.connected=b)a.failures=0,o(a.sID)&&(a.getAutoPlay()?a.play(void 0,a.getAutoPlay()):a._iO.autoLoad&&a.load()),a._iO.onconnect&&a._iO.onconnect.apply(a,[b])};this._ondataerror=function(b){a.playState>0&&(c._wD("SMSound._ondataerror(): "+
+b),a._iO.ondataerror&&a._iO.ondataerror.apply(a))}};Y=function(){return g.body||g._docElement||g.getElementsByTagName("div")[0]};u=function(b){return g.getElementById(b)};s=function(b,a){var e={},f,d;for(f in b)b.hasOwnProperty(f)&&(e[f]=b[f]);f=typeof a==="undefined"?c.defaultOptions:a;for(d in f)f.hasOwnProperty(d)&&typeof e[d]==="undefined"&&(e[d]=f[d]);return e};p=function(){function b(a){var a=Ia.call(a),b=a.length;c?(a[1]="on"+a[1],b>3&&a.pop()):b===3&&a.push(false);return a}function a(a,b){var g=
+a.shift(),j=[f[b]];if(c)g[j](a[0],a[1]);else g[j].apply(g,a)}var c=i.attachEvent,f={add:c?"attachEvent":"addEventListener",remove:c?"detachEvent":"removeEventListener"};return{add:function(){a(b(arguments),"add")},remove:function(){a(b(arguments),"remove")}}}();x={abort:k(function(){c._wD(h+"abort: "+this._t.sID)}),canplay:k(function(){if(this._t._html5_canplay)return true;this._t._html5_canplay=true;c._wD(h+"canplay: "+this._t.sID+", "+this._t.url);this._t._onbufferchange(0);var b=!isNaN(this._t.position)?
+this._t.position/1E3:null;if(this._t.position&&this.currentTime!==b){c._wD(h+"canplay: setting position to "+b);try{this.currentTime=b}catch(a){c._wD(h+"setting position failed: "+a.message,2)}}}),load:k(function(){this._t.loaded||(this._t._onbufferchange(0),this._t._whileloading(this._t.bytesTotal,this._t.bytesTotal,this._t._get_html5_duration()),this._t._onload(true))}),emptied:k(function(){c._wD(h+"emptied: "+this._t.sID)}),ended:k(function(){c._wD(h+"ended: "+this._t.sID);this._t._onfinish()}),
+error:k(function(){c._wD(h+"error: "+this.error.code);this._t._onload(false)}),loadeddata:k(function(){var b=this._t,a=b.bytesTotal||1;c._wD(h+"loadeddata: "+this._t.sID);if(!b._loaded&&!R)b.duration=b._get_html5_duration(),b._whileloading(a,a,b._get_html5_duration()),b._onload(true)}),loadedmetadata:k(function(){c._wD(h+"loadedmetadata: "+this._t.sID)}),loadstart:k(function(){c._wD(h+"loadstart: "+this._t.sID);this._t._onbufferchange(1)}),play:k(function(){c._wD(h+"play: "+this._t.sID+", "+this._t.url);
+this._t._onbufferchange(0)}),playing:k(function(){c._wD(h+"playing: "+this._t.sID+", "+this._t.url);this._t._onbufferchange(0)}),progress:k(function(b){if(this._t.loaded)return false;var a,e,f;f=0;var d=b.type==="progress";e=b.target.buffered;var g=b.loaded||0,xa=b.total||1;if(e&&e.length){for(a=e.length;a--;)f=e.end(a)-e.start(a);g=f/b.target.duration;if(d&&e.length>1){f=[];e=e.length;for(a=0;a<e;a++)f.push(b.target.buffered.start(a)+"-"+b.target.buffered.end(a));c._wD(h+"progress: timeRanges: "+
+f.join(", "))}d&&!isNaN(g)&&c._wD(h+"progress: "+this._t.sID+": "+Math.floor(g*100)+"% loaded")}isNaN(g)||(this._t._onbufferchange(0),this._t._whileloading(g,xa,this._t._get_html5_duration()),g&&xa&&g===xa&&x.load.call(this,b))}),ratechange:k(function(){c._wD(h+"ratechange: "+this._t.sID)}),suspend:k(function(b){c._wD(h+"suspend: "+this._t.sID);x.progress.call(this,b);this._t._onsuspend()}),stalled:k(function(){c._wD(h+"stalled: "+this._t.sID)}),timeupdate:k(function(){this._t._onTimer()}),waiting:k(function(){c._wD(h+
+"waiting: "+this._t.sID);this._t._onbufferchange(1)})};da=function(b){return!b.serverURL&&(b.type?P({type:b.type}):P({url:b.url})||c.html5Only)};ra=function(b){if(b)b.src=Sa?"":"about:blank"};P=function(b){function a(a){return c.preferFlash&&t&&!c.ignoreFlash&&typeof c.flash[a]!=="undefined"&&c.flash[a]}if(!c.useHTML5Audio||!c.hasHTML5)return false;var e=b.url||null,b=b.type||null,f=c.audioFormats,d;if(b&&c.html5[b]!=="undefined")return c.html5[b]&&!a(b);if(!z){z=[];for(d in f)f.hasOwnProperty(d)&&
+(z.push(d),f[d].related&&(z=z.concat(f[d].related)));z=RegExp("\\.("+z.join("|")+")(\\?.*)?$","i")}d=e?e.toLowerCase().match(z):null;if(!d||!d.length)if(b)e=b.indexOf(";"),d=(e!==-1?b.substr(0,e):b).substr(6);else return false;else d=d[1];return d&&typeof c.html5[d]!=="undefined"?c.html5[d]&&!a(d):(b="audio/"+d,e=c.html5.canPlayType({type:b}),(c.html5[d]=e)&&c.html5[b]&&!a(b))};Ha=function(){function b(b){var d,e,f=false;if(!a||typeof a.canPlayType!=="function")return false;if(b instanceof Array){for(d=
+0,e=b.length;d<e&&!f;d++)if(c.html5[b[d]]||a.canPlayType(b[d]).match(c.html5Test))f=true,c.html5[b[d]]=true,c.flash[b[d]]=!(!c.preferFlash||!t||!b[d].match(Ma));return f}else return b=a&&typeof a.canPlayType==="function"?a.canPlayType(b):false,!(!b||!b.match(c.html5Test))}if(!c.useHTML5Audio||typeof Audio==="undefined")return false;var a=typeof Audio!=="undefined"?Va?new Audio(null):new Audio:null,e,f={},d,g;d=c.audioFormats;for(e in d)if(d.hasOwnProperty(e)&&(f[e]=b(d[e].type),f["audio/"+e]=f[e],
+c.flash[e]=c.preferFlash&&!c.ignoreFlash&&e.match(Ma)?true:false,d[e]&&d[e].related))for(g=d[e].related.length;g--;)f["audio/"+d[e].related[g]]=f[e],c.html5[d[e].related[g]]=f[e],c.flash[d[e].related[g]]=f[e];f.canPlayType=a?b:null;c.html5=s(c.html5,f);return true};W={notReady:"Not loaded yet - wait for soundManager.onload()/onready()",notOK:"Audio support is not available.",domError:"soundManager::createMovie(): appendChild/innerHTML call failed. DOM not ready or other error.",spcWmode:"soundManager::createMovie(): Removing wmode, preventing known SWF loading issue(s)",
+swf404:"soundManager: Verify that %s is a valid path.",tryDebug:"Try soundManager.debugFlash = true for more security details (output goes to SWF.)",checkSWF:"See SWF output for more debug info.",localFail:"soundManager: Non-HTTP page ("+g.location.protocol+" URL?) Review Flash player security settings for this special case:\nhttp://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html\nMay need to add/allow path, eg. c:/sm2/ or /users/me/sm2/",waitFocus:"soundManager: Special case: Waiting for focus-related event..",
+waitImpatient:"soundManager: Getting impatient, still waiting for Flash%s...",waitForever:"soundManager: Waiting indefinitely for Flash (will recover if unblocked)...",needFunction:"soundManager: Function object expected for %s",badID:'Warning: Sound ID "%s" should be a string, starting with a non-numeric character',currentObj:"--- soundManager._debug(): Current sound objects ---",waitEI:"soundManager::initMovie(): Waiting for ExternalInterface call from Flash..",waitOnload:"soundManager: Waiting for window.onload()",
+docLoaded:"soundManager: Document already loaded",onload:"soundManager::initComplete(): calling soundManager.onload()",onloadOK:"soundManager.onload() complete",init:"soundManager::init()",didInit:"soundManager::init(): Already called?",flashJS:"soundManager: Attempting to call Flash from JS..",secNote:"Flash security note: Network/internet URLs will not load due to security restrictions. Access can be configured via Flash Player Global Security Settings Page: http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html",
+badRemove:"Warning: Failed to remove flash movie.",noPeak:"Warning: peakData features unsupported for movieStar formats",shutdown:"soundManager.disable(): Shutting down",queue:"soundManager: Queueing %s handler",smFail:"soundManager: Failed to initialise.",smError:"SMSound.load(): Exception: JS-Flash communication failed, or JS error.",fbTimeout:"No flash response, applying ."+c.swfCSS.swfTimedout+" CSS..",fbLoaded:"Flash loaded",fbHandler:"soundManager::flashBlockHandler()",manURL:"SMSound.load(): Using manually-assigned URL",
+onURL:"soundManager.load(): current URL already assigned.",badFV:'soundManager.flashVersion must be 8 or 9. "%s" is invalid. Reverting to %s.',as2loop:"Note: Setting stream:false so looping can work (flash 8 limitation)",noNSLoop:"Note: Looping not implemented for MovieStar formats",needfl9:"Note: Switching to flash 9, required for MP4 formats.",mfTimeout:"Setting flashLoadTimeout = 0 (infinite) for off-screen, mobile flash case",mfOn:"mobileFlash::enabling on-screen flash repositioning",policy:"Enabling usePolicyFile for data access"};
+n=function(){var b=Ia.call(arguments),a=b.shift(),a=W&&W[a]?W[a]:"",c,f;if(a&&b&&b.length)for(c=0,f=b.length;c<f;c++)a=a.replace("%s",b[c]);return a};aa=function(b){if(j===8&&b.loops>1&&b.stream)l("as2loop"),b.stream=false;return b};ba=function(b,a){if(b&&!b.usePolicyFile&&(b.onid3||b.usePeakData||b.useWaveformData||b.useEQData))c._wD((a||"")+n("policy")),b.usePolicyFile=true;return b};pa=function(b){typeof console!=="undefined"&&typeof console.warn!=="undefined"?console.warn(b):c._wD(b)};ga=function(){return false};
+Ba=function(b){for(var a in b)b.hasOwnProperty(a)&&typeof b[a]==="function"&&(b[a]=ga)};$=function(b){typeof b==="undefined"&&(b=false);if(v||b)l("smFail",2),c.disable(b)};Ca=function(b){var a=null;if(b)if(b.match(/\.swf(\?.*)?$/i)){if(a=b.substr(b.toLowerCase().lastIndexOf(".swf?")+4))return b}else b.lastIndexOf("/")!==b.length-1&&(b+="/");b=(b&&b.lastIndexOf("/")!==-1?b.substr(0,b.lastIndexOf("/")+1):"./")+c.movieURL;c.noSWFCache&&(b+="?ts="+(new Date).getTime());return b};ka=function(){j=parseInt(c.flashVersion,
+10);if(j!==8&&j!==9)c._wD(n("badFV",j,8)),c.flashVersion=j=8;var b=c.debugMode||c.debugFlash?"_debug.swf":".swf";if(c.useHTML5Audio&&!c.html5Only&&c.audioFormats.mp4.required&&j<9)c._wD(n("needfl9")),c.flashVersion=j=9;c.version=c.versionNumber+(c.html5Only?" (HTML5-only mode)":j===9?" (AS3/Flash 9)":" (AS2/Flash 8)");j>8?(c.defaultOptions=s(c.defaultOptions,c.flash9Options),c.features.buffering=true,c.defaultOptions=s(c.defaultOptions,c.movieStarOptions),c.filePatterns.flash9=RegExp("\\.(mp3|"+Pa.join("|")+
+")(\\?.*)?$","i"),c.features.movieStar=true):c.features.movieStar=false;c.filePattern=c.filePatterns[j!==8?"flash9":"flash8"];c.movieURL=(j===8?"soundmanager2.swf":"soundmanager2_flash9.swf").replace(".swf",b);c.features.peakData=c.features.waveformData=c.features.eqData=j>8};Aa=function(b,a){if(!c.o)return false;c.o._setPolling(b,a)};ma=function(){if(c.debugURLParam.test(K))c.debugMode=true;if(u(c.debugID))return false;var b,a,e,f;if(c.debugMode&&!u(c.debugID)&&(!va||!c.useConsole||c.useConsole&&
+va&&!c.consoleOnly)){b=g.createElement("div");b.id=c.debugID+"-toggle";a={position:"fixed",bottom:"0px",right:"0px",width:"1.2em",height:"1.2em",lineHeight:"1.2em",margin:"2px",textAlign:"center",border:"1px solid #999",cursor:"pointer",background:"#fff",color:"#333",zIndex:10001};b.appendChild(g.createTextNode("-"));b.onclick=Da;b.title="Toggle SM2 debug console";if(q.match(/msie 6/i))b.style.position="absolute",b.style.cursor="hand";for(f in a)a.hasOwnProperty(f)&&(b.style[f]=a[f]);a=g.createElement("div");
+a.id=c.debugID;a.style.display=c.debugMode?"block":"none";if(c.debugMode&&!u(b.id)){try{e=Y(),e.appendChild(b)}catch(d){throw Error(n("domError")+" \n"+d.toString());}e.appendChild(a)}}};o=this.getSoundById;l=function(b,a){return b?c._wD(n(b),a):""};if(K.indexOf("sm2-debug=alert")+1&&c.debugMode)c._wD=function(b){S.alert(b)};Da=function(){var b=u(c.debugID),a=u(c.debugID+"-toggle");if(!b)return false;ha?(a.innerHTML="+",b.style.display="none"):(a.innerHTML="-",b.style.display="block");ha=!ha};r=function(b,
+a,c){if(typeof sm2Debugger!=="undefined")try{sm2Debugger.handleEvent(b,a,c)}catch(f){}return true};G=function(){var b=[];c.debugMode&&b.push(c.swfCSS.sm2Debug);c.debugFlash&&b.push(c.swfCSS.flashDebug);c.useHighPerformance&&b.push(c.swfCSS.highPerf);return b.join(" ")};oa=function(){var b=n("fbHandler"),a=c.getMoviePercent(),e=c.swfCSS,f={type:"FLASHBLOCK"};if(c.html5Only)return false;if(c.ok()){if(c.didFlashBlock&&c._wD(b+": Unblocked"),c.oMC)c.oMC.className=[G(),e.swfDefault,e.swfLoaded+(c.didFlashBlock?
+" "+e.swfUnblocked:"")].join(" ")}else{if(w)c.oMC.className=G()+" "+e.swfDefault+" "+(a===null?e.swfTimedout:e.swfError),c._wD(b+": "+n("fbTimeout")+(a?" ("+n("fbLoaded")+")":""));c.didFlashBlock=true;C({type:"ontimeout",ignoreInit:true,error:f});F(f)}};ja=function(b,a,c){typeof y[b]==="undefined"&&(y[b]=[]);y[b].push({method:a,scope:c||null,fired:false})};C=function(b){b||(b={type:"onready"});if(!m&&b&&!b.ignoreInit)return false;if(b.type==="ontimeout"&&c.ok())return false;var a={success:b&&b.ignoreInit?
+c.ok():!v},e=b&&b.type?y[b.type]||[]:[],f=[],d,g=[a],j=w&&c.useFlashBlock&&!c.ok();if(b.error)g[0].error=b.error;for(a=0,d=e.length;a<d;a++)e[a].fired!==true&&f.push(e[a]);if(f.length){c._wD("soundManager: Firing "+f.length+" "+b.type+"() item"+(f.length===1?"":"s"));for(a=0,d=f.length;a<d;a++)if(f[a].scope?f[a].method.apply(f[a].scope,g):f[a].method.apply(this,g),!j)f[a].fired=true}return true};D=function(){i.setTimeout(function(){c.useFlashBlock&&oa();C();c.onload instanceof Function&&(l("onload",
+1),c.onload.apply(i),l("onloadOK",1));c.waitForWindowLoad&&p.add(i,"load",D)},1)};ea=function(){if(t!==void 0)return t;var b=false,a=navigator,c=a.plugins,f,d=i.ActiveXObject;if(c&&c.length)(a=a.mimeTypes)&&a["application/x-shockwave-flash"]&&a["application/x-shockwave-flash"].enabledPlugin&&a["application/x-shockwave-flash"].enabledPlugin.description&&(b=true);else if(typeof d!=="undefined"){try{f=new d("ShockwaveFlash.ShockwaveFlash")}catch(g){}b=!!f}return t=b};Ga=function(){var b,a;if(ta&&q.match(/os (1|2|3_0|3_1)/i)){c.hasHTML5=
+false;c.html5Only=true;if(c.oMC)c.oMC.style.display="none";return false}if(c.useHTML5Audio){if(!c.html5||!c.html5.canPlayType)return c._wD("SoundManager: No HTML5 Audio() support detected."),c.hasHTML5=false,true;else c.hasHTML5=true;if(ua&&(c._wD("soundManager::Note: Buggy HTML5 Audio in Safari on this OS X release, see https://bugs.webkit.org/show_bug.cgi?id=32159 - "+(!t?" would use flash fallback for MP3/MP4, but none detected.":"will use flash fallback for MP3/MP4, if available"),1),ea()))return true}else return true;
+for(a in c.audioFormats)if(c.audioFormats.hasOwnProperty(a)&&(c.audioFormats[a].required&&!c.html5.canPlayType(c.audioFormats[a].type)||c.flash[a]||c.flash[c.audioFormats[a].type]))b=true;c.ignoreFlash&&(b=false);c.html5Only=c.hasHTML5&&c.useHTML5Audio&&!b;return!c.html5Only};Ea=function(b){if(!b._hasTimer)b._hasTimer=true};Fa=function(b){if(b._hasTimer)b._hasTimer=false};F=function(b){b=typeof b!=="undefined"?b:{};c.onerror instanceof Function&&c.onerror.apply(i,[{type:typeof b.type!=="undefined"?
+b.type:null}]);typeof b.fatal!=="undefined"&&b.fatal&&c.disable()};Ja=function(){if(!ua||!ea())return false;var b=c.audioFormats,a,e;for(e in b)if(b.hasOwnProperty(e)&&(e==="mp3"||e==="mp4"))if(c._wD("soundManager: Using flash fallback for "+e+" format"),c.html5[e]=false,b[e]&&b[e].related)for(a=b[e].related.length;a--;)c.html5[b[e].related[a]]=false};this._setSandboxType=function(b){var a=c.sandbox;a.type=b;a.description=a.types[typeof a.types[b]!=="undefined"?b:"unknown"];c._wD("Flash security sandbox type: "+
+a.type);if(a.type==="localWithFile")a.noRemote=true,a.noLocal=false,l("secNote",2);else if(a.type==="localWithNetwork")a.noRemote=false,a.noLocal=true;else if(a.type==="localTrusted")a.noRemote=false,a.noLocal=false};this._externalInterfaceOK=function(b){if(c.swfLoaded)return false;var a=(new Date).getTime();c._wD("soundManager::externalInterfaceOK()"+(b?" (~"+(a-b)+" ms)":""));r("swf",true);r("flashtojs",true);c.swfLoaded=true;H=false;ua&&Ja();A?setTimeout(U,100):U()};Z=function(b,a){function e(){c._wD("-- SoundManager 2 "+
+c.version+(!c.html5Only&&c.useHTML5Audio?c.hasHTML5?" + HTML5 audio":", no HTML5 audio support":"")+(!c.html5Only?(c.useHighPerformance?", high performance mode, ":", ")+((c.flashPollingInterval?"custom ("+c.flashPollingInterval+"ms)":"normal")+" polling")+(c.wmode?", wmode: "+c.wmode:"")+(c.debugFlash?", flash debug mode":"")+(c.useFlashBlock?", flashBlock mode":""):"")+" --",1)}function f(a,b){return'<param name="'+a+'" value="'+b+'" />'}if(L&&M)return false;if(c.html5Only)return ka(),e(),c.oMC=
+u(c.movieID),U(),M=L=true,false;var d=a||c.url,j=c.altURL||d,h;h=Y();var i,o,k=G(),m,p=null,p=(p=g.getElementsByTagName("html")[0])&&p.dir&&p.dir.match(/rtl/i),b=typeof b==="undefined"?c.id:b;ka();c.url=Ca(I?d:j);a=c.url;c.wmode=!c.wmode&&c.useHighPerformance?"transparent":c.wmode;if(c.wmode!==null&&(q.match(/msie 8/i)||!A&&!c.useHighPerformance)&&navigator.platform.match(/win32|win64/i))c.specialWmodeCase=true,l("spcWmode"),c.wmode=null;h={name:b,id:b,src:a,width:"auto",height:"auto",quality:"high",
+allowScriptAccess:c.allowScriptAccess,bgcolor:c.bgColor,pluginspage:Na+"www.macromedia.com/go/getflashplayer",title:"JS/Flash audio component (SoundManager 2)",type:"application/x-shockwave-flash",wmode:c.wmode,hasPriority:"true"};if(c.debugFlash)h.FlashVars="debug=1";c.wmode||delete h.wmode;if(A)d=g.createElement("div"),o=['<object id="'+b+'" data="'+a+'" type="'+h.type+'" title="'+h.title+'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="'+Na+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" width="'+
+h.width+'" height="'+h.height+'">',f("movie",a),f("AllowScriptAccess",c.allowScriptAccess),f("quality",h.quality),c.wmode?f("wmode",c.wmode):"",f("bgcolor",c.bgColor),f("hasPriority","true"),c.debugFlash?f("FlashVars",h.FlashVars):"","</object>"].join("");else for(i in d=g.createElement("embed"),h)h.hasOwnProperty(i)&&d.setAttribute(i,h[i]);ma();k=G();if(h=Y())if(c.oMC=u(c.movieID)||g.createElement("div"),c.oMC.id){m=c.oMC.className;c.oMC.className=(m?m+" ":c.swfCSS.swfDefault)+(k?" "+k:"");c.oMC.appendChild(d);
+if(A)i=c.oMC.appendChild(g.createElement("div")),i.className=c.swfCSS.swfBox,i.innerHTML=o;M=true}else{c.oMC.id=c.movieID;c.oMC.className=c.swfCSS.swfDefault+" "+k;i=k=null;if(!c.useFlashBlock)if(c.useHighPerformance)k={position:"fixed",width:"8px",height:"8px",bottom:"0px",left:"0px",overflow:"hidden"};else if(k={position:"absolute",width:"6px",height:"6px",top:"-9999px",left:"-9999px"},p)k.left=Math.abs(parseInt(k.left,10))+"px";if(Ua)c.oMC.style.zIndex=1E4;if(!c.debugFlash)for(m in k)k.hasOwnProperty(m)&&
+(c.oMC.style[m]=k[m]);try{A||c.oMC.appendChild(d);h.appendChild(c.oMC);if(A)i=c.oMC.appendChild(g.createElement("div")),i.className=c.swfCSS.swfBox,i.innerHTML=o;M=true}catch(r){throw Error(n("domError")+" \n"+r.toString());}}L=true;e();c._wD("soundManager::createMovie(): Trying to load "+a+(!I&&c.altURL?" (alternate URL)":""),1);return true};X=function(){if(c.html5Only)return Z(),false;if(c.o)return false;c.o=c.getMovie(c.id);if(!c.o)O?(A?c.oMC.innerHTML=na:c.oMC.appendChild(O),O=null,L=true):Z(c.id,
+c.url),c.o=c.getMovie(c.id);c.o&&l("waitEI");c.oninitmovie instanceof Function&&setTimeout(c.oninitmovie,1);return true};V=function(){setTimeout(za,1E3)};za=function(){if(ca)return false;ca=true;p.remove(i,"load",V);if(H&&!wa)return l("waitFocus"),false;var b;m||(b=c.getMoviePercent(),c._wD(n("waitImpatient",b===100?" (SWF loaded)":b>0?" (SWF "+b+"% loaded)":"")));setTimeout(function(){b=c.getMoviePercent();m||(c._wD("soundManager: No Flash response within expected time.\nLikely causes: "+(b===0?
+"Loading "+c.movieURL+" may have failed (and/or Flash "+j+"+ not present?), ":"")+"Flash blocked or JS-Flash security error."+(c.debugFlash?" "+n("checkSWF"):""),2),!I&&b&&(l("localFail",2),c.debugFlash||l("tryDebug",2)),b===0&&c._wD(n("swf404",c.url)),r("flashtojs",false,": Timed out"+I?" (Check flash security or flash blockers)":" (No plugin/missing SWF?)"));!m&&La&&(b===null?c.useFlashBlock||c.flashLoadTimeout===0?(c.useFlashBlock&&oa(),l("waitForever")):$(true):c.flashLoadTimeout===0?l("waitForever"):
+$(true))},c.flashLoadTimeout)};B=function(){function b(){p.remove(i,"focus",B);p.remove(i,"load",B)}if(wa||!H)return b(),true;wa=La=true;c._wD("soundManager::handleFocus()");R&&H&&p.remove(i,"mousemove",B);ca=false;b();return true};Ka=function(){var b,a=[];if(c.useHTML5Audio&&c.hasHTML5){for(b in c.audioFormats)c.audioFormats.hasOwnProperty(b)&&a.push(b+": "+c.html5[b]+(!c.html5[b]&&t&&c.flash[b]?" (using flash)":c.preferFlash&&c.flash[b]&&t?" (preferring flash)":!c.html5[b]?" ("+(c.audioFormats[b].required?
+"required, ":"")+"and no flash support)":""));c._wD("-- SoundManager 2: HTML5 support tests ("+c.html5Test+"): "+a.join(", ")+" --",1)}};N=function(b){if(m)return false;if(c.html5Only)return c._wD("-- SoundManager 2: loaded --"),m=true,D(),r("onload",true),true;var a;if(!c.useFlashBlock||!c.flashLoadTimeout||c.getMoviePercent())m=true,v&&(a={type:!t&&w?"NO_FLASH":"INIT_TIMEOUT"});c._wD("-- SoundManager 2 "+(v?"failed to load":"loaded")+" ("+(v?"security/load error":"OK")+") --",1);if(v||b){if(c.useFlashBlock&&
+c.oMC)c.oMC.className=G()+" "+(c.getMoviePercent()===null?c.swfCSS.swfTimedout:c.swfCSS.swfError);C({type:"ontimeout",error:a});r("onload",false);F(a);return false}else r("onload",true);if(c.waitForWindowLoad&&!ia)return l("waitOnload"),p.add(i,"load",D),false;else c.waitForWindowLoad&&ia&&l("docLoaded"),D();return true};U=function(){l("init");if(m)return l("didInit"),false;if(c.html5Only){if(!m)p.remove(i,"load",c.beginDelayedInit),c.enabled=true,N();return true}X();try{l("flashJS"),c.o._externalInterfaceTest(false),
+Aa(true,c.flashPollingInterval||(c.useHighPerformance?10:50)),c.debugMode||c.o._disableDebug(),c.enabled=true,r("jstoflash",true),c.html5Only||p.add(i,"unload",ga)}catch(b){return c._wD("js/flash exception: "+b.toString()),r("jstoflash",false),F({type:"JS_TO_FLASH_EXCEPTION",fatal:true}),$(true),N(),false}N();p.remove(i,"load",c.beginDelayedInit);return true};E=function(){if(la)return false;la=true;ma();var b=K.toLowerCase(),a=null,a=null,e=typeof console!=="undefined"&&typeof console.log!=="undefined";
+if(b.indexOf("sm2-usehtml5audio=")!==-1)a=b.charAt(b.indexOf("sm2-usehtml5audio=")+18)==="1",e&&console.log((a?"Enabling ":"Disabling ")+"useHTML5Audio via URL parameter"),c.useHTML5Audio=a;if(b.indexOf("sm2-preferflash=")!==-1)a=b.charAt(b.indexOf("sm2-preferflash=")+16)==="1",e&&console.log((a?"Enabling ":"Disabling ")+"preferFlash via URL parameter"),c.preferFlash=a;if(!t&&c.hasHTML5)c._wD("SoundManager: No Flash detected"+(!c.useHTML5Audio?", enabling HTML5.":". Trying HTML5-only mode.")),c.useHTML5Audio=
+true,c.preferFlash=false;Ha();c.html5.usingFlash=Ga();w=c.html5.usingFlash;Ka();if(!t&&w)c._wD("SoundManager: Fatal error: Flash is needed to play some required formats, but is not available."),c.flashLoadTimeout=1;g.removeEventListener&&g.removeEventListener("DOMContentLoaded",E,false);X();return true};sa=function(){g.readyState==="complete"&&(E(),g.detachEvent("onreadystatechange",sa));return true};ea();p.add(i,"focus",B);p.add(i,"load",B);p.add(i,"load",V);R&&H&&p.add(i,"mousemove",B);g.addEventListener?
+g.addEventListener("DOMContentLoaded",E,false):g.attachEvent?g.attachEvent("onreadystatechange",sa):(r("onload",false),F({type:"NO_DOM2_EVENTS",fatal:true}));g.readyState==="complete"&&setTimeout(E,100)}var fa=null;if(typeof SM2_DEFER==="undefined"||!SM2_DEFER)fa=new T;S.SoundManager=T;S.soundManager=fa})(window);
\ No newline at end of file
--- /dev/null
+/** @license\r
+ *\r
+ * SoundManager 2: JavaScript Sound for the Web\r
+ * ----------------------------------------------\r
+ * http://schillmania.com/projects/soundmanager2/\r
+ *\r
+ * Copyright (c) 2007, Scott Schiller. All rights reserved.\r
+ * Code provided under the BSD License:\r
+ * http://schillmania.com/projects/soundmanager2/license.txt\r
+ *\r
+ * V2.97a.20111030\r
+ */\r
+(function($){function N(N,Z){function j(c){return function(a){return!this._t||!this._t._a?null:c.call(this,a)}}this.flashVersion=8;this.debugFlash=this.debugMode=false;this.useConsole=true;this.waitForWindowLoad=this.consoleOnly=false;this.bgColor="#ffffff";this.useHighPerformance=false;this.flashPollingInterval=null;this.flashLoadTimeout=1E3;this.wmode=null;this.allowScriptAccess="always";this.useFlashBlock=false;this.useHTML5Audio=true;this.html5Test=/^(probably|maybe)$/i;this.preferFlash=true;
+this.noSWFCache=false;this.audioFormats={mp3:{type:['audio/mpeg; codecs="mp3"',"audio/mpeg","audio/mp3","audio/MPA","audio/mpa-robust"],required:true},mp4:{related:["aac","m4a"],type:['audio/mp4; codecs="mp4a.40.2"',"audio/aac","audio/x-m4a","audio/MP4A-LATM","audio/mpeg4-generic"],required:false},ogg:{type:["audio/ogg; codecs=vorbis"],required:false},wav:{type:['audio/wav; codecs="1"',"audio/wav","audio/wave","audio/x-wav"],required:false}};this.defaultOptions={autoLoad:false,stream:true,autoPlay:false,
+loops:1,onid3:null,onload:null,whileloading:null,onplay:null,onpause:null,onresume:null,whileplaying:null,onstop:null,onfailure:null,onfinish:null,multiShot:true,multiShotEvents:false,position:null,pan:0,type:null,usePolicyFile:false,volume:100};this.flash9Options={isMovieStar:null,usePeakData:false,useWaveformData:false,useEQData:false,onbufferchange:null,ondataerror:null};this.movieStarOptions={bufferTime:3,serverURL:null,onconnect:null,duration:null};this.movieID="sm2-container";this.id=Z||"sm2movie";
+this.swfCSS={swfBox:"sm2-object-box",swfDefault:"movieContainer",swfError:"swf_error",swfTimedout:"swf_timedout",swfLoaded:"swf_loaded",swfUnblocked:"swf_unblocked",sm2Debug:"sm2_debug",highPerf:"high_performance",flashDebug:"flash_debug"};this.debugID="soundmanager-debug";this.debugURLParam=/([#?&])debug=1/i;this.versionNumber="V2.97a.20111030";this.movieURL=this.version=null;this.url=N||null;this.altURL=null;this.enabled=this.swfLoaded=false;this.oMC=this.o=null;this.sounds={};this.soundIDs=[];
+this.didFlashBlock=this.specialWmodeCase=this.muted=false;this.filePattern=null;this.filePatterns={flash8:/\.mp3(\?.*)?$/i,flash9:/\.mp3(\?.*)?$/i};this.features={buffering:false,peakData:false,waveformData:false,eqData:false,movieStar:false};this.sandbox={};var F;try{F=typeof Audio!=="undefined"&&typeof(new Audio).canPlayType!=="undefined"}catch(Oa){F=false}this.hasHTML5=F;this.html5={usingFlash:null};this.flash={};this.ignoreFlash=this.html5Only=false;var ra,c=this,O,o=navigator.userAgent,i=$,aa=
+i.location.href.toString(),h=document,ba,P,g,s=[],G=false,H=false,m=false,t=false,sa=false,I,n,ca,z,A,Q,ta,da,x,R,B,ea,fa,S,C,ua,ga,va,T,wa,J=null,ha=null,y,ia,D,U,V,ja,l,W=false,ka=false,xa,ya,q=null,za,X,K,u,la,ma,Aa,k,Ia=Array.prototype.slice,L=false,p,Y,Ba,r,Ca,na=o.match(/(ipad|iphone|ipod)/i),Ja=o.match(/firefox/i),Ka=o.match(/droid/i),v=o.match(/msie/i),La=o.match(/webkit/i),M=o.match(/safari/i)&&!o.match(/chrome/i),Ma=o.match(/opera/i);F=o.match(/(mobile|pre\/|xoom)/i)||na;var oa=!aa.match(/usehtml5audio/i)&&
+!aa.match(/sm2\-ignorebadua/i)&&M&&o.match(/OS X 10_6_([3-7])/i),pa=typeof h.hasFocus!=="undefined"?h.hasFocus():null,E=M&&typeof h.hasFocus==="undefined",Da=!E,Ea=/(mp3|mp4|mpa)/i,qa=h.location?h.location.protocol.match(/http/i):null,Fa=!qa?"http://":"",Ga=/^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|mp4v|3gp|3g2)\s*(?:$|;)/i,Ha="mpeg4,aac,flv,mov,mp4,m4v,f4v,m4a,mp4v,3gp,3g2".split(","),Na=RegExp("\\.("+Ha.join("|")+")(\\?.*)?$","i");this.mimePattern=/^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i;
+this.useAltURL=!qa;this._global_a=null;if(F&&(c.useHTML5Audio=true,c.preferFlash=false,na))L=c.ignoreFlash=true;this.supported=this.ok=function(){return q?m&&!t:c.useHTML5Audio&&c.hasHTML5};this.getMovie=function(c){return O(c)||h[c]||i[c]};this.createSound=function(b){function a(){e=U(e);c.sounds[d.id]=new ra(d);c.soundIDs.push(d.id);return c.sounds[d.id]}var e=null,f=null,d=null;if(!m||!c.ok())return ja("soundManager.createSound(): "+y(!m?"notReady":"notOK")),false;arguments.length===2&&(b={id:arguments[0],
+url:arguments[1]});d=e=n(b);if(l(d.id,true))return c.sounds[d.id];if(X(d))f=a(),f._setup_html5(d);else{if(g>8){if(d.isMovieStar===null)d.isMovieStar=d.serverURL||(d.type?d.type.match(Ga):false)||d.url.match(Na);if(d.isMovieStar&&d.usePeakData)d.usePeakData=false}d=V(d,"soundManager.createSound(): ");f=a();if(g===8)c.o._createSound(d.id,d.loops||1,d.usePolicyFile);else if(c.o._createSound(d.id,d.url,d.usePeakData,d.useWaveformData,d.useEQData,d.isMovieStar,d.isMovieStar?d.bufferTime:false,d.loops||
+1,d.serverURL,d.duration||null,d.autoPlay,true,d.autoLoad,d.usePolicyFile),!d.serverURL)f.connected=true,d.onconnect&&d.onconnect.apply(f);!d.serverURL&&(d.autoLoad||d.autoPlay)&&f.load(d)}!d.serverURL&&d.autoPlay&&f.play();return f};this.destroySound=function(b,a){if(!l(b))return false;var e=c.sounds[b],f;e._iO={};e.stop();e.unload();for(f=0;f<c.soundIDs.length;f++)if(c.soundIDs[f]===b){c.soundIDs.splice(f,1);break}a||e.destruct(true);delete c.sounds[b];return true};this.load=function(b,a){return!l(b)?
+false:c.sounds[b].load(a)};this.unload=function(b){return!l(b)?false:c.sounds[b].unload()};this.onposition=function(b,a,e,f){return!l(b)?false:c.sounds[b].onposition(a,e,f)};this.start=this.play=function(b,a){if(!m||!c.ok())return ja("soundManager.play(): "+y(!m?"notReady":"notOK")),false;return!l(b)?(a instanceof Object||(a={url:a}),a&&a.url?(a.id=b,c.createSound(a).play()):false):c.sounds[b].play(a)};this.setPosition=function(b,a){return!l(b)?false:c.sounds[b].setPosition(a)};this.stop=function(b){return!l(b)?
+false:c.sounds[b].stop()};this.stopAll=function(){for(var b in c.sounds)c.sounds.hasOwnProperty(b)&&c.sounds[b].stop()};this.pause=function(b){return!l(b)?false:c.sounds[b].pause()};this.pauseAll=function(){var b;for(b=c.soundIDs.length;b--;)c.sounds[c.soundIDs[b]].pause()};this.resume=function(b){return!l(b)?false:c.sounds[b].resume()};this.resumeAll=function(){var b;for(b=c.soundIDs.length;b--;)c.sounds[c.soundIDs[b]].resume()};this.togglePause=function(b){return!l(b)?false:c.sounds[b].togglePause()};
+this.setPan=function(b,a){return!l(b)?false:c.sounds[b].setPan(a)};this.setVolume=function(b,a){return!l(b)?false:c.sounds[b].setVolume(a)};this.mute=function(b){var a=0;typeof b!=="string"&&(b=null);if(b)return!l(b)?false:c.sounds[b].mute();else{for(a=c.soundIDs.length;a--;)c.sounds[c.soundIDs[a]].mute();c.muted=true}return true};this.muteAll=function(){c.mute()};this.unmute=function(b){typeof b!=="string"&&(b=null);if(b)return!l(b)?false:c.sounds[b].unmute();else{for(b=c.soundIDs.length;b--;)c.sounds[c.soundIDs[b]].unmute();
+c.muted=false}return true};this.unmuteAll=function(){c.unmute()};this.toggleMute=function(b){return!l(b)?false:c.sounds[b].toggleMute()};this.getMemoryUse=function(){var b=0;c.o&&g!==8&&(b=parseInt(c.o._getMemoryUse(),10));return b};this.disable=function(b){var a;typeof b==="undefined"&&(b=false);if(t)return false;t=true;for(a=c.soundIDs.length;a--;)va(c.sounds[c.soundIDs[a]]);I(b);k.remove(i,"load",A);return true};this.canPlayMIME=function(b){var a;c.hasHTML5&&(a=K({type:b}));return!q||a?a:b?!!(g>
+8&&b.match(Ga)||b.match(c.mimePattern)):null};this.canPlayURL=function(b){var a;c.hasHTML5&&(a=K({url:b}));return!q||a?a:b?!!b.match(c.filePattern):null};this.canPlayLink=function(b){return typeof b.type!=="undefined"&&b.type&&c.canPlayMIME(b.type)?true:c.canPlayURL(b.href)};this.getSoundById=function(b){if(!b)throw Error("soundManager.getSoundById(): sID is null/undefined");return c.sounds[b]};this.onready=function(c,a){if(c&&c instanceof Function)return a||(a=i),ca("onready",c,a),z(),true;else throw y("needFunction",
+"onready");};this.ontimeout=function(c,a){if(c&&c instanceof Function)return a||(a=i),ca("ontimeout",c,a),z({type:"ontimeout"}),true;else throw y("needFunction","ontimeout");};this._wD=this._writeDebug=function(){return true};this._debug=function(){};this.reboot=function(){var b,a;for(b=c.soundIDs.length;b--;)c.sounds[c.soundIDs[b]].destruct();try{if(v)ha=c.o.innerHTML;J=c.o.parentNode.removeChild(c.o)}catch(e){}ha=J=q=null;c.enabled=ea=m=W=ka=G=H=t=c.swfLoaded=false;c.soundIDs=c.sounds=[];c.o=null;
+for(b in s)if(s.hasOwnProperty(b))for(a=s[b].length;a--;)s[b][a].fired=false;i.setTimeout(c.beginDelayedInit,20)};this.getMoviePercent=function(){return c.o&&typeof c.o.PercentLoaded!=="undefined"?c.o.PercentLoaded():null};this.beginDelayedInit=function(){sa=true;B();setTimeout(function(){if(ka)return false;S();R();return ka=true},20);Q()};this.destruct=function(){c.disable(true)};ra=function(b){var a=this,e,f,d;this.sID=b.id;this.url=b.url;this._iO=this.instanceOptions=this.options=n(b);this.pan=
+this.options.pan;this.volume=this.options.volume;this._lastURL=null;this.isHTML5=false;this._a=null;this.id3={};this._debug=function(){};this.load=function(b){var d=null;if(typeof b!=="undefined")a._iO=n(b,a.options),a.instanceOptions=a._iO;else if(b=a.options,a._iO=b,a.instanceOptions=a._iO,a._lastURL&&a._lastURL!==a.url)a._iO.url=a.url,a.url=null;if(!a._iO.url)a._iO.url=a.url;if(a._iO.url===a.url&&a.readyState!==0&&a.readyState!==2)return a;a._lastURL=a.url;a.loaded=false;a.readyState=1;a.playState=
+0;if(X(a._iO)){if(d=a._setup_html5(a._iO),!d._called_load)a._html5_canplay=false,d.load(),d._called_load=true,a._iO.autoPlay&&a.play()}else try{a.isHTML5=false,a._iO=V(U(a._iO)),g===8?c.o._load(a.sID,a._iO.url,a._iO.stream,a._iO.autoPlay,a._iO.whileloading?1:0,a._iO.loops||1,a._iO.usePolicyFile):c.o._load(a.sID,a._iO.url,!!a._iO.stream,!!a._iO.autoPlay,a._iO.loops||1,!!a._iO.autoLoad,a._iO.usePolicyFile)}catch(e){C({type:"SMSOUND_LOAD_JS_EXCEPTION",fatal:true})}return a};this.unload=function(){a.readyState!==
+0&&(a.isHTML5?(f(),a._a&&(a._a.pause(),la(a._a))):g===8?c.o._unload(a.sID,"about:blank"):c.o._unload(a.sID),e());return a};this.destruct=function(b){if(a.isHTML5){if(f(),a._a)a._a.pause(),la(a._a),L||a._remove_html5_events(),a._a._t=null,a._a=null}else a._iO.onfailure=null,c.o._destroySound(a.sID);b||c.destroySound(a.sID,true)};this.start=this.play=function(b,w){var e,w=w===void 0?true:w;b||(b={});a._iO=n(b,a._iO);a._iO=n(a._iO,a.options);a.instanceOptions=a._iO;if(a._iO.serverURL&&!a.connected)return a.getAutoPlay()||
+a.setAutoPlay(true),a;X(a._iO)&&(a._setup_html5(a._iO),d());if(a.playState===1&&!a.paused&&(e=a._iO.multiShot,!e))return a;if(!a.loaded)if(a.readyState===0){if(!a.isHTML5)a._iO.autoPlay=true;a.load(a._iO)}else if(a.readyState===2)return a;if(!a.isHTML5&&g===9&&a.position>0&&a.position===a.duration)a._iO.position=0;if(a.paused&&a.position&&a.position>0)a.resume();else{a.playState=1;a.paused=false;(!a.instanceCount||a._iO.multiShotEvents||!a.isHTML5&&g>8&&!a.getAutoPlay())&&a.instanceCount++;a.position=
+typeof a._iO.position!=="undefined"&&!isNaN(a._iO.position)?a._iO.position:0;if(!a.isHTML5)a._iO=V(U(a._iO));if(a._iO.onplay&&w)a._iO.onplay.apply(a),a._onplay_called=true;a.setVolume(a._iO.volume,true);a.setPan(a._iO.pan,true);a.isHTML5?(d(),e=a._setup_html5(),a.setPosition(a._iO.position),e.play()):c.o._start(a.sID,a._iO.loops||1,g===9?a._iO.position:a._iO.position/1E3)}return a};this.stop=function(b){if(a.playState===1){a._onbufferchange(0);a.resetOnPosition(0);a.paused=false;if(!a.isHTML5)a.playState=
+0;a._iO.onstop&&a._iO.onstop.apply(a);if(a.isHTML5){if(a._a)a.setPosition(0),a._a.pause(),a.playState=0,a._onTimer(),f()}else c.o._stop(a.sID,b),a._iO.serverURL&&a.unload();a.instanceCount=0;a._iO={}}return a};this.setAutoPlay=function(b){a._iO.autoPlay=b;a.isHTML5||(c.o._setAutoPlay(a.sID,b),b&&!a.instanceCount&&a.readyState===1&&a.instanceCount++)};this.getAutoPlay=function(){return a._iO.autoPlay};this.setPosition=function(b){b===void 0&&(b=0);var d=a.isHTML5?Math.max(b,0):Math.min(a.duration||
+a._iO.duration,Math.max(b,0));a.position=d;b=a.position/1E3;a.resetOnPosition(a.position);a._iO.position=d;if(a.isHTML5){if(a._a&&a._html5_canplay&&a._a.currentTime!==b)try{a._a.currentTime=b,(a.playState===0||a.paused)&&a._a.pause()}catch(e){}}else b=g===9?a.position:b,a.readyState&&a.readyState!==2&&c.o._setPosition(a.sID,b,a.paused||!a.playState);a.isHTML5&&a.paused&&a._onTimer(true);return a};this.pause=function(b){if(a.paused||a.playState===0&&a.readyState!==1)return a;a.paused=true;a.isHTML5?
+(a._setup_html5().pause(),f()):(b||b===void 0)&&c.o._pause(a.sID);a._iO.onpause&&a._iO.onpause.apply(a);return a};this.resume=function(){if(!a.paused)return a;a.paused=false;a.playState=1;a.isHTML5?(a._setup_html5().play(),d()):(a._iO.isMovieStar&&a.setPosition(a.position),c.o._pause(a.sID));!a._onplay_called&&a._iO.onplay?(a._iO.onplay.apply(a),a._onplay_called=true):a._iO.onresume&&a._iO.onresume.apply(a);return a};this.togglePause=function(){if(a.playState===0)return a.play({position:g===9&&!a.isHTML5?
+a.position:a.position/1E3}),a;a.paused?a.resume():a.pause();return a};this.setPan=function(b,d){typeof b==="undefined"&&(b=0);typeof d==="undefined"&&(d=false);a.isHTML5||c.o._setPan(a.sID,b);a._iO.pan=b;if(!d)a.pan=b,a.options.pan=b;return a};this.setVolume=function(b,d){typeof b==="undefined"&&(b=100);typeof d==="undefined"&&(d=false);if(a.isHTML5){if(a._a)a._a.volume=Math.max(0,Math.min(1,b/100))}else c.o._setVolume(a.sID,c.muted&&!a.muted||a.muted?0:b);a._iO.volume=b;if(!d)a.volume=b,a.options.volume=
+b;return a};this.mute=function(){a.muted=true;if(a.isHTML5){if(a._a)a._a.muted=true}else c.o._setVolume(a.sID,0);return a};this.unmute=function(){a.muted=false;var b=typeof a._iO.volume!=="undefined";if(a.isHTML5){if(a._a)a._a.muted=false}else c.o._setVolume(a.sID,b?a._iO.volume:a.options.volume);return a};this.toggleMute=function(){return a.muted?a.unmute():a.mute()};this.onposition=function(b,c,d){a._onPositionItems.push({position:b,method:c,scope:typeof d!=="undefined"?d:a,fired:false});return a};
+this.processOnPosition=function(){var b,d;b=a._onPositionItems.length;if(!b||!a.playState||a._onPositionFired>=b)return false;for(;b--;)if(d=a._onPositionItems[b],!d.fired&&a.position>=d.position)d.fired=true,c._onPositionFired++,d.method.apply(d.scope,[d.position]);return true};this.resetOnPosition=function(b){var d,e;d=a._onPositionItems.length;if(!d)return false;for(;d--;)if(e=a._onPositionItems[d],e.fired&&b<=e.position)e.fired=false,c._onPositionFired--;return true};d=function(){a.isHTML5&&xa(a)};
+f=function(){a.isHTML5&&ya(a)};e=function(){a._onPositionItems=[];a._onPositionFired=0;a._hasTimer=null;a._onplay_called=false;a._a=null;a._html5_canplay=false;a.bytesLoaded=null;a.bytesTotal=null;a.position=null;a.duration=a._iO&&a._iO.duration?a._iO.duration:null;a.durationEstimate=null;a.failures=0;a.loaded=false;a.playState=0;a.paused=false;a.readyState=0;a.muted=false;a.isBuffering=false;a.instanceOptions={};a.instanceCount=0;a.peakData={left:0,right:0};a.waveformData={left:[],right:[]};a.eqData=
+[];a.eqData.left=[];a.eqData.right=[]};e();this._onTimer=function(b){var c={};if(a._hasTimer||b)return a._a&&(b||(a.playState>0||a.readyState===1)&&!a.paused)?(a.duration=a._get_html5_duration(),a.durationEstimate=a.duration,b=a._a.currentTime?a._a.currentTime*1E3:0,a._whileplaying(b,c,c,c,c),true):false};this._get_html5_duration=function(){var b=a._a?a._a.duration*1E3:a._iO?a._iO.duration:void 0;return b&&!isNaN(b)&&b!==Infinity?b:a._iO?a._iO.duration:null};this._setup_html5=function(b){var b=n(a._iO,
+b),d=L?c._global_a:a._a;decodeURI(b.url);var f=d&&d._t?d._t.instanceOptions:null;if(d){if(d._t&&f.url===b.url&&(!a._lastURL||a._lastURL===f.url))return d;L&&d._t&&d._t.playState&&b.url!==f.url&&d._t.stop();e();d.src=b.url;a.url=b.url;a._lastURL=b.url;d._called_load=false}else{d=new Audio(b.url);d._called_load=false;if(Ka)d._called_load=true;if(L)c._global_a=d}a.isHTML5=true;a._a=d;d._t=a;a._add_html5_events();d.loop=b.loops>1?"loop":"";b.autoLoad||b.autoPlay?(d.autobuffer="auto",d.preload="auto",
+a.load(),d._called_load=true):(d.autobuffer=false,d.preload="none");d.loop=b.loops>1?"loop":"";return d};this._add_html5_events=function(){if(a._a._added_events)return false;var b;a._a._added_events=true;for(b in r)r.hasOwnProperty(b)&&a._a&&a._a.addEventListener(b,r[b],false);return true};this._remove_html5_events=function(){var b;a._a._added_events=false;for(b in r)r.hasOwnProperty(b)&&a._a&&a._a.removeEventListener(b,r[b],false)};this._onload=function(b){b=!!b;a.loaded=b;a.readyState=b?3:2;a._onbufferchange(0);
+a._iO.onload&&a._iO.onload.apply(a,[b]);return true};this._onbufferchange=function(b){if(a.playState===0)return false;if(b&&a.isBuffering||!b&&!a.isBuffering)return false;a.isBuffering=b===1;a._iO.onbufferchange&&a._iO.onbufferchange.apply(a);return true};this._onsuspend=function(){a._iO.onsuspend&&a._iO.onsuspend.apply(a);return true};this._onfailure=function(b,c,d){a.failures++;if(a._iO.onfailure&&a.failures===1)a._iO.onfailure(a,b,c,d)};this._onfinish=function(){var b=a._iO.onfinish;a._onbufferchange(0);
+a.resetOnPosition(0);if(a.instanceCount){a.instanceCount--;if(!a.instanceCount)a.playState=0,a.paused=false,a.instanceCount=0,a.instanceOptions={},a._iO={},f();(!a.instanceCount||a._iO.multiShotEvents)&&b&&b.apply(a)}};this._whileloading=function(b,c,d,e){a.bytesLoaded=b;a.bytesTotal=c;a.duration=Math.floor(d);a.bufferLength=e;if(a._iO.isMovieStar)a.durationEstimate=a.duration;else if(a.durationEstimate=a._iO.duration?a.duration>a._iO.duration?a.duration:a._iO.duration:parseInt(a.bytesTotal/a.bytesLoaded*
+a.duration,10),a.durationEstimate===void 0)a.durationEstimate=a.duration;a.readyState!==3&&a._iO.whileloading&&a._iO.whileloading.apply(a)};this._whileplaying=function(b,c,d,e,f){if(isNaN(b)||b===null)return false;a.position=b;a.processOnPosition();if(!a.isHTML5&&g>8){if(a._iO.usePeakData&&typeof c!=="undefined"&&c)a.peakData={left:c.leftPeak,right:c.rightPeak};if(a._iO.useWaveformData&&typeof d!=="undefined"&&d)a.waveformData={left:d.split(","),right:e.split(",")};if(a._iO.useEQData&&typeof f!==
+"undefined"&&f&&f.leftEQ&&(b=f.leftEQ.split(","),a.eqData=b,a.eqData.left=b,typeof f.rightEQ!=="undefined"&&f.rightEQ))a.eqData.right=f.rightEQ.split(",")}a.playState===1&&(!a.isHTML5&&g===8&&!a.position&&a.isBuffering&&a._onbufferchange(0),a._iO.whileplaying&&a._iO.whileplaying.apply(a));return true};this._onid3=function(b,c){var d=[],e,f;for(e=0,f=b.length;e<f;e++)d[b[e]]=c[e];a.id3=n(a.id3,d);a._iO.onid3&&a._iO.onid3.apply(a)};this._onconnect=function(b){b=b===1;if(a.connected=b)a.failures=0,l(a.sID)&&
+(a.getAutoPlay()?a.play(void 0,a.getAutoPlay()):a._iO.autoLoad&&a.load()),a._iO.onconnect&&a._iO.onconnect.apply(a,[b])};this._ondataerror=function(){a.playState>0&&a._iO.ondataerror&&a._iO.ondataerror.apply(a)}};fa=function(){return h.body||h._docElement||h.getElementsByTagName("div")[0]};O=function(b){return h.getElementById(b)};n=function(b,a){var e={},f,d;for(f in b)b.hasOwnProperty(f)&&(e[f]=b[f]);f=typeof a==="undefined"?c.defaultOptions:a;for(d in f)f.hasOwnProperty(d)&&typeof e[d]==="undefined"&&
+(e[d]=f[d]);return e};k=function(){function b(a){var a=Ia.call(a),b=a.length;c?(a[1]="on"+a[1],b>3&&a.pop()):b===3&&a.push(false);return a}function a(a,b){var w=a.shift(),h=[f[b]];if(c)w[h](a[0],a[1]);else w[h].apply(w,a)}var c=i.attachEvent,f={add:c?"attachEvent":"addEventListener",remove:c?"detachEvent":"removeEventListener"};return{add:function(){a(b(arguments),"add")},remove:function(){a(b(arguments),"remove")}}}();r={abort:j(function(){}),canplay:j(function(){if(this._t._html5_canplay)return true;
+this._t._html5_canplay=true;this._t._onbufferchange(0);var b=!isNaN(this._t.position)?this._t.position/1E3:null;if(this._t.position&&this.currentTime!==b)try{this.currentTime=b}catch(a){}}),load:j(function(){this._t.loaded||(this._t._onbufferchange(0),this._t._whileloading(this._t.bytesTotal,this._t.bytesTotal,this._t._get_html5_duration()),this._t._onload(true))}),emptied:j(function(){}),ended:j(function(){this._t._onfinish()}),error:j(function(){this._t._onload(false)}),loadeddata:j(function(){var b=
+this._t,a=b.bytesTotal||1;if(!b._loaded&&!M)b.duration=b._get_html5_duration(),b._whileloading(a,a,b._get_html5_duration()),b._onload(true)}),loadedmetadata:j(function(){}),loadstart:j(function(){this._t._onbufferchange(1)}),play:j(function(){this._t._onbufferchange(0)}),playing:j(function(){this._t._onbufferchange(0)}),progress:j(function(b){if(this._t.loaded)return false;var a,c=0,f=b.target.buffered;a=b.loaded||0;var d=b.total||1;if(f&&f.length){for(a=f.length;a--;)c=f.end(a)-f.start(a);a=c/b.target.duration}isNaN(a)||
+(this._t._onbufferchange(0),this._t._whileloading(a,d,this._t._get_html5_duration()),a&&d&&a===d&&r.load.call(this,b))}),ratechange:j(function(){}),suspend:j(function(b){r.progress.call(this,b);this._t._onsuspend()}),stalled:j(function(){}),timeupdate:j(function(){this._t._onTimer()}),waiting:j(function(){this._t._onbufferchange(1)})};X=function(b){return!b.serverURL&&(b.type?K({type:b.type}):K({url:b.url})||c.html5Only)};la=function(b){if(b)b.src=Ja?"":"about:blank"};K=function(b){function a(a){return c.preferFlash&&
+p&&!c.ignoreFlash&&typeof c.flash[a]!=="undefined"&&c.flash[a]}if(!c.useHTML5Audio||!c.hasHTML5)return false;var e=b.url||null,b=b.type||null,f=c.audioFormats,d;if(b&&c.html5[b]!=="undefined")return c.html5[b]&&!a(b);if(!u){u=[];for(d in f)f.hasOwnProperty(d)&&(u.push(d),f[d].related&&(u=u.concat(f[d].related)));u=RegExp("\\.("+u.join("|")+")(\\?.*)?$","i")}d=e?e.toLowerCase().match(u):null;if(!d||!d.length)if(b)e=b.indexOf(";"),d=(e!==-1?b.substr(0,e):b).substr(6);else return false;else d=d[1];return d&&
+typeof c.html5[d]!=="undefined"?c.html5[d]&&!a(d):(b="audio/"+d,e=c.html5.canPlayType({type:b}),(c.html5[d]=e)&&c.html5[b]&&!a(b))};Aa=function(){function b(b){var d,e,f=false;if(!a||typeof a.canPlayType!=="function")return false;if(b instanceof Array){for(d=0,e=b.length;d<e&&!f;d++)if(c.html5[b[d]]||a.canPlayType(b[d]).match(c.html5Test))f=true,c.html5[b[d]]=true,c.flash[b[d]]=!(!c.preferFlash||!p||!b[d].match(Ea));return f}else return b=a&&typeof a.canPlayType==="function"?a.canPlayType(b):false,
+!(!b||!b.match(c.html5Test))}if(!c.useHTML5Audio||typeof Audio==="undefined")return false;var a=typeof Audio!=="undefined"?Ma?new Audio(null):new Audio:null,e,f={},d,h;d=c.audioFormats;for(e in d)if(d.hasOwnProperty(e)&&(f[e]=b(d[e].type),f["audio/"+e]=f[e],c.flash[e]=c.preferFlash&&!c.ignoreFlash&&e.match(Ea)?true:false,d[e]&&d[e].related))for(h=d[e].related.length;h--;)f["audio/"+d[e].related[h]]=f[e],c.html5[d[e].related[h]]=f[e],c.flash[d[e].related[h]]=f[e];f.canPlayType=a?b:null;c.html5=n(c.html5,
+f);return true};y=function(){};U=function(b){if(g===8&&b.loops>1&&b.stream)b.stream=false;return b};V=function(b){if(b&&!b.usePolicyFile&&(b.onid3||b.usePeakData||b.useWaveformData||b.useEQData))b.usePolicyFile=true;return b};ja=function(){};ba=function(){return false};va=function(b){for(var a in b)b.hasOwnProperty(a)&&typeof b[a]==="function"&&(b[a]=ba)};T=function(b){typeof b==="undefined"&&(b=false);(t||b)&&c.disable(b)};wa=function(b){var a=null;if(b)if(b.match(/\.swf(\?.*)?$/i)){if(a=b.substr(b.toLowerCase().lastIndexOf(".swf?")+
+4))return b}else b.lastIndexOf("/")!==b.length-1&&(b+="/");b=(b&&b.lastIndexOf("/")!==-1?b.substr(0,b.lastIndexOf("/")+1):"./")+c.movieURL;c.noSWFCache&&(b+="?ts="+(new Date).getTime());return b};da=function(){g=parseInt(c.flashVersion,10);if(g!==8&&g!==9)c.flashVersion=g=8;var b=c.debugMode||c.debugFlash?"_debug.swf":".swf";if(c.useHTML5Audio&&!c.html5Only&&c.audioFormats.mp4.required&&g<9)c.flashVersion=g=9;c.version=c.versionNumber+(c.html5Only?" (HTML5-only mode)":g===9?" (AS3/Flash 9)":" (AS2/Flash 8)");
+g>8?(c.defaultOptions=n(c.defaultOptions,c.flash9Options),c.features.buffering=true,c.defaultOptions=n(c.defaultOptions,c.movieStarOptions),c.filePatterns.flash9=RegExp("\\.(mp3|"+Ha.join("|")+")(\\?.*)?$","i"),c.features.movieStar=true):c.features.movieStar=false;c.filePattern=c.filePatterns[g!==8?"flash9":"flash8"];c.movieURL=(g===8?"soundmanager2.swf":"soundmanager2_flash9.swf").replace(".swf",b);c.features.peakData=c.features.waveformData=c.features.eqData=g>8};ua=function(b,a){if(!c.o)return false;
+c.o._setPolling(b,a)};ga=function(){if(c.debugURLParam.test(aa))c.debugMode=true};l=this.getSoundById;D=function(){var b=[];c.debugMode&&b.push(c.swfCSS.sm2Debug);c.debugFlash&&b.push(c.swfCSS.flashDebug);c.useHighPerformance&&b.push(c.swfCSS.highPerf);return b.join(" ")};ia=function(){y("fbHandler");var b=c.getMoviePercent(),a=c.swfCSS,e={type:"FLASHBLOCK"};if(c.html5Only)return false;if(c.ok()){if(c.oMC)c.oMC.className=[D(),a.swfDefault,a.swfLoaded+(c.didFlashBlock?" "+a.swfUnblocked:"")].join(" ")}else{if(q)c.oMC.className=
+D()+" "+a.swfDefault+" "+(b===null?a.swfTimedout:a.swfError);c.didFlashBlock=true;z({type:"ontimeout",ignoreInit:true,error:e});C(e)}};ca=function(b,a,c){typeof s[b]==="undefined"&&(s[b]=[]);s[b].push({method:a,scope:c||null,fired:false})};z=function(b){b||(b={type:"onready"});if(!m&&b&&!b.ignoreInit)return false;if(b.type==="ontimeout"&&c.ok())return false;var a={success:b&&b.ignoreInit?c.ok():!t},e=b&&b.type?s[b.type]||[]:[],f=[],d,a=[a],h=q&&c.useFlashBlock&&!c.ok();if(b.error)a[0].error=b.error;
+for(b=0,d=e.length;b<d;b++)e[b].fired!==true&&f.push(e[b]);if(f.length)for(b=0,d=f.length;b<d;b++)if(f[b].scope?f[b].method.apply(f[b].scope,a):f[b].method.apply(this,a),!h)f[b].fired=true;return true};A=function(){i.setTimeout(function(){c.useFlashBlock&&ia();z();c.onload instanceof Function&&c.onload.apply(i);c.waitForWindowLoad&&k.add(i,"load",A)},1)};Y=function(){if(p!==void 0)return p;var b=false,a=navigator,c=a.plugins,f,d=i.ActiveXObject;if(c&&c.length)(a=a.mimeTypes)&&a["application/x-shockwave-flash"]&&
+a["application/x-shockwave-flash"].enabledPlugin&&a["application/x-shockwave-flash"].enabledPlugin.description&&(b=true);else if(typeof d!=="undefined"){try{f=new d("ShockwaveFlash.ShockwaveFlash")}catch(h){}b=!!f}return p=b};za=function(){var b,a;if(na&&o.match(/os (1|2|3_0|3_1)/i)){c.hasHTML5=false;c.html5Only=true;if(c.oMC)c.oMC.style.display="none";return false}if(c.useHTML5Audio){if(!c.html5||!c.html5.canPlayType)return c.hasHTML5=false,true;else c.hasHTML5=true;if(oa&&Y())return true}else return true;
+for(a in c.audioFormats)if(c.audioFormats.hasOwnProperty(a)&&(c.audioFormats[a].required&&!c.html5.canPlayType(c.audioFormats[a].type)||c.flash[a]||c.flash[c.audioFormats[a].type]))b=true;c.ignoreFlash&&(b=false);c.html5Only=c.hasHTML5&&c.useHTML5Audio&&!b;return!c.html5Only};xa=function(b){if(!b._hasTimer)b._hasTimer=true};ya=function(b){if(b._hasTimer)b._hasTimer=false};C=function(b){b=typeof b!=="undefined"?b:{};c.onerror instanceof Function&&c.onerror.apply(i,[{type:typeof b.type!=="undefined"?
+b.type:null}]);typeof b.fatal!=="undefined"&&b.fatal&&c.disable()};Ba=function(){if(!oa||!Y())return false;var b=c.audioFormats,a,e;for(e in b)if(b.hasOwnProperty(e)&&(e==="mp3"||e==="mp4"))if(c.html5[e]=false,b[e]&&b[e].related)for(a=b[e].related.length;a--;)c.html5[b[e].related[a]]=false};this._setSandboxType=function(){};this._externalInterfaceOK=function(){if(c.swfLoaded)return false;(new Date).getTime();c.swfLoaded=true;E=false;oa&&Ba();v?setTimeout(P,100):P()};S=function(b,a){function e(a,b){return'<param name="'+
+a+'" value="'+b+'" />'}if(G&&H)return false;if(c.html5Only)return da(),c.oMC=O(c.movieID),P(),H=G=true,false;var f=a||c.url,d=c.altURL||f,g;g=fa();var i,l,j=D(),k,m=null,m=(m=h.getElementsByTagName("html")[0])&&m.dir&&m.dir.match(/rtl/i),b=typeof b==="undefined"?c.id:b;da();c.url=wa(qa?f:d);a=c.url;c.wmode=!c.wmode&&c.useHighPerformance?"transparent":c.wmode;if(c.wmode!==null&&(o.match(/msie 8/i)||!v&&!c.useHighPerformance)&&navigator.platform.match(/win32|win64/i))c.specialWmodeCase=true,c.wmode=
+null;g={name:b,id:b,src:a,width:"auto",height:"auto",quality:"high",allowScriptAccess:c.allowScriptAccess,bgcolor:c.bgColor,pluginspage:Fa+"www.macromedia.com/go/getflashplayer",title:"JS/Flash audio component (SoundManager 2)",type:"application/x-shockwave-flash",wmode:c.wmode,hasPriority:"true"};if(c.debugFlash)g.FlashVars="debug=1";c.wmode||delete g.wmode;if(v)f=h.createElement("div"),l=['<object id="'+b+'" data="'+a+'" type="'+g.type+'" title="'+g.title+'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="'+
+Fa+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" width="'+g.width+'" height="'+g.height+'">',e("movie",a),e("AllowScriptAccess",c.allowScriptAccess),e("quality",g.quality),c.wmode?e("wmode",c.wmode):"",e("bgcolor",c.bgColor),e("hasPriority","true"),c.debugFlash?e("FlashVars",g.FlashVars):"","</object>"].join("");else for(i in f=h.createElement("embed"),g)g.hasOwnProperty(i)&&f.setAttribute(i,g[i]);ga();j=D();if(g=fa())if(c.oMC=O(c.movieID)||h.createElement("div"),
+c.oMC.id){k=c.oMC.className;c.oMC.className=(k?k+" ":c.swfCSS.swfDefault)+(j?" "+j:"");c.oMC.appendChild(f);if(v)i=c.oMC.appendChild(h.createElement("div")),i.className=c.swfCSS.swfBox,i.innerHTML=l;H=true}else{c.oMC.id=c.movieID;c.oMC.className=c.swfCSS.swfDefault+" "+j;i=j=null;if(!c.useFlashBlock)if(c.useHighPerformance)j={position:"fixed",width:"8px",height:"8px",bottom:"0px",left:"0px",overflow:"hidden"};else if(j={position:"absolute",width:"6px",height:"6px",top:"-9999px",left:"-9999px"},m)j.left=
+Math.abs(parseInt(j.left,10))+"px";if(La)c.oMC.style.zIndex=1E4;if(!c.debugFlash)for(k in j)j.hasOwnProperty(k)&&(c.oMC.style[k]=j[k]);try{v||c.oMC.appendChild(f);g.appendChild(c.oMC);if(v)i=c.oMC.appendChild(h.createElement("div")),i.className=c.swfCSS.swfBox,i.innerHTML=l;H=true}catch(n){throw Error(y("domError")+" \n"+n.toString());}}return G=true};R=function(){if(c.html5Only)return S(),false;if(c.o)return false;c.o=c.getMovie(c.id);if(!c.o)J?(v?c.oMC.innerHTML=ha:c.oMC.appendChild(J),J=null,G=
+true):S(c.id,c.url),c.o=c.getMovie(c.id);c.oninitmovie instanceof Function&&setTimeout(c.oninitmovie,1);return true};Q=function(){setTimeout(ta,1E3)};ta=function(){if(W)return false;W=true;k.remove(i,"load",Q);if(E&&!pa)return false;var b;m||(b=c.getMoviePercent());setTimeout(function(){b=c.getMoviePercent();!m&&Da&&(b===null?c.useFlashBlock||c.flashLoadTimeout===0?c.useFlashBlock&&ia():T(true):c.flashLoadTimeout!==0&&T(true))},c.flashLoadTimeout)};x=function(){function b(){k.remove(i,"focus",x);
+k.remove(i,"load",x)}if(pa||!E)return b(),true;pa=Da=true;M&&E&&k.remove(i,"mousemove",x);W=false;b();return true};Ca=function(){var b,a=[];if(c.useHTML5Audio&&c.hasHTML5)for(b in c.audioFormats)c.audioFormats.hasOwnProperty(b)&&a.push(b+": "+c.html5[b]+(!c.html5[b]&&p&&c.flash[b]?" (using flash)":c.preferFlash&&c.flash[b]&&p?" (preferring flash)":!c.html5[b]?" ("+(c.audioFormats[b].required?"required, ":"")+"and no flash support)":""))};I=function(b){if(m)return false;if(c.html5Only)return m=true,
+A(),true;var a;if(!c.useFlashBlock||!c.flashLoadTimeout||c.getMoviePercent())m=true,t&&(a={type:!p&&q?"NO_FLASH":"INIT_TIMEOUT"});if(t||b){if(c.useFlashBlock&&c.oMC)c.oMC.className=D()+" "+(c.getMoviePercent()===null?c.swfCSS.swfTimedout:c.swfCSS.swfError);z({type:"ontimeout",error:a});C(a);return false}if(c.waitForWindowLoad&&!sa)return k.add(i,"load",A),false;else A();return true};P=function(){if(m)return false;if(c.html5Only){if(!m)k.remove(i,"load",c.beginDelayedInit),c.enabled=true,I();return true}R();
+try{c.o._externalInterfaceTest(false),ua(true,c.flashPollingInterval||(c.useHighPerformance?10:50)),c.debugMode||c.o._disableDebug(),c.enabled=true,c.html5Only||k.add(i,"unload",ba)}catch(b){return C({type:"JS_TO_FLASH_EXCEPTION",fatal:true}),T(true),I(),false}I();k.remove(i,"load",c.beginDelayedInit);return true};B=function(){if(ea)return false;ea=true;ga();if(!p&&c.hasHTML5)c.useHTML5Audio=true,c.preferFlash=false;Aa();c.html5.usingFlash=za();q=c.html5.usingFlash;Ca();if(!p&&q)c.flashLoadTimeout=
+1;h.removeEventListener&&h.removeEventListener("DOMContentLoaded",B,false);R();return true};ma=function(){h.readyState==="complete"&&(B(),h.detachEvent("onreadystatechange",ma));return true};Y();k.add(i,"focus",x);k.add(i,"load",x);k.add(i,"load",Q);M&&E&&k.add(i,"mousemove",x);h.addEventListener?h.addEventListener("DOMContentLoaded",B,false):h.attachEvent?h.attachEvent("onreadystatechange",ma):C({type:"NO_DOM2_EVENTS",fatal:true});h.readyState==="complete"&&setTimeout(B,100)}var Z=null;if(typeof SM2_DEFER===
+"undefined"||!SM2_DEFER)Z=new N;$.SoundManager=N;$.soundManager=Z})(window);
\ No newline at end of file
--- /dev/null
+/** @license\r
+ *\r
+ * SoundManager 2: JavaScript Sound for the Web\r
+ * ----------------------------------------------\r
+ * http://schillmania.com/projects/soundmanager2/\r
+ *\r
+ * Copyright (c) 2007, Scott Schiller. All rights reserved.\r
+ * Code provided under the BSD License:\r
+ * http://schillmania.com/projects/soundmanager2/license.txt\r
+ *\r
+ * V2.97a.20111030\r
+ */\r
+\r
+/*global window, SM2_DEFER, sm2Debugger, console, document, navigator, setTimeout, setInterval, clearInterval, Audio */\r
+/* jslint regexp: true, sloppy: true, white: true, nomen: true, plusplus: true */\r
+\r
+(function(window) {\r
+var soundManager = null;\r
+function SoundManager(smURL, smID) {\r
+ this.flashVersion = 8;\r
+ this.debugMode = false;\r
+ this.debugFlash = false;\r
+ this.useConsole = true;\r
+ this.consoleOnly = false;\r
+ this.waitForWindowLoad = false;\r
+ this.bgColor = '#ffffff';\r
+ this.useHighPerformance = false;\r
+ this.flashPollingInterval = null;\r
+ this.flashLoadTimeout = 1000;\r
+ this.wmode = null;\r
+ this.allowScriptAccess = 'always';\r
+ this.useFlashBlock = false;\r
+ this.useHTML5Audio = true;\r
+ this.html5Test = /^(probably|maybe)$/i;\r
+ this.preferFlash = true;\r
+ this.noSWFCache = false;\r
+ this.audioFormats = {\r
+ 'mp3': {\r
+ 'type': ['audio/mpeg; codecs="mp3"', 'audio/mpeg', 'audio/mp3', 'audio/MPA', 'audio/mpa-robust'],\r
+ 'required': true\r
+ },\r
+ 'mp4': {\r
+ 'related': ['aac','m4a'],\r
+ 'type': ['audio/mp4; codecs="mp4a.40.2"', 'audio/aac', 'audio/x-m4a', 'audio/MP4A-LATM', 'audio/mpeg4-generic'],\r
+ 'required': false\r
+ },\r
+ 'ogg': {\r
+ 'type': ['audio/ogg; codecs=vorbis'],\r
+ 'required': false\r
+ },\r
+ 'wav': {\r
+ 'type': ['audio/wav; codecs="1"', 'audio/wav', 'audio/wave', 'audio/x-wav'],\r
+ 'required': false\r
+ }\r
+ };\r
+ this.defaultOptions = {\r
+ 'autoLoad': false,\r
+ 'stream': true,\r
+ 'autoPlay': false,\r
+ 'loops': 1,\r
+ 'onid3': null,\r
+ 'onload': null,\r
+ 'whileloading': null,\r
+ 'onplay': null,\r
+ 'onpause': null,\r
+ 'onresume': null,\r
+ 'whileplaying': null,\r
+ 'onstop': null,\r
+ 'onfailure': null,\r
+ 'onfinish': null,\r
+ 'multiShot': true,\r
+ 'multiShotEvents': false,\r
+ 'position': null,\r
+ 'pan': 0,\r
+ 'type': null,\r
+ 'usePolicyFile': false,\r
+ 'volume': 100\r
+ };\r
+ this.flash9Options = {\r
+ 'isMovieStar': null,\r
+ 'usePeakData': false,\r
+ 'useWaveformData': false,\r
+ 'useEQData': false,\r
+ 'onbufferchange': null,\r
+ 'ondataerror': null\r
+ };\r
+ this.movieStarOptions = {\r
+ 'bufferTime': 3,\r
+ 'serverURL': null,\r
+ 'onconnect': null,\r
+ 'duration': null\r
+ };\r
+ this.movieID = 'sm2-container';\r
+ this.id = (smID || 'sm2movie');\r
+ this.swfCSS = {\r
+ 'swfBox': 'sm2-object-box',\r
+ 'swfDefault': 'movieContainer',\r
+ 'swfError': 'swf_error',\r
+ 'swfTimedout': 'swf_timedout',\r
+ 'swfLoaded': 'swf_loaded',\r
+ 'swfUnblocked': 'swf_unblocked',\r
+ 'sm2Debug': 'sm2_debug',\r
+ 'highPerf': 'high_performance',\r
+ 'flashDebug': 'flash_debug'\r
+ };\r
+ this.debugID = 'soundmanager-debug';\r
+ this.debugURLParam = /([#?&])debug=1/i;\r
+ this.versionNumber = 'V2.97a.20111030';\r
+ this.version = null;\r
+ this.movieURL = null;\r
+ this.url = (smURL || null);\r
+ this.altURL = null;\r
+ this.swfLoaded = false;\r
+ this.enabled = false;\r
+ this.o = null;\r
+ this.oMC = null;\r
+ this.sounds = {};\r
+ this.soundIDs = [];\r
+ this.muted = false;\r
+ this.specialWmodeCase = false;\r
+ this.didFlashBlock = false;\r
+ this.filePattern = null;\r
+ this.filePatterns = {\r
+ 'flash8': /\.mp3(\?.*)?$/i,\r
+ 'flash9': /\.mp3(\?.*)?$/i\r
+ };\r
+ this.features = {\r
+ 'buffering': false,\r
+ 'peakData': false,\r
+ 'waveformData': false,\r
+ 'eqData': false,\r
+ 'movieStar': false\r
+ };\r
+ this.sandbox = {\r
+ };\r
+ this.hasHTML5 = (function() {\r
+ try {\r
+ return (typeof Audio !== 'undefined' && typeof new Audio().canPlayType !== 'undefined');\r
+ } catch(e) {\r
+ return false;\r
+ }\r
+ }());\r
+ this.html5 = {\r
+ 'usingFlash': null\r
+ };\r
+ this.flash = {};\r
+ this.html5Only = false;\r
+ this.ignoreFlash = false;\r
+ var SMSound,\r
+ _s = this, _sm = 'soundManager', _smc = _sm+'::', _h5 = 'HTML5::', _id, _ua = navigator.userAgent, _win = window, _wl = _win.location.href.toString(), _doc = document, _doNothing, _init, _fV, _on_queue = [], _debugOpen = true, _debugTS, _didAppend = false, _appendSuccess = false, _didInit = false, _disabled = false, _windowLoaded = false, _wDS, _wdCount = 0, _initComplete, _mixin, _addOnEvent, _processOnEvents, _initUserOnload, _delayWaitForEI, _waitForEI, _setVersionInfo, _handleFocus, _strings, _initMovie, _domContentLoaded, _didDCLoaded, _getDocument, _createMovie, _catchError, _setPolling, _initDebug, _debugLevels = ['log', 'info', 'warn', 'error'], _defaultFlashVersion = 8, _disableObject, _failSafely, _normalizeMovieURL, _oRemoved = null, _oRemovedHTML = null, _str, _flashBlockHandler, _getSWFCSS, _toggleDebug, _loopFix, _policyFix, _complain, _idCheck, _waitingForEI = false, _initPending = false, _smTimer, _onTimer, _startTimer, _stopTimer, _needsFlash = null, _featureCheck, _html5OK, _html5CanPlay, _html5Ext, _html5Unload, _domContentLoadedIE, _testHTML5, _event, _slice = Array.prototype.slice, _useGlobalHTML5Audio = false, _hasFlash, _detectFlash, _badSafariFix, _html5_events, _showSupport,\r
+ _is_iDevice = _ua.match(/(ipad|iphone|ipod)/i), _is_firefox = _ua.match(/firefox/i), _is_android = _ua.match(/droid/i), _isIE = _ua.match(/msie/i), _isWebkit = _ua.match(/webkit/i), _isSafari = (_ua.match(/safari/i) && !_ua.match(/chrome/i)), _isOpera = (_ua.match(/opera/i)),\r
+ _likesHTML5 = (_ua.match(/(mobile|pre\/|xoom)/i) || _is_iDevice),\r
+ _isBadSafari = (!_wl.match(/usehtml5audio/i) && !_wl.match(/sm2\-ignorebadua/i) && _isSafari && _ua.match(/OS X 10_6_([3-7])/i)),\r
+ _hasConsole = (typeof console !== 'undefined' && typeof console.log !== 'undefined'), _isFocused = (typeof _doc.hasFocus !== 'undefined'?_doc.hasFocus():null), _tryInitOnFocus = (_isSafari && typeof _doc.hasFocus === 'undefined'), _okToDisable = !_tryInitOnFocus, _flashMIME = /(mp3|mp4|mpa)/i,\r
+ _emptyURL = 'about:blank',\r
+ _overHTTP = (_doc.location?_doc.location.protocol.match(/http/i):null),\r
+ _http = (!_overHTTP ? 'http:/'+'/' : ''),\r
+ _netStreamMimeTypes = /^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|mp4v|3gp|3g2)\s*(?:$|;)/i,\r
+ _netStreamTypes = ['mpeg4', 'aac', 'flv', 'mov', 'mp4', 'm4v', 'f4v', 'm4a', 'mp4v', '3gp', '3g2'],\r
+ _netStreamPattern = new RegExp('\\.(' + _netStreamTypes.join('|') + ')(\\?.*)?$', 'i');\r
+ this.mimePattern = /^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i;\r
+ this.useAltURL = !_overHTTP;\r
+ this._global_a = null;\r
+ if (_likesHTML5) {\r
+ _s.useHTML5Audio = true;\r
+ _s.preferFlash = false;\r
+ if (_is_iDevice) {\r
+ _s.ignoreFlash = true;\r
+ _useGlobalHTML5Audio = true;\r
+ }\r
+ }\r
+ this.ok = function() {\r
+ return (_needsFlash?(_didInit && !_disabled):(_s.useHTML5Audio && _s.hasHTML5));\r
+ };\r
+ this.supported = this.ok;\r
+ this.getMovie = function(smID) {\r
+ return _id(smID) || _doc[smID] || _win[smID];\r
+ };\r
+ this.createSound = function(oOptions) {\r
+ var _cs = _sm+'.createSound(): ',\r
+ thisOptions = null, oSound = null, _tO = null;\r
+ if (!_didInit || !_s.ok()) {\r
+ _complain(_cs + _str(!_didInit?'notReady':'notOK'));\r
+ return false;\r
+ }\r
+ if (arguments.length === 2) {\r
+ oOptions = {\r
+ 'id': arguments[0],\r
+ 'url': arguments[1]\r
+ };\r
+ }\r
+ thisOptions = _mixin(oOptions);\r
+ _tO = thisOptions;\r
+ if (_idCheck(_tO.id, true)) {\r
+ return _s.sounds[_tO.id];\r
+ }\r
+ function make() {\r
+ thisOptions = _loopFix(thisOptions);\r
+ _s.sounds[_tO.id] = new SMSound(_tO);\r
+ _s.soundIDs.push(_tO.id);\r
+ return _s.sounds[_tO.id];\r
+ }\r
+ if (_html5OK(_tO)) {\r
+ oSound = make();\r
+ oSound._setup_html5(_tO);\r
+ } else {\r
+ if (_fV > 8) {\r
+ if (_tO.isMovieStar === null) {\r
+ _tO.isMovieStar = (_tO.serverURL || (_tO.type ? _tO.type.match(_netStreamMimeTypes) : false) || _tO.url.match(_netStreamPattern));\r
+ }\r
+ if (_tO.isMovieStar) {\r
+ if (_tO.usePeakData) {\r
+ _tO.usePeakData = false;\r
+ }\r
+ }\r
+ }\r
+ _tO = _policyFix(_tO, _cs);\r
+ oSound = make();\r
+ if (_fV === 8) {\r
+ _s.o._createSound(_tO.id, _tO.loops||1, _tO.usePolicyFile);\r
+ } else {\r
+ _s.o._createSound(_tO.id, _tO.url, _tO.usePeakData, _tO.useWaveformData, _tO.useEQData, _tO.isMovieStar, (_tO.isMovieStar?_tO.bufferTime:false), _tO.loops||1, _tO.serverURL, _tO.duration||null, _tO.autoPlay, true, _tO.autoLoad, _tO.usePolicyFile);\r
+ if (!_tO.serverURL) {\r
+ oSound.connected = true;\r
+ if (_tO.onconnect) {\r
+ _tO.onconnect.apply(oSound);\r
+ }\r
+ }\r
+ }\r
+ if (!_tO.serverURL && (_tO.autoLoad || _tO.autoPlay)) {\r
+ oSound.load(_tO);\r
+ }\r
+ }\r
+ if (!_tO.serverURL && _tO.autoPlay) {\r
+ oSound.play();\r
+ }\r
+ return oSound;\r
+ };\r
+ this.destroySound = function(sID, _bFromSound) {\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+ var oS = _s.sounds[sID], i;\r
+ oS._iO = {};\r
+ oS.stop();\r
+ oS.unload();\r
+ for (i = 0; i < _s.soundIDs.length; i++) {\r
+ if (_s.soundIDs[i] === sID) {\r
+ _s.soundIDs.splice(i, 1);\r
+ break;\r
+ }\r
+ }\r
+ if (!_bFromSound) {\r
+ oS.destruct(true);\r
+ }\r
+ oS = null;\r
+ delete _s.sounds[sID];\r
+ return true;\r
+ };\r
+ this.load = function(sID, oOptions) {\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+ return _s.sounds[sID].load(oOptions);\r
+ };\r
+ this.unload = function(sID) {\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+ return _s.sounds[sID].unload();\r
+ };\r
+ this.onposition = function(sID, nPosition, oMethod, oScope) {\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+ return _s.sounds[sID].onposition(nPosition, oMethod, oScope);\r
+ };\r
+ this.play = function(sID, oOptions) {\r
+ var fN = _sm+'.play(): ';\r
+ if (!_didInit || !_s.ok()) {\r
+ _complain(fN + _str(!_didInit?'notReady':'notOK'));\r
+ return false;\r
+ }\r
+ if (!_idCheck(sID)) {\r
+ if (!(oOptions instanceof Object)) {\r
+ oOptions = {\r
+ url: oOptions\r
+ };\r
+ }\r
+ if (oOptions && oOptions.url) {\r
+ oOptions.id = sID;\r
+ return _s.createSound(oOptions).play();\r
+ } else {\r
+ return false;\r
+ }\r
+ }\r
+ return _s.sounds[sID].play(oOptions);\r
+ };\r
+ this.start = this.play;\r
+ this.setPosition = function(sID, nMsecOffset) {\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+ return _s.sounds[sID].setPosition(nMsecOffset);\r
+ };\r
+ this.stop = function(sID) {\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+ return _s.sounds[sID].stop();\r
+ };\r
+ this.stopAll = function() {\r
+ var oSound;\r
+ for (oSound in _s.sounds) {\r
+ if (_s.sounds.hasOwnProperty(oSound)) {\r
+ _s.sounds[oSound].stop();\r
+ }\r
+ }\r
+ };\r
+ this.pause = function(sID) {\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+ return _s.sounds[sID].pause();\r
+ };\r
+ this.pauseAll = function() {\r
+ var i;\r
+ for (i = _s.soundIDs.length; i--;) {\r
+ _s.sounds[_s.soundIDs[i]].pause();\r
+ }\r
+ };\r
+ this.resume = function(sID) {\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+ return _s.sounds[sID].resume();\r
+ };\r
+ this.resumeAll = function() {\r
+ var i;\r
+ for (i = _s.soundIDs.length; i--;) {\r
+ _s.sounds[_s.soundIDs[i]].resume();\r
+ }\r
+ };\r
+ this.togglePause = function(sID) {\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+ return _s.sounds[sID].togglePause();\r
+ };\r
+ this.setPan = function(sID, nPan) {\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+ return _s.sounds[sID].setPan(nPan);\r
+ };\r
+ this.setVolume = function(sID, nVol) {\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+ return _s.sounds[sID].setVolume(nVol);\r
+ };\r
+ this.mute = function(sID) {\r
+ var fN = _sm+'.mute(): ',\r
+ i = 0;\r
+ if (typeof sID !== 'string') {\r
+ sID = null;\r
+ }\r
+ if (!sID) {\r
+ for (i = _s.soundIDs.length; i--;) {\r
+ _s.sounds[_s.soundIDs[i]].mute();\r
+ }\r
+ _s.muted = true;\r
+ } else {\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+ return _s.sounds[sID].mute();\r
+ }\r
+ return true;\r
+ };\r
+ this.muteAll = function() {\r
+ _s.mute();\r
+ };\r
+ this.unmute = function(sID) {\r
+ var fN = _sm+'.unmute(): ', i;\r
+ if (typeof sID !== 'string') {\r
+ sID = null;\r
+ }\r
+ if (!sID) {\r
+ for (i = _s.soundIDs.length; i--;) {\r
+ _s.sounds[_s.soundIDs[i]].unmute();\r
+ }\r
+ _s.muted = false;\r
+ } else {\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+ return _s.sounds[sID].unmute();\r
+ }\r
+ return true;\r
+ };\r
+ this.unmuteAll = function() {\r
+ _s.unmute();\r
+ };\r
+ this.toggleMute = function(sID) {\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+ return _s.sounds[sID].toggleMute();\r
+ };\r
+ this.getMemoryUse = function() {\r
+ var ram = 0;\r
+ if (_s.o && _fV !== 8) {\r
+ ram = parseInt(_s.o._getMemoryUse(), 10);\r
+ }\r
+ return ram;\r
+ };\r
+ this.disable = function(bNoDisable) {\r
+ var i;\r
+ if (typeof bNoDisable === 'undefined') {\r
+ bNoDisable = false;\r
+ }\r
+ if (_disabled) {\r
+ return false;\r
+ }\r
+ _disabled = true;\r
+ for (i = _s.soundIDs.length; i--;) {\r
+ _disableObject(_s.sounds[_s.soundIDs[i]]);\r
+ }\r
+ _initComplete(bNoDisable);\r
+ _event.remove(_win, 'load', _initUserOnload);\r
+ return true;\r
+ };\r
+ this.canPlayMIME = function(sMIME) {\r
+ var result;\r
+ if (_s.hasHTML5) {\r
+ result = _html5CanPlay({type:sMIME});\r
+ }\r
+ if (!_needsFlash || result) {\r
+ return result;\r
+ } else {\r
+ return (sMIME ? !!((_fV > 8 ? sMIME.match(_netStreamMimeTypes) : null) || sMIME.match(_s.mimePattern)) : null);\r
+ }\r
+ };\r
+ this.canPlayURL = function(sURL) {\r
+ var result;\r
+ if (_s.hasHTML5) {\r
+ result = _html5CanPlay({url: sURL});\r
+ }\r
+ if (!_needsFlash || result) {\r
+ return result;\r
+ } else {\r
+ return (sURL ? !!(sURL.match(_s.filePattern)) : null);\r
+ }\r
+ };\r
+ this.canPlayLink = function(oLink) {\r
+ if (typeof oLink.type !== 'undefined' && oLink.type) {\r
+ if (_s.canPlayMIME(oLink.type)) {\r
+ return true;\r
+ }\r
+ }\r
+ return _s.canPlayURL(oLink.href);\r
+ };\r
+ this.getSoundById = function(sID, _suppressDebug) {\r
+ if (!sID) {\r
+ throw new Error(_sm+'.getSoundById(): sID is null/undefined');\r
+ }\r
+ var result = _s.sounds[sID];\r
+ return result;\r
+ };\r
+ this.onready = function(oMethod, oScope) {\r
+ var sType = 'onready';\r
+ if (oMethod && oMethod instanceof Function) {\r
+ if (!oScope) {\r
+ oScope = _win;\r
+ }\r
+ _addOnEvent(sType, oMethod, oScope);\r
+ _processOnEvents();\r
+ return true;\r
+ } else {\r
+ throw _str('needFunction', sType);\r
+ }\r
+ };\r
+ this.ontimeout = function(oMethod, oScope) {\r
+ var sType = 'ontimeout';\r
+ if (oMethod && oMethod instanceof Function) {\r
+ if (!oScope) {\r
+ oScope = _win;\r
+ }\r
+ _addOnEvent(sType, oMethod, oScope);\r
+ _processOnEvents({type:sType});\r
+ return true;\r
+ } else {\r
+ throw _str('needFunction', sType);\r
+ }\r
+ };\r
+ this._writeDebug = function(sText, sType, _bTimestamp) {\r
+ return true;\r
+ };\r
+ this._wD = this._writeDebug;\r
+ this._debug = function() {\r
+ };\r
+ this.reboot = function() {\r
+ var i, j;\r
+ for (i = _s.soundIDs.length; i--;) {\r
+ _s.sounds[_s.soundIDs[i]].destruct();\r
+ }\r
+ try {\r
+ if (_isIE) {\r
+ _oRemovedHTML = _s.o.innerHTML;\r
+ }\r
+ _oRemoved = _s.o.parentNode.removeChild(_s.o);\r
+ } catch(e) {\r
+ }\r
+ _oRemovedHTML = _oRemoved = _needsFlash = null;\r
+ _s.enabled = _didDCLoaded = _didInit = _waitingForEI = _initPending = _didAppend = _appendSuccess = _disabled = _s.swfLoaded = false;\r
+ _s.soundIDs = _s.sounds = [];\r
+ _s.o = null;\r
+ for (i in _on_queue) {\r
+ if (_on_queue.hasOwnProperty(i)) {\r
+ for (j = _on_queue[i].length; j--;) {\r
+ _on_queue[i][j].fired = false;\r
+ }\r
+ }\r
+ }\r
+ _win.setTimeout(_s.beginDelayedInit, 20);\r
+ };\r
+ this.getMoviePercent = function() {\r
+ return (_s.o && typeof _s.o.PercentLoaded !== 'undefined' ? _s.o.PercentLoaded() : null);\r
+ };\r
+ this.beginDelayedInit = function() {\r
+ _windowLoaded = true;\r
+ _domContentLoaded();\r
+ setTimeout(function() {\r
+ if (_initPending) {\r
+ return false;\r
+ }\r
+ _createMovie();\r
+ _initMovie();\r
+ _initPending = true;\r
+ return true;\r
+ }, 20);\r
+ _delayWaitForEI();\r
+ };\r
+ this.destruct = function() {\r
+ _s.disable(true);\r
+ };\r
+ SMSound = function(oOptions) {\r
+ var _t = this, _resetProperties, _stop_html5_timer, _start_html5_timer;\r
+ this.sID = oOptions.id;\r
+ this.url = oOptions.url;\r
+ this.options = _mixin(oOptions);\r
+ this.instanceOptions = this.options;\r
+ this._iO = this.instanceOptions;\r
+ this.pan = this.options.pan;\r
+ this.volume = this.options.volume;\r
+ this._lastURL = null;\r
+ this.isHTML5 = false;\r
+ this._a = null;\r
+ this.id3 = {};\r
+ this._debug = function() {\r
+ };\r
+ this.load = function(oOptions) {\r
+ var oS = null;\r
+ if (typeof oOptions !== 'undefined') {\r
+ _t._iO = _mixin(oOptions, _t.options);\r
+ _t.instanceOptions = _t._iO;\r
+ } else {\r
+ oOptions = _t.options;\r
+ _t._iO = oOptions;\r
+ _t.instanceOptions = _t._iO;\r
+ if (_t._lastURL && _t._lastURL !== _t.url) {\r
+ _t._iO.url = _t.url;\r
+ _t.url = null;\r
+ }\r
+ }\r
+ if (!_t._iO.url) {\r
+ _t._iO.url = _t.url;\r
+ }\r
+ if (_t._iO.url === _t.url && _t.readyState !== 0 && _t.readyState !== 2) {\r
+ return _t;\r
+ }\r
+ _t._lastURL = _t.url;\r
+ _t.loaded = false;\r
+ _t.readyState = 1;\r
+ _t.playState = 0;\r
+ if (_html5OK(_t._iO)) {\r
+ oS = _t._setup_html5(_t._iO);\r
+ if (!oS._called_load) {\r
+ _t._html5_canplay = false;\r
+ oS.load();\r
+ oS._called_load = true;\r
+ if (_t._iO.autoPlay) {\r
+ _t.play();\r
+ }\r
+ } else {\r
+ }\r
+ } else {\r
+ try {\r
+ _t.isHTML5 = false;\r
+ _t._iO = _policyFix(_loopFix(_t._iO));\r
+ if (_fV === 8) {\r
+ _s.o._load(_t.sID, _t._iO.url, _t._iO.stream, _t._iO.autoPlay, (_t._iO.whileloading?1:0), _t._iO.loops||1, _t._iO.usePolicyFile);\r
+ } else {\r
+ _s.o._load(_t.sID, _t._iO.url, !!(_t._iO.stream), !!(_t._iO.autoPlay), _t._iO.loops||1, !!(_t._iO.autoLoad), _t._iO.usePolicyFile);\r
+ }\r
+ } catch(e) {\r
+ _catchError({type:'SMSOUND_LOAD_JS_EXCEPTION', fatal:true});\r
+ }\r
+ }\r
+ return _t;\r
+ };\r
+ this.unload = function() {\r
+ if (_t.readyState !== 0) {\r
+ if (!_t.isHTML5) {\r
+ if (_fV === 8) {\r
+ _s.o._unload(_t.sID, _emptyURL);\r
+ } else {\r
+ _s.o._unload(_t.sID);\r
+ }\r
+ } else {\r
+ _stop_html5_timer();\r
+ if (_t._a) {\r
+ _t._a.pause();\r
+ _html5Unload(_t._a);\r
+ }\r
+ }\r
+ _resetProperties();\r
+ }\r
+ return _t;\r
+ };\r
+ this.destruct = function(_bFromSM) {\r
+ if (!_t.isHTML5) {\r
+ _t._iO.onfailure = null;\r
+ _s.o._destroySound(_t.sID);\r
+ } else {\r
+ _stop_html5_timer();\r
+ if (_t._a) {\r
+ _t._a.pause();\r
+ _html5Unload(_t._a);\r
+ if (!_useGlobalHTML5Audio) {\r
+ _t._remove_html5_events();\r
+ }\r
+ _t._a._t = null;\r
+ _t._a = null;\r
+ }\r
+ }\r
+ if (!_bFromSM) {\r
+ _s.destroySound(_t.sID, true);\r
+ }\r
+ };\r
+ this.play = function(oOptions, _updatePlayState) {\r
+ var fN = 'SMSound.play(): ', allowMulti, a;\r
+ _updatePlayState = _updatePlayState === undefined ? true : _updatePlayState;\r
+ if (!oOptions) {\r
+ oOptions = {};\r
+ }\r
+ _t._iO = _mixin(oOptions, _t._iO);\r
+ _t._iO = _mixin(_t._iO, _t.options);\r
+ _t.instanceOptions = _t._iO;\r
+ if (_t._iO.serverURL && !_t.connected) {\r
+ if (!_t.getAutoPlay()) {\r
+ _t.setAutoPlay(true);\r
+ }\r
+ return _t;\r
+ }\r
+ if (_html5OK(_t._iO)) {\r
+ _t._setup_html5(_t._iO);\r
+ _start_html5_timer();\r
+ }\r
+ if (_t.playState === 1 && !_t.paused) {\r
+ allowMulti = _t._iO.multiShot;\r
+ if (!allowMulti) {\r
+ return _t;\r
+ } else {\r
+ }\r
+ }\r
+ if (!_t.loaded) {\r
+ if (_t.readyState === 0) {\r
+ if (!_t.isHTML5) {\r
+ _t._iO.autoPlay = true;\r
+ }\r
+ _t.load(_t._iO);\r
+ } else if (_t.readyState === 2) {\r
+ return _t;\r
+ } else {\r
+ }\r
+ } else {\r
+ }\r
+ if (!_t.isHTML5 && _fV === 9 && _t.position > 0 && _t.position === _t.duration) {\r
+ _t._iO.position = 0;\r
+ }\r
+ if (_t.paused && _t.position && _t.position > 0) {\r
+ _t.resume();\r
+ } else {\r
+ _t.playState = 1;\r
+ _t.paused = false;\r
+ if (!_t.instanceCount || _t._iO.multiShotEvents || (!_t.isHTML5 && _fV > 8 && !_t.getAutoPlay())) {\r
+ _t.instanceCount++;\r
+ }\r
+ _t.position = (typeof _t._iO.position !== 'undefined' && !isNaN(_t._iO.position)?_t._iO.position:0);\r
+ if (!_t.isHTML5) {\r
+ _t._iO = _policyFix(_loopFix(_t._iO));\r
+ }\r
+ if (_t._iO.onplay && _updatePlayState) {\r
+ _t._iO.onplay.apply(_t);\r
+ _t._onplay_called = true;\r
+ }\r
+ _t.setVolume(_t._iO.volume, true);\r
+ _t.setPan(_t._iO.pan, true);\r
+ if (!_t.isHTML5) {\r
+ _s.o._start(_t.sID, _t._iO.loops || 1, (_fV === 9?_t._iO.position:_t._iO.position / 1000));\r
+ } else {\r
+ _start_html5_timer();\r
+ a = _t._setup_html5();\r
+ _t.setPosition(_t._iO.position);\r
+ a.play();\r
+ }\r
+ }\r
+ return _t;\r
+ };\r
+ this.start = this.play;\r
+ this.stop = function(bAll) {\r
+ if (_t.playState === 1) {\r
+ _t._onbufferchange(0);\r
+ _t.resetOnPosition(0);\r
+ _t.paused = false;\r
+ if (!_t.isHTML5) {\r
+ _t.playState = 0;\r
+ }\r
+ if (_t._iO.onstop) {\r
+ _t._iO.onstop.apply(_t);\r
+ }\r
+ if (!_t.isHTML5) {\r
+ _s.o._stop(_t.sID, bAll);\r
+ if (_t._iO.serverURL) {\r
+ _t.unload();\r
+ }\r
+ } else {\r
+ if (_t._a) {\r
+ _t.setPosition(0);\r
+ _t._a.pause();\r
+ _t.playState = 0;\r
+ _t._onTimer();\r
+ _stop_html5_timer();\r
+ }\r
+ }\r
+ _t.instanceCount = 0;\r
+ _t._iO = {};\r
+ }\r
+ return _t;\r
+ };\r
+ this.setAutoPlay = function(autoPlay) {\r
+ _t._iO.autoPlay = autoPlay;\r
+ if (!_t.isHTML5) {\r
+ _s.o._setAutoPlay(_t.sID, autoPlay);\r
+ if (autoPlay) {\r
+ if (!_t.instanceCount && _t.readyState === 1) {\r
+ _t.instanceCount++;\r
+ }\r
+ }\r
+ }\r
+ };\r
+ this.getAutoPlay = function() {\r
+ return _t._iO.autoPlay;\r
+ };\r
+ this.setPosition = function(nMsecOffset) {\r
+ if (nMsecOffset === undefined) {\r
+ nMsecOffset = 0;\r
+ }\r
+ var original_pos,\r
+ position, position1K,\r
+ offset = (_t.isHTML5 ? Math.max(nMsecOffset,0) : Math.min(_t.duration || _t._iO.duration, Math.max(nMsecOffset, 0)));\r
+ original_pos = _t.position;\r
+ _t.position = offset;\r
+ position1K = _t.position/1000;\r
+ _t.resetOnPosition(_t.position);\r
+ _t._iO.position = offset;\r
+ if (!_t.isHTML5) {\r
+ position = (_fV === 9 ? _t.position : position1K);\r
+ if (_t.readyState && _t.readyState !== 2) {\r
+ _s.o._setPosition(_t.sID, position, (_t.paused || !_t.playState));\r
+ }\r
+ } else if (_t._a) {\r
+ if (_t._html5_canplay) {\r
+ if (_t._a.currentTime !== position1K) {\r
+ try {\r
+ _t._a.currentTime = position1K;\r
+ if (_t.playState === 0 || _t.paused) {\r
+ _t._a.pause();\r
+ }\r
+ } catch(e) {\r
+ }\r
+ }\r
+ } else {\r
+ }\r
+ }\r
+ if (_t.isHTML5) {\r
+ if (_t.paused) {\r
+ _t._onTimer(true);\r
+ }\r
+ }\r
+ return _t;\r
+ };\r
+ this.pause = function(_bCallFlash) {\r
+ if (_t.paused || (_t.playState === 0 && _t.readyState !== 1)) {\r
+ return _t;\r
+ }\r
+ _t.paused = true;\r
+ if (!_t.isHTML5) {\r
+ if (_bCallFlash || _bCallFlash === undefined) {\r
+ _s.o._pause(_t.sID);\r
+ }\r
+ } else {\r
+ _t._setup_html5().pause();\r
+ _stop_html5_timer();\r
+ }\r
+ if (_t._iO.onpause) {\r
+ _t._iO.onpause.apply(_t);\r
+ }\r
+ return _t;\r
+ };\r
+ this.resume = function() {\r
+ if (!_t.paused) {\r
+ return _t;\r
+ }\r
+ _t.paused = false;\r
+ _t.playState = 1;\r
+ if (!_t.isHTML5) {\r
+ if (_t._iO.isMovieStar) {\r
+ _t.setPosition(_t.position);\r
+ }\r
+ _s.o._pause(_t.sID);\r
+ } else {\r
+ _t._setup_html5().play();\r
+ _start_html5_timer();\r
+ }\r
+ if (!_t._onplay_called && _t._iO.onplay) {\r
+ _t._iO.onplay.apply(_t);\r
+ _t._onplay_called = true;\r
+ } else if (_t._iO.onresume) {\r
+ _t._iO.onresume.apply(_t);\r
+ }\r
+ return _t;\r
+ };\r
+ this.togglePause = function() {\r
+ if (_t.playState === 0) {\r
+ _t.play({\r
+ position: (_fV === 9 && !_t.isHTML5 ? _t.position : _t.position / 1000)\r
+ });\r
+ return _t;\r
+ }\r
+ if (_t.paused) {\r
+ _t.resume();\r
+ } else {\r
+ _t.pause();\r
+ }\r
+ return _t;\r
+ };\r
+ this.setPan = function(nPan, bInstanceOnly) {\r
+ if (typeof nPan === 'undefined') {\r
+ nPan = 0;\r
+ }\r
+ if (typeof bInstanceOnly === 'undefined') {\r
+ bInstanceOnly = false;\r
+ }\r
+ if (!_t.isHTML5) {\r
+ _s.o._setPan(_t.sID, nPan);\r
+ }\r
+ _t._iO.pan = nPan;\r
+ if (!bInstanceOnly) {\r
+ _t.pan = nPan;\r
+ _t.options.pan = nPan;\r
+ }\r
+ return _t;\r
+ };\r
+ this.setVolume = function(nVol, _bInstanceOnly) {\r
+ if (typeof nVol === 'undefined') {\r
+ nVol = 100;\r
+ }\r
+ if (typeof _bInstanceOnly === 'undefined') {\r
+ _bInstanceOnly = false;\r
+ }\r
+ if (!_t.isHTML5) {\r
+ _s.o._setVolume(_t.sID, (_s.muted && !_t.muted) || _t.muted?0:nVol);\r
+ } else if (_t._a) {\r
+ _t._a.volume = Math.max(0, Math.min(1, nVol/100));\r
+ }\r
+ _t._iO.volume = nVol;\r
+ if (!_bInstanceOnly) {\r
+ _t.volume = nVol;\r
+ _t.options.volume = nVol;\r
+ }\r
+ return _t;\r
+ };\r
+ this.mute = function() {\r
+ _t.muted = true;\r
+ if (!_t.isHTML5) {\r
+ _s.o._setVolume(_t.sID, 0);\r
+ } else if (_t._a) {\r
+ _t._a.muted = true;\r
+ }\r
+ return _t;\r
+ };\r
+ this.unmute = function() {\r
+ _t.muted = false;\r
+ var hasIO = typeof _t._iO.volume !== 'undefined';\r
+ if (!_t.isHTML5) {\r
+ _s.o._setVolume(_t.sID, hasIO?_t._iO.volume:_t.options.volume);\r
+ } else if (_t._a) {\r
+ _t._a.muted = false;\r
+ }\r
+ return _t;\r
+ };\r
+ this.toggleMute = function() {\r
+ return (_t.muted?_t.unmute():_t.mute());\r
+ };\r
+ this.onposition = function(nPosition, oMethod, oScope) {\r
+ _t._onPositionItems.push({\r
+ position: nPosition,\r
+ method: oMethod,\r
+ scope: (typeof oScope !== 'undefined'?oScope:_t),\r
+ fired: false\r
+ });\r
+ return _t;\r
+ };\r
+ this.processOnPosition = function() {\r
+ var i, item, j = _t._onPositionItems.length;\r
+ if (!j || !_t.playState || _t._onPositionFired >= j) {\r
+ return false;\r
+ }\r
+ for (i=j; i--;) {\r
+ item = _t._onPositionItems[i];\r
+ if (!item.fired && _t.position >= item.position) {\r
+ item.fired = true;\r
+ _s._onPositionFired++;\r
+ item.method.apply(item.scope,[item.position]);\r
+ }\r
+ }\r
+ return true;\r
+ };\r
+ this.resetOnPosition = function(nPosition) {\r
+ var i, item, j = _t._onPositionItems.length;\r
+ if (!j) {\r
+ return false;\r
+ }\r
+ for (i=j; i--;) {\r
+ item = _t._onPositionItems[i];\r
+ if (item.fired && nPosition <= item.position) {\r
+ item.fired = false;\r
+ _s._onPositionFired--;\r
+ }\r
+ }\r
+ return true;\r
+ };\r
+ _start_html5_timer = function() {\r
+ if (_t.isHTML5) {\r
+ _startTimer(_t);\r
+ }\r
+ };\r
+ _stop_html5_timer = function() {\r
+ if (_t.isHTML5) {\r
+ _stopTimer(_t);\r
+ }\r
+ };\r
+ _resetProperties = function() {\r
+ _t._onPositionItems = [];\r
+ _t._onPositionFired = 0;\r
+ _t._hasTimer = null;\r
+ _t._onplay_called = false;\r
+ _t._a = null;\r
+ _t._html5_canplay = false;\r
+ _t.bytesLoaded = null;\r
+ _t.bytesTotal = null;\r
+ _t.position = null;\r
+ _t.duration = (_t._iO && _t._iO.duration?_t._iO.duration:null);\r
+ _t.durationEstimate = null;\r
+ _t.failures = 0;\r
+ _t.loaded = false;\r
+ _t.playState = 0;\r
+ _t.paused = false;\r
+ _t.readyState = 0;\r
+ _t.muted = false;\r
+ _t.isBuffering = false;\r
+ _t.instanceOptions = {};\r
+ _t.instanceCount = 0;\r
+ _t.peakData = {\r
+ left: 0,\r
+ right: 0\r
+ };\r
+ _t.waveformData = {\r
+ left: [],\r
+ right: []\r
+ };\r
+ _t.eqData = [];\r
+ _t.eqData.left = [];\r
+ _t.eqData.right = [];\r
+ };\r
+ _resetProperties();\r
+ this._onTimer = function(bForce) {\r
+ var time, x = {};\r
+ if (_t._hasTimer || bForce) {\r
+ if (_t._a && (bForce || ((_t.playState > 0 || _t.readyState === 1) && !_t.paused))) {\r
+ _t.duration = _t._get_html5_duration();\r
+ _t.durationEstimate = _t.duration;\r
+ time = _t._a.currentTime?_t._a.currentTime*1000:0;\r
+ _t._whileplaying(time,x,x,x,x);\r
+ return true;\r
+ } else {\r
+ return false;\r
+ }\r
+ }\r
+ };\r
+ this._get_html5_duration = function() {\r
+ var d = (_t._a ? _t._a.duration*1000 : (_t._iO ? _t._iO.duration : undefined)),\r
+ result = (d && !isNaN(d) && d !== Infinity ? d : (_t._iO ? _t._iO.duration : null));\r
+ return result;\r
+ };\r
+ this._setup_html5 = function(oOptions) {\r
+ var _iO = _mixin(_t._iO, oOptions), d = decodeURI,\r
+ _a = _useGlobalHTML5Audio ? _s._global_a : _t._a,\r
+ _dURL = d(_iO.url),\r
+ _oldIO = (_a && _a._t ? _a._t.instanceOptions : null);\r
+ if (_a) {\r
+ if (_a._t && _oldIO.url === _iO.url && (!_t._lastURL || (_t._lastURL === _oldIO.url))) {\r
+ return _a;\r
+ }\r
+ if (_useGlobalHTML5Audio && _a._t && _a._t.playState && _iO.url !== _oldIO.url) {\r
+ _a._t.stop();\r
+ }\r
+ _resetProperties();\r
+ _a.src = _iO.url;\r
+ _t.url = _iO.url;\r
+ _t._lastURL = _iO.url;\r
+ _a._called_load = false;\r
+ } else {\r
+ _a = new Audio(_iO.url);\r
+ _a._called_load = false;\r
+ if (_is_android) {\r
+ _a._called_load = true;\r
+ }\r
+ if (_useGlobalHTML5Audio) {\r
+ _s._global_a = _a;\r
+ }\r
+ }\r
+ _t.isHTML5 = true;\r
+ _t._a = _a;\r
+ _a._t = _t;\r
+ _t._add_html5_events();\r
+ _a.loop = (_iO.loops>1?'loop':'');\r
+ if (_iO.autoLoad || _iO.autoPlay) {\r
+ _a.autobuffer = 'auto';\r
+ _a.preload = 'auto';\r
+ _t.load();\r
+ _a._called_load = true;\r
+ } else {\r
+ _a.autobuffer = false;\r
+ _a.preload = 'none';\r
+ }\r
+ _a.loop = (_iO.loops>1?'loop':'');\r
+ return _a;\r
+ };\r
+ this._add_html5_events = function() {\r
+ if (_t._a._added_events) {\r
+ return false;\r
+ }\r
+ var f;\r
+ function add(oEvt, oFn, bCapture) {\r
+ return _t._a ? _t._a.addEventListener(oEvt, oFn, bCapture||false) : null;\r
+ }\r
+ _t._a._added_events = true;\r
+ for (f in _html5_events) {\r
+ if (_html5_events.hasOwnProperty(f)) {\r
+ add(f, _html5_events[f]);\r
+ }\r
+ }\r
+ return true;\r
+ };\r
+ this._remove_html5_events = function() {\r
+ var f;\r
+ function remove(oEvt, oFn, bCapture) {\r
+ return (_t._a ? _t._a.removeEventListener(oEvt, oFn, bCapture||false) : null);\r
+ }\r
+ _t._a._added_events = false;\r
+ for (f in _html5_events) {\r
+ if (_html5_events.hasOwnProperty(f)) {\r
+ remove(f, _html5_events[f]);\r
+ }\r
+ }\r
+ };\r
+ this._onload = function(nSuccess) {\r
+ var fN = 'SMSound._onload(): ', loadOK = !!(nSuccess);\r
+ _t.loaded = loadOK;\r
+ _t.readyState = loadOK?3:2;\r
+ _t._onbufferchange(0);\r
+ if (_t._iO.onload) {\r
+ _t._iO.onload.apply(_t, [loadOK]);\r
+ }\r
+ return true;\r
+ };\r
+ this._onbufferchange = function(nIsBuffering) {\r
+ var fN = 'SMSound._onbufferchange()';\r
+ if (_t.playState === 0) {\r
+ return false;\r
+ }\r
+ if ((nIsBuffering && _t.isBuffering) || (!nIsBuffering && !_t.isBuffering)) {\r
+ return false;\r
+ }\r
+ _t.isBuffering = (nIsBuffering === 1);\r
+ if (_t._iO.onbufferchange) {\r
+ _t._iO.onbufferchange.apply(_t);\r
+ }\r
+ return true;\r
+ };\r
+ this._onsuspend = function () {\r
+ if (_t._iO.onsuspend) {\r
+ _t._iO.onsuspend.apply(_t);\r
+ }\r
+ return true;\r
+ };\r
+ this._onfailure = function(msg, level, code) {\r
+ _t.failures++;\r
+ if (_t._iO.onfailure && _t.failures === 1) {\r
+ _t._iO.onfailure(_t, msg, level, code);\r
+ } else {\r
+ }\r
+ };\r
+ this._onfinish = function() {\r
+ var _io_onfinish = _t._iO.onfinish;\r
+ _t._onbufferchange(0);\r
+ _t.resetOnPosition(0);\r
+ if (_t.instanceCount) {\r
+ _t.instanceCount--;\r
+ if (!_t.instanceCount) {\r
+ _t.playState = 0;\r
+ _t.paused = false;\r
+ _t.instanceCount = 0;\r
+ _t.instanceOptions = {};\r
+ _t._iO = {};\r
+ _stop_html5_timer();\r
+ }\r
+ if (!_t.instanceCount || _t._iO.multiShotEvents) {\r
+ if (_io_onfinish) {\r
+ _io_onfinish.apply(_t);\r
+ }\r
+ }\r
+ }\r
+ };\r
+ this._whileloading = function(nBytesLoaded, nBytesTotal, nDuration, nBufferLength) {\r
+ _t.bytesLoaded = nBytesLoaded;\r
+ _t.bytesTotal = nBytesTotal;\r
+ _t.duration = Math.floor(nDuration);\r
+ _t.bufferLength = nBufferLength;\r
+ if (!_t._iO.isMovieStar) {\r
+ if (_t._iO.duration) {\r
+ _t.durationEstimate = (_t.duration > _t._iO.duration) ? _t.duration : _t._iO.duration;\r
+ } else {\r
+ _t.durationEstimate = parseInt((_t.bytesTotal / _t.bytesLoaded) * _t.duration, 10);\r
+ }\r
+ if (_t.durationEstimate === undefined) {\r
+ _t.durationEstimate = _t.duration;\r
+ }\r
+ if (_t.readyState !== 3 && _t._iO.whileloading) {\r
+ _t._iO.whileloading.apply(_t);\r
+ }\r
+ } else {\r
+ _t.durationEstimate = _t.duration;\r
+ if (_t.readyState !== 3 && _t._iO.whileloading) {\r
+ _t._iO.whileloading.apply(_t);\r
+ }\r
+ }\r
+ };\r
+ this._whileplaying = function(nPosition, oPeakData, oWaveformDataLeft, oWaveformDataRight, oEQData) {\r
+ if (isNaN(nPosition) || nPosition === null) {\r
+ return false;\r
+ }\r
+ _t.position = nPosition;\r
+ _t.processOnPosition();\r
+ if (!_t.isHTML5 && _fV > 8) {\r
+ if (_t._iO.usePeakData && typeof oPeakData !== 'undefined' && oPeakData) {\r
+ _t.peakData = {\r
+ left: oPeakData.leftPeak,\r
+ right: oPeakData.rightPeak\r
+ };\r
+ }\r
+ if (_t._iO.useWaveformData && typeof oWaveformDataLeft !== 'undefined' && oWaveformDataLeft) {\r
+ _t.waveformData = {\r
+ left: oWaveformDataLeft.split(','),\r
+ right: oWaveformDataRight.split(',')\r
+ };\r
+ }\r
+ if (_t._iO.useEQData) {\r
+ if (typeof oEQData !== 'undefined' && oEQData && oEQData.leftEQ) {\r
+ var eqLeft = oEQData.leftEQ.split(',');\r
+ _t.eqData = eqLeft;\r
+ _t.eqData.left = eqLeft;\r
+ if (typeof oEQData.rightEQ !== 'undefined' && oEQData.rightEQ) {\r
+ _t.eqData.right = oEQData.rightEQ.split(',');\r
+ }\r
+ }\r
+ }\r
+ }\r
+ if (_t.playState === 1) {\r
+ if (!_t.isHTML5 && _fV === 8 && !_t.position && _t.isBuffering) {\r
+ _t._onbufferchange(0);\r
+ }\r
+ if (_t._iO.whileplaying) {\r
+ _t._iO.whileplaying.apply(_t);\r
+ }\r
+ }\r
+ return true;\r
+ };\r
+ this._onid3 = function(oID3PropNames, oID3Data) {\r
+ var oData = [], i, j;\r
+ for (i = 0, j = oID3PropNames.length; i < j; i++) {\r
+ oData[oID3PropNames[i]] = oID3Data[i];\r
+ }\r
+ _t.id3 = _mixin(_t.id3, oData);\r
+ if (_t._iO.onid3) {\r
+ _t._iO.onid3.apply(_t);\r
+ }\r
+ };\r
+ this._onconnect = function(bSuccess) {\r
+ var fN = 'SMSound._onconnect(): ';\r
+ bSuccess = (bSuccess === 1);\r
+ _t.connected = bSuccess;\r
+ if (bSuccess) {\r
+ _t.failures = 0;\r
+ if (_idCheck(_t.sID)) {\r
+ if (_t.getAutoPlay()) {\r
+ _t.play(undefined, _t.getAutoPlay());\r
+ } else if (_t._iO.autoLoad) {\r
+ _t.load();\r
+ }\r
+ }\r
+ if (_t._iO.onconnect) {\r
+ _t._iO.onconnect.apply(_t,[bSuccess]);\r
+ }\r
+ }\r
+ };\r
+ this._ondataerror = function(sError) {\r
+ if (_t.playState > 0) {\r
+ if (_t._iO.ondataerror) {\r
+ _t._iO.ondataerror.apply(_t);\r
+ }\r
+ }\r
+ };\r
+ };\r
+ _getDocument = function() {\r
+ return (_doc.body || _doc._docElement || _doc.getElementsByTagName('div')[0]);\r
+ };\r
+ _id = function(sID) {\r
+ return _doc.getElementById(sID);\r
+ };\r
+ _mixin = function(oMain, oAdd) {\r
+ var o1 = {}, i, o2, o;\r
+ for (i in oMain) {\r
+ if (oMain.hasOwnProperty(i)) {\r
+ o1[i] = oMain[i];\r
+ }\r
+ }\r
+ o2 = (typeof oAdd === 'undefined'?_s.defaultOptions:oAdd);\r
+ for (o in o2) {\r
+ if (o2.hasOwnProperty(o) && typeof o1[o] === 'undefined') {\r
+ o1[o] = o2[o];\r
+ }\r
+ }\r
+ return o1;\r
+ };\r
+ _event = (function() {\r
+ var old = (_win.attachEvent),\r
+ evt = {\r
+ add: (old?'attachEvent':'addEventListener'),\r
+ remove: (old?'detachEvent':'removeEventListener')\r
+ };\r
+ function getArgs(oArgs) {\r
+ var args = _slice.call(oArgs), len = args.length;\r
+ if (old) {\r
+ args[1] = 'on' + args[1];\r
+ if (len > 3) {\r
+ args.pop();\r
+ }\r
+ } else if (len === 3) {\r
+ args.push(false);\r
+ }\r
+ return args;\r
+ }\r
+ function apply(args, sType) {\r
+ var element = args.shift(),\r
+ method = [evt[sType]];\r
+ if (old) {\r
+ element[method](args[0], args[1]);\r
+ } else {\r
+ element[method].apply(element, args);\r
+ }\r
+ }\r
+ function add() {\r
+ apply(getArgs(arguments), 'add');\r
+ }\r
+ function remove() {\r
+ apply(getArgs(arguments), 'remove');\r
+ }\r
+ return {\r
+ 'add': add,\r
+ 'remove': remove\r
+ };\r
+ }());\r
+ function _html5_event(oFn) {\r
+ return function(e) {\r
+ if (!this._t || !this._t._a) {\r
+ return null;\r
+ } else {\r
+ return oFn.call(this, e);\r
+ }\r
+ };\r
+ }\r
+ _html5_events = {\r
+ abort: _html5_event(function(e) {\r
+ }),\r
+ canplay: _html5_event(function(e) {\r
+ if (this._t._html5_canplay) {\r
+ return true;\r
+ }\r
+ this._t._html5_canplay = true;\r
+ this._t._onbufferchange(0);\r
+ var position1K = (!isNaN(this._t.position)?this._t.position/1000:null);\r
+ if (this._t.position && this.currentTime !== position1K) {\r
+ try {\r
+ this.currentTime = position1K;\r
+ } catch(ee) {\r
+ }\r
+ }\r
+ }),\r
+ load: _html5_event(function(e) {\r
+ if (!this._t.loaded) {\r
+ this._t._onbufferchange(0);\r
+ this._t._whileloading(this._t.bytesTotal, this._t.bytesTotal, this._t._get_html5_duration());\r
+ this._t._onload(true);\r
+ }\r
+ }),\r
+ emptied: _html5_event(function(e) {\r
+ }),\r
+ ended: _html5_event(function(e) {\r
+ this._t._onfinish();\r
+ }),\r
+ error: _html5_event(function(e) {\r
+ this._t._onload(false);\r
+ }),\r
+ loadeddata: _html5_event(function(e) {\r
+ var t = this._t,\r
+ bytesTotal = t.bytesTotal || 1;\r
+ if (!t._loaded && !_isSafari) {\r
+ t.duration = t._get_html5_duration();\r
+ t._whileloading(bytesTotal, bytesTotal, t._get_html5_duration());\r
+ t._onload(true);\r
+ }\r
+ }),\r
+ loadedmetadata: _html5_event(function(e) {\r
+ }),\r
+ loadstart: _html5_event(function(e) {\r
+ this._t._onbufferchange(1);\r
+ }),\r
+ play: _html5_event(function(e) {\r
+ this._t._onbufferchange(0);\r
+ }),\r
+ playing: _html5_event(function(e) {\r
+ this._t._onbufferchange(0);\r
+ }),\r
+ progress: _html5_event(function(e) {\r
+ if (this._t.loaded) {\r
+ return false;\r
+ }\r
+ var i, j, str, buffered = 0,\r
+ isProgress = (e.type === 'progress'),\r
+ ranges = e.target.buffered,\r
+ loaded = (e.loaded||0),\r
+ total = (e.total||1);\r
+ if (ranges && ranges.length) {\r
+ for (i=ranges.length; i--;) {\r
+ buffered = (ranges.end(i) - ranges.start(i));\r
+ }\r
+ loaded = buffered/e.target.duration;\r
+ }\r
+ if (!isNaN(loaded)) {\r
+ this._t._onbufferchange(0);\r
+ this._t._whileloading(loaded, total, this._t._get_html5_duration());\r
+ if (loaded && total && loaded === total) {\r
+ _html5_events.load.call(this, e);\r
+ }\r
+ }\r
+ }),\r
+ ratechange: _html5_event(function(e) {\r
+ }),\r
+ suspend: _html5_event(function(e) {\r
+ _html5_events.progress.call(this, e);\r
+ this._t._onsuspend();\r
+ }),\r
+ stalled: _html5_event(function(e) {\r
+ }),\r
+ timeupdate: _html5_event(function(e) {\r
+ this._t._onTimer();\r
+ }),\r
+ waiting: _html5_event(function(e) {\r
+ this._t._onbufferchange(1);\r
+ })\r
+ };\r
+ _html5OK = function(iO) {\r
+ return (!iO.serverURL && (iO.type?_html5CanPlay({type:iO.type}):_html5CanPlay({url:iO.url})||_s.html5Only));\r
+ };\r
+ _html5Unload = function(oAudio) {\r
+ if (oAudio) {\r
+ oAudio.src = (_is_firefox ? '' : _emptyURL);\r
+ }\r
+ };\r
+ _html5CanPlay = function(o) {\r
+ if (!_s.useHTML5Audio || !_s.hasHTML5) {\r
+ return false;\r
+ }\r
+ var url = (o.url || null),\r
+ mime = (o.type || null),\r
+ aF = _s.audioFormats,\r
+ result,\r
+ offset,\r
+ fileExt,\r
+ item;\r
+ function preferFlashCheck(kind) {\r
+ return (_s.preferFlash && _hasFlash && !_s.ignoreFlash && (typeof _s.flash[kind] !== 'undefined' && _s.flash[kind]));\r
+ }\r
+ if (mime && _s.html5[mime] !== 'undefined') {\r
+ return (_s.html5[mime] && !preferFlashCheck(mime));\r
+ }\r
+ if (!_html5Ext) {\r
+ _html5Ext = [];\r
+ for (item in aF) {\r
+ if (aF.hasOwnProperty(item)) {\r
+ _html5Ext.push(item);\r
+ if (aF[item].related) {\r
+ _html5Ext = _html5Ext.concat(aF[item].related);\r
+ }\r
+ }\r
+ }\r
+ _html5Ext = new RegExp('\\.('+_html5Ext.join('|')+')(\\?.*)?$','i');\r
+ }\r
+ fileExt = (url ? url.toLowerCase().match(_html5Ext) : null);\r
+ if (!fileExt || !fileExt.length) {\r
+ if (!mime) {\r
+ return false;\r
+ } else {\r
+ offset = mime.indexOf(';');\r
+ fileExt = (offset !== -1?mime.substr(0,offset):mime).substr(6);\r
+ }\r
+ } else {\r
+ fileExt = fileExt[1];\r
+ }\r
+ if (fileExt && typeof _s.html5[fileExt] !== 'undefined') {\r
+ return (_s.html5[fileExt] && !preferFlashCheck(fileExt));\r
+ } else {\r
+ mime = 'audio/'+fileExt;\r
+ result = _s.html5.canPlayType({type:mime});\r
+ _s.html5[fileExt] = result;\r
+ return (result && _s.html5[mime] && !preferFlashCheck(mime));\r
+ }\r
+ };\r
+ _testHTML5 = function() {\r
+ if (!_s.useHTML5Audio || typeof Audio === 'undefined') {\r
+ return false;\r
+ }\r
+ var a = (typeof Audio !== 'undefined' ? (_isOpera ? new Audio(null) : new Audio()) : null),\r
+ item, support = {}, aF, i;\r
+ function _cp(m) {\r
+ var canPlay, i, j, isOK = false;\r
+ if (!a || typeof a.canPlayType !== 'function') {\r
+ return false;\r
+ }\r
+ if (m instanceof Array) {\r
+ for (i=0, j=m.length; i<j && !isOK; i++) {\r
+ if (_s.html5[m[i]] || a.canPlayType(m[i]).match(_s.html5Test)) {\r
+ isOK = true;\r
+ _s.html5[m[i]] = true;\r
+ _s.flash[m[i]] = !!(_s.preferFlash && _hasFlash && m[i].match(_flashMIME));\r
+ }\r
+ }\r
+ return isOK;\r
+ } else {\r
+ canPlay = (a && typeof a.canPlayType === 'function' ? a.canPlayType(m) : false);\r
+ return !!(canPlay && (canPlay.match(_s.html5Test)));\r
+ }\r
+ }\r
+ aF = _s.audioFormats;\r
+ for (item in aF) {\r
+ if (aF.hasOwnProperty(item)) {\r
+ support[item] = _cp(aF[item].type);\r
+ support['audio/'+item] = support[item];\r
+ if (_s.preferFlash && !_s.ignoreFlash && item.match(_flashMIME)) {\r
+ _s.flash[item] = true;\r
+ } else {\r
+ _s.flash[item] = false;\r
+ }\r
+ if (aF[item] && aF[item].related) {\r
+ for (i=aF[item].related.length; i--;) {\r
+ support['audio/'+aF[item].related[i]] = support[item];\r
+ _s.html5[aF[item].related[i]] = support[item];\r
+ _s.flash[aF[item].related[i]] = support[item];\r
+ }\r
+ }\r
+ }\r
+ }\r
+ support.canPlayType = (a?_cp:null);\r
+ _s.html5 = _mixin(_s.html5, support);\r
+ return true;\r
+ };\r
+ _strings = {\r
+ };\r
+ _str = function() {\r
+ };\r
+ _loopFix = function(sOpt) {\r
+ if (_fV === 8 && sOpt.loops > 1 && sOpt.stream) {\r
+ sOpt.stream = false;\r
+ }\r
+ return sOpt;\r
+ };\r
+ _policyFix = function(sOpt, sPre) {\r
+ if (sOpt && !sOpt.usePolicyFile && (sOpt.onid3 || sOpt.usePeakData || sOpt.useWaveformData || sOpt.useEQData)) {\r
+ sOpt.usePolicyFile = true;\r
+ }\r
+ return sOpt;\r
+ };\r
+ _complain = function(sMsg) {\r
+ };\r
+ _doNothing = function() {\r
+ return false;\r
+ };\r
+ _disableObject = function(o) {\r
+ var oProp;\r
+ for (oProp in o) {\r
+ if (o.hasOwnProperty(oProp) && typeof o[oProp] === 'function') {\r
+ o[oProp] = _doNothing;\r
+ }\r
+ }\r
+ oProp = null;\r
+ };\r
+ _failSafely = function(bNoDisable) {\r
+ if (typeof bNoDisable === 'undefined') {\r
+ bNoDisable = false;\r
+ }\r
+ if (_disabled || bNoDisable) {\r
+ _s.disable(bNoDisable);\r
+ }\r
+ };\r
+ _normalizeMovieURL = function(smURL) {\r
+ var urlParams = null, url;\r
+ if (smURL) {\r
+ if (smURL.match(/\.swf(\?.*)?$/i)) {\r
+ urlParams = smURL.substr(smURL.toLowerCase().lastIndexOf('.swf?') + 4);\r
+ if (urlParams) {\r
+ return smURL;\r
+ }\r
+ } else if (smURL.lastIndexOf('/') !== smURL.length - 1) {\r
+ smURL += '/';\r
+ }\r
+ }\r
+ url = (smURL && smURL.lastIndexOf('/') !== - 1 ? smURL.substr(0, smURL.lastIndexOf('/') + 1) : './') + _s.movieURL;\r
+ if (_s.noSWFCache) {\r
+ url += ('?ts=' + new Date().getTime());\r
+ }\r
+ return url;\r
+ };\r
+ _setVersionInfo = function() {\r
+ _fV = parseInt(_s.flashVersion, 10);\r
+ if (_fV !== 8 && _fV !== 9) {\r
+ _s.flashVersion = _fV = _defaultFlashVersion;\r
+ }\r
+ var isDebug = (_s.debugMode || _s.debugFlash?'_debug.swf':'.swf');\r
+ if (_s.useHTML5Audio && !_s.html5Only && _s.audioFormats.mp4.required && _fV < 9) {\r
+ _s.flashVersion = _fV = 9;\r
+ }\r
+ _s.version = _s.versionNumber + (_s.html5Only?' (HTML5-only mode)':(_fV === 9?' (AS3/Flash 9)':' (AS2/Flash 8)'));\r
+ if (_fV > 8) {\r
+ _s.defaultOptions = _mixin(_s.defaultOptions, _s.flash9Options);\r
+ _s.features.buffering = true;\r
+ _s.defaultOptions = _mixin(_s.defaultOptions, _s.movieStarOptions);\r
+ _s.filePatterns.flash9 = new RegExp('\\.(mp3|' + _netStreamTypes.join('|') + ')(\\?.*)?$', 'i');\r
+ _s.features.movieStar = true;\r
+ } else {\r
+ _s.features.movieStar = false;\r
+ }\r
+ _s.filePattern = _s.filePatterns[(_fV !== 8?'flash9':'flash8')];\r
+ _s.movieURL = (_fV === 8?'soundmanager2.swf':'soundmanager2_flash9.swf').replace('.swf', isDebug);\r
+ _s.features.peakData = _s.features.waveformData = _s.features.eqData = (_fV > 8);\r
+ };\r
+ _setPolling = function(bPolling, bHighPerformance) {\r
+ if (!_s.o) {\r
+ return false;\r
+ }\r
+ _s.o._setPolling(bPolling, bHighPerformance);\r
+ };\r
+ _initDebug = function() {\r
+ if (_s.debugURLParam.test(_wl)) {\r
+ _s.debugMode = true;\r
+ }\r
+ };\r
+ _idCheck = this.getSoundById;\r
+ _getSWFCSS = function() {\r
+ var css = [];\r
+ if (_s.debugMode) {\r
+ css.push(_s.swfCSS.sm2Debug);\r
+ }\r
+ if (_s.debugFlash) {\r
+ css.push(_s.swfCSS.flashDebug);\r
+ }\r
+ if (_s.useHighPerformance) {\r
+ css.push(_s.swfCSS.highPerf);\r
+ }\r
+ return css.join(' ');\r
+ };\r
+ _flashBlockHandler = function() {\r
+ var name = _str('fbHandler'),\r
+ p = _s.getMoviePercent(),\r
+ css = _s.swfCSS,\r
+ error = {type:'FLASHBLOCK'};\r
+ if (_s.html5Only) {\r
+ return false;\r
+ }\r
+ if (!_s.ok()) {\r
+ if (_needsFlash) {\r
+ _s.oMC.className = _getSWFCSS() + ' ' + css.swfDefault + ' ' + (p === null?css.swfTimedout:css.swfError);\r
+ }\r
+ _s.didFlashBlock = true;\r
+ _processOnEvents({type:'ontimeout', ignoreInit:true, error:error});\r
+ _catchError(error);\r
+ } else {\r
+ if (_s.didFlashBlock) {\r
+ }\r
+ if (_s.oMC) {\r
+ _s.oMC.className = [_getSWFCSS(), css.swfDefault, css.swfLoaded + (_s.didFlashBlock?' '+css.swfUnblocked:'')].join(' ');\r
+ }\r
+ }\r
+ };\r
+ _addOnEvent = function(sType, oMethod, oScope) {\r
+ if (typeof _on_queue[sType] === 'undefined') {\r
+ _on_queue[sType] = [];\r
+ }\r
+ _on_queue[sType].push({\r
+ 'method': oMethod,\r
+ 'scope': (oScope || null),\r
+ 'fired': false\r
+ });\r
+ };\r
+ _processOnEvents = function(oOptions) {\r
+ if (!oOptions) {\r
+ oOptions = {\r
+ type: 'onready'\r
+ };\r
+ }\r
+ if (!_didInit && oOptions && !oOptions.ignoreInit) {\r
+ return false;\r
+ }\r
+ if (oOptions.type === 'ontimeout' && _s.ok()) {\r
+ return false;\r
+ }\r
+ var status = {\r
+ success: (oOptions && oOptions.ignoreInit?_s.ok():!_disabled)\r
+ },\r
+ srcQueue = (oOptions && oOptions.type?_on_queue[oOptions.type]||[]:[]),\r
+ queue = [], i, j,\r
+ args = [status],\r
+ canRetry = (_needsFlash && _s.useFlashBlock && !_s.ok());\r
+ if (oOptions.error) {\r
+ args[0].error = oOptions.error;\r
+ }\r
+ for (i = 0, j = srcQueue.length; i < j; i++) {\r
+ if (srcQueue[i].fired !== true) {\r
+ queue.push(srcQueue[i]);\r
+ }\r
+ }\r
+ if (queue.length) {\r
+ for (i = 0, j = queue.length; i < j; i++) {\r
+ if (queue[i].scope) {\r
+ queue[i].method.apply(queue[i].scope, args);\r
+ } else {\r
+ queue[i].method.apply(this, args);\r
+ }\r
+ if (!canRetry) {\r
+ queue[i].fired = true;\r
+ }\r
+ }\r
+ }\r
+ return true;\r
+ };\r
+ _initUserOnload = function() {\r
+ _win.setTimeout(function() {\r
+ if (_s.useFlashBlock) {\r
+ _flashBlockHandler();\r
+ }\r
+ _processOnEvents();\r
+ if (_s.onload instanceof Function) {\r
+ _s.onload.apply(_win);\r
+ }\r
+ if (_s.waitForWindowLoad) {\r
+ _event.add(_win, 'load', _initUserOnload);\r
+ }\r
+ },1);\r
+ };\r
+ _detectFlash = function() {\r
+ if (_hasFlash !== undefined) {\r
+ return _hasFlash;\r
+ }\r
+ var hasPlugin = false, n = navigator, nP = n.plugins, obj, type, types, AX = _win.ActiveXObject;\r
+ if (nP && nP.length) {\r
+ type = 'application/x-shockwave-flash';\r
+ types = n.mimeTypes;\r
+ if (types && types[type] && types[type].enabledPlugin && types[type].enabledPlugin.description) {\r
+ hasPlugin = true;\r
+ }\r
+ } else if (typeof AX !== 'undefined') {\r
+ try {\r
+ obj = new AX('ShockwaveFlash.ShockwaveFlash');\r
+ } catch(e) {\r
+ }\r
+ hasPlugin = (!!obj);\r
+ }\r
+ _hasFlash = hasPlugin;\r
+ return hasPlugin;\r
+ };\r
+ _featureCheck = function() {\r
+ var needsFlash, item,\r
+ isSpecial = (_is_iDevice && !!(_ua.match(/os (1|2|3_0|3_1)/i)));\r
+ if (isSpecial) {\r
+ _s.hasHTML5 = false;\r
+ _s.html5Only = true;\r
+ if (_s.oMC) {\r
+ _s.oMC.style.display = 'none';\r
+ }\r
+ return false;\r
+ }\r
+ if (_s.useHTML5Audio) {\r
+ if (!_s.html5 || !_s.html5.canPlayType) {\r
+ _s.hasHTML5 = false;\r
+ return true;\r
+ } else {\r
+ _s.hasHTML5 = true;\r
+ }\r
+ if (_isBadSafari) {\r
+ if (_detectFlash()) {\r
+ return true;\r
+ }\r
+ }\r
+ } else {\r
+ return true;\r
+ }\r
+ for (item in _s.audioFormats) {\r
+ if (_s.audioFormats.hasOwnProperty(item)) {\r
+ if ((_s.audioFormats[item].required && !_s.html5.canPlayType(_s.audioFormats[item].type)) || _s.flash[item] || _s.flash[_s.audioFormats[item].type]) {\r
+ needsFlash = true;\r
+ }\r
+ }\r
+ }\r
+ if (_s.ignoreFlash) {\r
+ needsFlash = false;\r
+ }\r
+ _s.html5Only = (_s.hasHTML5 && _s.useHTML5Audio && !needsFlash);\r
+ return (!_s.html5Only);\r
+ };\r
+ _startTimer = function(oSound) {\r
+ if (!oSound._hasTimer) {\r
+ oSound._hasTimer = true;\r
+ }\r
+ };\r
+ _stopTimer = function(oSound) {\r
+ if (oSound._hasTimer) {\r
+ oSound._hasTimer = false;\r
+ }\r
+ };\r
+ _catchError = function(options) {\r
+ options = (typeof options !== 'undefined' ? options : {});\r
+ if (_s.onerror instanceof Function) {\r
+ _s.onerror.apply(_win, [{type:(typeof options.type !== 'undefined' ? options.type : null)}]);\r
+ }\r
+ if (typeof options.fatal !== 'undefined' && options.fatal) {\r
+ _s.disable();\r
+ }\r
+ };\r
+ _badSafariFix = function() {\r
+ if (!_isBadSafari || !_detectFlash()) {\r
+ return false;\r
+ }\r
+ var aF = _s.audioFormats, i, item;\r
+ for (item in aF) {\r
+ if (aF.hasOwnProperty(item)) {\r
+ if (item === 'mp3' || item === 'mp4') {\r
+ _s.html5[item] = false;\r
+ if (aF[item] && aF[item].related) {\r
+ for (i = aF[item].related.length; i--;) {\r
+ _s.html5[aF[item].related[i]] = false;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ };\r
+ this._setSandboxType = function(sandboxType) {\r
+ };\r
+ this._externalInterfaceOK = function(flashDate) {\r
+ if (_s.swfLoaded) {\r
+ return false;\r
+ }\r
+ var eiTime = new Date().getTime();\r
+ _s.swfLoaded = true;\r
+ _tryInitOnFocus = false;\r
+ if (_isBadSafari) {\r
+ _badSafariFix();\r
+ }\r
+ if (_isIE) {\r
+ setTimeout(_init, 100);\r
+ } else {\r
+ _init();\r
+ }\r
+ };\r
+ _createMovie = function(smID, smURL) {\r
+ if (_didAppend && _appendSuccess) {\r
+ return false;\r
+ }\r
+ function _initMsg() {\r
+ }\r
+ if (_s.html5Only) {\r
+ _setVersionInfo();\r
+ _initMsg();\r
+ _s.oMC = _id(_s.movieID);\r
+ _init();\r
+ _didAppend = true;\r
+ _appendSuccess = true;\r
+ return false;\r
+ }\r
+ var remoteURL = (smURL || _s.url),\r
+ localURL = (_s.altURL || remoteURL),\r
+ swfTitle = 'JS/Flash audio component (SoundManager 2)',\r
+ oEmbed, oMovie, oTarget = _getDocument(), tmp, movieHTML, oEl, extraClass = _getSWFCSS(),\r
+ s, x, sClass, side = 'auto', isRTL = null,\r
+ html = _doc.getElementsByTagName('html')[0];\r
+ isRTL = (html && html.dir && html.dir.match(/rtl/i));\r
+ smID = (typeof smID === 'undefined'?_s.id:smID);\r
+ function param(name, value) {\r
+ return '<param name="'+name+'" value="'+value+'" />';\r
+ }\r
+ _setVersionInfo();\r
+ _s.url = _normalizeMovieURL(_overHTTP?remoteURL:localURL);\r
+ smURL = _s.url;\r
+ _s.wmode = (!_s.wmode && _s.useHighPerformance ? 'transparent' : _s.wmode);\r
+ if (_s.wmode !== null && (_ua.match(/msie 8/i) || (!_isIE && !_s.useHighPerformance)) && navigator.platform.match(/win32|win64/i)) {\r
+ _s.specialWmodeCase = true;\r
+ _s.wmode = null;\r
+ }\r
+ oEmbed = {\r
+ 'name': smID,\r
+ 'id': smID,\r
+ 'src': smURL,\r
+ 'width': side,\r
+ 'height': side,\r
+ 'quality': 'high',\r
+ 'allowScriptAccess': _s.allowScriptAccess,\r
+ 'bgcolor': _s.bgColor,\r
+ 'pluginspage': _http+'www.macromedia.com/go/getflashplayer',\r
+ 'title': swfTitle,\r
+ 'type': 'application/x-shockwave-flash',\r
+ 'wmode': _s.wmode,\r
+ 'hasPriority': 'true'\r
+ };\r
+ if (_s.debugFlash) {\r
+ oEmbed.FlashVars = 'debug=1';\r
+ }\r
+ if (!_s.wmode) {\r
+ delete oEmbed.wmode;\r
+ }\r
+ if (_isIE) {\r
+ oMovie = _doc.createElement('div');\r
+ movieHTML = [\r
+ '<object id="' + smID + '" data="' + smURL + '" type="' + oEmbed.type + '" title="' + oEmbed.title +'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="' + _http+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" width="' + oEmbed.width + '" height="' + oEmbed.height + '">',\r
+ param('movie', smURL),\r
+ param('AllowScriptAccess', _s.allowScriptAccess),\r
+ param('quality', oEmbed.quality),\r
+ (_s.wmode? param('wmode', _s.wmode): ''),\r
+ param('bgcolor', _s.bgColor),\r
+ param('hasPriority', 'true'),\r
+ (_s.debugFlash ? param('FlashVars', oEmbed.FlashVars) : ''),\r
+ '</object>'\r
+ ].join('');\r
+ } else {\r
+ oMovie = _doc.createElement('embed');\r
+ for (tmp in oEmbed) {\r
+ if (oEmbed.hasOwnProperty(tmp)) {\r
+ oMovie.setAttribute(tmp, oEmbed[tmp]);\r
+ }\r
+ }\r
+ }\r
+ _initDebug();\r
+ extraClass = _getSWFCSS();\r
+ oTarget = _getDocument();\r
+ if (oTarget) {\r
+ _s.oMC = (_id(_s.movieID) || _doc.createElement('div'));\r
+ if (!_s.oMC.id) {\r
+ _s.oMC.id = _s.movieID;\r
+ _s.oMC.className = _s.swfCSS.swfDefault + ' ' + extraClass;\r
+ s = null;\r
+ oEl = null;\r
+ if (!_s.useFlashBlock) {\r
+ if (_s.useHighPerformance) {\r
+ s = {\r
+ 'position': 'fixed',\r
+ 'width': '8px',\r
+ 'height': '8px',\r
+ 'bottom': '0px',\r
+ 'left': '0px',\r
+ 'overflow': 'hidden'\r
+ };\r
+ } else {\r
+ s = {\r
+ 'position': 'absolute',\r
+ 'width': '6px',\r
+ 'height': '6px',\r
+ 'top': '-9999px',\r
+ 'left': '-9999px'\r
+ };\r
+ if (isRTL) {\r
+ s.left = Math.abs(parseInt(s.left,10))+'px';\r
+ }\r
+ }\r
+ }\r
+ if (_isWebkit) {\r
+ _s.oMC.style.zIndex = 10000;\r
+ }\r
+ if (!_s.debugFlash) {\r
+ for (x in s) {\r
+ if (s.hasOwnProperty(x)) {\r
+ _s.oMC.style[x] = s[x];\r
+ }\r
+ }\r
+ }\r
+ try {\r
+ if (!_isIE) {\r
+ _s.oMC.appendChild(oMovie);\r
+ }\r
+ oTarget.appendChild(_s.oMC);\r
+ if (_isIE) {\r
+ oEl = _s.oMC.appendChild(_doc.createElement('div'));\r
+ oEl.className = _s.swfCSS.swfBox;\r
+ oEl.innerHTML = movieHTML;\r
+ }\r
+ _appendSuccess = true;\r
+ } catch(e) {\r
+ throw new Error(_str('domError')+' \n'+e.toString());\r
+ }\r
+ } else {\r
+ sClass = _s.oMC.className;\r
+ _s.oMC.className = (sClass?sClass+' ':_s.swfCSS.swfDefault) + (extraClass?' '+extraClass:'');\r
+ _s.oMC.appendChild(oMovie);\r
+ if (_isIE) {\r
+ oEl = _s.oMC.appendChild(_doc.createElement('div'));\r
+ oEl.className = _s.swfCSS.swfBox;\r
+ oEl.innerHTML = movieHTML;\r
+ }\r
+ _appendSuccess = true;\r
+ }\r
+ }\r
+ _didAppend = true;\r
+ _initMsg();\r
+ return true;\r
+ };\r
+ _initMovie = function() {\r
+ if (_s.html5Only) {\r
+ _createMovie();\r
+ return false;\r
+ }\r
+ if (_s.o) {\r
+ return false;\r
+ }\r
+ _s.o = _s.getMovie(_s.id);\r
+ if (!_s.o) {\r
+ if (!_oRemoved) {\r
+ _createMovie(_s.id, _s.url);\r
+ } else {\r
+ if (!_isIE) {\r
+ _s.oMC.appendChild(_oRemoved);\r
+ } else {\r
+ _s.oMC.innerHTML = _oRemovedHTML;\r
+ }\r
+ _oRemoved = null;\r
+ _didAppend = true;\r
+ }\r
+ _s.o = _s.getMovie(_s.id);\r
+ }\r
+ if (_s.oninitmovie instanceof Function) {\r
+ setTimeout(_s.oninitmovie, 1);\r
+ }\r
+ return true;\r
+ };\r
+ _delayWaitForEI = function() {\r
+ setTimeout(_waitForEI, 1000);\r
+ };\r
+ _waitForEI = function() {\r
+ if (_waitingForEI) {\r
+ return false;\r
+ }\r
+ _waitingForEI = true;\r
+ _event.remove(_win, 'load', _delayWaitForEI);\r
+ if (_tryInitOnFocus && !_isFocused) {\r
+ return false;\r
+ }\r
+ var p;\r
+ if (!_didInit) {\r
+ p = _s.getMoviePercent();\r
+ }\r
+ setTimeout(function() {\r
+ p = _s.getMoviePercent();\r
+ if (!_didInit && _okToDisable) {\r
+ if (p === null) {\r
+ if (_s.useFlashBlock || _s.flashLoadTimeout === 0) {\r
+ if (_s.useFlashBlock) {\r
+ _flashBlockHandler();\r
+ }\r
+ } else {\r
+ _failSafely(true);\r
+ }\r
+ } else {\r
+ if (_s.flashLoadTimeout === 0) {\r
+ } else {\r
+ _failSafely(true);\r
+ }\r
+ }\r
+ }\r
+ }, _s.flashLoadTimeout);\r
+ };\r
+ _handleFocus = function() {\r
+ function cleanup() {\r
+ _event.remove(_win, 'focus', _handleFocus);\r
+ _event.remove(_win, 'load', _handleFocus);\r
+ }\r
+ if (_isFocused || !_tryInitOnFocus) {\r
+ cleanup();\r
+ return true;\r
+ }\r
+ _okToDisable = true;\r
+ _isFocused = true;\r
+ if (_isSafari && _tryInitOnFocus) {\r
+ _event.remove(_win, 'mousemove', _handleFocus);\r
+ }\r
+ _waitingForEI = false;\r
+ cleanup();\r
+ return true;\r
+ };\r
+ _showSupport = function() {\r
+ var item, tests = [];\r
+ if (_s.useHTML5Audio && _s.hasHTML5) {\r
+ for (item in _s.audioFormats) {\r
+ if (_s.audioFormats.hasOwnProperty(item)) {\r
+ tests.push(item + ': ' + _s.html5[item] + (!_s.html5[item] && _hasFlash && _s.flash[item] ? ' (using flash)' : (_s.preferFlash && _s.flash[item] && _hasFlash ? ' (preferring flash)': (!_s.html5[item] ? ' (' + (_s.audioFormats[item].required ? 'required, ':'') + 'and no flash support)' : ''))));\r
+ }\r
+ }\r
+ }\r
+ };\r
+ _initComplete = function(bNoDisable) {\r
+ if (_didInit) {\r
+ return false;\r
+ }\r
+ if (_s.html5Only) {\r
+ _didInit = true;\r
+ _initUserOnload();\r
+ return true;\r
+ }\r
+ var wasTimeout = (_s.useFlashBlock && _s.flashLoadTimeout && !_s.getMoviePercent()),\r
+ error;\r
+ if (!wasTimeout) {\r
+ _didInit = true;\r
+ if (_disabled) {\r
+ error = {type: (!_hasFlash && _needsFlash ? 'NO_FLASH' : 'INIT_TIMEOUT')};\r
+ }\r
+ }\r
+ if (_disabled || bNoDisable) {\r
+ if (_s.useFlashBlock && _s.oMC) {\r
+ _s.oMC.className = _getSWFCSS() + ' ' + (_s.getMoviePercent() === null?_s.swfCSS.swfTimedout:_s.swfCSS.swfError);\r
+ }\r
+ _processOnEvents({type:'ontimeout', error:error});\r
+ _catchError(error);\r
+ return false;\r
+ } else {\r
+ }\r
+ if (_s.waitForWindowLoad && !_windowLoaded) {\r
+ _event.add(_win, 'load', _initUserOnload);\r
+ return false;\r
+ } else {\r
+ _initUserOnload();\r
+ }\r
+ return true;\r
+ };\r
+ _init = function() {\r
+ if (_didInit) {\r
+ return false;\r
+ }\r
+ function _cleanup() {\r
+ _event.remove(_win, 'load', _s.beginDelayedInit);\r
+ }\r
+ if (_s.html5Only) {\r
+ if (!_didInit) {\r
+ _cleanup();\r
+ _s.enabled = true;\r
+ _initComplete();\r
+ }\r
+ return true;\r
+ }\r
+ _initMovie();\r
+ try {\r
+ _s.o._externalInterfaceTest(false);\r
+ _setPolling(true, (_s.flashPollingInterval || (_s.useHighPerformance ? 10 : 50)));\r
+ if (!_s.debugMode) {\r
+ _s.o._disableDebug();\r
+ }\r
+ _s.enabled = true;\r
+ if (!_s.html5Only) {\r
+ _event.add(_win, 'unload', _doNothing);\r
+ }\r
+ } catch(e) {\r
+ _catchError({type:'JS_TO_FLASH_EXCEPTION', fatal:true});\r
+ _failSafely(true);\r
+ _initComplete();\r
+ return false;\r
+ }\r
+ _initComplete();\r
+ _cleanup();\r
+ return true;\r
+ };\r
+ _domContentLoaded = function() {\r
+ if (_didDCLoaded) {\r
+ return false;\r
+ }\r
+ _didDCLoaded = true;\r
+ _initDebug();\r
+ if (!_hasFlash && _s.hasHTML5) {\r
+ _s.useHTML5Audio = true;\r
+ _s.preferFlash = false;\r
+ }\r
+ _testHTML5();\r
+ _s.html5.usingFlash = _featureCheck();\r
+ _needsFlash = _s.html5.usingFlash;\r
+ _showSupport();\r
+ if (!_hasFlash && _needsFlash) {\r
+ _s.flashLoadTimeout = 1;\r
+ }\r
+ if (_doc.removeEventListener) {\r
+ _doc.removeEventListener('DOMContentLoaded', _domContentLoaded, false);\r
+ }\r
+ _initMovie();\r
+ return true;\r
+ };\r
+ _domContentLoadedIE = function() {\r
+ if (_doc.readyState === 'complete') {\r
+ _domContentLoaded();\r
+ _doc.detachEvent('onreadystatechange', _domContentLoadedIE);\r
+ }\r
+ return true;\r
+ };\r
+ _detectFlash();\r
+ _event.add(_win, 'focus', _handleFocus);\r
+ _event.add(_win, 'load', _handleFocus);\r
+ _event.add(_win, 'load', _delayWaitForEI);\r
+ if (_isSafari && _tryInitOnFocus) {\r
+ _event.add(_win, 'mousemove', _handleFocus);\r
+ }\r
+ if (_doc.addEventListener) {\r
+ _doc.addEventListener('DOMContentLoaded', _domContentLoaded, false);\r
+ } else if (_doc.attachEvent) {\r
+ _doc.attachEvent('onreadystatechange', _domContentLoadedIE);\r
+ } else {\r
+ _catchError({type:'NO_DOM2_EVENTS', fatal:true});\r
+ }\r
+ if (_doc.readyState === 'complete') {\r
+ setTimeout(_domContentLoaded,100);\r
+ }\r
+}\r
+// SM2_DEFER details: http://www.schillmania.com/projects/soundmanager2/doc/getstarted/#lazy-loading\r
+if (typeof SM2_DEFER === 'undefined' || !SM2_DEFER) {\r
+ soundManager = new SoundManager();\r
+}\r
+window.SoundManager = SoundManager;\r
+window.soundManager = soundManager;\r
+}(window));
\ No newline at end of file
--- /dev/null
+/** @license\r
+ *\r
+ * SoundManager 2: JavaScript Sound for the Web\r
+ * ----------------------------------------------\r
+ * http://schillmania.com/projects/soundmanager2/\r
+ *\r
+ * Copyright (c) 2007, Scott Schiller. All rights reserved.\r
+ * Code provided under the BSD License:\r
+ * http://schillmania.com/projects/soundmanager2/license.txt\r
+ *\r
+ * V2.97a.20111030\r
+ */\r
+\r
+/*global window, SM2_DEFER, sm2Debugger, console, document, navigator, setTimeout, setInterval, clearInterval, Audio */\r
+/* jslint regexp: true, sloppy: true, white: true, nomen: true, plusplus: true */\r
+\r
+/**\r
+ * About this file\r
+ * ---------------\r
+ * This is the fully-commented source version of the SoundManager 2 API,\r
+ * recommended for use during development and testing.\r
+ *\r
+ * See soundmanager2-nodebug-jsmin.js for an optimized build (~10KB with gzip.)\r
+ * http://schillmania.com/projects/soundmanager2/doc/getstarted/#basic-inclusion\r
+ * Alternately, serve this file with gzip for 75% compression savings (~30KB over HTTP.)\r
+ *\r
+ * You may notice <d> and </d> comments in this source; these are delimiters for\r
+ * debug blocks which are removed in the -nodebug builds, further optimizing code size.\r
+ */\r
+\r
+(function(window) {\r
+\r
+var soundManager = null;\r
+\r
+/**\r
+ * The SoundManager constructor.\r
+ *\r
+ * @constructor\r
+ * @param {string} smURL Optional: Path to SWF files\r
+ * @param {string} smID Optional: The ID to use for the SWF container element\r
+ * @this {SoundManager}\r
+ * @return {SoundManager} The new SoundManager instance\r
+ */\r
+\r
+function SoundManager(smURL, smID) {\r
+\r
+ // Top-level configuration options\r
+\r
+ this.flashVersion = 8; // version of flash to require, either 8 or 9. Some API features require Flash 9.\r
+ this.debugMode = true; // enable debugging output (div#soundmanager-debug, OR console if available+configured)\r
+ this.debugFlash = false; // enable debugging output inside SWF, troubleshoot Flash/browser issues\r
+ this.useConsole = true; // use firebug/safari console.log()-type debug console if available\r
+ this.consoleOnly = false; // if console is being used, do not create/write to #soundmanager-debug\r
+ this.waitForWindowLoad = false; // force SM2 to wait for window.onload() before trying to call soundManager.onload()\r
+ this.bgColor = '#ffffff'; // movie (.swf) background color, eg. '#000000'\r
+ this.useHighPerformance = false; // position:fixed flash movie can help increase js/flash speed, minimize lag\r
+ this.flashPollingInterval = null; // msec affecting whileplaying/loading callback frequency. If null, default of 50 msec is used.\r
+ this.flashLoadTimeout = 1000; // msec to wait for flash movie to load before failing (0 = infinity)\r
+ this.wmode = null; // string: flash rendering mode - null, transparent, opaque (last two allow layering of HTML on top)\r
+ this.allowScriptAccess = 'always'; // for scripting the SWF (object/embed property), either 'always' or 'sameDomain'\r
+ this.useFlashBlock = false; // *requires flashblock.css, see demos* - allow recovery from flash blockers. Wait indefinitely and apply timeout CSS to SWF, if applicable.\r
+ this.useHTML5Audio = true; // use HTML5 Audio() where API is supported (most Safari, Chrome versions), Firefox (no MP3/MP4.) Ideally, transparent vs. Flash API where possible.\r
+ this.html5Test = /^(probably|maybe)$/i; // HTML5 Audio() format support test. Use /^probably$/i; if you want to be more conservative.\r
+ this.preferFlash = true; // overrides useHTML5audio. if true and flash support present, will try to use flash for MP3/MP4 as needed since HTML5 audio support is still quirky in browsers.\r
+ this.noSWFCache = false; // if true, appends ?ts={date} to break aggressive SWF caching.\r
+\r
+ this.audioFormats = {\r
+\r
+ /**\r
+ * determines HTML5 support + flash requirements.\r
+ * if no support (via flash and/or HTML5) for a "required" format, SM2 will fail to start.\r
+ * flash fallback is used for MP3 or MP4 if HTML5 can't play it (or if preferFlash = true)\r
+ * multiple MIME types may be tested while trying to get a positive canPlayType() response.\r
+ */\r
+\r
+ 'mp3': {\r
+ 'type': ['audio/mpeg; codecs="mp3"', 'audio/mpeg', 'audio/mp3', 'audio/MPA', 'audio/mpa-robust'],\r
+ 'required': true\r
+ },\r
+\r
+ 'mp4': {\r
+ 'related': ['aac','m4a'], // additional formats under the MP4 container\r
+ 'type': ['audio/mp4; codecs="mp4a.40.2"', 'audio/aac', 'audio/x-m4a', 'audio/MP4A-LATM', 'audio/mpeg4-generic'],\r
+ 'required': false\r
+\r
+ },\r
+\r
+ 'ogg': {\r
+ 'type': ['audio/ogg; codecs=vorbis'],\r
+ 'required': false\r
+ },\r
+\r
+ 'wav': {\r
+ 'type': ['audio/wav; codecs="1"', 'audio/wav', 'audio/wave', 'audio/x-wav'],\r
+ 'required': false\r
+ }\r
+\r
+ };\r
+\r
+ this.defaultOptions = {\r
+\r
+ /**\r
+ * the default configuration for sound objects made with createSound() and related methods\r
+ * eg., volume, auto-load behaviour and so forth\r
+ */\r
+\r
+ 'autoLoad': false, // enable automatic loading (otherwise .load() will be called on demand with .play(), the latter being nicer on bandwidth - if you want to .load yourself, you also can)\r
+ 'stream': true, // allows playing before entire file has loaded (recommended)\r
+ 'autoPlay': false, // enable playing of file as soon as possible (much faster if "stream" is true)\r
+ 'loops': 1, // how many times to repeat the sound (position will wrap around to 0, setPosition() will break out of loop when >0)\r
+ 'onid3': null, // callback function for "ID3 data is added/available"\r
+ 'onload': null, // callback function for "load finished"\r
+ 'whileloading': null, // callback function for "download progress update" (X of Y bytes received)\r
+ 'onplay': null, // callback for "play" start\r
+ 'onpause': null, // callback for "pause"\r
+ 'onresume': null, // callback for "resume" (pause toggle)\r
+ 'whileplaying': null, // callback during play (position update)\r
+ 'onstop': null, // callback for "user stop"\r
+ 'onfailure': null, // callback function for when playing fails\r
+ 'onfinish': null, // callback function for "sound finished playing"\r
+ 'multiShot': true, // let sounds "restart" or layer on top of each other when played multiple times, rather than one-shot/one at a time\r
+ 'multiShotEvents': false, // fire multiple sound events (currently onfinish() only) when multiShot is enabled\r
+ 'position': null, // offset (milliseconds) to seek to within loaded sound data.\r
+ 'pan': 0, // "pan" settings, left-to-right, -100 to 100\r
+ 'type': null, // MIME-like hint for file pattern / canPlay() tests, eg. audio/mp3\r
+ 'usePolicyFile': false, // enable crossdomain.xml request for audio on remote domains (for ID3/waveform access)\r
+ 'volume': 100 // self-explanatory. 0-100, the latter being the max.\r
+\r
+ };\r
+\r
+ this.flash9Options = {\r
+\r
+ /**\r
+ * flash 9-only options,\r
+ * merged into defaultOptions if flash 9 is being used\r
+ */\r
+\r
+ 'isMovieStar': null, // "MovieStar" MPEG4 audio mode. Null (default) = auto detect MP4, AAC etc. based on URL. true = force on, ignore URL\r
+ 'usePeakData': false, // enable left/right channel peak (level) data\r
+ 'useWaveformData': false, // enable sound spectrum (raw waveform data) - NOTE: May increase CPU load.\r
+ 'useEQData': false, // enable sound EQ (frequency spectrum data) - NOTE: May increase CPU load.\r
+ 'onbufferchange': null, // callback for "isBuffering" property change\r
+ 'ondataerror': null // callback for waveform/eq data access error (flash playing audio in other tabs/domains)\r
+\r
+ };\r
+\r
+ this.movieStarOptions = {\r
+\r
+ /**\r
+ * flash 9.0r115+ MPEG4 audio options,\r
+ * merged into defaultOptions if flash 9+movieStar mode is enabled\r
+ */\r
+\r
+ 'bufferTime': 3, // seconds of data to buffer before playback begins (null = flash default of 0.1 seconds - if AAC playback is gappy, try increasing.)\r
+ 'serverURL': null, // rtmp: FMS or FMIS server to connect to, required when requesting media via RTMP or one of its variants\r
+ 'onconnect': null, // rtmp: callback for connection to flash media server\r
+ 'duration': null // rtmp: song duration (msec)\r
+\r
+ };\r
+\r
+ // HTML attributes (id + class names) for the SWF container\r
+\r
+ this.movieID = 'sm2-container';\r
+ this.id = (smID || 'sm2movie');\r
+\r
+ this.swfCSS = {\r
+\r
+ 'swfBox': 'sm2-object-box',\r
+ 'swfDefault': 'movieContainer',\r
+ 'swfError': 'swf_error', // SWF loaded, but SM2 couldn't start (other error)\r
+ 'swfTimedout': 'swf_timedout',\r
+ 'swfLoaded': 'swf_loaded',\r
+ 'swfUnblocked': 'swf_unblocked', // or loaded OK\r
+ 'sm2Debug': 'sm2_debug',\r
+ 'highPerf': 'high_performance',\r
+ 'flashDebug': 'flash_debug'\r
+\r
+ };\r
+\r
+ this.debugID = 'soundmanager-debug';\r
+ this.debugURLParam = /([#?&])debug=1/i;\r
+\r
+ // dynamic attributes\r
+\r
+ this.versionNumber = 'V2.97a.20111030';\r
+ this.version = null;\r
+ this.movieURL = null;\r
+ this.url = (smURL || null);\r
+ this.altURL = null;\r
+ this.swfLoaded = false;\r
+ this.enabled = false;\r
+ this.o = null;\r
+ this.oMC = null;\r
+ this.sounds = {};\r
+ this.soundIDs = [];\r
+ this.muted = false;\r
+ this.specialWmodeCase = false;\r
+ this.didFlashBlock = false;\r
+ this.filePattern = null;\r
+\r
+ this.filePatterns = {\r
+\r
+ 'flash8': /\.mp3(\?.*)?$/i,\r
+ 'flash9': /\.mp3(\?.*)?$/i\r
+\r
+ };\r
+\r
+ // support indicators, set at init\r
+\r
+ this.features = {\r
+\r
+ 'buffering': false,\r
+ 'peakData': false,\r
+ 'waveformData': false,\r
+ 'eqData': false,\r
+ 'movieStar': false\r
+\r
+ };\r
+\r
+ // flash sandbox info, used primarily in troubleshooting\r
+\r
+ this.sandbox = {\r
+\r
+ // <d>\r
+ 'type': null,\r
+ 'types': {\r
+ 'remote': 'remote (domain-based) rules',\r
+ 'localWithFile': 'local with file access (no internet access)',\r
+ 'localWithNetwork': 'local with network (internet access only, no local access)',\r
+ 'localTrusted': 'local, trusted (local+internet access)'\r
+ },\r
+ 'description': null,\r
+ 'noRemote': null,\r
+ 'noLocal': null\r
+ // </d>\r
+\r
+ };\r
+\r
+ /**\r
+ * basic HTML5 Audio() support test\r
+ * try...catch because of IE 9 "not implemented" nonsense\r
+ * https://github.com/Modernizr/Modernizr/issues/224\r
+ */\r
+\r
+ this.hasHTML5 = (function() {\r
+ try {\r
+ return (typeof Audio !== 'undefined' && typeof new Audio().canPlayType !== 'undefined');\r
+ } catch(e) {\r
+ return false;\r
+ }\r
+ }());\r
+\r
+ /**\r
+ * format support (html5/flash)\r
+ * stores canPlayType() results based on audioFormats.\r
+ * eg. { mp3: boolean, mp4: boolean }\r
+ * treat as read-only.\r
+ */\r
+\r
+ this.html5 = {\r
+ 'usingFlash': null // set if/when flash fallback is needed\r
+ };\r
+\r
+ this.flash = {};\r
+\r
+ this.html5Only = false; // determined at init time\r
+ this.ignoreFlash = false; // used for special cases (eg. iPad/iPhone/palm OS?)\r
+\r
+ /**\r
+ * a few private internals (OK, a lot. :D)\r
+ */\r
+\r
+ var SMSound,\r
+ _s = this, _sm = 'soundManager', _smc = _sm+'::', _h5 = 'HTML5::', _id, _ua = navigator.userAgent, _win = window, _wl = _win.location.href.toString(), _doc = document, _doNothing, _init, _fV, _on_queue = [], _debugOpen = true, _debugTS, _didAppend = false, _appendSuccess = false, _didInit = false, _disabled = false, _windowLoaded = false, _wDS, _wdCount = 0, _initComplete, _mixin, _addOnEvent, _processOnEvents, _initUserOnload, _delayWaitForEI, _waitForEI, _setVersionInfo, _handleFocus, _strings, _initMovie, _domContentLoaded, _didDCLoaded, _getDocument, _createMovie, _catchError, _setPolling, _initDebug, _debugLevels = ['log', 'info', 'warn', 'error'], _defaultFlashVersion = 8, _disableObject, _failSafely, _normalizeMovieURL, _oRemoved = null, _oRemovedHTML = null, _str, _flashBlockHandler, _getSWFCSS, _toggleDebug, _loopFix, _policyFix, _complain, _idCheck, _waitingForEI = false, _initPending = false, _smTimer, _onTimer, _startTimer, _stopTimer, _needsFlash = null, _featureCheck, _html5OK, _html5CanPlay, _html5Ext, _html5Unload, _domContentLoadedIE, _testHTML5, _event, _slice = Array.prototype.slice, _useGlobalHTML5Audio = false, _hasFlash, _detectFlash, _badSafariFix, _html5_events, _showSupport,\r
+ _is_iDevice = _ua.match(/(ipad|iphone|ipod)/i), _is_firefox = _ua.match(/firefox/i), _is_android = _ua.match(/droid/i), _isIE = _ua.match(/msie/i), _isWebkit = _ua.match(/webkit/i), _isSafari = (_ua.match(/safari/i) && !_ua.match(/chrome/i)), _isOpera = (_ua.match(/opera/i)), \r
+ _likesHTML5 = (_ua.match(/(mobile|pre\/|xoom)/i) || _is_iDevice),\r
+ _isBadSafari = (!_wl.match(/usehtml5audio/i) && !_wl.match(/sm2\-ignorebadua/i) && _isSafari && _ua.match(/OS X 10_6_([3-7])/i)), // Safari 4 and 5 occasionally fail to load/play HTML5 audio on Snow Leopard 10.6.3 through 10.6.7 due to bug(s) in QuickTime X and/or other underlying frameworks. :/ Confirmed bug. https://bugs.webkit.org/show_bug.cgi?id=32159\r
+ _hasConsole = (typeof console !== 'undefined' && typeof console.log !== 'undefined'), _isFocused = (typeof _doc.hasFocus !== 'undefined'?_doc.hasFocus():null), _tryInitOnFocus = (_isSafari && typeof _doc.hasFocus === 'undefined'), _okToDisable = !_tryInitOnFocus, _flashMIME = /(mp3|mp4|mpa)/i,\r
+ _emptyURL = 'about:blank', // safe URL to unload, or load nothing from (flash 8 + most HTML5 UAs)\r
+ _overHTTP = (_doc.location?_doc.location.protocol.match(/http/i):null),\r
+ _http = (!_overHTTP ? 'http:/'+'/' : ''),\r
+ // mp3, mp4, aac etc.\r
+ _netStreamMimeTypes = /^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|mp4v|3gp|3g2)\s*(?:$|;)/i,\r
+ // Flash v9.0r115+ "moviestar" formats\r
+ _netStreamTypes = ['mpeg4', 'aac', 'flv', 'mov', 'mp4', 'm4v', 'f4v', 'm4a', 'mp4v', '3gp', '3g2'],\r
+ _netStreamPattern = new RegExp('\\.(' + _netStreamTypes.join('|') + ')(\\?.*)?$', 'i');\r
+ this.mimePattern = /^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i; // default mp3 set\r
+\r
+ // use altURL if not "online"\r
+ this.useAltURL = !_overHTTP;\r
+ this._global_a = null;\r
+\r
+ if (_likesHTML5) {\r
+\r
+ // prefer HTML5 for mobile + tablet-like devices, probably more reliable vs. flash at this point.\r
+ _s.useHTML5Audio = true;\r
+ _s.preferFlash = false;\r
+\r
+ if (_is_iDevice) {\r
+ // by default, use global feature. iOS onfinish() -> next may fail otherwise.\r
+ _s.ignoreFlash = true;\r
+ _useGlobalHTML5Audio = true;\r
+ }\r
+\r
+ }\r
+\r
+ /**\r
+ * Public SoundManager API\r
+ * -----------------------\r
+ */\r
+\r
+ this.ok = function() {\r
+\r
+ return (_needsFlash?(_didInit && !_disabled):(_s.useHTML5Audio && _s.hasHTML5));\r
+\r
+ };\r
+\r
+ this.supported = this.ok; // legacy\r
+\r
+ this.getMovie = function(smID) {\r
+\r
+ // safety net: some old browsers differ on SWF references, possibly related to ExternalInterface / flash version\r
+ return _id(smID) || _doc[smID] || _win[smID];\r
+\r
+ };\r
+\r
+ /**\r
+ * Creates a SMSound sound object instance.\r
+ *\r
+ * @param {object} oOptions Sound options (at minimum, id and url are required.)\r
+ * @return {object} SMSound The new SMSound object.\r
+ */\r
+\r
+ this.createSound = function(oOptions) {\r
+\r
+ var _cs = _sm+'.createSound(): ',\r
+ thisOptions = null, oSound = null, _tO = null;\r
+\r
+ if (!_didInit || !_s.ok()) {\r
+ _complain(_cs + _str(!_didInit?'notReady':'notOK'));\r
+ return false;\r
+ }\r
+\r
+ if (arguments.length === 2) {\r
+ // function overloading in JS! :) ..assume simple createSound(id,url) use case\r
+ oOptions = {\r
+ 'id': arguments[0],\r
+ 'url': arguments[1]\r
+ };\r
+ }\r
+\r
+ // inherit from defaultOptions\r
+ thisOptions = _mixin(oOptions);\r
+\r
+ // alias\r
+ _tO = thisOptions;\r
+\r
+ // <d>\r
+ if (_tO.id.toString().charAt(0).match(/^[0-9]$/)) {\r
+ _s._wD(_cs + _str('badID', _tO.id), 2);\r
+ }\r
+\r
+ _s._wD(_cs + _tO.id + ' (' + _tO.url + ')', 1);\r
+ // </d>\r
+\r
+ if (_idCheck(_tO.id, true)) {\r
+ _s._wD(_cs + _tO.id + ' exists', 1);\r
+ return _s.sounds[_tO.id];\r
+ }\r
+\r
+ function make() {\r
+\r
+ thisOptions = _loopFix(thisOptions);\r
+ _s.sounds[_tO.id] = new SMSound(_tO);\r
+ _s.soundIDs.push(_tO.id);\r
+ return _s.sounds[_tO.id];\r
+\r
+ }\r
+\r
+ if (_html5OK(_tO)) {\r
+\r
+ oSound = make();\r
+ _s._wD('Loading sound '+_tO.id+' via HTML5');\r
+ oSound._setup_html5(_tO);\r
+\r
+ } else {\r
+\r
+ if (_fV > 8) {\r
+ if (_tO.isMovieStar === null) {\r
+ // attempt to detect MPEG-4 formats\r
+ _tO.isMovieStar = (_tO.serverURL || (_tO.type ? _tO.type.match(_netStreamMimeTypes) : false) || _tO.url.match(_netStreamPattern));\r
+ }\r
+ // <d>\r
+ if (_tO.isMovieStar) {\r
+ _s._wD(_cs + 'using MovieStar handling');\r
+ }\r
+ // </d>\r
+ if (_tO.isMovieStar) {\r
+ if (_tO.usePeakData) {\r
+ _wDS('noPeak');\r
+ _tO.usePeakData = false;\r
+ }\r
+ // <d>\r
+ if (_tO.loops > 1) {\r
+ _wDS('noNSLoop');\r
+ }\r
+ // </d>\r
+ }\r
+ }\r
+\r
+ _tO = _policyFix(_tO, _cs);\r
+ oSound = make();\r
+\r
+ if (_fV === 8) {\r
+ _s.o._createSound(_tO.id, _tO.loops||1, _tO.usePolicyFile);\r
+ } else {\r
+ _s.o._createSound(_tO.id, _tO.url, _tO.usePeakData, _tO.useWaveformData, _tO.useEQData, _tO.isMovieStar, (_tO.isMovieStar?_tO.bufferTime:false), _tO.loops||1, _tO.serverURL, _tO.duration||null, _tO.autoPlay, true, _tO.autoLoad, _tO.usePolicyFile);\r
+ if (!_tO.serverURL) {\r
+ // We are connected immediately\r
+ oSound.connected = true;\r
+ if (_tO.onconnect) {\r
+ _tO.onconnect.apply(oSound);\r
+ }\r
+ }\r
+ }\r
+\r
+ if (!_tO.serverURL && (_tO.autoLoad || _tO.autoPlay)) {\r
+ // call load for non-rtmp streams\r
+ oSound.load(_tO);\r
+ }\r
+\r
+ }\r
+\r
+ // rtmp will play in onconnect\r
+ if (!_tO.serverURL && _tO.autoPlay) {\r
+ oSound.play();\r
+ }\r
+\r
+ return oSound;\r
+\r
+ };\r
+\r
+ /**\r
+ * Destroys a SMSound sound object instance.\r
+ *\r
+ * @param {string} sID The ID of the sound to destroy\r
+ */\r
+\r
+ this.destroySound = function(sID, _bFromSound) {\r
+\r
+ // explicitly destroy a sound before normal page unload, etc.\r
+\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+\r
+ var oS = _s.sounds[sID], i;\r
+\r
+ // Disable all callbacks while the sound is being destroyed\r
+ oS._iO = {};\r
+\r
+ oS.stop();\r
+ oS.unload();\r
+\r
+ for (i = 0; i < _s.soundIDs.length; i++) {\r
+ if (_s.soundIDs[i] === sID) {\r
+ _s.soundIDs.splice(i, 1);\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (!_bFromSound) {\r
+ // ignore if being called from SMSound instance\r
+ oS.destruct(true);\r
+ }\r
+\r
+ oS = null;\r
+ delete _s.sounds[sID];\r
+\r
+ return true;\r
+\r
+ };\r
+\r
+ /**\r
+ * Calls the load() method of a SMSound object by ID.\r
+ *\r
+ * @param {string} sID The ID of the sound\r
+ * @param {object} oOptions Optional: Sound options\r
+ */\r
+\r
+ this.load = function(sID, oOptions) {\r
+\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+ return _s.sounds[sID].load(oOptions);\r
+\r
+ };\r
+\r
+ /**\r
+ * Calls the unload() method of a SMSound object by ID.\r
+ *\r
+ * @param {string} sID The ID of the sound\r
+ */\r
+\r
+ this.unload = function(sID) {\r
+\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+\r
+ return _s.sounds[sID].unload();\r
+\r
+ };\r
+\r
+ /**\r
+ * Calls the onposition() method of a SMSound object by ID.\r
+ *\r
+ * @param {string} sID The ID of the sound\r
+ * @param {number} nPosition The position to watch for\r
+ * @param {function} oMethod The relevant callback to fire\r
+ * @param {object} oScope Optional: The scope to apply the callback to\r
+ * @return {SMSound} The SMSound object\r
+ */\r
+\r
+ this.onposition = function(sID, nPosition, oMethod, oScope) {\r
+\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+ return _s.sounds[sID].onposition(nPosition, oMethod, oScope);\r
+\r
+ };\r
+\r
+ /**\r
+ * Calls the play() method of a SMSound object by ID.\r
+ *\r
+ * @param {string} sID The ID of the sound\r
+ * @param {object} oOptions Optional: Sound options\r
+ * @return {SMSound} The SMSound object\r
+ */\r
+\r
+ this.play = function(sID, oOptions) {\r
+\r
+ var fN = _sm+'.play(): ';\r
+\r
+ if (!_didInit || !_s.ok()) {\r
+ _complain(fN + _str(!_didInit?'notReady':'notOK'));\r
+ return false;\r
+ }\r
+\r
+ if (!_idCheck(sID)) {\r
+ if (!(oOptions instanceof Object)) {\r
+ oOptions = {\r
+ url: oOptions\r
+ }; // overloading use case: play('mySound','/path/to/some.mp3');\r
+ }\r
+ if (oOptions && oOptions.url) {\r
+ // overloading use case, create+play: .play('someID',{url:'/path/to.mp3'});\r
+ _s._wD(fN + 'attempting to create "' + sID + '"', 1);\r
+ oOptions.id = sID;\r
+ return _s.createSound(oOptions).play();\r
+ } else {\r
+ return false;\r
+ }\r
+ }\r
+\r
+ return _s.sounds[sID].play(oOptions);\r
+\r
+ };\r
+\r
+ this.start = this.play; // just for convenience\r
+\r
+ /**\r
+ * Calls the setPosition() method of a SMSound object by ID.\r
+ *\r
+ * @param {string} sID The ID of the sound\r
+ * @param {number} nMsecOffset Position (milliseconds)\r
+ * @return {SMSound} The SMSound object\r
+ */\r
+\r
+ this.setPosition = function(sID, nMsecOffset) {\r
+\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+\r
+ }\r
+ return _s.sounds[sID].setPosition(nMsecOffset);\r
+\r
+ };\r
+\r
+ /**\r
+ * Calls the stop() method of a SMSound object by ID.\r
+ *\r
+ * @param {string} sID The ID of the sound\r
+ * @return {SMSound} The SMSound object\r
+ */\r
+\r
+ this.stop = function(sID) {\r
+\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+ _s._wD(_sm+'.stop(' + sID + ')', 1);\r
+ return _s.sounds[sID].stop();\r
+\r
+ };\r
+\r
+ /**\r
+ * Stops all currently-playing sounds.\r
+ */\r
+\r
+ this.stopAll = function() {\r
+\r
+ var oSound;\r
+ _s._wD(_sm+'.stopAll()', 1);\r
+\r
+ for (oSound in _s.sounds) {\r
+ if (_s.sounds.hasOwnProperty(oSound)) {\r
+ // apply only to sound objects\r
+ _s.sounds[oSound].stop();\r
+ }\r
+ }\r
+\r
+ };\r
+\r
+ /**\r
+ * Calls the pause() method of a SMSound object by ID.\r
+ *\r
+ * @param {string} sID The ID of the sound\r
+ * @return {SMSound} The SMSound object\r
+ */\r
+\r
+ this.pause = function(sID) {\r
+\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+ return _s.sounds[sID].pause();\r
+\r
+ };\r
+\r
+ /**\r
+ * Pauses all currently-playing sounds.\r
+ */\r
+\r
+ this.pauseAll = function() {\r
+\r
+ var i;\r
+ for (i = _s.soundIDs.length; i--;) {\r
+ _s.sounds[_s.soundIDs[i]].pause();\r
+ }\r
+\r
+ };\r
+\r
+ /**\r
+ * Calls the resume() method of a SMSound object by ID.\r
+ *\r
+ * @param {string} sID The ID of the sound\r
+ * @return {SMSound} The SMSound object\r
+ */\r
+\r
+ this.resume = function(sID) {\r
+\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+ return _s.sounds[sID].resume();\r
+\r
+ };\r
+\r
+ /**\r
+ * Resumes all currently-paused sounds.\r
+ */\r
+\r
+ this.resumeAll = function() {\r
+\r
+ var i;\r
+ for (i = _s.soundIDs.length; i--;) {\r
+ _s.sounds[_s.soundIDs[i]].resume();\r
+ }\r
+\r
+ };\r
+\r
+ /**\r
+ * Calls the togglePause() method of a SMSound object by ID.\r
+ *\r
+ * @param {string} sID The ID of the sound\r
+ * @return {SMSound} The SMSound object\r
+ */\r
+\r
+ this.togglePause = function(sID) {\r
+\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+ return _s.sounds[sID].togglePause();\r
+\r
+ };\r
+\r
+ /**\r
+ * Calls the setPan() method of a SMSound object by ID.\r
+ *\r
+ * @param {string} sID The ID of the sound\r
+ * @param {number} nPan The pan value (-100 to 100)\r
+ * @return {SMSound} The SMSound object\r
+ */\r
+\r
+ this.setPan = function(sID, nPan) {\r
+\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+ return _s.sounds[sID].setPan(nPan);\r
+\r
+ };\r
+\r
+ /**\r
+ * Calls the setVolume() method of a SMSound object by ID.\r
+ *\r
+ * @param {string} sID The ID of the sound\r
+ * @param {number} nVol The volume value (0 to 100)\r
+ * @return {SMSound} The SMSound object\r
+ */\r
+\r
+ this.setVolume = function(sID, nVol) {\r
+\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+ return _s.sounds[sID].setVolume(nVol);\r
+\r
+ };\r
+\r
+ /**\r
+ * Calls the mute() method of either a single SMSound object by ID, or all sound objects.\r
+ *\r
+ * @param {string} sID Optional: The ID of the sound (if omitted, all sounds will be used.)\r
+ */\r
+\r
+ this.mute = function(sID) {\r
+\r
+ var fN = _sm+'.mute(): ',\r
+ i = 0;\r
+\r
+ if (typeof sID !== 'string') {\r
+ sID = null;\r
+ }\r
+\r
+ if (!sID) {\r
+ _s._wD(fN + 'Muting all sounds');\r
+ for (i = _s.soundIDs.length; i--;) {\r
+ _s.sounds[_s.soundIDs[i]].mute();\r
+ }\r
+ _s.muted = true;\r
+ } else {\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+ _s._wD(fN + 'Muting "' + sID + '"');\r
+ return _s.sounds[sID].mute();\r
+ }\r
+\r
+ return true;\r
+\r
+ };\r
+\r
+ /**\r
+ * Mutes all sounds.\r
+ */\r
+\r
+ this.muteAll = function() {\r
+\r
+ _s.mute();\r
+\r
+ };\r
+\r
+ /**\r
+ * Calls the unmute() method of either a single SMSound object by ID, or all sound objects.\r
+ *\r
+ * @param {string} sID Optional: The ID of the sound (if omitted, all sounds will be used.)\r
+ */\r
+\r
+ this.unmute = function(sID) {\r
+\r
+ var fN = _sm+'.unmute(): ', i;\r
+\r
+ if (typeof sID !== 'string') {\r
+ sID = null;\r
+ }\r
+\r
+ if (!sID) {\r
+\r
+ _s._wD(fN + 'Unmuting all sounds');\r
+ for (i = _s.soundIDs.length; i--;) {\r
+ _s.sounds[_s.soundIDs[i]].unmute();\r
+ }\r
+ _s.muted = false;\r
+\r
+ } else {\r
+\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+ _s._wD(fN + 'Unmuting "' + sID + '"');\r
+ return _s.sounds[sID].unmute();\r
+\r
+ }\r
+\r
+ return true;\r
+\r
+ };\r
+\r
+ /**\r
+ * Unmutes all sounds.\r
+ */\r
+\r
+ this.unmuteAll = function() {\r
+\r
+ _s.unmute();\r
+\r
+ };\r
+\r
+ /**\r
+ * Calls the toggleMute() method of a SMSound object by ID.\r
+ *\r
+ * @param {string} sID The ID of the sound\r
+ * @return {SMSound} The SMSound object\r
+ */\r
+\r
+ this.toggleMute = function(sID) {\r
+\r
+ if (!_idCheck(sID)) {\r
+ return false;\r
+ }\r
+\r
+ return _s.sounds[sID].toggleMute();\r
+\r
+ };\r
+\r
+ /**\r
+ * Retrieves the memory used by the flash plugin.\r
+ *\r
+ * @return {number} The amount of memory in use\r
+ */\r
+\r
+ this.getMemoryUse = function() {\r
+\r
+ // flash-only\r
+ var ram = 0;\r
+\r
+ if (_s.o && _fV !== 8) {\r
+ ram = parseInt(_s.o._getMemoryUse(), 10);\r
+ }\r
+\r
+ return ram;\r
+\r
+ };\r
+\r
+ /**\r
+ * Undocumented: NOPs soundManager and all SMSound objects.\r
+ */\r
+\r
+ this.disable = function(bNoDisable) {\r
+\r
+ // destroy all functions\r
+ var i;\r
+\r
+ if (typeof bNoDisable === 'undefined') {\r
+ bNoDisable = false;\r
+ }\r
+\r
+ if (_disabled) {\r
+ return false;\r
+ }\r
+\r
+ _disabled = true;\r
+ _wDS('shutdown', 1);\r
+\r
+ for (i = _s.soundIDs.length; i--;) {\r
+ _disableObject(_s.sounds[_s.soundIDs[i]]);\r
+ }\r
+\r
+ // fire "complete", despite fail\r
+ _initComplete(bNoDisable);\r
+ _event.remove(_win, 'load', _initUserOnload);\r
+\r
+ return true;\r
+\r
+ };\r
+\r
+ /**\r
+ * Determines playability of a MIME type, eg. 'audio/mp3'.\r
+ */\r
+\r
+ this.canPlayMIME = function(sMIME) {\r
+\r
+ var result;\r
+\r
+ if (_s.hasHTML5) {\r
+ result = _html5CanPlay({type:sMIME});\r
+ }\r
+\r
+ if (!_needsFlash || result) {\r
+ // no flash, or OK\r
+ return result;\r
+ } else {\r
+ // if flash 9, test netStream (movieStar) types as well.\r
+ return (sMIME ? !!((_fV > 8 ? sMIME.match(_netStreamMimeTypes) : null) || sMIME.match(_s.mimePattern)) : null);\r
+ }\r
+\r
+ };\r
+\r
+ /**\r
+ * Determines playability of a URL based on audio support.\r
+ *\r
+ * @param {string} sURL The URL to test\r
+ * @return {boolean} URL playability\r
+ */\r
+\r
+ this.canPlayURL = function(sURL) {\r
+\r
+ var result;\r
+\r
+ if (_s.hasHTML5) {\r
+ result = _html5CanPlay({url: sURL});\r
+ }\r
+\r
+ if (!_needsFlash || result) {\r
+ // no flash, or OK\r
+ return result;\r
+ } else {\r
+ return (sURL ? !!(sURL.match(_s.filePattern)) : null);\r
+ }\r
+\r
+ };\r
+\r
+ /**\r
+ * Determines playability of an HTML DOM <a> object (or similar object literal) based on audio support.\r
+ *\r
+ * @param {object} oLink an HTML DOM <a> object or object literal including href and/or type attributes\r
+ * @return {boolean} URL playability\r
+ */\r
+\r
+ this.canPlayLink = function(oLink) {\r
+\r
+ if (typeof oLink.type !== 'undefined' && oLink.type) {\r
+ if (_s.canPlayMIME(oLink.type)) {\r
+ return true;\r
+ }\r
+ }\r
+\r
+ return _s.canPlayURL(oLink.href);\r
+\r
+ };\r
+\r
+ /**\r
+ * Retrieves a SMSound object by ID.\r
+ *\r
+ * @param {string} sID The ID of the sound\r
+ * @return {SMSound} The SMSound object\r
+ */\r
+\r
+ this.getSoundById = function(sID, _suppressDebug) {\r
+\r
+ if (!sID) {\r
+ throw new Error(_sm+'.getSoundById(): sID is null/undefined');\r
+ }\r
+\r
+ var result = _s.sounds[sID];\r
+\r
+ // <d>\r
+ if (!result && !_suppressDebug) {\r
+ _s._wD('"' + sID + '" is an invalid sound ID.', 2);\r
+ }\r
+ // </d>\r
+\r
+ return result;\r
+\r
+ };\r
+\r
+ /**\r
+ * Queues a callback for execution when SoundManager has successfully initialized.\r
+ *\r
+ * @param {function} oMethod The callback method to fire\r
+ * @param {object} oScope Optional: The scope to apply to the callback\r
+ */\r
+\r
+ this.onready = function(oMethod, oScope) {\r
+\r
+ var sType = 'onready';\r
+\r
+ if (oMethod && oMethod instanceof Function) {\r
+\r
+ // <d>\r
+ if (_didInit) {\r
+ _s._wD(_str('queue', sType));\r
+ }\r
+ // </d>\r
+\r
+ if (!oScope) {\r
+ oScope = _win;\r
+ }\r
+\r
+ _addOnEvent(sType, oMethod, oScope);\r
+ _processOnEvents();\r
+\r
+ return true;\r
+\r
+ } else {\r
+\r
+ throw _str('needFunction', sType);\r
+\r
+ }\r
+\r
+ };\r
+\r
+ /**\r
+ * Queues a callback for execution when SoundManager has failed to initialize.\r
+ *\r
+ * @param {function} oMethod The callback method to fire\r
+ * @param {object} oScope Optional: The scope to apply to the callback\r
+ */\r
+\r
+ this.ontimeout = function(oMethod, oScope) {\r
+\r
+ var sType = 'ontimeout';\r
+\r
+ if (oMethod && oMethod instanceof Function) {\r
+\r
+ // <d>\r
+ if (_didInit) {\r
+ _s._wD(_str('queue', sType));\r
+ }\r
+ // </d>\r
+\r
+ if (!oScope) {\r
+ oScope = _win;\r
+ }\r
+\r
+ _addOnEvent(sType, oMethod, oScope);\r
+ _processOnEvents({type:sType});\r
+\r
+ return true;\r
+\r
+ } else {\r
+\r
+ throw _str('needFunction', sType);\r
+\r
+ }\r
+\r
+ };\r
+\r
+ /**\r
+ * Writes console.log()-style debug output to a console or in-browser element.\r
+ * Applies when SoundManager.debugMode = true\r
+ *\r
+ * @param {string} sText The console message\r
+ * @param {string} sType Optional: Log type of 'info', 'warn' or 'error'\r
+ * @param {object} Optional: The scope to apply to the callback\r
+ */\r
+\r
+ this._writeDebug = function(sText, sType, _bTimestamp) {\r
+\r
+ // pseudo-private console.log()-style output\r
+ // <d>\r
+\r
+ var sDID = 'soundmanager-debug', o, oItem, sMethod;\r
+\r
+ if (!_s.debugMode) {\r
+ return false;\r
+ }\r
+\r
+ if (typeof _bTimestamp !== 'undefined' && _bTimestamp) {\r
+ sText = sText + ' | ' + new Date().getTime();\r
+ }\r
+\r
+ if (_hasConsole && _s.useConsole) {\r
+ sMethod = _debugLevels[sType];\r
+ if (typeof console[sMethod] !== 'undefined') {\r
+ console[sMethod](sText);\r
+ } else {\r
+ console.log(sText);\r
+ }\r
+ if (_s.useConsoleOnly) {\r
+ return true;\r
+ }\r
+ }\r
+\r
+ try {\r
+\r
+ o = _id(sDID);\r
+\r
+ if (!o) {\r
+ return false;\r
+ }\r
+\r
+ oItem = _doc.createElement('div');\r
+\r
+ if (++_wdCount % 2 === 0) {\r
+ oItem.className = 'sm2-alt';\r
+ }\r
+\r
+ if (typeof sType === 'undefined') {\r
+ sType = 0;\r
+ } else {\r
+ sType = parseInt(sType, 10);\r
+ }\r
+\r
+ oItem.appendChild(_doc.createTextNode(sText));\r
+\r
+ if (sType) {\r
+ if (sType >= 2) {\r
+ oItem.style.fontWeight = 'bold';\r
+ }\r
+ if (sType === 3) {\r
+ oItem.style.color = '#ff3333';\r
+ }\r
+ }\r
+\r
+ // top-to-bottom\r
+ // o.appendChild(oItem);\r
+\r
+ // bottom-to-top\r
+ o.insertBefore(oItem, o.firstChild);\r
+\r
+ } catch(e) {\r
+ // oh well\r
+ }\r
+\r
+ o = null;\r
+ // </d>\r
+\r
+ return true;\r
+\r
+ };\r
+\r
+ // alias\r
+ this._wD = this._writeDebug;\r
+\r
+ /**\r
+ * Provides debug / state information on all SMSound objects.\r
+ */\r
+\r
+ this._debug = function() {\r
+\r
+ // <d>\r
+ var i, j;\r
+ _wDS('currentObj', 1);\r
+\r
+ for (i = 0, j = _s.soundIDs.length; i < j; i++) {\r
+ _s.sounds[_s.soundIDs[i]]._debug();\r
+ }\r
+ // </d>\r
+\r
+ };\r
+\r
+ /**\r
+ * Restarts and re-initializes the SoundManager instance.\r
+ */\r
+\r
+ this.reboot = function() {\r
+\r
+ // attempt to reset and init SM2\r
+ _s._wD(_sm+'.reboot()');\r
+\r
+ // <d>\r
+ if (_s.soundIDs.length) {\r
+ _s._wD('Destroying ' + _s.soundIDs.length + ' SMSound objects...');\r
+ }\r
+ // </d>\r
+\r
+ var i, j;\r
+\r
+ for (i = _s.soundIDs.length; i--;) {\r
+ _s.sounds[_s.soundIDs[i]].destruct();\r
+ }\r
+\r
+ // trash ze flash\r
+\r
+ try {\r
+ if (_isIE) {\r
+ _oRemovedHTML = _s.o.innerHTML;\r
+ }\r
+ _oRemoved = _s.o.parentNode.removeChild(_s.o);\r
+ _s._wD('Flash movie removed.');\r
+ } catch(e) {\r
+ // uh-oh.\r
+ _wDS('badRemove', 2);\r
+ }\r
+\r
+ // actually, force recreate of movie.\r
+ _oRemovedHTML = _oRemoved = _needsFlash = null;\r
+\r
+ _s.enabled = _didDCLoaded = _didInit = _waitingForEI = _initPending = _didAppend = _appendSuccess = _disabled = _s.swfLoaded = false;\r
+ _s.soundIDs = _s.sounds = [];\r
+ _s.o = null;\r
+\r
+ for (i in _on_queue) {\r
+ if (_on_queue.hasOwnProperty(i)) {\r
+ for (j = _on_queue[i].length; j--;) {\r
+ _on_queue[i][j].fired = false;\r
+ }\r
+ }\r
+ }\r
+\r
+ _s._wD(_sm + ': Rebooting...');\r
+ _win.setTimeout(_s.beginDelayedInit, 20);\r
+\r
+ };\r
+\r
+ /**\r
+ * Undocumented: Determines the SM2 flash movie's load progress.\r
+ *\r
+ * @return {number or null} Percent loaded, or if invalid/unsupported, null.\r
+ */\r
+\r
+ this.getMoviePercent = function() {\r
+\r
+ return (_s.o && typeof _s.o.PercentLoaded !== 'undefined' ? _s.o.PercentLoaded() : null);\r
+\r
+ };\r
+\r
+ /**\r
+ * Additional helper for manually invoking SM2's init process after DOM Ready / window.onload().\r
+ */\r
+\r
+ this.beginDelayedInit = function() {\r
+\r
+ _windowLoaded = true;\r
+ _domContentLoaded();\r
+\r
+ setTimeout(function() {\r
+\r
+ if (_initPending) {\r
+ return false;\r
+ }\r
+\r
+ _createMovie();\r
+ _initMovie();\r
+ _initPending = true;\r
+\r
+ return true;\r
+\r
+ }, 20);\r
+\r
+ _delayWaitForEI();\r
+\r
+ };\r
+\r
+ /**\r
+ * Destroys the SoundManager instance and all SMSound instances.\r
+ */\r
+\r
+ this.destruct = function() {\r
+\r
+ _s._wD(_sm+'.destruct()');\r
+ _s.disable(true);\r
+\r
+ };\r
+\r
+ /**\r
+ * SMSound() (sound object) constructor\r
+ * ------------------------------------\r
+ *\r
+ * @param {object} oOptions Sound options (id and url are required attributes)\r
+ * @return {SMSound} The new SMSound object\r
+ */\r
+\r
+ SMSound = function(oOptions) {\r
+\r
+ var _t = this, _resetProperties, _stop_html5_timer, _start_html5_timer;\r
+ this.sID = oOptions.id;\r
+ this.url = oOptions.url;\r
+ this.options = _mixin(oOptions);\r
+\r
+ // per-play-instance-specific options\r
+ this.instanceOptions = this.options;\r
+\r
+ // short alias\r
+ this._iO = this.instanceOptions;\r
+\r
+ // assign property defaults\r
+ this.pan = this.options.pan;\r
+ this.volume = this.options.volume;\r
+ this._lastURL = null;\r
+ this.isHTML5 = false;\r
+ this._a = null;\r
+\r
+ /**\r
+ * SMSound() public methods\r
+ * ------------------------\r
+ */\r
+\r
+ this.id3 = {};\r
+\r
+ /**\r
+ * Writes SMSound object parameters to debug console\r
+ */\r
+\r
+ this._debug = function() {\r
+\r
+ // <d>\r
+ // pseudo-private console.log()-style output\r
+\r
+ if (_s.debugMode) {\r
+\r
+ var stuff = null, msg = [], sF, sfBracket, maxLength = 64;\r
+\r
+ for (stuff in _t.options) {\r
+ if (_t.options[stuff] !== null) {\r
+ if (_t.options[stuff] instanceof Function) {\r
+ // handle functions specially\r
+ sF = _t.options[stuff].toString();\r
+ // normalize spaces\r
+ sF = sF.replace(/\s\s+/g, ' ');\r
+ sfBracket = sF.indexOf('{');\r
+ msg.push(' ' + stuff + ': {' + sF.substr(sfBracket + 1, (Math.min(Math.max(sF.indexOf('\n') - 1, maxLength), maxLength))).replace(/\n/g, '') + '... }');\r
+ } else {\r
+ msg.push(' ' + stuff + ': ' + _t.options[stuff]);\r
+ }\r
+ }\r
+ }\r
+\r
+ _s._wD('SMSound() merged options: {\n' + msg.join(', \n') + '\n}');\r
+\r
+ }\r
+ // </d>\r
+\r
+ };\r
+\r
+ // <d>\r
+ this._debug();\r
+ // </d>\r
+\r
+ /**\r
+ * Begins loading a sound per its *url*.\r
+ *\r
+ * @param {object} oOptions Optional: Sound options\r
+ * @return {SMSound} The SMSound object\r
+ */\r
+\r
+ this.load = function(oOptions) {\r
+\r
+ var oS = null;\r
+\r
+ if (typeof oOptions !== 'undefined') {\r
+ _t._iO = _mixin(oOptions, _t.options);\r
+ _t.instanceOptions = _t._iO;\r
+ } else {\r
+ oOptions = _t.options;\r
+ _t._iO = oOptions;\r
+ _t.instanceOptions = _t._iO;\r
+ if (_t._lastURL && _t._lastURL !== _t.url) {\r
+ _wDS('manURL');\r
+ _t._iO.url = _t.url;\r
+ _t.url = null;\r
+ }\r
+ }\r
+\r
+ if (!_t._iO.url) {\r
+ _t._iO.url = _t.url;\r
+ }\r
+\r
+ _s._wD('SMSound.load(): ' + _t._iO.url, 1);\r
+\r
+ if (_t._iO.url === _t.url && _t.readyState !== 0 && _t.readyState !== 2) {\r
+ _wDS('onURL', 1);\r
+ return _t;\r
+ }\r
+\r
+ _t._lastURL = _t.url;\r
+ _t.loaded = false;\r
+ _t.readyState = 1;\r
+ _t.playState = 0;\r
+\r
+ // TODO: If switching from HTML5 -> flash (or vice versa), stop currently-playing audio.\r
+\r
+ if (_html5OK(_t._iO)) {\r
+\r
+ oS = _t._setup_html5(_t._iO);\r
+ if (!oS._called_load) {\r
+ _s._wD(_h5+'load: '+_t.sID);\r
+ _t._html5_canplay = false;\r
+ oS.load();\r
+ oS._called_load = true;\r
+ if (_t._iO.autoPlay) {\r
+ _t.play();\r
+ }\r
+ } else {\r
+ _s._wD(_h5+'ignoring request to load again: '+_t.sID);\r
+ }\r
+\r
+ } else {\r
+\r
+ try {\r
+ _t.isHTML5 = false;\r
+ _t._iO = _policyFix(_loopFix(_t._iO));\r
+ if (_fV === 8) {\r
+ _s.o._load(_t.sID, _t._iO.url, _t._iO.stream, _t._iO.autoPlay, (_t._iO.whileloading?1:0), _t._iO.loops||1, _t._iO.usePolicyFile);\r
+ } else {\r
+ _s.o._load(_t.sID, _t._iO.url, !!(_t._iO.stream), !!(_t._iO.autoPlay), _t._iO.loops||1, !!(_t._iO.autoLoad), _t._iO.usePolicyFile);\r
+ }\r
+ } catch(e) {\r
+ _wDS('smError', 2);\r
+ _debugTS('onload', false);\r
+ _catchError({type:'SMSOUND_LOAD_JS_EXCEPTION', fatal:true});\r
+\r
+ }\r
+\r
+ }\r
+\r
+ return _t;\r
+\r
+ };\r
+\r
+ /**\r
+ * Unloads a sound, canceling any open HTTP requests.\r
+ *\r
+ * @return {SMSound} The SMSound object\r
+ */\r
+\r
+ this.unload = function() {\r
+\r
+ // Flash 8/AS2 can't "close" a stream - fake it by loading an empty URL\r
+ // Flash 9/AS3: Close stream, preventing further load\r
+ // HTML5: Most UAs will use empty URL\r
+\r
+ if (_t.readyState !== 0) {\r
+\r
+ _s._wD('SMSound.unload(): "' + _t.sID + '"');\r
+\r
+ if (!_t.isHTML5) {\r
+ if (_fV === 8) {\r
+ _s.o._unload(_t.sID, _emptyURL);\r
+ } else {\r
+ _s.o._unload(_t.sID);\r
+ }\r
+ } else {\r
+ _stop_html5_timer();\r
+ if (_t._a) {\r
+ _t._a.pause();\r
+ _html5Unload(_t._a);\r
+ }\r
+ }\r
+\r
+ // reset load/status flags\r
+ _resetProperties();\r
+\r
+ }\r
+\r
+ return _t;\r
+\r
+ };\r
+\r
+ /**\r
+ * Unloads and destroys a sound.\r
+ */\r
+\r
+ this.destruct = function(_bFromSM) {\r
+\r
+ _s._wD('SMSound.destruct(): "' + _t.sID + '"');\r
+\r
+ if (!_t.isHTML5) {\r
+\r
+ // kill sound within Flash\r
+ // Disable the onfailure handler\r
+ _t._iO.onfailure = null;\r
+ _s.o._destroySound(_t.sID);\r
+\r
+ } else {\r
+\r
+ _stop_html5_timer();\r
+\r
+ if (_t._a) {\r
+ _t._a.pause();\r
+ _html5Unload(_t._a);\r
+ if (!_useGlobalHTML5Audio) {\r
+ _t._remove_html5_events();\r
+ }\r
+ // break obvious circular reference\r
+ _t._a._t = null;\r
+ _t._a = null;\r
+ }\r
+\r
+ }\r
+\r
+ if (!_bFromSM) {\r
+ // ensure deletion from controller\r
+ _s.destroySound(_t.sID, true);\r
+\r
+ }\r
+\r
+ };\r
+\r
+ /**\r
+ * Begins playing a sound.\r
+ *\r
+ * @param {object} oOptions Optional: Sound options\r
+ * @return {SMSound} The SMSound object\r
+ */\r
+\r
+ this.play = function(oOptions, _updatePlayState) {\r
+\r
+ var fN = 'SMSound.play(): ', allowMulti, a;\r
+\r
+ _updatePlayState = _updatePlayState === undefined ? true : _updatePlayState; // default to true\r
+\r
+ if (!oOptions) {\r
+ oOptions = {};\r
+ }\r
+\r
+ _t._iO = _mixin(oOptions, _t._iO);\r
+ _t._iO = _mixin(_t._iO, _t.options);\r
+ _t.instanceOptions = _t._iO;\r
+\r
+ // RTMP-only\r
+ if (_t._iO.serverURL && !_t.connected) {\r
+ if (!_t.getAutoPlay()) {\r
+ _s._wD(fN+' Netstream not connected yet - setting autoPlay');\r
+ _t.setAutoPlay(true);\r
+ }\r
+ // play will be called in _onconnect()\r
+ return _t;\r
+ }\r
+\r
+ if (_html5OK(_t._iO)) {\r
+ _t._setup_html5(_t._iO);\r
+ _start_html5_timer();\r
+ }\r
+\r
+ if (_t.playState === 1 && !_t.paused) {\r
+ allowMulti = _t._iO.multiShot;\r
+ if (!allowMulti) {\r
+ _s._wD(fN + '"' + _t.sID + '" already playing (one-shot)', 1);\r
+ return _t;\r
+ } else {\r
+ _s._wD(fN + '"' + _t.sID + '" already playing (multi-shot)', 1);\r
+ }\r
+ }\r
+\r
+ if (!_t.loaded) {\r
+\r
+ if (_t.readyState === 0) {\r
+\r
+ _s._wD(fN + 'Attempting to load "' + _t.sID + '"', 1);\r
+ // try to get this sound playing ASAP\r
+ if (!_t.isHTML5) {\r
+ // assign directly because setAutoPlay() increments the instanceCount\r
+ _t._iO.autoPlay = true;\r
+ }\r
+ _t.load(_t._iO);\r
+\r
+ } else if (_t.readyState === 2) {\r
+\r
+ _s._wD(fN + 'Could not load "' + _t.sID + '" - exiting', 2);\r
+ return _t;\r
+\r
+ } else {\r
+\r
+ _s._wD(fN + '"' + _t.sID + '" is loading - attempting to play..', 1);\r
+\r
+ }\r
+\r
+ } else {\r
+\r
+ _s._wD(fN + '"' + _t.sID + '"');\r
+\r
+ }\r
+\r
+ if (!_t.isHTML5 && _fV === 9 && _t.position > 0 && _t.position === _t.duration) {\r
+ // flash 9 needs a position reset if play() is called while at the end of a sound.\r
+ _s._wD(fN + '"' + _t.sID + '": Sound at end, resetting to position:0');\r
+ _t._iO.position = 0;\r
+ }\r
+\r
+ /**\r
+ * Streams will pause when their buffer is full if they are being loaded.\r
+ * In this case paused is true, but the song hasn't started playing yet.\r
+ * If we just call resume() the onplay() callback will never be called.\r
+ * So only call resume() if the position is > 0.\r
+ * Another reason is because options like volume won't have been applied yet.\r
+ */\r
+\r
+ if (_t.paused && _t.position && _t.position > 0) {\r
+\r
+ // https://gist.github.com/37b17df75cc4d7a90bf6\r
+ _s._wD(fN + '"' + _t.sID + '" is resuming from paused state',1);\r
+ _t.resume();\r
+\r
+ } else {\r
+\r
+ _s._wD(fN+'"'+ _t.sID+'" is starting to play');\r
+ _t.playState = 1;\r
+ _t.paused = false;\r
+\r
+ if (!_t.instanceCount || _t._iO.multiShotEvents || (!_t.isHTML5 && _fV > 8 && !_t.getAutoPlay())) {\r
+ _t.instanceCount++;\r
+ }\r
+\r
+ _t.position = (typeof _t._iO.position !== 'undefined' && !isNaN(_t._iO.position)?_t._iO.position:0);\r
+\r
+ if (!_t.isHTML5) {\r
+ _t._iO = _policyFix(_loopFix(_t._iO));\r
+ }\r
+\r
+ if (_t._iO.onplay && _updatePlayState) {\r
+ _t._iO.onplay.apply(_t);\r
+ _t._onplay_called = true;\r
+ }\r
+\r
+ _t.setVolume(_t._iO.volume, true);\r
+ _t.setPan(_t._iO.pan, true);\r
+\r
+ if (!_t.isHTML5) {\r
+ _s.o._start(_t.sID, _t._iO.loops || 1, (_fV === 9?_t._iO.position:_t._iO.position / 1000));\r
+ } else {\r
+ _start_html5_timer();\r
+ a = _t._setup_html5();\r
+ _t.setPosition(_t._iO.position);\r
+ a.play();\r
+ }\r
+\r
+ }\r
+\r
+ return _t;\r
+\r
+ };\r
+\r
+ // just for convenience\r
+ this.start = this.play;\r
+\r
+ /**\r
+ * Stops playing a sound (and optionally, all sounds)\r
+ *\r
+ * @param {boolean} bAll Optional: Whether to stop all sounds\r
+ * @return {SMSound} The SMSound object\r
+ */\r
+\r
+ this.stop = function(bAll) {\r
+\r
+ if (_t.playState === 1) {\r
+\r
+ _t._onbufferchange(0);\r
+ _t.resetOnPosition(0);\r
+ _t.paused = false;\r
+\r
+ if (!_t.isHTML5) {\r
+ _t.playState = 0;\r
+ }\r
+\r
+ if (_t._iO.onstop) {\r
+ _t._iO.onstop.apply(_t);\r
+ }\r
+\r
+ if (!_t.isHTML5) {\r
+\r
+ _s.o._stop(_t.sID, bAll);\r
+ // hack for netStream: just unload\r
+ if (_t._iO.serverURL) {\r
+ _t.unload();\r
+ }\r
+\r
+ } else {\r
+\r
+ if (_t._a) {\r
+\r
+ // act like Flash, though\r
+ _t.setPosition(0);\r
+\r
+ // html5 has no stop()\r
+ _t._a.pause();\r
+\r
+ _t.playState = 0;\r
+\r
+ // and update UI\r
+ _t._onTimer();\r
+\r
+ _stop_html5_timer();\r
+\r
+ }\r
+\r
+ }\r
+\r
+ _t.instanceCount = 0;\r
+ _t._iO = {};\r
+\r
+ }\r
+\r
+ return _t;\r
+\r
+ };\r
+\r
+ /**\r
+ * Undocumented/internal: Sets autoPlay for RTMP.\r
+ *\r
+ * @param {boolean} autoPlay state\r
+ */\r
+\r
+ this.setAutoPlay = function(autoPlay) {\r
+\r
+ _s._wD('sound '+_t.sID+' turned autoplay ' + (autoPlay ? 'on' : 'off'));\r
+ _t._iO.autoPlay = autoPlay;\r
+\r
+ if (!_t.isHTML5) {\r
+ _s.o._setAutoPlay(_t.sID, autoPlay);\r
+ if (autoPlay) {\r
+ // only increment the instanceCount if the sound isn't loaded (TODO: verify RTMP)\r
+ if (!_t.instanceCount && _t.readyState === 1) {\r
+ _t.instanceCount++;\r
+ _s._wD('sound '+_t.sID+' incremented instance count to '+_t.instanceCount);\r
+ }\r
+ }\r
+ }\r
+\r
+ };\r
+\r
+ /**\r
+ * Undocumented/internal: Returns the autoPlay boolean.\r
+ *\r
+ * @return {boolean} The current autoPlay value\r
+ */\r
+\r
+ this.getAutoPlay = function() {\r
+\r
+ return _t._iO.autoPlay;\r
+\r
+ };\r
+\r
+ /**\r
+ * Sets the position of a sound.\r
+ *\r
+ * @param {number} nMsecOffset Position (milliseconds)\r
+ * @return {SMSound} The SMSound object\r
+ */\r
+\r
+ this.setPosition = function(nMsecOffset) {\r
+\r
+ if (nMsecOffset === undefined) {\r
+ nMsecOffset = 0;\r
+ }\r
+\r
+ var original_pos,\r
+ position, position1K,\r
+ // Use the duration from the instance options, if we don't have a track duration yet.\r
+ // position >= 0 and <= current available (loaded) duration\r
+ offset = (_t.isHTML5 ? Math.max(nMsecOffset,0) : Math.min(_t.duration || _t._iO.duration, Math.max(nMsecOffset, 0)));\r
+\r
+ original_pos = _t.position;\r
+ _t.position = offset;\r
+ position1K = _t.position/1000;\r
+ _t.resetOnPosition(_t.position);\r
+ _t._iO.position = offset;\r
+\r
+ if (!_t.isHTML5) {\r
+\r
+ position = (_fV === 9 ? _t.position : position1K);\r
+ if (_t.readyState && _t.readyState !== 2) {\r
+ // if paused or not playing, will not resume (by playing)\r
+ _s.o._setPosition(_t.sID, position, (_t.paused || !_t.playState));\r
+ }\r
+\r
+ } else if (_t._a) {\r
+\r
+ // Set the position in the canplay handler if the sound is not ready yet\r
+ if (_t._html5_canplay) {\r
+ if (_t._a.currentTime !== position1K) {\r
+ /*\r
+ * DOM/JS errors/exceptions to watch out for:\r
+ * if seek is beyond (loaded?) position, "DOM exception 11"\r
+ * "INDEX_SIZE_ERR": DOM exception 1\r
+ */\r
+ _s._wD('setPosition('+position1K+'): setting position');\r
+ try {\r
+ _t._a.currentTime = position1K;\r
+ if (_t.playState === 0 || _t.paused) {\r
+ // allow seek without auto-play/resume\r
+ _t._a.pause();\r
+ }\r
+ } catch(e) {\r
+ _s._wD('setPosition('+position1K+'): setting position failed: '+e.message, 2);\r
+ }\r
+ }\r
+ } else {\r
+ _s._wD('setPosition('+position1K+'): delaying, sound not ready');\r
+ }\r
+\r
+ }\r
+\r
+ if (_t.isHTML5) {\r
+ if (_t.paused) {\r
+ // if paused, refresh UI right away\r
+ // force update\r
+ _t._onTimer(true);\r
+ }\r
+ }\r
+\r
+ return _t;\r
+\r
+ };\r
+\r
+ /**\r
+ * Pauses sound playback.\r
+ *\r
+ * @return {SMSound} The SMSound object\r
+ */\r
+\r
+ this.pause = function(_bCallFlash) {\r
+\r
+ if (_t.paused || (_t.playState === 0 && _t.readyState !== 1)) {\r
+ return _t;\r
+ }\r
+\r
+ _s._wD('SMSound.pause()');\r
+ _t.paused = true;\r
+\r
+ if (!_t.isHTML5) {\r
+ if (_bCallFlash || _bCallFlash === undefined) {\r
+ _s.o._pause(_t.sID);\r
+ }\r
+ } else {\r
+ _t._setup_html5().pause();\r
+ _stop_html5_timer();\r
+ }\r
+\r
+ if (_t._iO.onpause) {\r
+ _t._iO.onpause.apply(_t);\r
+ }\r
+\r
+ return _t;\r
+\r
+ };\r
+\r
+ /**\r
+ * Resumes sound playback.\r
+ *\r
+ * @return {SMSound} The SMSound object\r
+ */\r
+\r
+ /**\r
+ * When auto-loaded streams pause on buffer full they have a playState of 0.\r
+ * We need to make sure that the playState is set to 1 when these streams "resume".\r
+ * When a paused stream is resumed, we need to trigger the onplay() callback if it\r
+ * hasn't been called already. In this case since the sound is being played for the\r
+ * first time, I think it's more appropriate to call onplay() rather than onresume().\r
+ */\r
+\r
+ this.resume = function() {\r
+\r
+ if (!_t.paused) {\r
+ return _t;\r
+ }\r
+\r
+ _s._wD('SMSound.resume()');\r
+ _t.paused = false;\r
+ _t.playState = 1;\r
+\r
+ if (!_t.isHTML5) {\r
+ if (_t._iO.isMovieStar) {\r
+ // Bizarre Webkit bug (Chrome reported via 8tracks.com dudes): AAC content paused for 30+ seconds(?) will not resume without a reposition.\r
+ _t.setPosition(_t.position);\r
+ }\r
+ // flash method is toggle-based (pause/resume)\r
+ _s.o._pause(_t.sID);\r
+ } else {\r
+ _t._setup_html5().play();\r
+ _start_html5_timer();\r
+ }\r
+\r
+ if (!_t._onplay_called && _t._iO.onplay) {\r
+ _t._iO.onplay.apply(_t);\r
+ _t._onplay_called = true;\r
+ } else if (_t._iO.onresume) {\r
+ _t._iO.onresume.apply(_t);\r
+ }\r
+\r
+ return _t;\r
+\r
+ };\r
+\r
+ /**\r
+ * Toggles sound playback.\r
+ *\r
+ * @return {SMSound} The SMSound object\r
+ */\r
+\r
+ this.togglePause = function() {\r
+\r
+ _s._wD('SMSound.togglePause()');\r
+\r
+ if (_t.playState === 0) {\r
+ _t.play({\r
+ position: (_fV === 9 && !_t.isHTML5 ? _t.position : _t.position / 1000)\r
+ });\r
+ return _t;\r
+ }\r
+\r
+ if (_t.paused) {\r
+ _t.resume();\r
+ } else {\r
+ _t.pause();\r
+ }\r
+\r
+ return _t;\r
+\r
+ };\r
+\r
+ /**\r
+ * Sets the panning (L-R) effect.\r
+ *\r
+ * @param {number} nPan The pan value (-100 to 100)\r
+ * @return {SMSound} The SMSound object\r
+ */\r
+\r
+ this.setPan = function(nPan, bInstanceOnly) {\r
+\r
+ if (typeof nPan === 'undefined') {\r
+ nPan = 0;\r
+ }\r
+\r
+ if (typeof bInstanceOnly === 'undefined') {\r
+ bInstanceOnly = false;\r
+ }\r
+\r
+ if (!_t.isHTML5) {\r
+ _s.o._setPan(_t.sID, nPan);\r
+ } // else { no HTML5 pan? }\r
+\r
+ _t._iO.pan = nPan;\r
+\r
+ if (!bInstanceOnly) {\r
+ _t.pan = nPan;\r
+ _t.options.pan = nPan;\r
+ }\r
+\r
+ return _t;\r
+\r
+ };\r
+\r
+ /**\r
+ * Sets the volume.\r
+ *\r
+ * @param {number} nVol The volume value (0 to 100)\r
+ * @return {SMSound} The SMSound object\r
+ */\r
+\r
+ this.setVolume = function(nVol, _bInstanceOnly) {\r
+\r
+ if (typeof nVol === 'undefined') {\r
+ nVol = 100;\r
+ }\r
+\r
+ if (typeof _bInstanceOnly === 'undefined') {\r
+ _bInstanceOnly = false;\r
+ }\r
+\r
+ if (!_t.isHTML5) {\r
+ _s.o._setVolume(_t.sID, (_s.muted && !_t.muted) || _t.muted?0:nVol);\r
+ } else if (_t._a) {\r
+ _t._a.volume = Math.max(0, Math.min(1, nVol/100)); // valid range: 0-1\r
+ }\r
+\r
+ _t._iO.volume = nVol;\r
+\r
+ if (!_bInstanceOnly) {\r
+ _t.volume = nVol;\r
+ _t.options.volume = nVol;\r
+ }\r
+\r
+ return _t;\r
+\r
+ };\r
+\r
+ /**\r
+ * Mutes the sound.\r
+ *\r
+ * @return {SMSound} The SMSound object\r
+ */\r
+\r
+ this.mute = function() {\r
+\r
+ _t.muted = true;\r
+\r
+ if (!_t.isHTML5) {\r
+ _s.o._setVolume(_t.sID, 0);\r
+ } else if (_t._a) {\r
+ _t._a.muted = true;\r
+ }\r
+\r
+ return _t;\r
+\r
+ };\r
+\r
+ /**\r
+ * Unmutes the sound.\r
+ *\r
+ * @return {SMSound} The SMSound object\r
+ */\r
+\r
+ this.unmute = function() {\r
+\r
+ _t.muted = false;\r
+ var hasIO = typeof _t._iO.volume !== 'undefined';\r
+\r
+ if (!_t.isHTML5) {\r
+ _s.o._setVolume(_t.sID, hasIO?_t._iO.volume:_t.options.volume);\r
+ } else if (_t._a) {\r
+ _t._a.muted = false;\r
+ }\r
+\r
+ return _t;\r
+\r
+ };\r
+\r
+ /**\r
+ * Toggles the muted state of a sound.\r
+ *\r
+ * @return {SMSound} The SMSound object\r
+ */\r
+\r
+ this.toggleMute = function() {\r
+\r
+ return (_t.muted?_t.unmute():_t.mute());\r
+\r
+ };\r
+\r
+ /**\r
+ * Calls the onposition() method of a SMSound object.\r
+ *\r
+ * @param {number} nPosition The position to watch for\r
+ * @param {function} oMethod The relevant callback to fire\r
+ * @param {object} oScope Optional: The scope to apply the callback to\r
+ * @return {SMSound} The SMSound object\r
+ */\r
+\r
+ this.onposition = function(nPosition, oMethod, oScope) {\r
+\r
+ // TODO: allow for ranges, too? eg. (nPosition instanceof Array)\r
+\r
+ _t._onPositionItems.push({\r
+ position: nPosition,\r
+ method: oMethod,\r
+ scope: (typeof oScope !== 'undefined'?oScope:_t),\r
+ fired: false\r
+ });\r
+\r
+ return _t;\r
+\r
+ };\r
+\r
+ /**\r
+ * TODO: This should be marked as pseudo-private.\r
+ */\r
+\r
+ this.processOnPosition = function() {\r
+\r
+ var i, item, j = _t._onPositionItems.length;\r
+\r
+ if (!j || !_t.playState || _t._onPositionFired >= j) {\r
+ return false;\r
+ }\r
+\r
+ for (i=j; i--;) {\r
+ item = _t._onPositionItems[i];\r
+ if (!item.fired && _t.position >= item.position) {\r
+ item.fired = true;\r
+ _s._onPositionFired++;\r
+ item.method.apply(item.scope,[item.position]);\r
+ }\r
+ }\r
+\r
+ return true;\r
+\r
+ };\r
+\r
+ this.resetOnPosition = function(nPosition) {\r
+\r
+ // reset "fired" for items interested in this position\r
+ var i, item, j = _t._onPositionItems.length;\r
+\r
+ if (!j) {\r
+ return false;\r
+ }\r
+\r
+ for (i=j; i--;) {\r
+ item = _t._onPositionItems[i];\r
+ if (item.fired && nPosition <= item.position) {\r
+ item.fired = false;\r
+ _s._onPositionFired--;\r
+ }\r
+ }\r
+\r
+ return true;\r
+\r
+ };\r
+\r
+ /**\r
+ * SoundManager() private internals\r
+ * --------------------------------\r
+ */\r
+\r
+ _start_html5_timer = function() {\r
+\r
+ if (_t.isHTML5) {\r
+ _startTimer(_t);\r
+ }\r
+\r
+ };\r
+\r
+ _stop_html5_timer = function() {\r
+\r
+ if (_t.isHTML5) {\r
+ _stopTimer(_t);\r
+ }\r
+\r
+ };\r
+\r
+ _resetProperties = function() {\r
+\r
+ _t._onPositionItems = [];\r
+ _t._onPositionFired = 0;\r
+ _t._hasTimer = null;\r
+ _t._onplay_called = false;\r
+ _t._a = null;\r
+ _t._html5_canplay = false;\r
+ _t.bytesLoaded = null;\r
+ _t.bytesTotal = null;\r
+ _t.position = null;\r
+ _t.duration = (_t._iO && _t._iO.duration?_t._iO.duration:null);\r
+ _t.durationEstimate = null;\r
+ _t.failures = 0;\r
+ _t.loaded = false;\r
+ _t.playState = 0;\r
+ _t.paused = false;\r
+\r
+ // 0 = uninitialised, 1 = loading, 2 = failed/error, 3 = loaded/success\r
+ _t.readyState = 0;\r
+\r
+ _t.muted = false;\r
+ _t.isBuffering = false;\r
+ _t.instanceOptions = {};\r
+ _t.instanceCount = 0;\r
+\r
+ _t.peakData = {\r
+ left: 0,\r
+ right: 0\r
+ };\r
+\r
+ _t.waveformData = {\r
+ left: [],\r
+ right: []\r
+ };\r
+\r
+ // legacy: 1D array\r
+ _t.eqData = [];\r
+\r
+ _t.eqData.left = [];\r
+ _t.eqData.right = [];\r
+\r
+ };\r
+\r
+ _resetProperties();\r
+\r
+ /**\r
+ * Pseudo-private SMSound internals\r
+ * --------------------------------\r
+ */\r
+\r
+ this._onTimer = function(bForce) {\r
+\r
+ // HTML5-only _whileplaying() etc.\r
+\r
+ var time, x = {};\r
+\r
+ if (_t._hasTimer || bForce) {\r
+\r
+ // TODO: May not need to track readyState (1 = loading)\r
+\r
+ if (_t._a && (bForce || ((_t.playState > 0 || _t.readyState === 1) && !_t.paused))) {\r
+\r
+ _t.duration = _t._get_html5_duration();\r
+ _t.durationEstimate = _t.duration;\r
+ time = _t._a.currentTime?_t._a.currentTime*1000:0;\r
+ _t._whileplaying(time,x,x,x,x);\r
+ return true;\r
+\r
+ } else {\r
+\r
+ _s._wD('_onTimer: Warn for "'+_t.sID+'": '+(!_t._a?'Could not find element. ':'')+(_t.playState === 0?'playState bad, 0?':'playState = '+_t.playState+', OK'));\r
+ return false;\r
+\r
+ }\r
+\r
+ }\r
+\r
+ };\r
+\r
+ this._get_html5_duration = function() {\r
+\r
+ var d = (_t._a ? _t._a.duration*1000 : (_t._iO ? _t._iO.duration : undefined)),\r
+ result = (d && !isNaN(d) && d !== Infinity ? d : (_t._iO ? _t._iO.duration : null));\r
+\r
+ return result;\r
+\r
+ };\r
+\r
+ this._setup_html5 = function(oOptions) {\r
+\r
+ var _iO = _mixin(_t._iO, oOptions), d = decodeURI,\r
+ _a = _useGlobalHTML5Audio ? _s._global_a : _t._a,\r
+ _dURL = d(_iO.url),\r
+ _oldIO = (_a && _a._t ? _a._t.instanceOptions : null);\r
+\r
+ if (_a) {\r
+\r
+ if (_a._t && _oldIO.url === _iO.url && (!_t._lastURL || (_t._lastURL === _oldIO.url))) {\r
+ // same url, ignore request\r
+ return _a; \r
+ }\r
+\r
+ _s._wD('setting new URL on existing object: ' + _dURL + (_t._lastURL ? ', old URL: ' + _t._lastURL : ''));\r
+\r
+ /**\r
+ * "First things first, I, Poppa.." (reset the previous state of the old sound, if playing)\r
+ * Fixes case with devices that can only play one sound at a time\r
+ * Otherwise, other sounds in mid-play will be terminated without warning and in a stuck state\r
+ */\r
+\r
+ if (_useGlobalHTML5Audio && _a._t && _a._t.playState && _iO.url !== _oldIO.url) {\r
+ _a._t.stop();\r
+ }\r
+\r
+ // new URL, so reset load/playstate and so on\r
+ _resetProperties();\r
+\r
+ _a.src = _iO.url;\r
+ _t.url = _iO.url;\r
+ _t._lastURL = _iO.url;\r
+ _a._called_load = false;\r
+\r
+ } else {\r
+\r
+ _s._wD('creating HTML5 Audio() element with URL: '+_dURL);\r
+ _a = new Audio(_iO.url);\r
+\r
+ _a._called_load = false;\r
+\r
+ // android (seen in 2.3/Honeycomb) sometimes fails first .load() -> .play(), results in playback failure and ended() events?\r
+ if (_is_android) {\r
+ _a._called_load = true;\r
+ }\r
+\r
+ if (_useGlobalHTML5Audio) {\r
+ _s._global_a = _a;\r
+ }\r
+\r
+ }\r
+ _t.isHTML5 = true;\r
+\r
+ // store a ref on the track\r
+ _t._a = _a;\r
+\r
+ // store a ref on the audio\r
+ _a._t = _t;\r
+\r
+ _t._add_html5_events();\r
+ _a.loop = (_iO.loops>1?'loop':'');\r
+\r
+ if (_iO.autoLoad || _iO.autoPlay) {\r
+\r
+ // early HTML5 implementation (non-standard)\r
+ _a.autobuffer = 'auto';\r
+\r
+ // standard\r
+ _a.preload = 'auto';\r
+\r
+ _t.load();\r
+ _a._called_load = true;\r
+\r
+ } else {\r
+\r
+ // early HTML5 implementation (non-standard)\r
+ _a.autobuffer = false;\r
+\r
+ // standard\r
+ _a.preload = 'none';\r
+\r
+ }\r
+\r
+ // boolean instead of "loop", for webkit? - spec says string. http://www.w3.org/TR/html-markup/audio.html#audio.attrs.loop\r
+ _a.loop = (_iO.loops>1?'loop':'');\r
+\r
+ return _a;\r
+\r
+ };\r
+\r
+ this._add_html5_events = function() {\r
+\r
+ if (_t._a._added_events) {\r
+ return false;\r
+ }\r
+\r
+ var f;\r
+\r
+ function add(oEvt, oFn, bCapture) {\r
+ return _t._a ? _t._a.addEventListener(oEvt, oFn, bCapture||false) : null;\r
+ }\r
+\r
+ _s._wD(_h5+'adding event listeners: '+_t.sID);\r
+ _t._a._added_events = true;\r
+\r
+ for (f in _html5_events) {\r
+ if (_html5_events.hasOwnProperty(f)) {\r
+ add(f, _html5_events[f]);\r
+ }\r
+ }\r
+\r
+ return true;\r
+\r
+ };\r
+\r
+ this._remove_html5_events = function() {\r
+\r
+ // Remove event listeners\r
+\r
+ var f;\r
+\r
+ function remove(oEvt, oFn, bCapture) {\r
+ return (_t._a ? _t._a.removeEventListener(oEvt, oFn, bCapture||false) : null);\r
+ }\r
+\r
+ _s._wD(_h5+'removing event listeners: '+_t.sID);\r
+ _t._a._added_events = false;\r
+\r
+ for (f in _html5_events) {\r
+ if (_html5_events.hasOwnProperty(f)) {\r
+ remove(f, _html5_events[f]);\r
+ }\r
+ }\r
+\r
+ };\r
+\r
+ /**\r
+ * Pseudo-private event internals\r
+ * ------------------------------\r
+ */\r
+\r
+ this._onload = function(nSuccess) {\r
+\r
+\r
+ var fN = 'SMSound._onload(): ', loadOK = !!(nSuccess);\r
+ _s._wD(fN + '"' + _t.sID + '"' + (loadOK?' loaded.':' failed to load? - ' + _t.url), (loadOK?1:2));\r
+ // <d>\r
+\r
+ if (!loadOK && !_t.isHTML5) {\r
+ if (_s.sandbox.noRemote === true) {\r
+ _s._wD(fN + _str('noNet'), 1);\r
+ }\r
+ if (_s.sandbox.noLocal === true) {\r
+ _s._wD(fN + _str('noLocal'), 1);\r
+ }\r
+ }\r
+ // </d>\r
+\r
+ _t.loaded = loadOK;\r
+ _t.readyState = loadOK?3:2;\r
+ _t._onbufferchange(0);\r
+\r
+ if (_t._iO.onload) {\r
+ _t._iO.onload.apply(_t, [loadOK]);\r
+ }\r
+\r
+ return true;\r
+\r
+ };\r
+\r
+ this._onbufferchange = function(nIsBuffering) {\r
+\r
+ var fN = 'SMSound._onbufferchange()';\r
+\r
+ if (_t.playState === 0) {\r
+ // ignore if not playing\r
+ return false;\r
+ }\r
+\r
+ if ((nIsBuffering && _t.isBuffering) || (!nIsBuffering && !_t.isBuffering)) {\r
+ return false;\r
+ }\r
+\r
+ _t.isBuffering = (nIsBuffering === 1);\r
+ if (_t._iO.onbufferchange) {\r
+ _s._wD(fN + ': ' + nIsBuffering);\r
+ _t._iO.onbufferchange.apply(_t);\r
+ }\r
+\r
+ return true;\r
+\r
+ };\r
+\r
+ /**\r
+ * Notify Mobile Safari that user action is required\r
+ * to continue playing / loading the audio file.\r
+ */\r
+\r
+ this._onsuspend = function () {\r
+\r
+ if (_t._iO.onsuspend) {\r
+ _s._wD('SMSound._onsuspend()');\r
+ _t._iO.onsuspend.apply(_t);\r
+ }\r
+\r
+ return true;\r
+\r
+ };\r
+\r
+ /**\r
+ * flash 9/movieStar + RTMP-only method, should fire only once at most\r
+ * at this point we just recreate failed sounds rather than trying to reconnect\r
+ */\r
+\r
+ this._onfailure = function(msg, level, code) {\r
+\r
+ _t.failures++;\r
+ _s._wD('SMSound._onfailure(): "'+_t.sID+'" count '+_t.failures);\r
+\r
+ if (_t._iO.onfailure && _t.failures === 1) {\r
+ _t._iO.onfailure(_t, msg, level, code);\r
+ } else {\r
+ _s._wD('SMSound._onfailure(): ignoring');\r
+ }\r
+\r
+ };\r
+\r
+ this._onfinish = function() {\r
+\r
+ // store local copy before it gets trashed..\r
+ var _io_onfinish = _t._iO.onfinish;\r
+ _t._onbufferchange(0);\r
+ _t.resetOnPosition(0);\r
+\r
+ // reset some state items\r
+ if (_t.instanceCount) {\r
+\r
+ _t.instanceCount--;\r
+ if (!_t.instanceCount) {\r
+ // reset instance options\r
+ _t.playState = 0;\r
+ _t.paused = false;\r
+ _t.instanceCount = 0;\r
+ _t.instanceOptions = {};\r
+ _t._iO = {};\r
+ _stop_html5_timer();\r
+ }\r
+\r
+ if (!_t.instanceCount || _t._iO.multiShotEvents) {\r
+ // fire onfinish for last, or every instance\r
+ if (_io_onfinish) {\r
+ _s._wD('SMSound._onfinish(): "' + _t.sID + '"');\r
+ _io_onfinish.apply(_t);\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ };\r
+\r
+ this._whileloading = function(nBytesLoaded, nBytesTotal, nDuration, nBufferLength) {\r
+\r
+ _t.bytesLoaded = nBytesLoaded;\r
+ _t.bytesTotal = nBytesTotal;\r
+ _t.duration = Math.floor(nDuration);\r
+ _t.bufferLength = nBufferLength;\r
+\r
+ if (!_t._iO.isMovieStar) {\r
+\r
+ if (_t._iO.duration) {\r
+ // use options, if specified and larger\r
+ _t.durationEstimate = (_t.duration > _t._iO.duration) ? _t.duration : _t._iO.duration;\r
+ } else {\r
+ _t.durationEstimate = parseInt((_t.bytesTotal / _t.bytesLoaded) * _t.duration, 10);\r
+\r
+ }\r
+\r
+ if (_t.durationEstimate === undefined) {\r
+ _t.durationEstimate = _t.duration;\r
+ }\r
+\r
+ if (_t.readyState !== 3 && _t._iO.whileloading) {\r
+ _t._iO.whileloading.apply(_t);\r
+ }\r
+\r
+ } else {\r
+\r
+ _t.durationEstimate = _t.duration;\r
+ if (_t.readyState !== 3 && _t._iO.whileloading) {\r
+ _t._iO.whileloading.apply(_t);\r
+ }\r
+\r
+ }\r
+\r
+ };\r
+\r
+ this._whileplaying = function(nPosition, oPeakData, oWaveformDataLeft, oWaveformDataRight, oEQData) {\r
+\r
+ if (isNaN(nPosition) || nPosition === null) {\r
+ // flash safety net\r
+ return false;\r
+ }\r
+\r
+ _t.position = nPosition;\r
+ _t.processOnPosition();\r
+\r
+ if (!_t.isHTML5 && _fV > 8) {\r
+\r
+ if (_t._iO.usePeakData && typeof oPeakData !== 'undefined' && oPeakData) {\r
+ _t.peakData = {\r
+ left: oPeakData.leftPeak,\r
+ right: oPeakData.rightPeak\r
+ };\r
+ }\r
+\r
+ if (_t._iO.useWaveformData && typeof oWaveformDataLeft !== 'undefined' && oWaveformDataLeft) {\r
+ _t.waveformData = {\r
+ left: oWaveformDataLeft.split(','),\r
+ right: oWaveformDataRight.split(',')\r
+ };\r
+ }\r
+\r
+ if (_t._iO.useEQData) {\r
+ if (typeof oEQData !== 'undefined' && oEQData && oEQData.leftEQ) {\r
+ var eqLeft = oEQData.leftEQ.split(',');\r
+ _t.eqData = eqLeft;\r
+ _t.eqData.left = eqLeft;\r
+ if (typeof oEQData.rightEQ !== 'undefined' && oEQData.rightEQ) {\r
+ _t.eqData.right = oEQData.rightEQ.split(',');\r
+ }\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ if (_t.playState === 1) {\r
+\r
+ // special case/hack: ensure buffering is false if loading from cache (and not yet started)\r
+ if (!_t.isHTML5 && _fV === 8 && !_t.position && _t.isBuffering) {\r
+ _t._onbufferchange(0);\r
+ }\r
+\r
+ if (_t._iO.whileplaying) {\r
+ // flash may call after actual finish\r
+ _t._iO.whileplaying.apply(_t);\r
+ }\r
+\r
+ }\r
+\r
+ return true;\r
+\r
+ };\r
+\r
+ this._onid3 = function(oID3PropNames, oID3Data) {\r
+\r
+ // oID3PropNames: string array (names)\r
+ // ID3Data: string array (data)\r
+ _s._wD('SMSound._onid3(): "' + this.sID + '" ID3 data received.');\r
+\r
+ var oData = [], i, j;\r
+\r
+ for (i = 0, j = oID3PropNames.length; i < j; i++) {\r
+ oData[oID3PropNames[i]] = oID3Data[i];\r
+ }\r
+ _t.id3 = _mixin(_t.id3, oData);\r
+\r
+ if (_t._iO.onid3) {\r
+ _t._iO.onid3.apply(_t);\r
+ }\r
+\r
+ };\r
+\r
+ // flash/RTMP-only\r
+\r
+ this._onconnect = function(bSuccess) {\r
+\r
+ var fN = 'SMSound._onconnect(): ';\r
+ bSuccess = (bSuccess === 1);\r
+ _s._wD(fN+'"'+_t.sID+'"'+(bSuccess?' connected.':' failed to connect? - '+_t.url), (bSuccess?1:2));\r
+ _t.connected = bSuccess;\r
+\r
+ if (bSuccess) {\r
+\r
+ _t.failures = 0;\r
+\r
+ if (_idCheck(_t.sID)) {\r
+ if (_t.getAutoPlay()) {\r
+ // only update the play state if auto playing\r
+ _t.play(undefined, _t.getAutoPlay());\r
+ } else if (_t._iO.autoLoad) {\r
+ _t.load();\r
+ }\r
+ }\r
+\r
+ if (_t._iO.onconnect) {\r
+ _t._iO.onconnect.apply(_t,[bSuccess]);\r
+ }\r
+\r
+ }\r
+\r
+ };\r
+\r
+ this._ondataerror = function(sError) {\r
+\r
+ // flash 9 wave/eq data handler\r
+ // hack: called at start, and end from flash at/after onfinish()\r
+ if (_t.playState > 0) {\r
+ _s._wD('SMSound._ondataerror(): ' + sError);\r
+ if (_t._iO.ondataerror) {\r
+ _t._iO.ondataerror.apply(_t);\r
+ }\r
+ }\r
+\r
+ };\r
+\r
+ }; // SMSound()\r
+\r
+ /**\r
+ * Private SoundManager internals\r
+ * ------------------------------\r
+ */\r
+\r
+ _getDocument = function() {\r
+\r
+ return (_doc.body || _doc._docElement || _doc.getElementsByTagName('div')[0]);\r
+\r
+ };\r
+\r
+ _id = function(sID) {\r
+\r
+ return _doc.getElementById(sID);\r
+\r
+ };\r
+\r
+ _mixin = function(oMain, oAdd) {\r
+\r
+ // non-destructive merge\r
+ var o1 = {}, i, o2, o;\r
+\r
+ // clone c1\r
+ for (i in oMain) {\r
+ if (oMain.hasOwnProperty(i)) {\r
+ o1[i] = oMain[i];\r
+ }\r
+ }\r
+\r
+ o2 = (typeof oAdd === 'undefined'?_s.defaultOptions:oAdd);\r
+ for (o in o2) {\r
+ if (o2.hasOwnProperty(o) && typeof o1[o] === 'undefined') {\r
+ o1[o] = o2[o];\r
+ }\r
+ }\r
+ return o1;\r
+\r
+ };\r
+\r
+ _event = (function() {\r
+\r
+ var old = (_win.attachEvent),\r
+ evt = {\r
+ add: (old?'attachEvent':'addEventListener'),\r
+ remove: (old?'detachEvent':'removeEventListener')\r
+ };\r
+\r
+ function getArgs(oArgs) {\r
+\r
+ var args = _slice.call(oArgs), len = args.length;\r
+\r
+ if (old) {\r
+ // prefix\r
+ args[1] = 'on' + args[1];\r
+ if (len > 3) {\r
+ // no capture\r
+ args.pop();\r
+ }\r
+ } else if (len === 3) {\r
+ args.push(false);\r
+ }\r
+ return args;\r
+\r
+ }\r
+\r
+ function apply(args, sType) {\r
+\r
+ var element = args.shift(),\r
+ method = [evt[sType]];\r
+\r
+ if (old) {\r
+ element[method](args[0], args[1]);\r
+ } else {\r
+ element[method].apply(element, args);\r
+ }\r
+\r
+ }\r
+\r
+ function add() {\r
+\r
+ apply(getArgs(arguments), 'add');\r
+\r
+ }\r
+\r
+ function remove() {\r
+\r
+ apply(getArgs(arguments), 'remove');\r
+\r
+ }\r
+\r
+ return {\r
+ 'add': add,\r
+ 'remove': remove\r
+ };\r
+\r
+ }());\r
+\r
+ /**\r
+ * Internal HTML5 event handling\r
+ * -----------------------------\r
+ */\r
+\r
+ function _html5_event(oFn) {\r
+\r
+ // wrap html5 event handlers so we don't call them on destroyed sounds\r
+\r
+ return function(e) {\r
+\r
+ if (!this._t || !this._t._a) {\r
+ // <d>\r
+ if (this._t && this._t.sID) {\r
+ _s._wD(_h5+'ignoring '+e.type+': '+this._t.sID);\r
+ } else {\r
+ _s._wD(_h5+'ignoring '+e.type);\r
+ }\r
+ // </d>\r
+ return null;\r
+ } else {\r
+ return oFn.call(this, e);\r
+ }\r
+\r
+ };\r
+\r
+ }\r
+\r
+ _html5_events = {\r
+\r
+ // HTML5 event-name-to-handler map\r
+\r
+ abort: _html5_event(function(e) {\r
+\r
+ _s._wD(_h5+'abort: '+this._t.sID);\r
+\r
+ }),\r
+\r
+ // enough has loaded to play\r
+\r
+ canplay: _html5_event(function(e) {\r
+\r
+ if (this._t._html5_canplay) {\r
+ // this event has already fired. ignore.\r
+ return true;\r
+ }\r
+\r
+ this._t._html5_canplay = true;\r
+ _s._wD(_h5+'canplay: '+this._t.sID+', '+this._t.url);\r
+ this._t._onbufferchange(0);\r
+ var position1K = (!isNaN(this._t.position)?this._t.position/1000:null);\r
+\r
+ // set the position if position was set before the sound loaded\r
+ if (this._t.position && this.currentTime !== position1K) {\r
+ _s._wD(_h5+'canplay: setting position to '+position1K);\r
+ try {\r
+ this.currentTime = position1K;\r
+ } catch(ee) {\r
+ _s._wD(_h5+'setting position failed: '+ee.message, 2);\r
+ }\r
+ }\r
+\r
+ }),\r
+\r
+ load: _html5_event(function(e) {\r
+\r
+ if (!this._t.loaded) {\r
+ this._t._onbufferchange(0);\r
+ // should be 1, and the same\r
+ this._t._whileloading(this._t.bytesTotal, this._t.bytesTotal, this._t._get_html5_duration());\r
+ this._t._onload(true);\r
+ }\r
+\r
+ }),\r
+\r
+ emptied: _html5_event(function(e) {\r
+\r
+ _s._wD(_h5+'emptied: '+this._t.sID);\r
+\r
+ }),\r
+\r
+ ended: _html5_event(function(e) {\r
+\r
+ _s._wD(_h5+'ended: '+this._t.sID);\r
+ this._t._onfinish();\r
+\r
+ }),\r
+\r
+ error: _html5_event(function(e) {\r
+\r
+ _s._wD(_h5+'error: '+this.error.code);\r
+ // call load with error state?\r
+ this._t._onload(false);\r
+\r
+ }),\r
+\r
+ loadeddata: _html5_event(function(e) {\r
+\r
+ var t = this._t,\r
+ // at least 1 byte, so math works\r
+ bytesTotal = t.bytesTotal || 1;\r
+\r
+ _s._wD(_h5+'loadeddata: '+this._t.sID);\r
+\r
+ // safari seems to nicely report progress events, eventually totalling 100%\r
+ if (!t._loaded && !_isSafari) {\r
+ t.duration = t._get_html5_duration();\r
+ // fire whileloading() with 100% values\r
+ t._whileloading(bytesTotal, bytesTotal, t._get_html5_duration());\r
+ t._onload(true);\r
+ }\r
+\r
+ }),\r
+\r
+ loadedmetadata: _html5_event(function(e) {\r
+\r
+ _s._wD(_h5+'loadedmetadata: '+this._t.sID);\r
+\r
+ }),\r
+\r
+ loadstart: _html5_event(function(e) {\r
+\r
+ _s._wD(_h5+'loadstart: '+this._t.sID);\r
+ // assume buffering at first\r
+ this._t._onbufferchange(1);\r
+\r
+ }),\r
+\r
+ play: _html5_event(function(e) {\r
+\r
+ _s._wD(_h5+'play: '+this._t.sID+', '+this._t.url);\r
+ // once play starts, no buffering\r
+ this._t._onbufferchange(0);\r
+\r
+ }),\r
+\r
+ // TODO: verify if this is actually implemented anywhere yet.\r
+ playing: _html5_event(function(e) {\r
+\r
+ _s._wD(_h5+'playing: '+this._t.sID+', '+this._t.url);\r
+\r
+ // once play starts, no buffering\r
+ this._t._onbufferchange(0);\r
+\r
+ }),\r
+\r
+ progress: _html5_event(function(e) {\r
+\r
+ if (this._t.loaded) {\r
+ return false;\r
+ }\r
+\r
+ var i, j, str, buffered = 0,\r
+ isProgress = (e.type === 'progress'),\r
+ ranges = e.target.buffered,\r
+\r
+ // firefox 3.6 implements e.loaded/total (bytes)\r
+ loaded = (e.loaded||0),\r
+\r
+ total = (e.total||1);\r
+\r
+ if (ranges && ranges.length) {\r
+\r
+ // if loaded is 0, try TimeRanges implementation as % of load\r
+ // https://developer.mozilla.org/en/DOM/TimeRanges\r
+\r
+ for (i=ranges.length; i--;) {\r
+ buffered = (ranges.end(i) - ranges.start(i));\r
+ }\r
+\r
+ // linear case, buffer sum; does not account for seeking and HTTP partials / byte ranges\r
+ loaded = buffered/e.target.duration;\r
+\r
+ // <d>\r
+ if (isProgress && ranges.length > 1) {\r
+ str = [];\r
+ j = ranges.length;\r
+ for (i=0; i<j; i++) {\r
+ str.push(e.target.buffered.start(i) +'-'+ e.target.buffered.end(i));\r
+ }\r
+ _s._wD(_h5+'progress: timeRanges: '+str.join(', '));\r
+ }\r
+\r
+ if (isProgress && !isNaN(loaded)) {\r
+ _s._wD(_h5+'progress: '+this._t.sID+': ' + Math.floor(loaded*100)+'% loaded');\r
+ }\r
+ // </d>\r
+\r
+ }\r
+\r
+ if (!isNaN(loaded)) {\r
+\r
+ // if progress, likely not buffering\r
+ this._t._onbufferchange(0);\r
+ this._t._whileloading(loaded, total, this._t._get_html5_duration());\r
+ if (loaded && total && loaded === total) {\r
+ // in case "onload" doesn't fire (eg. gecko 1.9.2)\r
+ _html5_events.load.call(this, e);\r
+ }\r
+\r
+ }\r
+\r
+ }),\r
+\r
+ ratechange: _html5_event(function(e) {\r
+\r
+ _s._wD(_h5+'ratechange: '+this._t.sID);\r
+\r
+ }),\r
+\r
+ suspend: _html5_event(function(e) {\r
+\r
+ // download paused/stopped, may have finished (eg. onload)\r
+\r
+ _s._wD(_h5+'suspend: '+this._t.sID);\r
+ _html5_events.progress.call(this, e);\r
+ this._t._onsuspend();\r
+\r
+ }),\r
+\r
+ stalled: _html5_event(function(e) {\r
+\r
+ _s._wD(_h5+'stalled: '+this._t.sID);\r
+\r
+ }),\r
+\r
+ timeupdate: _html5_event(function(e) {\r
+\r
+ this._t._onTimer();\r
+\r
+ }),\r
+\r
+ waiting: _html5_event(function(e) {\r
+\r
+ // see also: seeking\r
+ _s._wD(_h5+'waiting: '+this._t.sID);\r
+\r
+ // playback faster than download rate, etc.\r
+ this._t._onbufferchange(1);\r
+\r
+ })\r
+\r
+ };\r
+\r
+ _html5OK = function(iO) {\r
+\r
+ // Use type, if specified. If HTML5-only mode, no other options, so just give 'er\r
+ return (!iO.serverURL && (iO.type?_html5CanPlay({type:iO.type}):_html5CanPlay({url:iO.url})||_s.html5Only));\r
+\r
+ };\r
+\r
+ _html5Unload = function(oAudio) {\r
+\r
+ /**\r
+ * Internal method: Unload media, and cancel any current/pending network requests.\r
+ * Firefox can load an empty URL, which allegedly destroys the decoder and stops the download.\r
+ * https://developer.mozilla.org/En/Using_audio_and_video_in_Firefox#Stopping_the_download_of_media\r
+ * Other UA behaviour is unclear, so everyone else gets an about:blank-style URL.\r
+ */\r
+\r
+ if (oAudio) {\r
+ // Firefox likes '' for unload, most other UAs don't and fail to unload.\r
+ oAudio.src = (_is_firefox ? '' : _emptyURL);\r
+ }\r
+\r
+ };\r
+\r
+ _html5CanPlay = function(o) {\r
+\r
+ /**\r
+ * Try to find MIME, test and return truthiness\r
+ * o = {\r
+ * url: '/path/to/an.mp3',\r
+ * type: 'audio/mp3'\r
+ * }\r
+ */\r
+\r
+ if (!_s.useHTML5Audio || !_s.hasHTML5) {\r
+ return false;\r
+ }\r
+\r
+ var url = (o.url || null),\r
+ mime = (o.type || null),\r
+ aF = _s.audioFormats,\r
+ result,\r
+ offset,\r
+ fileExt,\r
+ item;\r
+\r
+ function preferFlashCheck(kind) {\r
+\r
+ // whether flash should play a given type\r
+ return (_s.preferFlash && _hasFlash && !_s.ignoreFlash && (typeof _s.flash[kind] !== 'undefined' && _s.flash[kind]));\r
+\r
+ }\r
+\r
+ // account for known cases like audio/mp3\r
+\r
+ if (mime && _s.html5[mime] !== 'undefined') {\r
+ return (_s.html5[mime] && !preferFlashCheck(mime));\r
+ }\r
+\r
+ if (!_html5Ext) {\r
+ _html5Ext = [];\r
+ for (item in aF) {\r
+ if (aF.hasOwnProperty(item)) {\r
+ _html5Ext.push(item);\r
+ if (aF[item].related) {\r
+ _html5Ext = _html5Ext.concat(aF[item].related);\r
+ }\r
+ }\r
+ }\r
+ _html5Ext = new RegExp('\\.('+_html5Ext.join('|')+')(\\?.*)?$','i');\r
+ }\r
+\r
+ // TODO: Strip URL queries, etc.\r
+ fileExt = (url ? url.toLowerCase().match(_html5Ext) : null);\r
+\r
+ if (!fileExt || !fileExt.length) {\r
+ if (!mime) {\r
+ return false;\r
+ } else {\r
+ // audio/mp3 -> mp3, result should be known\r
+ offset = mime.indexOf(';');\r
+ // strip "audio/X; codecs.."\r
+ fileExt = (offset !== -1?mime.substr(0,offset):mime).substr(6);\r
+ }\r
+ } else {\r
+ // match the raw extension name - "mp3", for example\r
+ fileExt = fileExt[1];\r
+ }\r
+\r
+ if (fileExt && typeof _s.html5[fileExt] !== 'undefined') {\r
+ // result known\r
+ return (_s.html5[fileExt] && !preferFlashCheck(fileExt));\r
+ } else {\r
+ mime = 'audio/'+fileExt;\r
+ result = _s.html5.canPlayType({type:mime});\r
+ _s.html5[fileExt] = result;\r
+ // _s._wD('canPlayType, found result: '+result);\r
+ return (result && _s.html5[mime] && !preferFlashCheck(mime));\r
+ }\r
+\r
+ };\r
+\r
+ _testHTML5 = function() {\r
+\r
+ if (!_s.useHTML5Audio || typeof Audio === 'undefined') {\r
+ return false;\r
+ }\r
+\r
+ // double-whammy: Opera 9.64 throws WRONG_ARGUMENTS_ERR if no parameter passed to Audio(), and Webkit + iOS happily tries to load "null" as a URL. :/\r
+ var a = (typeof Audio !== 'undefined' ? (_isOpera ? new Audio(null) : new Audio()) : null),\r
+ item, support = {}, aF, i;\r
+\r
+ function _cp(m) {\r
+\r
+ var canPlay, i, j, isOK = false;\r
+\r
+ if (!a || typeof a.canPlayType !== 'function') {\r
+ return false;\r
+ }\r
+\r
+ if (m instanceof Array) {\r
+ // iterate through all mime types, return any successes\r
+ for (i=0, j=m.length; i<j && !isOK; i++) {\r
+ if (_s.html5[m[i]] || a.canPlayType(m[i]).match(_s.html5Test)) {\r
+ isOK = true;\r
+ _s.html5[m[i]] = true;\r
+\r
+ // if flash can play and preferred, also mark it for use.\r
+ _s.flash[m[i]] = !!(_s.preferFlash && _hasFlash && m[i].match(_flashMIME));\r
+\r
+ }\r
+ }\r
+ return isOK;\r
+ } else {\r
+ canPlay = (a && typeof a.canPlayType === 'function' ? a.canPlayType(m) : false);\r
+ return !!(canPlay && (canPlay.match(_s.html5Test)));\r
+ }\r
+\r
+ }\r
+\r
+ // test all registered formats + codecs\r
+\r
+ aF = _s.audioFormats;\r
+\r
+ for (item in aF) {\r
+ if (aF.hasOwnProperty(item)) {\r
+ support[item] = _cp(aF[item].type);\r
+\r
+ // write back generic type too, eg. audio/mp3\r
+ support['audio/'+item] = support[item];\r
+\r
+ // assign flash\r
+ if (_s.preferFlash && !_s.ignoreFlash && item.match(_flashMIME)) {\r
+ _s.flash[item] = true;\r
+ } else {\r
+ _s.flash[item] = false;\r
+ }\r
+\r
+ // assign result to related formats, too\r
+ if (aF[item] && aF[item].related) {\r
+ for (i=aF[item].related.length; i--;) {\r
+ // eg. audio/m4a\r
+ support['audio/'+aF[item].related[i]] = support[item];\r
+ _s.html5[aF[item].related[i]] = support[item];\r
+ _s.flash[aF[item].related[i]] = support[item];\r
+\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ support.canPlayType = (a?_cp:null);\r
+ _s.html5 = _mixin(_s.html5, support);\r
+\r
+ return true;\r
+\r
+ };\r
+\r
+ _strings = {\r
+\r
+ // <d>\r
+ notReady: 'Not loaded yet - wait for soundManager.onload()/onready()',\r
+ notOK: 'Audio support is not available.',\r
+ domError: _smc + 'createMovie(): appendChild/innerHTML call failed. DOM not ready or other error.',\r
+ spcWmode: _smc + 'createMovie(): Removing wmode, preventing known SWF loading issue(s)',\r
+ swf404: _sm + ': Verify that %s is a valid path.',\r
+ tryDebug: 'Try ' + _sm + '.debugFlash = true for more security details (output goes to SWF.)',\r
+ checkSWF: 'See SWF output for more debug info.',\r
+ localFail: _sm + ': Non-HTTP page (' + _doc.location.protocol + ' URL?) Review Flash player security settings for this special case:\nhttp://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html\nMay need to add/allow path, eg. c:/sm2/ or /users/me/sm2/',\r
+ waitFocus: _sm + ': Special case: Waiting for focus-related event..',\r
+ waitImpatient: _sm + ': Getting impatient, still waiting for Flash%s...',\r
+ waitForever: _sm + ': Waiting indefinitely for Flash (will recover if unblocked)...',\r
+ needFunction: _sm + ': Function object expected for %s',\r
+ badID: 'Warning: Sound ID "%s" should be a string, starting with a non-numeric character',\r
+ currentObj: '--- ' + _sm + '._debug(): Current sound objects ---',\r
+ waitEI: _smc + 'initMovie(): Waiting for ExternalInterface call from Flash..',\r
+ waitOnload: _sm + ': Waiting for window.onload()',\r
+ docLoaded: _sm + ': Document already loaded',\r
+ onload: _smc + 'initComplete(): calling soundManager.onload()',\r
+ onloadOK: _sm + '.onload() complete',\r
+ init: _smc + 'init()',\r
+ didInit: _smc + 'init(): Already called?',\r
+ flashJS: _sm + ': Attempting to call Flash from JS..',\r
+ secNote: 'Flash security note: Network/internet URLs will not load due to security restrictions. Access can be configured via Flash Player Global Security Settings Page: http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html',\r
+ badRemove: 'Warning: Failed to remove flash movie.',\r
+ noPeak: 'Warning: peakData features unsupported for movieStar formats',\r
+ shutdown: _sm + '.disable(): Shutting down',\r
+ queue: _sm + ': Queueing %s handler',\r
+ smFail: _sm + ': Failed to initialise.',\r
+ smError: 'SMSound.load(): Exception: JS-Flash communication failed, or JS error.',\r
+ fbTimeout: 'No flash response, applying .'+_s.swfCSS.swfTimedout+' CSS..',\r
+ fbLoaded: 'Flash loaded',\r
+ fbHandler: _smc+'flashBlockHandler()',\r
+ manURL: 'SMSound.load(): Using manually-assigned URL',\r
+ onURL: _sm + '.load(): current URL already assigned.',\r
+ badFV: _sm + '.flashVersion must be 8 or 9. "%s" is invalid. Reverting to %s.',\r
+ as2loop: 'Note: Setting stream:false so looping can work (flash 8 limitation)',\r
+ noNSLoop: 'Note: Looping not implemented for MovieStar formats',\r
+ needfl9: 'Note: Switching to flash 9, required for MP4 formats.',\r
+ mfTimeout: 'Setting flashLoadTimeout = 0 (infinite) for off-screen, mobile flash case',\r
+ mfOn: 'mobileFlash::enabling on-screen flash repositioning',\r
+ policy: 'Enabling usePolicyFile for data access'\r
+ // </d>\r
+\r
+ };\r
+\r
+ _str = function() {\r
+\r
+ // internal string replace helper.\r
+ // arguments: o [,items to replace]\r
+ // <d>\r
+\r
+ // real array, please\r
+ var args = _slice.call(arguments),\r
+\r
+ // first arg\r
+ o = args.shift(),\r
+\r
+ str = (_strings && _strings[o]?_strings[o]:''), i, j;\r
+ if (str && args && args.length) {\r
+ for (i = 0, j = args.length; i < j; i++) {\r
+ str = str.replace('%s', args[i]);\r
+ }\r
+ }\r
+\r
+ return str;\r
+ // </d>\r
+\r
+ };\r
+\r
+ _loopFix = function(sOpt) {\r
+\r
+ // flash 8 requires stream = false for looping to work\r
+ if (_fV === 8 && sOpt.loops > 1 && sOpt.stream) {\r
+ _wDS('as2loop');\r
+ sOpt.stream = false;\r
+ }\r
+\r
+ return sOpt;\r
+\r
+ };\r
+\r
+ _policyFix = function(sOpt, sPre) {\r
+\r
+ if (sOpt && !sOpt.usePolicyFile && (sOpt.onid3 || sOpt.usePeakData || sOpt.useWaveformData || sOpt.useEQData)) {\r
+ _s._wD((sPre || '') + _str('policy'));\r
+ sOpt.usePolicyFile = true;\r
+ }\r
+\r
+ return sOpt;\r
+\r
+ };\r
+\r
+ _complain = function(sMsg) {\r
+\r
+ // <d>\r
+ if (typeof console !== 'undefined' && typeof console.warn !== 'undefined') {\r
+ console.warn(sMsg);\r
+ } else {\r
+ _s._wD(sMsg);\r
+ }\r
+ // </d>\r
+\r
+ };\r
+\r
+ _doNothing = function() {\r
+\r
+ return false;\r
+\r
+ };\r
+\r
+ _disableObject = function(o) {\r
+\r
+ var oProp;\r
+\r
+ for (oProp in o) {\r
+ if (o.hasOwnProperty(oProp) && typeof o[oProp] === 'function') {\r
+ o[oProp] = _doNothing;\r
+ }\r
+ }\r
+\r
+ oProp = null;\r
+\r
+ };\r
+\r
+ _failSafely = function(bNoDisable) {\r
+\r
+ // general failure exception handler\r
+\r
+ if (typeof bNoDisable === 'undefined') {\r
+ bNoDisable = false;\r
+ }\r
+\r
+ if (_disabled || bNoDisable) {\r
+ _wDS('smFail', 2);\r
+ _s.disable(bNoDisable);\r
+ }\r
+\r
+ };\r
+\r
+ _normalizeMovieURL = function(smURL) {\r
+\r
+ var urlParams = null, url;\r
+\r
+ if (smURL) {\r
+ if (smURL.match(/\.swf(\?.*)?$/i)) {\r
+ urlParams = smURL.substr(smURL.toLowerCase().lastIndexOf('.swf?') + 4);\r
+ if (urlParams) {\r
+ // assume user knows what they're doing\r
+ return smURL;\r
+ }\r
+ } else if (smURL.lastIndexOf('/') !== smURL.length - 1) {\r
+ // append trailing slash, if needed\r
+ smURL += '/';\r
+ }\r
+ }\r
+\r
+ url = (smURL && smURL.lastIndexOf('/') !== - 1 ? smURL.substr(0, smURL.lastIndexOf('/') + 1) : './') + _s.movieURL;\r
+\r
+ if (_s.noSWFCache) {\r
+ url += ('?ts=' + new Date().getTime());\r
+ }\r
+\r
+ return url;\r
+\r
+ };\r
+\r
+ _setVersionInfo = function() {\r
+\r
+ // short-hand for internal use\r
+\r
+ _fV = parseInt(_s.flashVersion, 10);\r
+\r
+ if (_fV !== 8 && _fV !== 9) {\r
+ _s._wD(_str('badFV', _fV, _defaultFlashVersion));\r
+ _s.flashVersion = _fV = _defaultFlashVersion;\r
+ }\r
+\r
+ // debug flash movie, if applicable\r
+\r
+ var isDebug = (_s.debugMode || _s.debugFlash?'_debug.swf':'.swf');\r
+\r
+ if (_s.useHTML5Audio && !_s.html5Only && _s.audioFormats.mp4.required && _fV < 9) {\r
+ _s._wD(_str('needfl9'));\r
+ _s.flashVersion = _fV = 9;\r
+ }\r
+\r
+ _s.version = _s.versionNumber + (_s.html5Only?' (HTML5-only mode)':(_fV === 9?' (AS3/Flash 9)':' (AS2/Flash 8)'));\r
+\r
+ // set up default options\r
+ if (_fV > 8) {\r
+ // +flash 9 base options\r
+ _s.defaultOptions = _mixin(_s.defaultOptions, _s.flash9Options);\r
+ _s.features.buffering = true;\r
+ // +moviestar support\r
+ _s.defaultOptions = _mixin(_s.defaultOptions, _s.movieStarOptions);\r
+ _s.filePatterns.flash9 = new RegExp('\\.(mp3|' + _netStreamTypes.join('|') + ')(\\?.*)?$', 'i');\r
+ _s.features.movieStar = true;\r
+ } else {\r
+ _s.features.movieStar = false;\r
+ }\r
+\r
+ // regExp for flash canPlay(), etc.\r
+ _s.filePattern = _s.filePatterns[(_fV !== 8?'flash9':'flash8')];\r
+\r
+ // if applicable, use _debug versions of SWFs\r
+ _s.movieURL = (_fV === 8?'soundmanager2.swf':'soundmanager2_flash9.swf').replace('.swf', isDebug);\r
+\r
+ _s.features.peakData = _s.features.waveformData = _s.features.eqData = (_fV > 8);\r
+\r
+ };\r
+\r
+ _setPolling = function(bPolling, bHighPerformance) {\r
+\r
+ if (!_s.o) {\r
+ return false;\r
+ }\r
+\r
+ _s.o._setPolling(bPolling, bHighPerformance);\r
+\r
+ };\r
+\r
+ _initDebug = function() {\r
+\r
+ // starts debug mode, creating output <div> for UAs without console object\r
+\r
+ // allow force of debug mode via URL\r
+ if (_s.debugURLParam.test(_wl)) {\r
+ _s.debugMode = true;\r
+ }\r
+\r
+ // <d>\r
+ if (_id(_s.debugID)) {\r
+ return false;\r
+ }\r
+\r
+ var oD, oDebug, oTarget, oToggle, tmp;\r
+\r
+ if (_s.debugMode && !_id(_s.debugID) && ((!_hasConsole || !_s.useConsole) || (_s.useConsole && _hasConsole && !_s.consoleOnly))) {\r
+\r
+ oD = _doc.createElement('div');\r
+ oD.id = _s.debugID + '-toggle';\r
+\r
+ oToggle = {\r
+ 'position': 'fixed',\r
+ 'bottom': '0px',\r
+ 'right': '0px',\r
+ 'width': '1.2em',\r
+ 'height': '1.2em',\r
+ 'lineHeight': '1.2em',\r
+ 'margin': '2px',\r
+ 'textAlign': 'center',\r
+ 'border': '1px solid #999',\r
+ 'cursor': 'pointer',\r
+ 'background': '#fff',\r
+ 'color': '#333',\r
+ 'zIndex': 10001\r
+ };\r
+\r
+ oD.appendChild(_doc.createTextNode('-'));\r
+ oD.onclick = _toggleDebug;\r
+ oD.title = 'Toggle SM2 debug console';\r
+\r
+ if (_ua.match(/msie 6/i)) {\r
+ oD.style.position = 'absolute';\r
+ oD.style.cursor = 'hand';\r
+ }\r
+\r
+ for (tmp in oToggle) {\r
+ if (oToggle.hasOwnProperty(tmp)) {\r
+ oD.style[tmp] = oToggle[tmp];\r
+ }\r
+ }\r
+\r
+ oDebug = _doc.createElement('div');\r
+ oDebug.id = _s.debugID;\r
+ oDebug.style.display = (_s.debugMode?'block':'none');\r
+\r
+ if (_s.debugMode && !_id(oD.id)) {\r
+ try {\r
+ oTarget = _getDocument();\r
+ oTarget.appendChild(oD);\r
+ } catch(e2) {\r
+ throw new Error(_str('domError')+' \n'+e2.toString());\r
+ }\r
+ oTarget.appendChild(oDebug);\r
+ }\r
+\r
+ }\r
+\r
+ oTarget = null;\r
+ // </d>\r
+\r
+ };\r
+\r
+ _idCheck = this.getSoundById;\r
+\r
+ // <d>\r
+ _wDS = function(o, errorLevel) {\r
+\r
+ if (!o) {\r
+ return '';\r
+ } else {\r
+ return _s._wD(_str(o), errorLevel);\r
+ }\r
+\r
+ };\r
+\r
+ // last-resort debugging option\r
+\r
+ if (_wl.indexOf('sm2-debug=alert') + 1 && _s.debugMode) {\r
+ _s._wD = function(sText) {window.alert(sText);};\r
+ }\r
+\r
+ _toggleDebug = function() {\r
+\r
+ var o = _id(_s.debugID),\r
+ oT = _id(_s.debugID + '-toggle');\r
+\r
+ if (!o) {\r
+ return false;\r
+ }\r
+\r
+ if (_debugOpen) {\r
+ // minimize\r
+ oT.innerHTML = '+';\r
+ o.style.display = 'none';\r
+ } else {\r
+ oT.innerHTML = '-';\r
+ o.style.display = 'block';\r
+ }\r
+\r
+ _debugOpen = !_debugOpen;\r
+\r
+ };\r
+\r
+ _debugTS = function(sEventType, bSuccess, sMessage) {\r
+\r
+ // troubleshooter debug hooks\r
+\r
+ if (typeof sm2Debugger !== 'undefined') {\r
+ try {\r
+ sm2Debugger.handleEvent(sEventType, bSuccess, sMessage);\r
+ } catch(e) {\r
+ // oh well\r
+ }\r
+ }\r
+\r
+ return true;\r
+\r
+ };\r
+ // </d>\r
+\r
+ _getSWFCSS = function() {\r
+\r
+ var css = [];\r
+\r
+ if (_s.debugMode) {\r
+ css.push(_s.swfCSS.sm2Debug);\r
+ }\r
+\r
+ if (_s.debugFlash) {\r
+ css.push(_s.swfCSS.flashDebug);\r
+ }\r
+\r
+ if (_s.useHighPerformance) {\r
+ css.push(_s.swfCSS.highPerf);\r
+ }\r
+\r
+ return css.join(' ');\r
+\r
+ };\r
+\r
+ _flashBlockHandler = function() {\r
+\r
+ // *possible* flash block situation.\r
+\r
+ var name = _str('fbHandler'),\r
+ p = _s.getMoviePercent(),\r
+ css = _s.swfCSS,\r
+ error = {type:'FLASHBLOCK'};\r
+\r
+ if (_s.html5Only) {\r
+ return false;\r
+ }\r
+\r
+ if (!_s.ok()) {\r
+\r
+ if (_needsFlash) {\r
+ // make the movie more visible, so user can fix\r
+ _s.oMC.className = _getSWFCSS() + ' ' + css.swfDefault + ' ' + (p === null?css.swfTimedout:css.swfError);\r
+ _s._wD(name+': '+_str('fbTimeout')+(p?' ('+_str('fbLoaded')+')':''));\r
+ }\r
+\r
+ _s.didFlashBlock = true;\r
+\r
+ // fire onready(), complain lightly\r
+ _processOnEvents({type:'ontimeout', ignoreInit:true, error:error});\r
+ _catchError(error);\r
+\r
+ } else {\r
+\r
+ // SM2 loaded OK (or recovered)\r
+\r
+ if (_s.didFlashBlock) {\r
+ _s._wD(name+': Unblocked');\r
+ }\r
+\r
+ if (_s.oMC) {\r
+ _s.oMC.className = [_getSWFCSS(), css.swfDefault, css.swfLoaded + (_s.didFlashBlock?' '+css.swfUnblocked:'')].join(' ');\r
+ }\r
+\r
+ }\r
+\r
+ };\r
+\r
+ _addOnEvent = function(sType, oMethod, oScope) {\r
+\r
+ if (typeof _on_queue[sType] === 'undefined') {\r
+ _on_queue[sType] = [];\r
+ }\r
+\r
+ _on_queue[sType].push({\r
+ 'method': oMethod,\r
+ 'scope': (oScope || null),\r
+ 'fired': false\r
+ });\r
+\r
+ };\r
+\r
+ _processOnEvents = function(oOptions) {\r
+\r
+ // assume onready, if unspecified\r
+\r
+ if (!oOptions) {\r
+ oOptions = {\r
+ type: 'onready'\r
+ };\r
+ }\r
+\r
+ if (!_didInit && oOptions && !oOptions.ignoreInit) {\r
+ // not ready yet.\r
+ return false;\r
+ }\r
+\r
+ if (oOptions.type === 'ontimeout' && _s.ok()) {\r
+ // invalid case\r
+ return false;\r
+ }\r
+\r
+ var status = {\r
+ success: (oOptions && oOptions.ignoreInit?_s.ok():!_disabled)\r
+ },\r
+\r
+ // queue specified by type, or none\r
+ srcQueue = (oOptions && oOptions.type?_on_queue[oOptions.type]||[]:[]),\r
+\r
+ queue = [], i, j,\r
+ args = [status],\r
+ canRetry = (_needsFlash && _s.useFlashBlock && !_s.ok());\r
+\r
+ if (oOptions.error) {\r
+ args[0].error = oOptions.error;\r
+ }\r
+\r
+ for (i = 0, j = srcQueue.length; i < j; i++) {\r
+ if (srcQueue[i].fired !== true) {\r
+ queue.push(srcQueue[i]);\r
+ }\r
+ }\r
+\r
+ if (queue.length) {\r
+ _s._wD(_sm + ': Firing ' + queue.length + ' '+oOptions.type+'() item' + (queue.length === 1?'':'s'));\r
+ for (i = 0, j = queue.length; i < j; i++) {\r
+ if (queue[i].scope) {\r
+ queue[i].method.apply(queue[i].scope, args);\r
+ } else {\r
+ queue[i].method.apply(this, args);\r
+ }\r
+ if (!canRetry) {\r
+ // flashblock case doesn't count here\r
+ queue[i].fired = true;\r
+ }\r
+ }\r
+ }\r
+\r
+ return true;\r
+\r
+ };\r
+\r
+ _initUserOnload = function() {\r
+\r
+ _win.setTimeout(function() {\r
+\r
+ if (_s.useFlashBlock) {\r
+ _flashBlockHandler();\r
+ }\r
+\r
+ _processOnEvents();\r
+\r
+ // call user-defined "onload", scoped to window\r
+\r
+ if (_s.onload instanceof Function) {\r
+ _wDS('onload', 1);\r
+ _s.onload.apply(_win);\r
+ _wDS('onloadOK', 1);\r
+ }\r
+\r
+ if (_s.waitForWindowLoad) {\r
+ _event.add(_win, 'load', _initUserOnload);\r
+ }\r
+\r
+ },1);\r
+\r
+ };\r
+\r
+ _detectFlash = function() {\r
+\r
+ // hat tip: Flash Detect library (BSD, (C) 2007) by Carl "DocYes" S. Yestrau - http://featureblend.com/javascript-flash-detection-library.html / http://featureblend.com/license.txt\r
+\r
+ if (_hasFlash !== undefined) {\r
+ // this work has already been done.\r
+ return _hasFlash;\r
+ }\r
+\r
+ var hasPlugin = false, n = navigator, nP = n.plugins, obj, type, types, AX = _win.ActiveXObject;\r
+\r
+ if (nP && nP.length) {\r
+ type = 'application/x-shockwave-flash';\r
+ types = n.mimeTypes;\r
+ if (types && types[type] && types[type].enabledPlugin && types[type].enabledPlugin.description) {\r
+ hasPlugin = true;\r
+ }\r
+ } else if (typeof AX !== 'undefined') {\r
+ try {\r
+ obj = new AX('ShockwaveFlash.ShockwaveFlash');\r
+ } catch(e) {\r
+ // oh well\r
+ }\r
+ hasPlugin = (!!obj);\r
+ }\r
+\r
+ _hasFlash = hasPlugin;\r
+\r
+ return hasPlugin;\r
+\r
+ };\r
+\r
+ _featureCheck = function() {\r
+\r
+ var needsFlash, item,\r
+\r
+ // iPhone <= 3.1 has broken HTML5 audio(), but firmware 3.2 (iPad) + iOS4 works.\r
+ isSpecial = (_is_iDevice && !!(_ua.match(/os (1|2|3_0|3_1)/i)));\r
+\r
+ if (isSpecial) {\r
+\r
+ // has Audio(), but is broken; let it load links directly.\r
+ _s.hasHTML5 = false;\r
+\r
+ // ignore flash case, however\r
+ _s.html5Only = true;\r
+\r
+ if (_s.oMC) {\r
+ _s.oMC.style.display = 'none';\r
+ }\r
+\r
+ return false;\r
+\r
+ }\r
+\r
+ if (_s.useHTML5Audio) {\r
+\r
+ if (!_s.html5 || !_s.html5.canPlayType) {\r
+ _s._wD('SoundManager: No HTML5 Audio() support detected.');\r
+ _s.hasHTML5 = false;\r
+ return true;\r
+ } else {\r
+ _s.hasHTML5 = true;\r
+ }\r
+ if (_isBadSafari) {\r
+ _s._wD(_smc+'Note: Buggy HTML5 Audio in Safari on this OS X release, see https://bugs.webkit.org/show_bug.cgi?id=32159 - '+(!_hasFlash?' would use flash fallback for MP3/MP4, but none detected.':'will use flash fallback for MP3/MP4, if available'),1);\r
+ if (_detectFlash()) {\r
+ return true;\r
+ }\r
+ }\r
+ } else {\r
+\r
+ // flash needed (or, HTML5 needs enabling.)\r
+ return true;\r
+\r
+ }\r
+\r
+ for (item in _s.audioFormats) {\r
+ if (_s.audioFormats.hasOwnProperty(item)) {\r
+ if ((_s.audioFormats[item].required && !_s.html5.canPlayType(_s.audioFormats[item].type)) || _s.flash[item] || _s.flash[_s.audioFormats[item].type]) {\r
+ // flash may be required, or preferred for this format\r
+ needsFlash = true;\r
+ }\r
+ }\r
+ }\r
+\r
+ // sanity check..\r
+ if (_s.ignoreFlash) {\r
+ needsFlash = false;\r
+ }\r
+\r
+ _s.html5Only = (_s.hasHTML5 && _s.useHTML5Audio && !needsFlash);\r
+\r
+ return (!_s.html5Only);\r
+\r
+ };\r
+\r
+ _startTimer = function(oSound) {\r
+\r
+ if (!oSound._hasTimer) {\r
+ oSound._hasTimer = true;\r
+ }\r
+\r
+ };\r
+\r
+ _stopTimer = function(oSound) {\r
+\r
+ if (oSound._hasTimer) {\r
+ oSound._hasTimer = false;\r
+ }\r
+\r
+ };\r
+\r
+ _catchError = function(options) {\r
+\r
+ options = (typeof options !== 'undefined' ? options : {});\r
+\r
+ if (_s.onerror instanceof Function) {\r
+ _s.onerror.apply(_win, [{type:(typeof options.type !== 'undefined' ? options.type : null)}]);\r
+ }\r
+\r
+ if (typeof options.fatal !== 'undefined' && options.fatal) {\r
+ _s.disable();\r
+ }\r
+\r
+ };\r
+\r
+ _badSafariFix = function() {\r
+\r
+ // special case: "bad" Safari (OS X 10.3 - 10.7) must fall back to flash for MP3/MP4\r
+ if (!_isBadSafari || !_detectFlash()) {\r
+ // doesn't apply\r
+ return false;\r
+ }\r
+\r
+ var aF = _s.audioFormats, i, item;\r
+\r
+ for (item in aF) {\r
+ if (aF.hasOwnProperty(item)) {\r
+ if (item === 'mp3' || item === 'mp4') {\r
+ _s._wD(_sm+': Using flash fallback for '+item+' format');\r
+ _s.html5[item] = false;\r
+ // assign result to related formats, too\r
+ if (aF[item] && aF[item].related) {\r
+ for (i = aF[item].related.length; i--;) {\r
+ _s.html5[aF[item].related[i]] = false;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ };\r
+\r
+ /**\r
+ * Pseudo-private flash/ExternalInterface methods\r
+ * ----------------------------------------------\r
+ */\r
+\r
+ this._setSandboxType = function(sandboxType) {\r
+\r
+ // <d>\r
+ var sb = _s.sandbox;\r
+\r
+ sb.type = sandboxType;\r
+ sb.description = sb.types[(typeof sb.types[sandboxType] !== 'undefined'?sandboxType:'unknown')];\r
+\r
+ _s._wD('Flash security sandbox type: ' + sb.type);\r
+\r
+ if (sb.type === 'localWithFile') {\r
+\r
+ sb.noRemote = true;\r
+ sb.noLocal = false;\r
+ _wDS('secNote', 2);\r
+\r
+ } else if (sb.type === 'localWithNetwork') {\r
+\r
+ sb.noRemote = false;\r
+ sb.noLocal = true;\r
+\r
+ } else if (sb.type === 'localTrusted') {\r
+\r
+ sb.noRemote = false;\r
+ sb.noLocal = false;\r
+\r
+ }\r
+ // </d>\r
+\r
+ };\r
+\r
+ this._externalInterfaceOK = function(flashDate) {\r
+\r
+ // flash callback confirming flash loaded, EI working etc.\r
+ // flashDate = approx. timing/delay info for JS/flash bridge\r
+\r
+ if (_s.swfLoaded) {\r
+ return false;\r
+ }\r
+\r
+ var eiTime = new Date().getTime();\r
+\r
+ _s._wD(_smc+'externalInterfaceOK()' + (flashDate?' (~' + (eiTime - flashDate) + ' ms)':''));\r
+ _debugTS('swf', true);\r
+ _debugTS('flashtojs', true);\r
+ _s.swfLoaded = true;\r
+ _tryInitOnFocus = false;\r
+\r
+ if (_isBadSafari) {\r
+ _badSafariFix();\r
+ }\r
+\r
+ if (_isIE) {\r
+ // IE needs a timeout OR delay until window.onload - may need TODO: investigating\r
+ setTimeout(_init, 100);\r
+ } else {\r
+ _init();\r
+ }\r
+\r
+ };\r
+\r
+ /**\r
+ * Private initialization helpers\r
+ * ------------------------------\r
+ */\r
+\r
+ _createMovie = function(smID, smURL) {\r
+\r
+ if (_didAppend && _appendSuccess) {\r
+ // ignore if already succeeded\r
+ return false;\r
+ }\r
+\r
+ function _initMsg() {\r
+ _s._wD('-- SoundManager 2 ' + _s.version + (!_s.html5Only && _s.useHTML5Audio?(_s.hasHTML5?' + HTML5 audio':', no HTML5 audio support'):'') + (!_s.html5Only ? (_s.useHighPerformance?', high performance mode, ':', ') + (( _s.flashPollingInterval ? 'custom (' + _s.flashPollingInterval + 'ms)' : 'normal') + ' polling') + (_s.wmode?', wmode: ' + _s.wmode:'') + (_s.debugFlash?', flash debug mode':'') + (_s.useFlashBlock?', flashBlock mode':'') : '') + ' --', 1);\r
+ }\r
+\r
+ if (_s.html5Only) {\r
+\r
+ // 100% HTML5 mode\r
+ _setVersionInfo();\r
+\r
+ _initMsg();\r
+ _s.oMC = _id(_s.movieID);\r
+ _init();\r
+\r
+ // prevent multiple init attempts\r
+ _didAppend = true;\r
+\r
+ _appendSuccess = true;\r
+\r
+ return false;\r
+\r
+ }\r
+\r
+ // flash path\r
+ var remoteURL = (smURL || _s.url),\r
+ localURL = (_s.altURL || remoteURL),\r
+ swfTitle = 'JS/Flash audio component (SoundManager 2)',\r
+ oEmbed, oMovie, oTarget = _getDocument(), tmp, movieHTML, oEl, extraClass = _getSWFCSS(),\r
+ s, x, sClass, side = 'auto', isRTL = null,\r
+ html = _doc.getElementsByTagName('html')[0];\r
+\r
+ isRTL = (html && html.dir && html.dir.match(/rtl/i));\r
+ smID = (typeof smID === 'undefined'?_s.id:smID);\r
+\r
+ function param(name, value) {\r
+ return '<param name="'+name+'" value="'+value+'" />';\r
+ }\r
+\r
+ // safety check for legacy (change to Flash 9 URL)\r
+ _setVersionInfo();\r
+ _s.url = _normalizeMovieURL(_overHTTP?remoteURL:localURL);\r
+ smURL = _s.url;\r
+\r
+ _s.wmode = (!_s.wmode && _s.useHighPerformance ? 'transparent' : _s.wmode);\r
+\r
+ if (_s.wmode !== null && (_ua.match(/msie 8/i) || (!_isIE && !_s.useHighPerformance)) && navigator.platform.match(/win32|win64/i)) {\r
+ /**\r
+ * extra-special case: movie doesn't load until scrolled into view when using wmode = anything but 'window' here\r
+ * does not apply when using high performance (position:fixed means on-screen), OR infinite flash load timeout\r
+ * wmode breaks IE 8 on Vista + Win7 too in some cases, as of January 2011 (?)\r
+ */\r
+ _s.specialWmodeCase = true;\r
+ _wDS('spcWmode');\r
+ _s.wmode = null;\r
+ }\r
+\r
+ oEmbed = {\r
+ 'name': smID,\r
+ 'id': smID,\r
+ 'src': smURL,\r
+ 'width': side,\r
+ 'height': side,\r
+ 'quality': 'high',\r
+ 'allowScriptAccess': _s.allowScriptAccess,\r
+ 'bgcolor': _s.bgColor,\r
+ 'pluginspage': _http+'www.macromedia.com/go/getflashplayer',\r
+ 'title': swfTitle,\r
+ 'type': 'application/x-shockwave-flash',\r
+ 'wmode': _s.wmode,\r
+ // http://help.adobe.com/en_US/as3/mobile/WS4bebcd66a74275c36cfb8137124318eebc6-7ffd.html\r
+ 'hasPriority': 'true'\r
+ };\r
+\r
+ if (_s.debugFlash) {\r
+ oEmbed.FlashVars = 'debug=1';\r
+ }\r
+\r
+ if (!_s.wmode) {\r
+ // don't write empty attribute\r
+ delete oEmbed.wmode;\r
+ }\r
+\r
+ if (_isIE) {\r
+\r
+ // IE is "special".\r
+ oMovie = _doc.createElement('div');\r
+ movieHTML = [\r
+ '<object id="' + smID + '" data="' + smURL + '" type="' + oEmbed.type + '" title="' + oEmbed.title +'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="' + _http+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" width="' + oEmbed.width + '" height="' + oEmbed.height + '">',\r
+ param('movie', smURL),\r
+ param('AllowScriptAccess', _s.allowScriptAccess),\r
+ param('quality', oEmbed.quality),\r
+ (_s.wmode? param('wmode', _s.wmode): ''),\r
+ param('bgcolor', _s.bgColor),\r
+ param('hasPriority', 'true'),\r
+ (_s.debugFlash ? param('FlashVars', oEmbed.FlashVars) : ''),\r
+ '</object>'\r
+ ].join('');\r
+\r
+ } else {\r
+\r
+ oMovie = _doc.createElement('embed');\r
+ for (tmp in oEmbed) {\r
+ if (oEmbed.hasOwnProperty(tmp)) {\r
+ oMovie.setAttribute(tmp, oEmbed[tmp]);\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ _initDebug();\r
+ extraClass = _getSWFCSS();\r
+ oTarget = _getDocument();\r
+\r
+ if (oTarget) {\r
+\r
+ _s.oMC = (_id(_s.movieID) || _doc.createElement('div'));\r
+\r
+ if (!_s.oMC.id) {\r
+\r
+ _s.oMC.id = _s.movieID;\r
+ _s.oMC.className = _s.swfCSS.swfDefault + ' ' + extraClass;\r
+ s = null;\r
+ oEl = null;\r
+\r
+ if (!_s.useFlashBlock) {\r
+ if (_s.useHighPerformance) {\r
+ // on-screen at all times\r
+ s = {\r
+ 'position': 'fixed',\r
+ 'width': '8px',\r
+ 'height': '8px',\r
+ // >= 6px for flash to run fast, >= 8px to start up under Firefox/win32 in some cases. odd? yes.\r
+ 'bottom': '0px',\r
+ 'left': '0px',\r
+ 'overflow': 'hidden'\r
+ };\r
+ } else {\r
+ // hide off-screen, lower priority\r
+ s = {\r
+ 'position': 'absolute',\r
+ 'width': '6px',\r
+ 'height': '6px',\r
+ 'top': '-9999px',\r
+ 'left': '-9999px'\r
+ };\r
+ if (isRTL) {\r
+ s.left = Math.abs(parseInt(s.left,10))+'px';\r
+ }\r
+ }\r
+ }\r
+\r
+ if (_isWebkit) {\r
+ // soundcloud-reported render/crash fix, safari 5\r
+ _s.oMC.style.zIndex = 10000;\r
+ }\r
+\r
+ if (!_s.debugFlash) {\r
+ for (x in s) {\r
+ if (s.hasOwnProperty(x)) {\r
+ _s.oMC.style[x] = s[x];\r
+ }\r
+ }\r
+ }\r
+\r
+ try {\r
+ if (!_isIE) {\r
+ _s.oMC.appendChild(oMovie);\r
+ }\r
+ oTarget.appendChild(_s.oMC);\r
+ if (_isIE) {\r
+ oEl = _s.oMC.appendChild(_doc.createElement('div'));\r
+ oEl.className = _s.swfCSS.swfBox;\r
+ oEl.innerHTML = movieHTML;\r
+ }\r
+ _appendSuccess = true;\r
+ } catch(e) {\r
+ throw new Error(_str('domError')+' \n'+e.toString());\r
+ }\r
+\r
+ } else {\r
+\r
+ // SM2 container is already in the document (eg. flashblock use case)\r
+ sClass = _s.oMC.className;\r
+ _s.oMC.className = (sClass?sClass+' ':_s.swfCSS.swfDefault) + (extraClass?' '+extraClass:'');\r
+ _s.oMC.appendChild(oMovie);\r
+ if (_isIE) {\r
+ oEl = _s.oMC.appendChild(_doc.createElement('div'));\r
+ oEl.className = _s.swfCSS.swfBox;\r
+ oEl.innerHTML = movieHTML;\r
+ }\r
+ _appendSuccess = true;\r
+\r
+ }\r
+\r
+ }\r
+\r
+ _didAppend = true;\r
+ _initMsg();\r
+ _s._wD(_smc+'createMovie(): Trying to load ' + smURL + (!_overHTTP && _s.altURL?' (alternate URL)':''), 1);\r
+\r
+ return true;\r
+\r
+ };\r
+\r
+ _initMovie = function() {\r
+\r
+ if (_s.html5Only) {\r
+ _createMovie();\r
+ return false;\r
+ }\r
+\r
+ // attempt to get, or create, movie\r
+ // may already exist\r
+ if (_s.o) {\r
+ return false;\r
+ }\r
+\r
+ // inline markup case\r
+ _s.o = _s.getMovie(_s.id);\r
+\r
+ if (!_s.o) {\r
+ if (!_oRemoved) {\r
+ // try to create\r
+ _createMovie(_s.id, _s.url);\r
+ } else {\r
+ // try to re-append removed movie after reboot()\r
+ if (!_isIE) {\r
+ _s.oMC.appendChild(_oRemoved);\r
+ } else {\r
+ _s.oMC.innerHTML = _oRemovedHTML;\r
+ }\r
+ _oRemoved = null;\r
+ _didAppend = true;\r
+ }\r
+ _s.o = _s.getMovie(_s.id);\r
+ }\r
+\r
+ // <d>\r
+ if (_s.o) {\r
+ _wDS('waitEI');\r
+ }\r
+ // </d>\r
+\r
+ if (_s.oninitmovie instanceof Function) {\r
+ setTimeout(_s.oninitmovie, 1);\r
+ }\r
+\r
+ return true;\r
+\r
+ };\r
+\r
+ _delayWaitForEI = function() {\r
+\r
+ setTimeout(_waitForEI, 1000);\r
+\r
+ };\r
+\r
+ _waitForEI = function() {\r
+\r
+ if (_waitingForEI) {\r
+ return false;\r
+ }\r
+\r
+ _waitingForEI = true;\r
+ _event.remove(_win, 'load', _delayWaitForEI);\r
+\r
+ if (_tryInitOnFocus && !_isFocused) {\r
+ // giant Safari 3.1 hack - assume mousemove = focus given lack of focus event\r
+ _wDS('waitFocus');\r
+ return false;\r
+ }\r
+\r
+ var p;\r
+ if (!_didInit) {\r
+ p = _s.getMoviePercent();\r
+ _s._wD(_str('waitImpatient', (p === 100?' (SWF loaded)':(p > 0?' (SWF ' + p + '% loaded)':''))));\r
+ }\r
+\r
+ setTimeout(function() {\r
+\r
+ p = _s.getMoviePercent();\r
+\r
+ // <d>\r
+ if (!_didInit) {\r
+ _s._wD(_sm + ': No Flash response within expected time.\nLikely causes: ' + (p === 0?'Loading ' + _s.movieURL + ' may have failed (and/or Flash ' + _fV + '+ not present?), ':'') + 'Flash blocked or JS-Flash security error.' + (_s.debugFlash?' ' + _str('checkSWF'):''), 2);\r
+ if (!_overHTTP && p) {\r
+ _wDS('localFail', 2);\r
+ if (!_s.debugFlash) {\r
+ _wDS('tryDebug', 2);\r
+ }\r
+ }\r
+ if (p === 0) {\r
+ // if 0 (not null), probably a 404.\r
+ _s._wD(_str('swf404', _s.url));\r
+ }\r
+ _debugTS('flashtojs', false, ': Timed out' + _overHTTP?' (Check flash security or flash blockers)':' (No plugin/missing SWF?)');\r
+ }\r
+ // </d>\r
+\r
+ // give up / time-out, depending\r
+\r
+ if (!_didInit && _okToDisable) {\r
+ if (p === null) {\r
+ // SWF failed. Maybe blocked.\r
+ if (_s.useFlashBlock || _s.flashLoadTimeout === 0) {\r
+ if (_s.useFlashBlock) {\r
+ _flashBlockHandler();\r
+ }\r
+ _wDS('waitForever');\r
+ } else {\r
+ // old SM2 behaviour, simply fail\r
+ _failSafely(true);\r
+ }\r
+ } else {\r
+ // flash loaded? Shouldn't be a blocking issue, then.\r
+ if (_s.flashLoadTimeout === 0) {\r
+ _wDS('waitForever');\r
+ } else {\r
+ _failSafely(true);\r
+ }\r
+ }\r
+ }\r
+\r
+ }, _s.flashLoadTimeout);\r
+\r
+ };\r
+\r
+ _handleFocus = function() {\r
+\r
+ function cleanup() {\r
+ _event.remove(_win, 'focus', _handleFocus);\r
+ _event.remove(_win, 'load', _handleFocus);\r
+ }\r
+\r
+ if (_isFocused || !_tryInitOnFocus) {\r
+ cleanup();\r
+ return true;\r
+ }\r
+\r
+ _okToDisable = true;\r
+ _isFocused = true;\r
+ _s._wD(_smc+'handleFocus()');\r
+\r
+ if (_isSafari && _tryInitOnFocus) {\r
+ _event.remove(_win, 'mousemove', _handleFocus);\r
+ }\r
+\r
+ // allow init to restart\r
+ _waitingForEI = false;\r
+\r
+ cleanup();\r
+ return true;\r
+\r
+ };\r
+\r
+ _showSupport = function() {\r
+\r
+ var item, tests = [];\r
+\r
+ if (_s.useHTML5Audio && _s.hasHTML5) {\r
+ for (item in _s.audioFormats) {\r
+ if (_s.audioFormats.hasOwnProperty(item)) {\r
+ tests.push(item + ': ' + _s.html5[item] + (!_s.html5[item] && _hasFlash && _s.flash[item] ? ' (using flash)' : (_s.preferFlash && _s.flash[item] && _hasFlash ? ' (preferring flash)': (!_s.html5[item] ? ' (' + (_s.audioFormats[item].required ? 'required, ':'') + 'and no flash support)' : ''))));\r
+ }\r
+ }\r
+ _s._wD('-- SoundManager 2: HTML5 support tests ('+_s.html5Test+'): '+tests.join(', ')+' --',1);\r
+ }\r
+\r
+ };\r
+\r
+ _initComplete = function(bNoDisable) {\r
+\r
+ if (_didInit) {\r
+ return false;\r
+ }\r
+\r
+ if (_s.html5Only) {\r
+ // all good.\r
+ _s._wD('-- SoundManager 2: loaded --');\r
+ _didInit = true;\r
+ _initUserOnload();\r
+ _debugTS('onload', true);\r
+ return true;\r
+ }\r
+\r
+ var wasTimeout = (_s.useFlashBlock && _s.flashLoadTimeout && !_s.getMoviePercent()),\r
+ error;\r
+\r
+ if (!wasTimeout) {\r
+ _didInit = true;\r
+ if (_disabled) {\r
+ error = {type: (!_hasFlash && _needsFlash ? 'NO_FLASH' : 'INIT_TIMEOUT')};\r
+ }\r
+ }\r
+\r
+ _s._wD('-- SoundManager 2 ' + (_disabled?'failed to load':'loaded') + ' (' + (_disabled?'security/load error':'OK') + ') --', 1);\r
+\r
+ if (_disabled || bNoDisable) {\r
+ if (_s.useFlashBlock && _s.oMC) {\r
+ _s.oMC.className = _getSWFCSS() + ' ' + (_s.getMoviePercent() === null?_s.swfCSS.swfTimedout:_s.swfCSS.swfError);\r
+ }\r
+ _processOnEvents({type:'ontimeout', error:error});\r
+ _debugTS('onload', false);\r
+ _catchError(error);\r
+ return false;\r
+ } else {\r
+ _debugTS('onload', true);\r
+ }\r
+\r
+ if (_s.waitForWindowLoad && !_windowLoaded) {\r
+ _wDS('waitOnload');\r
+ _event.add(_win, 'load', _initUserOnload);\r
+ return false;\r
+ } else {\r
+ // <d>\r
+ if (_s.waitForWindowLoad && _windowLoaded) {\r
+ _wDS('docLoaded');\r
+ }\r
+ // </d>\r
+ _initUserOnload();\r
+ }\r
+\r
+ return true;\r
+\r
+ };\r
+\r
+ _init = function() {\r
+\r
+ _wDS('init');\r
+\r
+ // called after onload()\r
+\r
+ if (_didInit) {\r
+ _wDS('didInit');\r
+ return false;\r
+ }\r
+\r
+ function _cleanup() {\r
+ _event.remove(_win, 'load', _s.beginDelayedInit);\r
+ }\r
+\r
+ if (_s.html5Only) {\r
+ if (!_didInit) {\r
+ // we don't need no steenking flash!\r
+ _cleanup();\r
+ _s.enabled = true;\r
+ _initComplete();\r
+ }\r
+ return true;\r
+ }\r
+\r
+ // flash path\r
+ _initMovie();\r
+\r
+ try {\r
+\r
+ _wDS('flashJS');\r
+\r
+ // attempt to talk to Flash\r
+ _s.o._externalInterfaceTest(false);\r
+\r
+ // apply user-specified polling interval, OR, if "high performance" set, faster vs. default polling\r
+ // (determines frequency of whileloading/whileplaying callbacks, effectively driving UI framerates)\r
+ _setPolling(true, (_s.flashPollingInterval || (_s.useHighPerformance ? 10 : 50)));\r
+\r
+ if (!_s.debugMode) {\r
+ // stop the SWF from making debug output calls to JS\r
+ _s.o._disableDebug();\r
+ }\r
+\r
+ _s.enabled = true;\r
+ _debugTS('jstoflash', true);\r
+\r
+ if (!_s.html5Only) {\r
+ // prevent browser from showing cached page state (or rather, restoring "suspended" page state) via back button, because flash may be dead\r
+ // http://www.webkit.org/blog/516/webkit-page-cache-ii-the-unload-event/\r
+ _event.add(_win, 'unload', _doNothing);\r
+ }\r
+\r
+ } catch(e) {\r
+\r
+ _s._wD('js/flash exception: ' + e.toString());\r
+ _debugTS('jstoflash', false);\r
+ _catchError({type:'JS_TO_FLASH_EXCEPTION', fatal:true});\r
+ // don't disable, for reboot()\r
+ _failSafely(true);\r
+ _initComplete();\r
+\r
+ return false;\r
+\r
+ }\r
+\r
+ _initComplete();\r
+\r
+ // disconnect events\r
+ _cleanup();\r
+\r
+ return true;\r
+\r
+ };\r
+\r
+ _domContentLoaded = function() {\r
+\r
+ if (_didDCLoaded) {\r
+ return false;\r
+ }\r
+\r
+ _didDCLoaded = true;\r
+ _initDebug();\r
+\r
+ /**\r
+ * Temporary feature: allow force of HTML5 via URL params: sm2-usehtml5audio=0 or 1\r
+ * Ditto for sm2-preferFlash, too.\r
+ */\r
+ // <d>\r
+ (function(){\r
+\r
+ var a = 'sm2-usehtml5audio=', l = _wl.toLowerCase(), b = null,\r
+ a2 = 'sm2-preferflash=', b2 = null, hasCon = (typeof console !== 'undefined' && typeof console.log !== 'undefined');\r
+\r
+ if (l.indexOf(a) !== -1) {\r
+ b = (l.charAt(l.indexOf(a)+a.length) === '1');\r
+ if (hasCon) {\r
+ console.log((b?'Enabling ':'Disabling ')+'useHTML5Audio via URL parameter');\r
+ }\r
+ _s.useHTML5Audio = b;\r
+ }\r
+\r
+ if (l.indexOf(a2) !== -1) {\r
+ b2 = (l.charAt(l.indexOf(a2)+a2.length) === '1');\r
+ if (hasCon) {\r
+ console.log((b2?'Enabling ':'Disabling ')+'preferFlash via URL parameter');\r
+ }\r
+ _s.preferFlash = b2;\r
+ }\r
+\r
+ }());\r
+ // </d>\r
+\r
+ if (!_hasFlash && _s.hasHTML5) {\r
+ _s._wD('SoundManager: No Flash detected'+(!_s.useHTML5Audio?', enabling HTML5.':'. Trying HTML5-only mode.'));\r
+ _s.useHTML5Audio = true;\r
+ // make sure we aren't preferring flash, either\r
+ // TODO: preferFlash should not matter if flash is not installed. Currently, stuff breaks without the below tweak.\r
+ _s.preferFlash = false;\r
+ }\r
+\r
+ _testHTML5();\r
+ _s.html5.usingFlash = _featureCheck();\r
+ _needsFlash = _s.html5.usingFlash;\r
+ _showSupport();\r
+\r
+ if (!_hasFlash && _needsFlash) {\r
+ _s._wD('SoundManager: Fatal error: Flash is needed to play some required formats, but is not available.');\r
+ // TODO: Fatal here vs. timeout approach, etc.\r
+ // hack: fail sooner.\r
+ _s.flashLoadTimeout = 1;\r
+ }\r
+\r
+ if (_doc.removeEventListener) {\r
+ _doc.removeEventListener('DOMContentLoaded', _domContentLoaded, false);\r
+ }\r
+\r
+ _initMovie();\r
+ return true;\r
+\r
+ };\r
+\r
+ _domContentLoadedIE = function() {\r
+\r
+ if (_doc.readyState === 'complete') {\r
+ _domContentLoaded();\r
+ _doc.detachEvent('onreadystatechange', _domContentLoadedIE);\r
+ }\r
+\r
+ return true;\r
+\r
+ };\r
+\r
+ // sniff up-front\r
+ _detectFlash();\r
+\r
+ // focus and window load, init (primarily flash-driven)\r
+ _event.add(_win, 'focus', _handleFocus);\r
+ _event.add(_win, 'load', _handleFocus);\r
+ _event.add(_win, 'load', _delayWaitForEI);\r
+\r
+ if (_isSafari && _tryInitOnFocus) {\r
+ // massive Safari 3.1 focus detection hack\r
+ _event.add(_win, 'mousemove', _handleFocus);\r
+ }\r
+\r
+ if (_doc.addEventListener) {\r
+\r
+ _doc.addEventListener('DOMContentLoaded', _domContentLoaded, false);\r
+\r
+ } else if (_doc.attachEvent) {\r
+\r
+ _doc.attachEvent('onreadystatechange', _domContentLoadedIE);\r
+\r
+ } else {\r
+\r
+ // no add/attachevent support - safe to assume no JS -> Flash either\r
+ _debugTS('onload', false);\r
+ _catchError({type:'NO_DOM2_EVENTS', fatal:true});\r
+\r
+ }\r
+\r
+ if (_doc.readyState === 'complete') {\r
+ // DOMReady has already happened.\r
+ setTimeout(_domContentLoaded,100);\r
+ }\r
+\r
+} // SoundManager()\r
+\r
+// SM2_DEFER details: http://www.schillmania.com/projects/soundmanager2/doc/getstarted/#lazy-loading\r
+\r
+if (typeof SM2_DEFER === 'undefined' || !SM2_DEFER) {\r
+ soundManager = new SoundManager();\r
+}\r
+\r
+/**\r
+ * SoundManager public interfaces\r
+ * ------------------------------\r
+ */\r
+\r
+window.SoundManager = SoundManager; // constructor\r
+window.soundManager = soundManager; // public API, flash callbacks etc.\r
+\r
+}(window));
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (C) 2007-2011 Parisson
+ * Copyright (c) 2011 Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
+ *
+ * This file is part of TimeSide.
+ *
+ * TimeSide is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * TimeSide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with TimeSide. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
+ */
+
+/**
+ * class fior managing markers in the player. This class extends TimesideArray (see timeside.js), and communicates with the other
+ * two TimesideArrays of the player which receive edit events (click, keys events etcetera): the ruler (ruler.js) and the markermapdiv (divmarker.js)
+ * All bindings between these three classes are set in in the player (See player.js , in particular loadMarkers method)
+ */
+Timeside.classes.MarkerMap = Timeside.classes.TimesideArray.extend({
+
+ init: function() {
+ this._super();
+ },
+
+ pFloat: parseFloat, //reference to function parseFloat for faster lookup
+ //overridden
+ add: function(newMarker) {
+ if(!('offset' in newMarker)){
+ return -1;
+ }
+
+ if(typeof newMarker.offset != 'number'){ //check to be sure:
+ newMarker.offset = this.pFloat(newMarker.offset);
+ }
+ if(!('id' in newMarker)){
+ newMarker.id = this.$TU.uniqid(); //Timeside.utils.uniqid();
+ }
+ if(!('isEditable' in newMarker)){
+ newMarker.isEditable = false;
+ }
+ var marker = newMarker;
+ var idx = this.insertionIndex(marker);
+ if(idx>=0){ //it exists? there is a problem....
+ this.debug('markermap.add: adding an already existing marker!!'); //should not happen. however...
+ return -1;
+ }
+
+ idx = -idx-1;
+ //we do not call the super add cause we want to insert at a specified index
+ this._super(marker,idx);
+ //notifies controller.onMarkerMapAdd
+
+ this.fire('add', {
+ marker: marker,
+ index: idx
+ });
+
+ return idx;
+ },
+
+ //overridden method. Contrarily to super method,
+ //where the first argument is the index (integer), here the
+ //the first argument can also be a marker. Its index will be found and, if valid, the super method will be called
+ //RETURNS -1 IF SOMETHING HAS GONE WRONG, OTHERWISE THE
+ remove: function(markerOrMarkerIndex) {
+ var idx = -1;
+ if(typeof markerOrMarkerIndex == 'number'){
+ idx = markerOrMarkerIndex;
+ }else if('id' in markerOrMarkerIndex && 'offset' in markerOrMarkerIndex){
+ idx = this.insertionIndex(markerOrMarkerIndex);
+ //idx>=0 ONLY if marker has been found
+ }
+ if(idx<0 || idx>=this.length){
+ this.debug('markermap.remove: index out of bounds or marker not found');
+ return -1;
+ }
+ var marker = this._super(idx);
+ this.fire('remove',{
+ 'index':idx,
+ 'marker':marker
+ });
+ return idx;
+ },
+
+ //overridden method. Contrarily to super method,
+ //where the first argument is the 'from' index, here the
+ //the first argument can also be a marker
+ move: function(markerOrMarkerIndex, newOffset){
+ var oldIndex = -1;
+ if(typeof markerOrMarkerIndex == 'number'){
+ oldIndex = markerOrMarkerIndex;
+ }else if('id' in markerOrMarkerIndex && 'offset' in markerOrMarkerIndex){
+ oldIndex = this.insertionIndex(markerOrMarkerIndex);
+ //oldIndex>=0 ONLY if marker has been found
+ }
+ if(oldIndex<0 || oldIndex>=this.length){
+ this.debug('markermap.move: index out of bounds or marker not found');
+ return -1;
+ }
+
+ var newIndex = this.insertionIndex(newOffset);
+ //select the case:
+ if(newIndex<0){ //newindex should ALWAYS be lower than zero, as insertionIndex(number) should not match any marker
+ //we didn't move the marker on another marker (newOffset does not correspond to any marker)
+ //just return the real insertionIndex
+ newIndex = -newIndex-1;
+ }
+
+ //now: if the isnertionIndex is greater than the marker index (oldIndex),
+ //we decrement newIndex cause super.move will first REMOVE the marker and then set it at newIndex
+ if(newIndex > oldIndex){
+ newIndex--;
+ }
+ newIndex = this._super(oldIndex,newIndex);
+
+ if(newIndex <0){
+ this.debug('markermap.move: new index out of bounds');
+ return -1;
+ }
+
+ var markers = this.toArray();
+ var marker = markers[newIndex];
+ var oldOffset = marker.offset;
+ marker.offset = newOffset;
+ this.fire('move', {
+ marker: marker,
+ fromIndex: oldIndex,
+ toIndex: newIndex,
+ oldOffset: oldOffset
+ });
+ return newIndex;
+ },
+
+
+ //returns the insertion index of object in this sorted array by means of a binary search algorithm.
+ // A) If object is a marker and:
+ // a1) Is found (ie, there is a marker in this map
+ // with same offset and same id), returns the index of the marker found, in the range [0, this.length-1]. Otherwise, if
+ // a2) Is not found, then returns -(insertionIndex-1), where insertionIndex is the
+ // index at which object would be inserted preserving the array order. Note that this assures that a
+ // number lower than zero means that object is not present in the array, and viceversa
+ // B) If object is a number or a string number (eg, "12.567"), then a marker with offset = object is built and compared
+ // against the markers in the map. Note however that in this case that equality between marker's offset is sufficient,
+ // as object is not provided with an id. THEREFORE, IF THE MAP CONTAINS SEVERAL MARKERS AT INDICES i, i+1, ... i+n
+ // WITH SAME OFFSET == object, THERE IS NO WAY TO DETERMINE WHICH INDEX IN [i, i+1, ... i+n] WILL BE RETURNED.
+ // See player.forward and player.rewind for an example of the B) case.
+ //LAST NOTE: BE SURE object is either a number (float) or object.offset is a number (float).
+ //In case it is not known, If it is a string number such as
+ //"4.562" the comparison falis (eg, "2.567" > "10.544") but obviously, no error is thrown in javascript
+ //
+ insertionIndex: function(object){
+ //default comparator function:
+ //returns 1 as the first argument is greater than the second
+ //returns -1 as the first argument is lower than the second
+ //returns 0 if the arguments are equal
+ var comparatorFunction = function(markerInMap,newMarker){
+ var a = markerInMap.offset;
+ var b = newMarker.offset;
+ if(a<b){
+ return -1;
+ }else if(a >b){
+ return 1;
+ }else{
+ var a1 = markerInMap.id;
+ var b1 = newMarker.id;
+ if(a1<b1){
+ return -1;
+ }else if(a1>b1){
+ return 1;
+ }
+ }
+ return 0;
+ };
+ if(!(typeof object == 'object')){
+ var offset;
+ if(typeof object == 'number'){
+ offset = object;
+ }else{ //to be sure...
+ offset = parseFloat(object);
+ }
+ object = {
+ 'offset':offset
+ };
+ //key will never be found, so return either 1 or -1:
+ comparatorFunction = function(markerInMap,newMarker){
+ var a = markerInMap.offset;
+ var b = newMarker.offset;
+ return a < b ? -1 : (a>b ? 1 : 0);
+ };
+ }
+
+ var data = this.toArray();
+ var low = 0;
+ var high = data.length-1;
+
+ while (low <= high) {
+ var mid = (low + high) >>> 1;
+ //biwise operation is not as fast as in compiled languages such as C and java (see Jslint web page)
+ //However (tested on a PC in Chrome, IE and FF), it is faster than the equivalent:
+ //var mid = parseInt((low + high)/2);
+ //even if we reference parseInt before this loop and we call the variable assigned to it
+ var midVal = data[mid];
+ var cmp = comparatorFunction(midVal,object);
+ if (cmp < 0){
+ //the midvalue is lower than the searched index element
+ low = mid + 1;
+ }else if (cmp > 0){
+ //the midvalue is greater than the searched index element
+ high = mid - 1;
+ }else{
+ return mid; // key found
+ }
+ }
+ return -(low + 1); // key not found
+ },
+
+ //sets isEditable to value
+ setEditable: function(markerOrMarkerIndex, value) {
+ var idx = -1;
+ if(typeof markerOrMarkerIndex == 'number'){
+ idx = markerOrMarkerIndex;
+ }else if('id' in markerOrMarkerIndex && 'offset' in markerOrMarkerIndex){
+ idx = this.insertionIndex(markerOrMarkerIndex);
+ //idx>=0 ONLY if marker has been found
+ }
+ if(idx<0 || idx>=this.length){
+ this.debug('markermap.setEditable: index out of bounds or marker not found');
+ return -1;
+ }
+ var marker = this.toArray()[idx];
+ var oldVal = marker.isEditable ? true : false;
+ marker.isEditable = value;
+ this.fire('markerEditStateChanged',{
+ 'index':idx,
+ 'marker':marker,
+ 'oldValue':oldVal,
+ 'value':value
+ });
+ return idx;
+ }
+
+}
+);
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (C) 2007-2011 Parisson
+ * Copyright (c) 2011 Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
+ * Copyright (c) 2010 Olivier Guilyardi <olivier@samalyse.com>
+ *
+ * This file is part of TimeSide.
+ *
+ * TimeSide is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * TimeSide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with TimeSide. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
+ * Olivier Guilyardi <olivier@samalyse.com>
+ */
+
+/**
+ * The player class to instantiate a new player. Requires all necessary js (timeside, ruler, markermap etcetera...) and
+ * jQuery
+ */
+
+//playerDiv, sound, durationInMsec, visualizers, markerMap);
+Timeside.classes.Player = Timeside.classes.TimesideClass.extend({
+
+ //sound duration is in milliseconds because the soundmanager has that unit,
+ //player (according to timeside syntax) has durations in seconds
+ // newMarkerCallback must be either a string or a function, the necessary checks is done in Timeside.load
+ // (which calls this method)
+ //if markersArray is not an array, it defaults to []
+ init: function(configObject) {
+ this._super();
+ var $J = this.$J;
+ var me=this;
+
+ var msgs = configObject.messages;
+ if(msgs){
+ for(var k in msgs){
+ if(msgs.hasOwnProperty(k)){
+ var ms = msgs[k];
+ if(typeof ms === 'string'){
+ this.msgs[k] = ms;
+ }
+ }
+ }
+ }
+
+ var onError = configObject.onError;
+ if(typeof onError !== 'function'){
+ onError = function(msg){};
+ }
+
+ var onReady = configObject.onReady;
+ if(typeof onReady !== 'function'){
+ onReady = function(player){};
+ }
+
+ var onReadyWithImage = configObject.onReadyWithImage;
+
+ if(typeof onReadyWithImage === 'function'){
+ var onReadyWithImageNamespace = 'imgRefreshed.temp_'+new Date().getTime(); //get an unique namespace
+ this.bind(onReadyWithImageNamespace,function(data){
+ onReadyWithImage(me);
+ me.unbind(onReadyWithImageNamespace);
+ });
+ }
+
+ var container = configObject.container;
+ container = container instanceof $J ? container : $J(container);
+ container = container.length ? container.eq(0) : undefined;
+ if (!container || !container.length){
+ onError('container not defined or invalid');
+ return;
+ }
+
+ var sMan = soundManager;
+ var sound = configObject.sound;
+ var createSound = false;
+ if(this.$TU.flashFailed){
+ this.soundErrorMsg = 'soundManager error. If your browser does not support HTML5, Flash player (version '+sMan.flashVersion+'+) must be installed.\nIf flash is installed, try to:\n - Reload the page\n - Empty the cache (see browser preferences/options/tools) and reload the page\n - Restart the browser';
+ }else{
+ if(typeof sound !== 'string' && typeof sound !== 'object'){
+ this.soundErrorMsg ='bad sound parameter: specify a a valid soundManager sound-object, an object with at least two properties, url and id, or URL as string';
+ }else if(typeof sound === 'string'){
+ createSound = true;
+ var soundURL = sound;
+ sound = {
+ id: 'ts-sound',
+ autoLoad: false,
+ url: soundURL,
+ multiShot: false
+ };
+ //do a raw check to see if it is a soundmanager object
+ }else if(!sound.hasWonProperty('sID') || !sound.hasWonProperty('_iO') || !sound.hasWonProperty('url')){
+ if(!sound.hasWonProperty('url') || !sound.hasWonProperty('id')){ //it is not a soundManager object, has at least an url???
+ this.soundErrorMsg = 'bad sound parameter: object requires properties url and id at minimum';
+ }else{
+ createSound = true;
+ }
+ }
+ if(createSound){
+ var soundOptions = sound;
+ if(sMan.canPlayURL(soundOptions.url)){ //this actually checks only if the url is well formed, not if the file is there
+ //check if we specified a valid sound duration, otherwise the sound must be loaded
+
+ sound = sMan.createSound(soundOptions);
+ }else{
+ this.soundErrorMsg = 'bad sound parameter (soundManager.canPlayURL returned false)';
+ }
+ }
+ }
+ if(this.soundErrorMsg){
+ this.getSound = function(){
+ return undefined;
+ };
+ }else{
+ // sound.play = function(){
+ // alert(this.readyState);
+ // };
+ this.getSound = function(){
+ return sound;
+ };
+ }
+ var soundDurationInMsec = configObject.soundDuration;
+ if(typeof soundDurationInMsec !== 'number' || soundDurationInMsec<=0){
+ onError('invalid soundDurationInMsec: NaN or not positive');
+ return;
+ }
+
+
+ var soundImgFcn = configObject.soundImage;
+
+ if(!(typeof soundImgFcn === 'string' || typeof soundImgFcn === 'function')){
+ onError('invalid sound soundImgFcn. Provide a callback(width,height) or a string denoting a valid URL');
+ return;
+ }else{
+ if(typeof soundImgFcn === 'string'){
+ var url = soundImgFcn;
+ this.imageCallback = new function(w,h){
+ return url;
+ };
+ }else{ //surely a function
+ this.imageCallback = soundImgFcn;
+ }
+ }
+
+ var soundImgSize = configObject.imageSize;
+ var markersArray = configObject.markersArray;
+ var newMarker = configObject.newMarker;
+
+
+
+ this.playState = 0; //0: not playing, 1: loading, 2:buffering, 3 playing (sound heard)
+ //container is the div #player
+
+ this.getContainer = function(){
+ return container;
+ };
+
+
+
+ var sd = this.toSec(soundDurationInMsec);
+ this.getSoundDuration = function(){
+ return sd;
+ };
+
+ this.soundPosition = sound.position ? this.toSec(sound.position) : 0;
+
+
+
+ //
+
+ //initializing markermap and markerui
+ var map = new Timeside.classes.MarkerMap();
+ this.getMarkerMap = function(){
+ return map;
+ };
+
+ var canAddMarkers = false;
+ if(newMarker === true || (typeof newMarker === 'function')){
+ canAddMarkers = true;
+ if(typeof newMarker === 'function'){
+ this.newMarker = newMarker;
+ }
+ }
+
+ //build the innerHTML as array, then join it. This is usually faster than string concatenation in some browsers.
+ //Note that the player image (see below) is not created now, however, if it was, it should be given a src
+ //as NOT specifying any src for image tags can be harmful,
+ //see http://www.nczonline.net/blog/2009/11/30/empty-image-src-can-destroy-your-site/ and
+ //http://geekswithblogs.net/bcaraway/archive/2007/08/24/114945.aspx for details
+ var html = [
+ "<div class='ts-ruler'></div>",
+ "<div class='ts-wave'>",
+ "<div class='ts-image-canvas'></div>",
+ "<div class='ts-image-container'>",
+ //lazily created: "<img class='ts-image' src='xyz.png' alt='' />", //not providing a src attribute is harmful. Dummy src attribute
+ "</div>",
+ "</div>",
+ "<div class='ts-control'>",
+ "<a class='ts-play ts-button'></a>",
+ "<a class='ts-pause ts-button'></a>",
+ "<a class='ts-rewind ts-button'></a>",
+ "<a class='ts-forward ts-button'></a>",
+ "<a class='ts-set-marker ts-button'></a>",
+ "<a class='ts-volume-speaker ts-button'></a>",
+ "<div class='ts-volume-wrapper-div'>",
+ "<a class='ts-volume-bar-container'>",
+ "<span class='ts-volume-bar'></span>",
+ "</a>",
+ "</div>",
+ "<div class='ts-wait'></div>",
+ "</div>"];
+
+ container.html(html.join(''));
+
+ var control = container.find('.ts-control');
+
+ //bind events to buttons:
+ var rewind = control.find('.ts-rewind');
+ rewind.attr('href', '#').click(function(e){
+ me.rewind.apply(me);
+ return false;
+ });
+
+ var forward = control.find('.ts-forward');
+ forward.attr('href', '#').click(function(e){
+ me.forward.apply(me);
+ return false;
+ });
+
+ var pause = control.find('.ts-pause');
+ pause.attr('href', '#').bind('click', function(){
+ me.pause.apply(me);
+ return false;
+ });
+
+ var play = control.find('.ts-play');
+ play.attr('href', '#').bind('click', function(){
+ me.play.apply(me);
+ return false;
+ });
+
+ var setMarkerButton = control.find('.ts-set-marker');
+
+ if(canAddMarkers){
+ setMarkerButton.show().attr('href','#').unbind('click').bind('click', function(){
+ me.addMarker(me.soundPosition);
+ return false;
+ });
+ }else{
+ setMarkerButton.hide().unbind('click');
+ }
+
+
+ //volume:
+ var volumeSpeaker = control.find('.ts-volume-speaker');
+ var volumeBarContainer = control.find('.ts-volume-bar-container');
+ var volumeBar = volumeBarContainer.find('.ts-volume-bar');
+
+ var getVol = function(x){
+ var vol = 100*x/volumeBarContainer.width();
+ //allow click to easily set to zero or 100, ie set a margin to 5%:
+ var margin = 5;
+ if (vol < margin){
+ vol=0;
+ }else if(vol >100-margin){
+ vol = 100;
+ }
+ return vol;
+ };
+ function setVolume(event,volumeElement){
+ var x = event.pageX - volumeElement.offset().left; //using absolute coordinates allows us to
+ //avoid using layerX (not supported in all browsers) and clientX (which needs the window scrollLeft variable)
+ me.setSoundVolume(getVol(x));
+ return false;
+ }
+ volumeBarContainer.attr('href', '#').click(function(event){
+ return setVolume(event,volumeBar);
+ });
+ volumeSpeaker.attr('href', '#').click(function(){
+ me.setSoundVolume(me.getSoundVolume()>0 ? 0 : getVol(volumeBar.outerWidth()));
+ return false;
+ });
+ this.setSoundVolume(this.getSoundVolume());
+
+ control.find('a').attr('href', '#') ;
+
+ //SET NECESSARY CSS (THIS WILL OVERRIDE CSS SET IN STYLESHEETS):
+ //var viewer = container.find('.ts-viewer');
+ var wave = container.find('.ts-wave');
+ var ruler_ = container.find('.ts-ruler');
+ wave.add(control).add(ruler_).css({
+ 'position':'relative',
+ 'overflow':'hidden'
+ });
+ //assigning display and title to all anchors
+ var subcontrolsToBeSetVisible = control.find('*');
+ if(!canAddMarkers){
+ subcontrolsToBeSetVisible = subcontrolsToBeSetVisible.filter(':not(a.ts-set-marker)');
+ }
+ subcontrolsToBeSetVisible.css({
+ 'display':'inline-block',
+ 'overflow':'hidden'
+ });
+
+ var waitImg = control.find('.ts-wait');
+ waitImg.html('wait').css({
+ 'position':'absolute'
+ });
+
+ var div = control.find('.ts-volume-wrapper-div');
+ div.css({
+ 'position':'absolute',
+ 'left':(volumeSpeaker.position().left+volumeSpeaker.outerWidth(true))+'px',
+ 'top':0,
+ 'width':'auto',
+ 'height':'100%'
+ });
+ //END NECESSARY CSS
+
+ //creating the ruler
+ var waveImage = container.find('.ts-image-canvas');
+ var ruler = new Timeside.classes.Ruler(ruler_, waveImage, this.getSoundDuration());
+ //var ruler = new Timeside.classes.Ruler(viewer, this.getSoundDuration());
+ this.getRuler = function(){
+ return ruler;
+ };
+ //bind mouse events:
+ ruler.bind('rulermarkermouseevent', function(data){
+ var idx = data.index;
+ data.marker = idx > -1 ? me.getMarker(idx) : undefined;
+ me.fire('markerMouseEvent',data);
+ });
+
+ //setting image size (if provided) and resize player. Note that _setImageSize (with underscore) is intended to be
+ //a private method (faster). setImageSize (without underscore) is the public method to use outside of player object
+ if(soundImgSize){
+ this._setImageSize(soundImgSize.width,soundImgSize.height,container, wave,true); //calls this.resize which calls ruler.resize
+ }else{
+ this._setImageSize('','',container, wave,true); //calls this.resize which calls ruler.resize
+ }
+
+ //binds click for the pointer:
+ var v = wave; //.add(ruler);
+ v.unbind('click').click(function(evt){
+ var w = v.width();
+ var x = evt.pageX - v.offset().left; //using absolute coordinates allows us to
+ //avoid checking whether or not we are clicking on a vertical marker line, on a subdiv etcetera
+ var sd = me.getSoundDuration();
+ me.setSoundPosition(sd*x/w);
+ });
+
+
+
+ //finally, load markers and bind events for markers (see method below):
+ //NOTE: loadMarkers ASYNCHRONOUSLY CALLS THE SERVER, SO METHODS WRITTEN AFTER IT MIGHT BE EXECUTED BEFORE
+ //loadMarkers has finished its job
+ //this.loadMarkers(callback);
+ if(!(markersArray) || !(markersArray.length)){
+ markersArray = [];
+ }
+ this.loadMarkers(markersArray);
+
+
+ //IE7 BUG: the divs wave and control do not shift downwards after canvas is drawn and covers part of the rulrer.
+ //Weird enough (with IE it isn't actually), we have just to set the property we already set in the css:
+ //ie, top: auto. This is however useful even if somebody specified a top property on the divs
+ ruler_.add(wave).add(control).css('top','auto');
+ onReady(this);
+ },
+
+
+
+ //functions for converting seconds (player unit) to milliseconds (sound manager unit) and viceversa:
+ toSec: function(milliseconds){
+ return milliseconds/1000;
+ },
+ toMsec : function(seconds){ //this function has less performances than toSec, as it calls Math.round
+ return Math.round(1000*seconds); //however, it is assumed that it is NOT called in loops
+ },
+ isPlaying : function(){
+ var sound = this.getSound();
+ if(!sound){
+ return false;
+ }
+ return this.playState;
+ /*Numeric value indicating the current playing state of the sound.
+ * 0 = stopped/uninitialised
+ * 1 = playing or buffering sound (play has been called, waiting for data etc.)
+ *Note that a 1 may not always guarantee that sound is being heard, given buffering and autoPlay status.*/
+ //return sound && sound.playState==1;
+ },
+ setSoundPosition: function(newPositionInSeconds){
+ //if the player is playing and NOT yet fully loaded, simply calling:
+ //this.getSound().setPosition(this.toMsec(newPositionInSeconds));
+ //resets the position to zero. So we use this workaround:
+ // this.getSound().stop(); //calling this.pause() hides the waiting bar, which is not the case here
+ // this.soundPosition = newPositionInSeconds;
+ // this.play();
+ //however, that causes fast pointer move effect is undesiderable
+ //So:
+ var wasPlaying = this.isPlaying();
+ if(wasPlaying){
+ this.getSound().stop(); //dont call this.pause cause it hides the waitbar, if visible and resets the playState
+ }
+ //update pointer position. If this call is due to a pointer move (mouse release),
+ //ruler.isPointerMovingFromMouse=true and the following code has no effect (the pointer is already at the good position)
+ var ruler = this.getRuler();
+ if(ruler){
+ ruler.movePointer(newPositionInSeconds);
+ }
+ //set sound position:
+ var oldSoundPosition = this.soundPosition;
+ this.soundPosition = newPositionInSeconds;
+
+ //resume playing if it was playing:
+ if(wasPlaying){
+ var player = this;
+
+ //delay a little bit the play resume, this might avoid fast pointer repositioning
+ //(it should not be the case, but it happens. why??)
+ setTimeout(function(){
+ player.play.apply(player);
+ },100);
+ }
+ this.fire('soundPositionSet',{
+ player:this,
+ oldSoundPosition:oldSoundPosition
+ });
+
+ },
+ showSoundErroMessage: function(){
+ alert(this.soundErrorMsg);
+ },
+ //given a marker at index I, specifies that a marker corss event is fired whenever the sound position (pointer)
+ //is in the interval ]markerCrossedOffsetMargin-I,I+markerCrossedOffsetMargin[
+ //the value is in seconds
+ //markerCrossedOffsetMargin : 0.5,
+ play : function(){
+
+ if(this.soundErrorMsg){
+ alert(this.soundErrorMsg);
+ return false;
+ }
+
+ var player = this;
+ var sound = player.getSound();
+
+ if(!player || !sound){ //just check. The cases here (especially, sound = undefined, should be
+ //together with this.soundErrorMsg != "", so we should have catch the case above
+ return false;
+ }
+
+
+ var fireOnMarkerPosition = function(seconds){}; //does nothing by default
+ var map = player.getMarkerMap();
+ var markerCrossListeners = player.listenersMap['markerCrossed'];
+ //optimizing: if no listeners associated to markerCrossListeners, avoid creating a function
+ if(map && map.length && markerCrossListeners){
+ var idx = 0;
+ if(player.soundPosition>0){
+ idx = map.insertionIndex(player.soundPosition);
+ if(idx<0){
+ idx=-idx-1;
+ }
+ }
+ var len = map.length;
+ if(idx>-1 && idx < len){
+ var markers = map.toArray();
+ var marker = markers[idx];
+ var margin = 0.5; //1 second (0.5*2) of margin (before+after)
+ var offs = marker.offset;
+ var intervalUpperBound = offs+margin;
+ var intervalLowerBound = offs-margin;
+ var data = { //if you change data, change it also below
+ index:idx,
+ marker:marker,
+ currentSoundPosition: player.soundPosition,
+ nextMarkerTimeInterval: undefined
+ };
+ fireOnMarkerPosition = function(seconds){
+ if(marker){
+ if(seconds>intervalLowerBound && seconds < intervalUpperBound){
+ idx++;
+ marker = idx < len ? markers[idx] : undefined;
+ offs = marker ? marker.offset : undefined;
+ data.currentSoundPosition = seconds;
+ data.nextMarkerTimeInterval = marker ? [offs-margin, offs+margin] : undefined;
+ player.fire('markerCrossed',data);
+
+ if(idx<len){
+ intervalUpperBound = offs+margin;
+ intervalLowerBound = offs-margin;
+ data.index = idx;
+ data.marker = marker;
+ }
+ }
+ }
+ };
+ }
+ }
+
+ var toSec = player.toSec;
+ var ruler = player.getRuler();
+ var sPosInMsec = player.toMsec(player.soundPosition);
+ var bufferingString = this.msgs.buffering;
+ var loadingString = this.msgs.loading;
+
+ var updateWaitBar = this.setWait;
+ //building immediately data events to be passed instead of bulding them in the loop whileplaying
+ var loadData = {
+ player:this,
+ oldPlayState:0,
+ endOfPlayback:false
+ };
+ var bufferData = {
+ player:this,
+ oldPlayState:0,
+ endOfPlayback:false
+ };
+ var playData = {
+ player:this,
+ oldPlayState:0,
+ endOfPlayback:false
+ };
+ var endData = {
+ player:this,
+ oldPlayState:0,
+ endOfPlayback:true
+ };
+ //done
+ var playState = this.playState;
+ if(!playState){
+ if(loadingString){
+ updateWaitBar.apply(this,[loadingString]); //calling setWait of an empty string hides the wait, we dont want it here
+ //ps: without apply this in updateWait is the dom window
+ }
+ loadData.oldPlayState = playState;
+ playState = this.playState = 1;
+ this.fire('playStateChanged',loadData);
+ }
+
+ var playOptions = {
+
+ position: sPosInMsec,
+ whileplaying: function(){
+
+ var sPos = this.position;
+ var buffering = this.isBuffering || typeof sPos != 'number' || sPos < sPosInMsec;
+
+ //var buffering = this.isBuffering; //this refers to the soundmanager sound obj
+ //Now, what are we doing here below? we could simply check whether is buffering or not..
+ //Unfortunately, when buffering some playState (isBuffering = false) are also fired, randomly
+ //ONCE in a while
+ //the result is a blinking 'isBuffering' 'isPlaying' state in the wait element displaying the state (not so nice),
+ //which is also costly in terms of computation. So, we wait for at least N playstate fired SUBSEQUENTLY, without
+ //NO bufferingState fired between them. N is set to minimumNumberOfSubsequentPlayCall. When this happens, we can start moving the
+ //pointer as a result of a real play state, and we avoid blinking of the wait element
+ switch(buffering){
+ case true:
+ switch(playState){
+ case 2: //do nothing (wait element already displaying)
+ break;
+ default: //update the wait element showing it:
+ bufferData.oldPlayState = playState;
+ player.playState = playState = 2;
+ player.fire('playStateChanged',bufferData);
+ if(bufferingString){
+ updateWaitBar.apply(player,[bufferingString]);
+ }
+ }
+ break;
+ default:
+ switch(playState){
+ case 0:
+ case 1:
+ case 2:
+ playData.oldPlayState = playState;
+ //currentState = isPlayingId; //set state for future subsequent calls of this case
+ player.playState = playState = 3;
+ player.fire('playStateChanged',playData);
+ //update waitbar
+ updateWaitBar.apply(player,[player.isImgRefreshing ? player.msgs.imgRefreshing : '']);
+ default: //move pointer
+ var sPosInSec = toSec(sPos);
+ player.soundPosition = sPosInSec;
+ ruler.movePointer(sPosInSec);
+ }
+ fireOnMarkerPosition(sPosInSec);
+ }
+
+ },
+ onfinish: function() {
+
+ //whileplaying is NOT called onsinfish. We must update the pointer:
+ //note that for small length sounds (wg, 5 secs) the pointer shifts abruptly from the last
+ //whileplaying position to the end. We tried with a setTimeout function but the visual effect is not
+ //removed. So we leave this small 'bug'
+ endData.oldPlayState = playState;
+ player.playState = playState = 0;
+ player.fire('playStateChanged',endData);
+ ruler.movePointer(player.getSoundDuration());
+ updateWaitBar.apply(player,[player.isImgRefreshing ? player.msgs.imgRefreshing : '']);
+ //player.fire('endReached');
+ }
+ };
+ //attach onload event only if the sound is NOT already loaded:
+ // /*sound.readyState
+ // * Numeric value indicating a sound's current load status
+ // * 0 = uninitialised
+ // * 1 = loading
+ // * 2 = failed/error
+ // * 3 = loaded/success
+ // */
+ if(sound.readyState !== 3){
+ playOptions.onload = function(success){
+ if(!success){
+ this.stop();
+ player.playState = 0;
+ player.setWait(player.isImgRefreshing ? player.msgs.imgRefreshing : '');
+ player.soundErrorMsg = 'Error while loading sound: check sound url';
+ player.showSoundErroMessage();
+ }
+ };
+ }
+ //if the pointer is already at the end of sound, soundmanager does not fire onfinish but starts buffering
+ //forever. Therefore, we must check this case here.
+ //We use a margin of time of 20 milliseconds (.2 seconds) to indicate that inside this margin the sound is at its end
+ if(this.soundPosition + 0.2 >= this.getSoundDuration()){
+ playOptions.onfinish();
+ }else{
+ sound.setVolume(sound.volume); //workaround. Just to be sure. Sometimes it fails when we re-play
+ sound.play(playOptions);
+ // soundManager.play(sound.sId,{
+ // onload: function(success){
+ // alert(success);
+ // }
+ // });
+ }
+
+ return false;
+ },
+
+ msgs : {
+ loading : 'loading',
+ buffering: 'buffering',
+ imgRefreshing : 'refreshing img'
+ },
+ pause: function(){
+ var sound = this.getSound();
+ //we don't check if it's playing, as the stop must really stop anyway
+ //if(sound && this.isPlaying()){
+ if(sound){
+ var v = this.isPlaying();
+ sound.stop();
+ var data = {
+ player:this,
+ oldPlayState:this.playState,
+ endOfPlayback:false
+ };
+ this.playState = 0;
+ this.fire('playStateChanged',data);
+ this.setWait(this.isImgRefreshing ? this.msgs.imgRefreshing : '');
+ }
+ return false;
+ },
+
+ getWaitElement: function(){
+ return this.getContainer().find('.ts-control').find('.ts-wait');
+ },
+
+ setWait: function(msg){
+ var wait = undefined;
+
+ wait = this.getWaitElement();
+ if(!wait || msg === undefined){
+ return;
+ }
+ if(wait.html()!=msg){
+ wait.html(msg);
+ }
+
+ var visible = wait.css('display') != 'none';
+
+ if(msg && !visible){
+ wait.show();
+ this.fire('waitShown');
+ }else if(!msg && visible){
+ wait.hide();
+ this.fire('waitHidden');
+ }
+ },
+
+ /**
+ * sets whether or not window resize resizes also this player. When true, a variable _dynamicResize =setInterval(...) is attached to
+ * this class. When false, if _dynamicResize is in this class, clearInterval(_dynamicResize) is called and then the key is deleted
+ */
+ setDynamicResize: function(value){
+ var key = '_dynamicResize';
+ if(!value && key in this){
+ clearInterval(this[key]);
+ delete this[key];
+ return;
+ }
+ var wdw = this.$J(window);
+ var w = wdw.width();
+ //var h = wdw.height();
+ var me = this;
+ this.dynamicResize = setInterval(function(){
+ var newW = wdw.width();
+ if(w!=newW){
+ w = newW;
+ //still wait a second: are we still adjusting the window? (call resize just once):
+ setTimeout(function(){
+ if(wdw.width()==newW){
+ me.resize.apply(me);
+ }
+ },200);
+ }
+ },100);
+ },
+
+ resize: function() {
+ var height;
+ var container = this.getContainer();
+
+ var wave = container.find('.ts-wave');
+
+ height = wave.height();
+ // if(!height){
+ // height = this.minWaveHeight;
+ // wave.css('height',height+'px');
+ // }
+ //if (height) {
+ //set image, imagecontainer and canvas (container on imagecontainer for lines and pointer triangles) css
+ var elements = wave.find('.ts-image-container').css('zIndex','0')
+ .add(wave.find('.ts-image-canvas').css('zIndex','1')); //the two children of ts-wave. Set also the zIndex
+ //in order to visualize the canvas OVER the wav image
+ var style = {
+ width: wave.width(),
+ height: height,
+ border: 0,
+ padding:0,
+ margin:0,
+ top:0,
+ left:0
+ };
+ elements.css(style);
+ elements.css('position','absolute');
+ //}
+
+ //refreshing images:
+ this.refreshImage();
+ this.getRuler().resize();
+ },
+ getImageUrl : function(){
+ var image = this.getContainer().find('.ts-image');
+ if(image && image.length){
+ return image.attr('src');
+ }
+ return '';
+ },
+ refreshImage: function(){
+ var container = this.getContainer();
+ var imageC = container.find('.ts-image-container');
+ var image = imageC.find('.ts-image');
+
+
+ var size = this.getImageSize();
+
+ if(!size.width || !size.height){
+ return;
+ }
+ var imgSrc = this.imageCallback(size.width,size.height);
+ var imageNotYetCreated = image.length == 0;
+ if(!imageNotYetCreated && image.attr('src')==imgSrc){
+ return;
+ }
+
+ var player= this;
+
+ if(imageNotYetCreated){
+ image = this.$J('<img/>');
+ }
+
+ //image inside ts-image-container:
+ image.css({
+ 'width':'100%',
+ 'height':'100%'
+ }); // for IE7. Does not seem to hurt IE8, FF, Chrome
+
+ var updateWait = function(){};
+ var ir = player.msgs.imgRefreshing;
+ var we = player.getWaitElement();
+ if(ir && we){
+ updateWait = function(){
+ if(!player.playState || player.playState==3){
+ player.setWait('');
+ }
+ }
+ }
+ image.load(function(){
+ image.unbind('load');
+ if(imageNotYetCreated){
+ imageC.append(image.addClass('ts-image'));
+ }
+ updateWait();
+ player.isImgRefreshing = false;
+ player.fire('imgRefreshed');
+ });
+ if(ir && we && (!this.playState || this.playState===3)){ //if loading (1) or buffering (2) do not update wait.
+ //If not playing (undefined or 0) playing (3) update wait
+ this.setWait(ir);
+ }
+ this.isImgRefreshing = true;
+ this.fire('imgRefreshing');
+ image.attr('src', imgSrc);
+
+ },
+ getImageSize: function(){
+ var wave = this.getContainer().find('.ts-wave');
+ return {
+ width: wave.width(),
+ height:wave.height()
+ }
+ },
+
+ setImageSize: function(width,height){
+ var container = this.getContainer();
+ var wave = container.find('.ts-wave');
+ this._setImageSize(width,height,container, wave,true);
+ },
+ //this is intended to be a private method, use setImageSize from outside the player object)
+ _setImageSize: function(width,height,jQueryContainerElement, jQueryWaveElement, resize){
+ if(width || height){
+ var re = /(?:px|ex|em|%)$/;
+ if(width){
+ width+='';
+ width = re.exec(width) ? width : width+'px';
+ jQueryContainerElement.css('width',width);
+ }
+ if(height){
+ height+='';
+ height = re.exec(height) ? height : height+'px';
+ jQueryWaveElement.css('height',height);
+ }
+ }
+ if(resize){
+ this.resize();
+ }
+ },
+
+ getSoundVolume :function(){
+ var s = this.getSound();
+ return s ? s.volume : 0;
+ },
+ //moves the pointer (and sound position) forward till the next marker or the end of sound
+ forward: function() {
+ var map = this.getMarkerMap();
+ var markers = map.toArray();
+ var len = markers.length;
+ var offset = this.getSoundDuration();
+ var position = this.soundPosition; //parseFloat(this.getSoundPosition());
+ var idx = map.insertionIndex(position);
+ if(idx<0){
+ idx = -idx-1; //cursor is not on a a marker, get the insertion index
+ }else{
+ //cursor is on a marker. As there might be several markers with the same offset
+ //(see MarkerMap.insertionIndex), move to the outmost right
+ while(idx<len && markers[idx].offset == position){
+ idx++;
+ }
+ }
+
+ if(idx< len){
+ offset = markers[idx].offset;
+ }
+ this.setSoundPosition(offset);
+ return false;
+ },
+ //moves the pointer (and sound position) backward till the previous marker or the start of sound
+ rewind: function() {
+ var map = this.getMarkerMap();
+ var markers = map.toArray();
+ var offset = 0;
+ var position = this.soundPosition; //parseFloat(this.getSoundPosition());
+ var idx = map.insertionIndex(position);
+ if(idx<0){
+ idx = -idx-1; //cursor is not on a a marker, get the insertion index
+ }else{
+ //cursor is on a marker. As there might be several markers with the same offset
+ //(see MarkerMap.insertionIndex), move to the outmost left
+ while(idx>0 && markers[idx-1].offset == position){
+ idx--;
+ }
+ }
+ idx--; //move backward (rewind)
+ if(idx>=0){
+ offset = markers[idx].offset;
+ }
+ this.setSoundPosition(offset);
+ return false;
+ },
+
+ setSoundVolume: function(volume){
+ if(typeof volume != 'number'){ //note: typeof for primitive values, instanceof for the rest
+ //see topic http://stackoverflow.com/questions/472418/why-is-4-not-an-instance-of-number
+ volume = 100;
+ }
+ if(volume<0){
+ volume = 0;
+ }else if(volume>100){
+ volume = 100;
+ }
+ volume = Math.round(volume);
+ var sound = this.getSound();
+ if(sound){
+ sound.setVolume(volume);
+ }
+ var control = this.getContainer().find('.ts-control');
+ var volumeSpeaker = control.find('.ts-volume-speaker');
+ var volumeBarContainer = control.find('.ts-volume-bar-container');
+ var volumeBar = volumeBarContainer.find('.ts-volume-bar');
+ if(volume==0){
+ volumeSpeaker.removeClass('ts-volume-speaker-on').addClass('ts-volume-speaker-off');
+ volumeBar.css('visibility','hidden');
+ }else{
+ volumeSpeaker.removeClass('ts-volume-speaker-off').addClass('ts-volume-speaker-on');
+ volumeBar.css('visibility','visible');
+ volumeBar.css({
+ 'height':'100%',
+ 'width':volume+'%'
+ });
+ }
+ },
+
+ each: function(){
+ var map = this.getMarkerMap();
+ if(map){
+ map.each.apply(map,arguments);
+ }
+ },
+
+ newMarker: function(offset){
+ return {
+ offset:offset
+ };
+ },
+ addMarker: function(offset){
+ var map = this.getMarkerMap();
+ if(map){
+ map.add(this.newMarker(offset));
+ }
+ },
+
+ removeMarker: function(identifier){ //identifier can be an number (marker index) or a marker (the index will be aearched)
+ //see marlermap.remove
+ var map = this.getMarkerMap();
+ if(map){
+ map.remove(identifier);
+ }
+ },
+
+ moveMarker: function(identifier, newOffset){ //identifier can be an number (marker index) or a marker (the index will be aearched)
+ var map = this.getMarkerMap();
+ if(map){
+ map.move(identifier,newOffset);
+ }
+ },
+
+ getMarker: function(index){
+ var map = this.getMarkerMap();
+ if(map){
+ return map.toArray()[index];
+ }
+ return undefined;
+ },
+
+ setMarkerEditable: function(identifier, value){
+ var map = this.getMarkerMap();
+ if(map){
+ return map.setEditable(identifier,value);
+ }
+ return undefined;
+ },
+
+ //markers is an array of objects with at least the field offset:sconds.milliseconds
+ loadMarkers: function(markers){
+ //ruler.bind('markermoved',this.markerMoved,this);
+ //var $J = this.$J; //reference to jQuery
+
+ var player = this;
+ //initialize the map.
+ var map = this.getMarkerMap();
+ //var mapUI = this.getMarkersUI();
+ var ruler = this.getRuler();
+
+ //TODO: think about if clearing or not: we assign some bindings in the constructor, too:
+ // map.clear();
+ // ruler.clear();
+
+ var rulerAdd = ruler.add;
+
+ if(markers){
+ //add markers to the map. No listeners associated to it (for the moment)
+ for(var i =0; i< markers.length; i++){
+ map.add.apply(map,[markers[i]]);
+ }
+ //add markers to ruler and div
+ map.each(function(i,marker){
+ //isEditable and id are added if not present
+ rulerAdd.apply(ruler,[marker.offset, i, marker.isEditable]);
+ });
+ }
+
+ //the function above calls map.add:
+ //add bindings when adding a marker:
+ map.bind('add',function(data){
+ //mapuiAdd.apply(mapUI,[data.marker, data.index,data.isNew]);
+ rulerAdd.apply(ruler,[data.marker.offset, data.index,data.marker.isEditable]);
+ player.fire('markerAdded',data);
+ });
+
+ //2) MOVE
+
+ //add the binding when we move a marker on the ruler:
+ ruler.bind('markermoved',function(data){
+ var soundPos = data.soundPosition;
+ var isPointer = data.isPointer;
+ if(isPointer){
+ player.setSoundPosition(soundPos);
+ }else{
+ map.move(data.markerElement.getIndex(), soundPos);
+ }
+ });
+
+ //and now add a binding to the map when we move a marker:
+
+ map.bind('move', function(data){
+ var from = data.fromIndex;
+ var to = data.toIndex;
+ ruler.move.apply(ruler,[from,to,data.marker.offset]);
+ player.fire('markerMoved',data);
+ });
+
+ //remove
+ map.bind('remove',function(data){
+ ruler.remove.apply(ruler, [data.index]);
+ player.fire('markerRemoved',data);
+ });
+
+ //edit state changed
+ map.bind('markerEditStateChanged',function(data){
+ ruler.setEditable.apply(ruler, [data.index, data.value]);
+ player.fire('markerEditStateChanged',data);
+ });
+ }
+});
--- /dev/null
+/*
+ * Copyright (C) 2007-2011 Parisson
+ * Copyright (c) 2011 Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
+ * Copyright (c) 2010 Olivier Guilyardi <olivier@samalyse.com>
+ *
+ * This file is part of TimeSide.
+ *
+ * TimeSide is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * TimeSide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with TimeSide. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
+ * Olivier Guilyardi <olivier@samalyse.com>
+ */
+
+/**
+ * Class representing the ruler (upper part) of the player. Requires jQuery
+ * and Raphael
+ */
+Timeside.classes.Ruler = Timeside.classes.TimesideArray.extend({
+ //init constructor: soundDuration is IN SECONDS!!! (float)
+ init: function(rulerContainer, waveContainer, soundDuration){
+ this._super();
+
+ this.getSoundDuration= function(){
+ return soundDuration;
+ };
+
+ this.getWaveContainer =function(){
+ return waveContainer;
+ };
+
+ this.getContainerWidth =function(){
+ return waveContainer.width();
+ };
+
+ this.getRulerContainer = function(){
+ return rulerContainer;
+ }
+ },
+
+ resize : function(){
+ var duration = this.getSoundDuration(); //in seconds
+ if (!duration) {
+ this.debug("ruler.resize: Can't draw ruler with a duration of 0");
+ return;
+ }
+
+ var $J = this.$J;
+ var rulerContainer = this.getRulerContainer();
+
+ //remove all elements not pointer or marker
+ rulerContainer.find(':not(a.ts-pointer,a.ts-marker,a.ts-pointer>*,a.ts-marker>*)').remove();
+
+ //calculate h with an artifice: create a span (that will be reused later) with the "standard" label
+ var firstSpan = $J('<span/>').css({
+ 'display':'block',
+ 'position':'absolute'
+ }).html('00000'); //typical timelabel should be '00:00', with '00000' we assure a bit of extra safety space
+ //note also that display and position must be set as below to calculate the proper outerHeight
+ rulerContainer.append(firstSpan); //to calculate height, element must be in the document, append it
+ var verticalMargin = 1;
+ var h = 2*(verticalMargin+firstSpan.outerHeight());
+ //h is the default height of the ruler svg (according to ruler font size)
+ //to accomodate the necessary space for the labels
+ //however, if we set a custom height on the ruler, ie h2 is nonzero:
+ var h2 = rulerContainer.height();
+ //then, set the custom height as height for the canvas:
+ //note that, as markers and pointer have position: absolute, they do not affect div height
+ if(h2){
+ h = h2;
+ }
+ var obj = this.calculateRulerElements(rulerContainer.width(),h,firstSpan.outerWidth());
+ this.drawRuler(rulerContainer,h,obj.path);
+
+ var labels = obj.labels;
+ if(labels && labels.length){
+ for(var i=0; i <labels.length;i++){
+ var span = (i==0 ? firstSpan : $J('<span/>'));
+ span.html(labels[i][0]).css({
+ 'display':'block',
+ 'position':'absolute',
+ 'width':'',
+ 'height':'',
+ 'right':'',
+ 'bottom':'',
+ 'top':'0',
+ 'left':labels[i][1]+'px'
+ });
+ rulerContainer.append(span);
+ }
+ }else{
+ firstSpan.html(this.makeTimeLabel(0));
+ }
+
+ var pointer = undefined;
+ if('getPointer' in this){
+ pointer = this.getPointer();
+ }
+ if(!pointer){
+ pointer = this.add(0,-1);
+ this.getPointer = function(){
+ return pointer;
+ };
+ }else{
+ pointer.refreshPosition();
+
+ }
+ this.each(function(i,rulermarker){
+ rulermarker.refreshPosition();
+ });
+
+
+ },
+
+ drawRuler: function(rulerContainer,h,rulerLinesPath){
+ var cssPref = this.cssPrefix;
+ var upperRectClass = cssPref + 'svg-' + 'ruler-upper-rect';
+ var rulerLinesClass = cssPref + 'svg-' + 'ruler-lines';
+
+ var vml = this.$TU.vml;
+ if(vml){
+ //we create each time a new Raphael object. This is not a big performance issue
+ var paper = Raphael(rulerContainer[0], rulerContainer.width(), h);
+ var rect = paper.rect(0,0, rulerContainer.width(), h/2);
+ var path = paper.path(rulerLinesPath);
+ var attr = vml.getVmlAttr;
+ rect.attr(attr(upperRectClass));
+ path.attr(attr(rulerLinesClass));
+ return;
+ }
+ //create svg. Note that elements must be created within a namespace (createElementNS)
+ //and attributes must be set via .setAttributeNS(null,name,value)
+ //in other words, jQuery does not work (maybe in future releases)
+ var $J = this.$J;
+ var svgNS = "http://www.w3.org/2000/svg";
+ var d = document;
+ var svg = d.createElementNS(svgNS, "svg:svg");
+ svg.setAttributeNS( null, "width", rulerContainer.width()); //TODO: optimize width is called also below
+ svg.setAttributeNS( null, "height", h);
+ rulerContainer.append($J(svg));
+
+ var rect = d.createElementNS(svgNS, "svg:rect");
+ rect.setAttributeNS( null, "x", 0);
+ rect.setAttributeNS( null, "y", 0);
+ rect.setAttributeNS( null, "width", rulerContainer.width());
+ rect.setAttributeNS( null, "height", (h/2));
+ rect.setAttributeNS( null, "class", upperRectClass);
+ svg.appendChild(rect);
+ var lines = d.createElementNS(svgNS, "svg:path");
+ lines.setAttributeNS( null, "d", rulerLinesPath);
+ lines.setAttributeNS( null, "class", rulerLinesClass);
+ svg.appendChild(lines);
+ },
+ /**
+ * returns an object with the following properties:
+ * path: (string) the path of the ruler to be drawn
+ * labels (array) an array of arrays ['text',x,y]
+ */
+ calculateRulerElements: function(w,h,timeLabelWidth){
+
+ var duration = this.getSoundDuration();
+
+ var fontLeftMargin = 2; //should be eual or greater to the ruler stroke width, so that
+ //the labels are not overlapping the vertical ruler lines
+ timeLabelWidth+=fontLeftMargin;
+
+ var timeLabelDuration = timeLabelWidth*duration/w;
+
+ //determine the ticks:
+ var sectionDurations = [1,2,5,10,30,60,120,300,1800,3600,7200,18000,36000];
+ //sectionDurations in seconds. Note that 60=1 minute, 3600=1 hour (so the maximum sectionDuration is 36000=10hours)
+ var i=0;
+ var len = sectionDurations.length;
+ while(i<len && timeLabelDuration>sectionDurations[i]){
+ i++;
+ }
+ var sectionDuration = sectionDurations[i];
+ var sectionNums = parseInt(0.5+(duration/sectionDurations[i])); //ceil
+ var sectionWidth = w*sectionDuration/duration;
+
+
+ var tickCounts = [10,5,2,1];
+ i=0;
+ var tickCount = tickCounts[0];
+ while(i<tickCounts.length-1 && tickCounts[i]*2>sectionWidth){
+ i++;
+ }
+ var tickAtHalfSectionWidthHigher = i==0 || i==2; //draw tick at half section higher if ticks are even
+ tickCount = tickCounts[i];
+ var tickWidth = sectionWidth/tickCount;
+ var makeTimeLabel = this.makeTimeLabel;
+ var h_1 = h-1; //TODO: use line tickness instead of 1
+ var path = new Array(parseInt(0.5+(w/tickWidth)));
+ path[0] = ['M 0 '+h_1];
+ len = path.length;
+ for(i=0; i < len; i+=tickCount){
+ for(var j=1; j<tickCount+1; j++){
+ var k = i+j;
+ var x = (k*tickWidth);
+ var y = (j==tickCount ? 0 : tickAtHalfSectionWidthHigher && j==(tickCount)/2 ? .5*h : .75*h);
+ var baseline = ' L '+x+' '+h_1;
+ path[k] = baseline;
+ path[k] += ' L '+x+' '+y;
+ path[k] += baseline;
+ }
+ }
+ var labels = new Array(sectionNums);
+ for(i=0; i<sectionNums; i++){
+ labels[i] = [makeTimeLabel(sectionDuration*i),fontLeftMargin+i*sectionWidth];
+ }
+ return {
+ 'path': path.join(''),
+ 'labels':labels
+ };
+ },
+
+ //overridden: Note that the pointer is NOT cleared!!!!!
+ clear: function(){
+ var markers = this._super();
+ //now remove also the labels in the player ruler:
+ for( var i=0; i<markers.length; i++){
+ markers[i].remove();
+ }
+ return markers;
+ },
+
+ //overridden
+ remove: function(index){
+ var rulermarker = this._super(index);
+ rulermarker.remove();
+ this.each(index, function(i,rulermarker){
+ rulermarker.setIndex(i, true);
+ });
+ },
+
+ //overridden: do not call directly this method, use markermap.move
+ move: function(from, to, newOffset){
+ to = this._super(from,to);
+ if(to <0){ //no move (some error)
+ return -1;
+ }
+ //update label if it is the case:
+ var rulermarker = this.toArray()[to];
+ var pixelOffset = this.toPixelOffset(newOffset);
+ if(rulermarker.positionInPixels != pixelOffset){ //should not be the case if this method is called from a mouse event
+ rulermarker.move(pixelOffset);
+ }
+
+ if(to!=from){
+ var i1 = Math.min(from,to);
+ var i2 = Math.max(from,to)+1;
+ this.each(i1,i2, function(index,rulermarker){
+ rulermarker.setIndex(index, true);
+ });
+ }
+ return to;
+ },
+ //overridden
+ //add(offset.-1) adds the pointer, isMovable is ingored
+ //add(offset, index, isMovable) adds a marker, movable if isMovable == true
+ add: function(offset, index, isMovable){
+ var soundPosition;
+ var markerClass;
+
+ if(index<0){
+ soundPosition = offset;
+ isMovable = true;
+ markerClass='pointer';
+ }else{
+ soundPosition = offset;
+ //isMovable = offset.isEditable;
+ markerClass='marker';
+ }
+
+
+ var pointerOrMarker = new Timeside.classes.RulerMarker(this,this.getWaveContainer(),markerClass);
+
+ //call super constructor
+ //if it is a pointer, dont add it
+ if(markerClass != 'pointer'){
+ this._super(pointerOrMarker,index); //add at the end
+ //note that setText is called BEFORE move as move must have the proper label width
+ this.each(index, function(i,rulermarker){
+ rulermarker.setIndex(i,i!=index);//update label width only if it is not this marker added
+ });
+ }else{
+ //note that setText is called BEFORE move as move must have the proper label width
+ pointerOrMarker.setText(this.makeTimeLabel(0));
+ }
+ //proceed with events and other stuff: move (called AFTER setText or setText)
+ pointerOrMarker.move(this.toPixelOffset(soundPosition));
+ //set mouse events:
+ var isPointer = markerClass === 'pointer';
+ this._setEditable(pointerOrMarker, isMovable, isPointer);
+ return pointerOrMarker;
+
+ },
+
+ eventNamespace : 'rulerMouseEvent', //namespace for mouse events
+ mouseEventType : 'rulermarkermouseevent', //event type for fire TO THE PLAYER. The player then fires markerMouseEvent to outside
+
+ setEditable: function(index, value){
+ var a = this.toArray();
+ if(index>=0 && index < a.length){
+ this._setEditable(a[index],value,false);
+ }
+ },
+ //do not call, use setEditable(index,value) instead
+ _setEditable: function(pointerOrMarker, value, isPointer){
+ var eventNamespace = this.eventNamespace;
+ var doc = this.$J(document);
+ var lbl = pointerOrMarker.getLabel();
+ var me = this;
+ var mme = this.mouseEventType;
+
+
+ lbl.unbind('.'+eventNamespace); //this should delete all previous events
+
+ lbl.bind('mouseenter.'+eventNamespace,function(evt){
+ me.fire(mme,{
+ eventName: 'mouseenter',
+ eventObj: evt,
+ index: isPointer ? -1 : pointerOrMarker.getIndex()
+ });
+ return false;
+ });
+ lbl.bind('mouseleave.'+eventNamespace,function(evt){
+ me.fire(mme,{
+ eventName: 'mouseleave',
+ eventObj: evt,
+ index: isPointer ? -1 : pointerOrMarker.getIndex()
+ });
+ return false;
+ });
+
+ //to prevent page scrolling after mouseup, as click is also fired
+ lbl.bind('click.'+this.eventNamespace, function(evt){
+ return false;
+ });
+
+
+ lbl.bind('mousedown.'+eventNamespace,function(evt) {
+ if(evt.which===1){
+ if(value){
+ pointerOrMarker.isMovedByMouse = true;
+ }
+
+ var launchDragStart = true;
+
+ var startX = evt.pageX;
+ var startPos = lbl.position().left+lbl.width()/2;
+
+ evt.stopPropagation(); //dont notify the ruler or other elements;
+ var newPos = startPos;
+ doc.bind('mousemove.'+eventNamespace, function(evt_){
+ //preventClickFire=true;
+ if(value){
+ var x = evt_.pageX;
+ newPos = startPos+(x-startX);
+ pointerOrMarker.move(newPos);
+ //update the text if pointer
+ if(isPointer){
+ pointerOrMarker.setText(me.makeTimeLabel(me.toSoundPosition(newPos)));
+ }
+ }
+ if(launchDragStart){
+ launchDragStart = false;
+ me.fire(mme,{
+ eventName: 'dragstart',
+ eventObj: evt_,
+ index: isPointer ? -1 : pointerOrMarker.getIndex()
+ });
+ }
+ return false;
+
+ });
+ //to avoid scrolling
+ ////TODO: check IE bug on mouseup on the ruler (pointer is moving too)
+ //TODO: what happens if the user releases the mouse OUTSIDE the browser???? check bug in IE (mouse release)
+ var mouseup = function(evt_){
+
+ doc.unbind('mousemove.'+eventNamespace);
+ doc.unbind('mouseup.'+eventNamespace);
+ evt_.stopPropagation();
+ if(value){
+ if(newPos !== startPos){
+
+ var data = {
+ 'markerElement':pointerOrMarker,
+ 'soundPosition': me.toSoundPosition.apply(me,[newPos]),
+ 'isPointer':isPointer
+ };
+ me.fire('markermoved',data);
+ }
+ pointerOrMarker.isMovedByMouse = false;
+ }
+ if(evt_.pageX !== startX){
+ me.fire(mme,{
+ eventName: 'dragend',
+ eventObj: evt_,
+ index: isPointer ? -1 : pointerOrMarker.getIndex()
+ });
+ }else{
+ me.fire(mme,{
+ eventName: 'click',
+ eventObj: evt_,
+ index: isPointer ? -1 : pointerOrMarker.getIndex()
+ });
+ }
+ return false;
+ };
+ doc.bind('mouseup.'+eventNamespace, mouseup);
+ }
+
+ me.fire(mme,{
+ eventName: 'mousedown',
+ eventObj: evt,
+ index: isPointer ? -1 : pointerOrMarker.getIndex()
+ });
+
+
+ return false;
+ });
+ },
+
+ //moves the pointer, does not notify any listener.
+ //soundPosition is in seconds (float)
+ movePointer : function(soundPosition) {
+ var pointer = this.getPointer();
+ if (pointer && !pointer.isMovedByMouse) {
+ var pixelOffset = this.toPixelOffset(soundPosition);
+ //first set text, so the label width is set, then call move:
+ pointer.setText(this.makeTimeLabel(soundPosition));
+ pointer.move(pixelOffset); //does NOT fire any move method
+ }
+ return soundPosition;
+ },
+
+ //soundPosition is in seconds (float)
+ toPixelOffset: function(soundPosition) {
+ var duration = this.getSoundDuration();
+ if (soundPosition < 0){
+ soundPosition = 0;
+ }else if (soundPosition > duration){
+ soundPosition = duration;
+ }
+ var width = this.getContainerWidth();
+ var pixelOffset = (soundPosition / duration) * width;
+ return pixelOffset;
+ },
+
+ //returns the soundPosition is in seconds (float)
+ toSoundPosition: function(pixelOffset) {
+ var width = this.getContainerWidth();
+
+ if (pixelOffset < 0){
+ pixelOffset = 0;
+ }else if (pixelOffset > width){
+ pixelOffset = width;
+ }
+ var duration = this.getSoundDuration();
+ var soundPosition = (pixelOffset / width) *duration;
+ return soundPosition;
+ }
+});
--- /dev/null
+/*
+ * Copyright (C) 2007-2011 Parisson
+ * Copyright (c) 2011 Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
+ * Copyright (c) 2010 Olivier Guilyardi <olivier@samalyse.com>
+ *
+ * This file is part of TimeSide.
+ *
+ * TimeSide is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * TimeSide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with TimeSide. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
+ * Olivier Guilyardi <olivier@samalyse.com>
+ */
+
+/**
+ * Class representing a RulerMarker in TimesideUI
+ * Requires jQuery Raphael and all associated player classes. rulerDiv position MUST be relative
+ * (if this class is called from within player, it is)
+ */
+
+Timeside.classes.RulerMarker = Timeside.classes.TimesideClass.extend({
+
+
+ init: function(ruler, waveImgDiv, className) {
+ this._super();
+ var rulerDiv = ruler.getRulerContainer();
+ var $J = this.$J;
+
+ var tooltip = '';
+
+ var cssPref = this.cssPrefix;
+
+ var label = $J('<a/>')
+ .addClass(cssPref + className)
+ .css({
+ display: 'block',
+ textAlign: 'center',
+ position: 'absolute',
+ zIndex: 1000
+ }).append($J('<span/>')).attr('href', '#');
+
+ if (tooltip){
+ label.attr('title', tooltip);
+ }
+ rulerDiv.append(label);
+
+ //rulerDiv MUST HAVE POSITON relative or absolute (it is relative, see player.resize)
+ if(className != "pointer"){
+ label.css('bottom','0');
+ }else{
+ label.css('top','0');
+ }
+
+ //set the index,
+ var index = -1;
+ this.setIndex = function(idx, optionalUpdateLabelWidth){
+ index = idx;
+ this.setText(idx+1, optionalUpdateLabelWidth ? true : false);
+ };
+ this.getIndex = function(){
+ return index;
+ };
+
+ //end=======================================================
+ //creating public methods:
+ this.getLabel = function(){
+ return label;
+ };
+
+
+ this.getRulerWidth = function(){
+ return rulerDiv.width();
+ };
+ this.getWaveHeight = function(){
+ return waveImgDiv.height();
+ };
+
+ this.positionInPixels = 0;
+ this.positionAsViewerRatio = 0;
+
+ var arrowBaselineWidth = 9;
+
+ var canvas = undefined;
+ var canvasClass = cssPref + 'svg-'+className+'-line';
+ var vml = this.$TU.vml; //if vml, this class is populated with methods and NOT undefined
+ var round = Math.round;
+ if(!vml){
+ canvas = this.createCanvasSvg(waveImgDiv, arrowBaselineWidth);
+ var path = canvas.childNodes[0]; //note that $J(canvas).find('path') does not work in FF at least 3.5
+ path.setAttributeNS(null,'class',canvasClass);
+ this.moveCanvas = function(pixelOffset){
+ pixelOffset = round(pixelOffset);
+ canvas.setAttributeNS( null, "transform", "translate("+pixelOffset+",0)");
+ };
+ this.jQueryCanvas = $J(canvas);
+ }else{
+ canvas = this.createCanvasVml(waveImgDiv, arrowBaselineWidth);
+ this.jQueryCanvas = $J(canvas.node);
+ var attributes = vml.getVmlAttr(canvasClass);
+ canvas.attr(attributes); //Raphael method
+ this.moveCanvas = function(pixelOffset){
+ pixelOffset = round(pixelOffset);
+ //for some reason, coordinates inside the VML object are stored by raphael with a zoom of 10:
+ this.jQueryCanvas.css('left',(10*pixelOffset)+'px');
+ };
+ //apparently, when resizing the markers loose their attributes. Therefore:
+ var r = this.refreshPosition; //reference to current refreshPosition
+ this.refreshPosition = function(){
+ r.apply(this);
+ canvas.attr(attributes);
+ }
+ }
+ },
+
+ //sets the text of the marker, if the text changes the marker width and optionalUpdateLabelPosition=true,
+ //re-arranges the marker position to be center-aligned with its vertical line (the one lying on the wav image)
+ setText: function(text, optionalUpdateLabelPosition) {
+ var label = this.getLabel();
+ if (label) {
+ var oldWidth = label.width();
+ label.find('span').html(text);
+ var labelWidth = label.width();
+ if(oldWidth != labelWidth && optionalUpdateLabelPosition){
+ this.refreshLabelPosition();
+ }
+ }
+ return this;
+ },
+
+ //these methods are executed only if marker is movable (see Ruler.js)
+ move : function(pixelOffset) {
+ var width = this.getRulerWidth();
+ if (this.positionInPixels != pixelOffset) {
+ if (pixelOffset < 0) {
+ pixelOffset = 0;
+ } else if (pixelOffset >= width) {
+ pixelOffset = width - 1;
+ }
+ //defined in the init method (it depends on wehter the current browser supports SVG or not)
+ this.moveCanvas(pixelOffset);
+
+ this.positionInPixels = pixelOffset;
+ this.refreshLabelPosition(width);
+ //store relative position (see refreshPosition below)
+ this.positionAsViewerRatio = pixelOffset == width-1 ? 1 : pixelOffset/width;
+ }
+ return this;
+ },
+
+ refreshLabelPosition : function(optionalContainerWidth){
+ if(!(optionalContainerWidth)){
+ optionalContainerWidth = this.getRulerWidth();
+ }
+ var label = this.getLabel();
+ var width = optionalContainerWidth;
+ var pixelOffset = this.positionInPixels;
+ var labelWidth = label.outerWidth(); //consider margins and padding
+ var labelPixelOffset = pixelOffset - labelWidth / 2;
+ if (labelPixelOffset < 0){
+ labelPixelOffset = 0;
+ }else if (labelPixelOffset + labelWidth > width){
+ labelPixelOffset = width - labelWidth;
+ }
+ label.css({
+ left: this.mRound(labelPixelOffset) + 'px'
+ });
+
+ },
+
+ //function called on ruler.resize. Instead of recreating all markers, simply redraw them
+ refreshPosition : function(){
+ var width = this.getRulerWidth();
+ //store relativePosition:
+ var rp = this.positionAsViewerRatio;
+ this.move(this.mRound(this.positionAsViewerRatio*width));
+ //reset relative position, which does not have to change
+ //but in move might have been rounded:
+ this.positionAsViewerRatio = rp;
+ },
+
+
+ remove : function() {
+ var label = this.getLabel();
+ label.remove();
+ this.jQueryCanvas.remove(); //defined in the constructor
+ return this;
+ },
+
+
+ createCanvasSvg: function(container, arrowBaseWidth){
+ //create svg. Note that elements must be created within a namespace (createElementNS)
+ //and attributes must be set via .setAttributeNS(null,name,value)
+ //in other words, jQuery does not work (maybe in future releases)
+ var $J = this.$J;
+ var svgNS = "http://www.w3.org/2000/svg";
+ var d = document;
+ var svg = undefined;
+ if(container.children().length>0){
+ svg = container.children().get(0);
+ }else{
+ svg = d.createElementNS(svgNS, "svg:svg");
+ container.append($J(svg));
+ }
+ var group = d.createElementNS(svgNS, "svg:g");
+ group.setAttributeNS( null, "transform", "translate(0,0)");
+
+ var path = d.createElementNS(svgNS, "svg:path");
+ path.setAttributeNS( null, "d", this.createCanvasPath(0,arrowBaseWidth));
+
+ group.appendChild(path);
+ svg.appendChild(group);
+
+ return group; //return the group, not the path, as it is the group that will be translated when moving
+ },
+
+ createCanvasVml: function(container, arrowBaseWidth){
+ var vml = this.$TU.vml;
+ var paper = vml.Raphael(container.get(0),container.width(),container.height());
+ var shape = paper.path(this.createCanvasPath(0, arrowBaseWidth));
+ return shape;
+ },
+
+ //w must be odd. Cause the central line must be centered. Example:
+ //
+ // xxxxx
+ // xxx
+ // x
+ // x
+ // x
+ //
+ createCanvasPath: function(x,w){
+ var halfW = w >>> 1;
+ //in order to calculate the line height, we could simply set the wave height. However, due to potential
+ //resizing afterwards, the line could not stretch till the bottom (if it overflows it's fine, as the wave div container has
+ //overflow = hidden). As we do not want to rebuild the canvas on resize,
+ //we assess an height which will 99% overflow the wave height in any case.
+ //We use the wave height and the window height, and take 2 times
+ //the maximum of those heights:
+ var wdwH = this.$J(window).height();
+ var waveH = this.getWaveHeight();
+ var h = 2* (wdwH > waveH ? wdwH : waveH);
+ return 'M '+(x-halfW)+' 0 L '+(x)+' '+(halfW)+' L '+x+' '+h+
+ ' L '+ (x+1)+' '+h+' L '+(x+1)+ ' '+(halfW)+' L '+(x+halfW+1)+' 0 z';
+ },
+
+ //used for faster lookup
+ mRound: Math.round
+
+});
--- /dev/null
+/*
+ * Copyright (C) 2007-2011 Parisson
+ * Copyright (c) 2011 Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
+ * Copyright (c) 2010 Olivier Guilyardi <olivier@samalyse.com>
+ *
+ * This file is part of TimeSide.
+ *
+ * TimeSide is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * TimeSide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with TimeSide. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
+ * Olivier Guilyardi <olivier@samalyse.com>
+ */
+
+/**
+ * Root javascript file for TimesideUI, to be manually included in your web page (see online doc)
+ */
+
+/**
+ *global variable housing all Timeside variables/mathods/classes:
+ */
+var Timeside = {
+ Class:undefined,
+ classes:{},
+ player:undefined,
+ config: {
+ /**
+ *set to true to see debug messages on the console (only error or warning messages shown)
+ */
+ debug: false,
+ /*
+ * timeside scripts to be loaded when Timeside.load is called. URL paths are relative to the timeside folder, which
+ * will be determined according to the src attribute of the timeside.js script path (to be included in the <head> of the page)
+ */
+ timesideScripts: ['rulermarker.js','markermap.js', 'player.js', 'ruler.js'],
+ //vml config variables. Used only if svg is NOT supported
+ vml : {
+ /*
+ * raphael script to be loaded when Timeside.load is called and svg is not supported. It will be prepended to the
+ * timesideScripts array defined above in config. URL paths are relative to the timeside folder, which
+ * will be determined according to the src attribute of the timeside.js script path (to be included in the <head> of the page)
+ */
+ raphaelScript : 'libs/raphael-min.js',
+ /*
+ * available attributes which can be converted from css-svg to Raphael attributes (see Raphael.js):
+ */
+ raphaelAttributes : ["clip-rect", "cursor",'fill', "fill-opacity",'opacity', 'stroke', "stroke-dasharray", "stroke-linecap", "stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width", "text-anchor"]
+ }
+ },
+ utils:{
+ /**
+ * Returns an uniqid by creating the current local time in millisecond + a random number.
+ * Used for markers in markermap. The method is kind of public in order to be more accessible for other functions
+ * by calling Timeside.utils.uniqid(), in case it is needed
+ */
+ uniqid : function() {
+ var d = new Date();
+ return new String(d.getTime() + '' + Math.floor(Math.random() * 1000000)).substr(0, 18);
+ },
+ /**
+ * vml object which will be populated by vml functions to interface timeside and raphael. See timeside.load.
+ * We could implement functions here for code readability, however,
+ * we delegate Timeside.load so that if svg is supported memory is free from unused vml methods.
+ * IN ANY CASE, svg support can be detected anywhere by calling, eg:
+ * var svg = !Timeside.utils.vml;
+ */
+ vml: undefined,
+
+ /**
+ * property that will be set to false if soundManager fails to initialize flash
+ */
+ flashFailed : false
+ }
+};
+
+
+/* Simple JavaScript Inheritance
+ * By John Resig http://ejohn.org/
+ * MIT Licensed.
+ * (Inspired by base2 and Prototype)
+ */
+
+/*
+ * In few words: the lightest and most-comprehensive way to implement inhertance and OOP in javascript. Usages can be found below.
+ * Basically,
+ * 1) a new Class is instantiated with Class.extend(). This function takes a dictionary
+ * of properties/methods which will be put IN THE PROTOTYPE of the class, so that each instance will share the same properties/methods
+ * and the latter don't have to be created for each instance separately.
+ * 2) If var A = Class.extend({...}) and var B = A.extend({..}), then methods which are found in B will override the same methods in A.
+ * In this case, the variable this._super inside the overridden methods will refers to the super-method and can thus be called safely.
+ * Consequently, if a _super property/method is implemented in the extend dictionary, it WILL NOT be accessible
+ * to the overriding methods of B. Basically, don't use _super as a key of the argument of extend.
+ * 3) AFTER the prototype has been populated, the init function, if exists, is called. The latter can be seen as a class constructor in java,
+ * with a substantial difference: when executing the init() method the class prototype has already been populated with all inherited methods.
+ * Private variable can be declared in the init function, as well as
+ * relative getters and setters, if needed. Downside is that the privileged getters and setters can’t be put in the prototype,
+ * i.e. they are created for each instance separately, and the _super keyword does not apply to them. Another issue is the overhead of closures in general (basically, write as less as possible
+ * in the init function, in particular if the class has to be declared several times)
+ * Of course, the this._super keyword of methods implemented in the init constructor does not work
+ *
+ * EXAMPLE:
+ * var MyClass = Class.extend({
+ * init: function(optionalArray){ //constructor
+ * this._super(); //!!!ERROR: Class is the base class and does not have a super construcor
+ * var me = []; //private variable
+ * this.count = 6; //set the value of the public property defined below
+ * this.getMe = function(){ //public method
+ * this._super(); //!!!ERROR: methods defined in the init function don't have acces to _super
+ * }
+ * this.alert = function(){ //another public method, !!!WARNING: this will be put in the MyClass scope (NOT in the prototype)
+ * alert('ok');
+ * }
+ * },
+ * count:0, //public property
+ * alert: function(){ //public method. !!!WARNING: this method will be put in the prototype BEFORE the init is called,
+ * alert('no'); // so the alert defined above will be actually called
+ * }
+ * });
+ * var MyClass2 = MyClass.extend({
+ * init: function(){
+ * this._super(); //call the super constructor
+ * }
+ * alert: function(){ //override a method
+ * this._super(); //call the super method, ie alerts 'no'. WARNING: However, as long as there is an alert written
+ * //in the init method of the superclass (see above), THAT method will be called
+ * }
+ * });
+ *
+ */
+
+
+(function(parent){
+
+ var initializing = false, fnTest = /xyz/.test(function(){
+ xyz;
+ }) ? /\b_super\b/ : /.*/;
+
+ /*The xyz test above determines whether the browser can inspect the textual body of a function.
+ *If it can, you can perform an optimization by only wrapping an overridden method if it
+ *actually calls this._super() somewhere in its body.
+ *Since it requires an additional closure and function call overhead to support _super,
+ *it’s nice to skip that step if it isn’t needed.
+ */
+
+ //ADDED BY ME:
+ // before was: this.Class = function(){}, where this here is the DomWindow
+ // In order to chose where to attach the Class object, we added the argument parent (see above):
+ //if parent is undefined, attach Class to the DomWindow (same as before):
+ if(!parent){
+ parent= window;
+ }
+ parent.Class = function(){};
+
+ //from here on, the code is untouched:
+ //
+ //We have the base Class implementation (does nothing)
+ //and we write here below the method extend which returns the Class with inhertance implemented:
+ // Create a new Class that inherits from this class
+ parent.Class.extend = function(prop) {
+ var _super = this.prototype;
+
+ // Instantiate a base class (but only create the instance,
+ // don't run the init constructor)
+ initializing = true;
+ var prototype = new this();
+ initializing = false;
+
+ // Copy the properties over onto the new prototype
+ for (var name in prop) {
+ // Check if we're overwriting an existing function
+ prototype[name] = typeof prop[name] == "function" &&
+ typeof _super[name] == "function" && fnTest.test(prop[name]) ?
+ (function(name, fn){
+ return function() {
+ var tmp = this._super;
+
+ // Add a new ._super() method that is the same method
+ // but on the super-class
+ this._super = _super[name];
+
+ // The method only need to be bound temporarily, so we
+ // remove it when we're done executing
+ var ret = fn.apply(this, arguments);
+ this._super = tmp;
+
+ return ret;
+ };
+ })(name, prop[name]) :
+ prop[name];
+ }
+
+ // The dummy class constructor
+ function Class() {
+ // All construction is actually done in the init method
+ if ( !initializing && this.init ){
+ this.init.apply(this, arguments);
+ }
+ }
+
+ // Populate our constructed prototype object
+ Class.prototype = prototype;
+
+ // Enforce the constructor to be what we expect
+ Class.constructor = Class;
+
+ // And make this class extendable
+ Class.extend = arguments.callee;
+
+ return Class;
+ };
+})(Timeside);
+
+
+
+//Defining the base TimeClass class. Timeside.classes.[Player, Ruler, MarkerMap...] are typical implementations (see js files)
+//Basically we store here static methods which must be accessible in several timside sub-classes
+Timeside.classes.TimesideClass = Timeside.Class.extend({
+ //init constructor. Define the 'bind' and 'fire' (TODO: rename as 'trigger'?) methods
+ //we do it in the init function so that we can set a private variable storing all
+ //listeners. This means we have to re-write all methods
+ init: function(){
+ //the map for listeners. Must be declared in the init as it's private and NOT shared by all instances
+ //(ie, every instance has its own copy)
+ this.listenersMap={};
+ },
+
+ cssPrefix : 'ts-', //actually almost uneuseful, still here for backward compatibility with old code (TODO: remove?)
+ $J : jQuery, //reference to jQuery for faster lookup inside methods
+ $TU : Timeside.utils, //reference to Timeside variable for faster lookup inside methods
+ debugging : false,
+ debug : Timeside.config.debug ? function(message) {
+ var C = console;
+ if (C && C.log) {
+ C.log(message);
+ }
+ } : function(message){},
+
+ /**
+ * 3 methods defining listeners, events fire and bind (aloing the lines of jQuery.bind, unbind and trigger.
+ * the only difference is that 'trigger' is 'fire' here). namespaces are allowed as in jQuery
+ */
+ bind : function(eventType, callback, optionalThisArgInCallback){
+ if(!callback || typeof callback !== 'function'){
+ this.debug('TimesideClass.bind: cannot bind '+eventType+' to callback: the latter is null or not a function');
+ return;
+ }
+ if(!eventType){
+ this.debug('TimesideClass.bind: eventType is empty in bind');
+ return;
+ }
+ var listenersMap = this.listenersMap;
+ if(optionalThisArgInCallback){
+ var cb = callback;
+ callback = function(data){
+ cb.apply(optionalThisArgInCallback,[data]);
+ };
+ }
+
+ if(listenersMap.hasOwnProperty(eventType)){
+ listenersMap[eventType].push(callback);
+ }else{
+ listenersMap[eventType] = [callback];
+ }
+
+ var idx = eventType.indexOf('.');
+ if(idx <= 0 || idx >= eventType.length-1){
+ return;
+ }
+
+ eventType = eventType.substring(0,idx);
+
+
+ if(listenersMap.hasOwnProperty(eventType)){
+ listenersMap[eventType].push(callback);
+ }else{
+ listenersMap[eventType] = [callback];
+ }
+
+ },
+ unbind : function(){
+ var listenersMap = this.listenersMap;
+ var key,keyPlusDot;
+ if(arguments.length>0){
+ key = arguments[0];
+ if(listenersMap.hasOwnProperty(key)){
+ var callbacks = listenersMap[key];
+ var idx = key.indexOf('.');
+ if(idx>0 && idx < key.length-1){
+ //key is "eventtype.namespace", delete also functions stored in "eventType", if any
+ var baseKey = key.substring(0,idx);
+ var baseCallbacks = listenersMap[baseKey];
+ if(baseCallbacks){
+ for( var i = baseCallbacks.length; i>-1; i--){
+ var bc = baseCallbacks[i];
+ for( var j = callbacks.length; j>-1; j--){
+ if(bc === callbacks[j]){
+ baseCallbacks.splice(i,1);
+ }
+ }
+ }
+ }
+ }else if(idx<0){
+ //key is "eventtype", delete also all functions stored in "eventType.namespace", if any
+ keyPlusDot = key+'.';
+ for(var k in listenersMap){
+ if(listenersMap.hasOwnProperty(k) && k.indexOf(keyPlusDot)==0 && k.length > keyPlusDot.length){
+ delete listenersMap[k];
+ }
+ }
+ }
+ delete listenersMap[key];
+ }
+ }else{
+ for(key in listenersMap){
+ if(listenersMap.hasOwnProperty(key)){
+ delete listenersMap[key];
+ }
+ }
+ }
+ },
+ fire : function(key, dataArgument){
+ var listenersMap = this.listenersMap;
+ if(!(listenersMap.hasOwnProperty(key))){
+ return;
+ }
+ if(arguments.length < 2 || !dataArgument){
+ dataArgument = {};
+ }
+ var callbacks = listenersMap[key];
+ var len = callbacks && callbacks.length ? callbacks.length : 0;
+ for(var i=0; i<len; i++){
+ callbacks[i](dataArgument);
+ }
+ },
+
+ /*
+ *formats (ie returns a string representation of) a time which is in the form seconds,milliseconds (eg 07.6750067)
+ * formatArray is an array of strings which can be:
+ * 'h' hours. Use 'hh' for a zero-padding to 10 (so that 6 hours is rendered as '06')
+ * 'm' hours. Use 'mm' for a zero-padding to 10 (so that 6 minutes is rendered as '06')
+ * 's' hours. Use 'ss' foar a zero-padding to 10 (so that 6 seconds is rendered as '06')
+ * 'D' deciseconds
+ * 'C' centiseconds (it will be padded to 10, so that 5 centiseconds will be rendered as '05')
+ * 'S' milliseconds (it will be padded to 100, so that 5 milliseconds will be rendered as '005')
+ * If formatArray is null or undefined or zero-length, it defaults to ['mm','ss']
+ * 'h','m' and 's' will be prepended the separator ':'. For the others, the prepended separator is '.'
+ * Examples:
+ * makeTimeLabel(607,087) returns '10:07' (formatArray defaults to ['mm','ss'])
+ * makeTimeLabel(607,087,['m':'s']) returns '10:7'
+ * makeTimeLabel(607,087,['m':'s','C']) returns '10:7.09'
+ */
+ makeTimeLabel: function(time, formatArray){
+ if(!(formatArray)){
+ formatArray = ['mm','ss'];
+ }
+
+ //marker offset is in float format second.decimalPart
+ var pInt = parseInt;
+ var round = Math.round;
+ var factor = 3600;
+ var hours = pInt(time/factor);
+ time-=hours*factor;
+ factor = 60;
+ var minutes = pInt(time/factor);
+ time-=minutes*factor;
+ var seconds = pInt(time);
+ time-=seconds;
+
+ //here below the function to format a number
+ //ceilAsPowerOfTen is the ceil specifiedas integer indicating the relative power of ten
+ //(0: return the number as it is, 1: format as "0#" and so on)
+ //Examples: format(6) = "6", format(6,1)= "06", format(23,1)= "23"
+
+ //first of all, instantiate the power function once (and not inside the function or function's loop):
+ //note that minimumNumberOfDigits lower to 2 returns integer as it is
+ var mpow = Math.pow; //instantiate mpow once
+ var format = function(integer,minimumNumberOfDigits){
+ var n = ""+integer;
+ var zero = "0"; //instantiating once increases performances???
+ for(var i=1; i< minimumNumberOfDigits; i++){
+ if(integer<mpow(10,i)){
+ n = zero+n;
+ }
+ }
+ return n;
+ };
+ var ret = [];
+ for(var i =0; i<formatArray.length; i++){
+ var f = formatArray[i];
+ var separator = ":";
+ if(f=='h'){
+ ret[i]=hours;
+ }else if(f=='hh'){
+ ret[i]=format(hours,2);
+ }else if(f=='m'){
+ ret[i]=minutes;
+ }else if(f=='mm'){
+ ret[i]=format(minutes,2);
+ }else if(f=='s'){
+ ret[i]=seconds;
+ }else if(f=='ss'){
+ ret[i]=format(seconds,2);
+ }else if(f=='S'){
+ separator = ".";
+ ret[i]=format(round(time*1000),3);
+ }else if(f=='C'){
+ separator = ".";
+ ret[i]=format(round(time*100),2);
+ }else if(f=='D'){
+ separator = ".";
+ ret[i]= round(time*10);
+ }
+ if(i>0){
+ ret[i] = separator+ret[i];
+ }
+ }
+ return ret.join("");
+ }
+});
+
+/**
+ * An Array-like implementation that suits the need of Marker mnanagement
+ * Ruler, MarkerMap and MarkerMapDiv implement this class
+ */
+Timeside.classes.TimesideArray = Timeside.classes.TimesideClass.extend({
+ init: function(optionalArray){
+ this._super();
+ //here methods that CANNOT be overridden
+ var me= optionalArray ? optionalArray : [];
+ //note that this method written here OVERRIDES the same method written outside init in the children!!!!
+ this.toArray = function(returnACopy){
+ if(returnACopy){
+ var ret = [];
+ for(var i=0; i<me.length; i++){
+ ret.push(me[i]);
+ }
+ return ret;
+ }
+ return me;
+ };
+ this.length = me.length; //in order to match the javascript array property
+ },
+ //adds at the end of the array. If index is missing the object is appended at the end
+ add : function(object, index){
+ var array = this.toArray();
+ if(arguments.length<2){
+ index = array.length;
+ }
+ array.splice(index,0,object);
+ this.length = array.length; //note that length is a property and must be updated!!!
+ return object;
+ },
+ //removes item at index, returns the removed element
+ remove : function(index){
+ var array = this.toArray();
+ var ret = array.splice(index,1)[0];
+ this.length = array.length; //note that length is a property and must be updated!!!
+ return ret;
+ },
+ //Iterate over the array, with the same syntax of jQuery.each, ie, executes a function(index,element)
+ //for each element from startIndexInclusive to
+ //endIndexExclusive.
+ //The only required argument is callback:
+ //1) each(callback) iterates over all elements executing callback
+ //2) each(m, callback) iterates over the elements from m executing callback
+ //3) each(m,n,callback) iterates over the elements from m (inclusive) to n-1 (inclusive) executing callback
+
+ //NOTE: writing each : function(startInclusive, endExclusive, callback) throws an error in chrome, as the last
+ //argument (even if it is a function) is a number. Why?????
+ //Anyway, we write the function arguments as empty
+ each : function(){
+ var startInclusive, endExclusive, callback;
+
+ var arg = arguments;
+ var len = arg.length;
+ var l = this.length;
+ switch(len){
+ case 0:
+ this.debug('TimesideClass.each: each called without arguments!!!');
+ return;
+ case 1:
+ startInclusive = 0;
+ endExclusive = l;
+ break;
+ case 2:
+ if(arg[0] >= l){
+ return;
+ }
+ startInclusive = arg[0]=== undefined ? 0 : arg[0];
+ endExclusive = l;
+ break;
+ default:
+ startInclusive = arg[0]=== undefined ? 0 : arg[0];
+ endExclusive = arg[1]=== undefined ? l : arg[1];
+ }
+ callback = arg[len-1];
+ if(!(callback instanceof Function)){
+ this.debug('TimesideClass.each: callback NOT a function!!!');
+ return;
+ }
+ var me =this.toArray();
+ for(var i = startInclusive; i<endExclusive; i++){
+ callback(i,me[i]);
+ }
+
+ },
+
+ //clears the array and the events associated to it, ie removes all its elements and calls unbind(). Returns the array of the removed elements
+ clear: function(){
+ this.unbind();
+ var me = this.toArray();
+ var l = me.length;
+ this.length = 0;
+ if(l==0){
+ return [];
+ }
+ return me.splice(0,l);
+ },
+ //moves the element at position from into position to
+ //the element that was at from will be at position to
+ //returns:
+ //-1 if from or to not integers, or from or to not within the array bounds (lower than zero or greater or equal to this.length)
+ //from if from === to (no move)
+ //to otherwise (move succesful)
+ move : function(from, to){
+
+ var pInt = parseInt;
+ if(pInt(from)!==from || pInt(to)!==to){ //just a check
+ return -1;
+ }
+ if(from === to){
+ return from;
+ }
+ var me =this.toArray();
+ var len = me.length;
+ if((from<0 || from>=len)||(to<0 || to>=len)){
+ return -1;
+ }
+ var elm = me.splice(from,1)[0];
+ me.splice(to,0,elm);
+
+ return to;
+ }
+});
+
+
+
+/**
+ *Main Timeside method to load player (see Timeside online doc)
+ */
+
+Timeside.load =function(config){
+
+ var $J = jQuery;
+ var win = window;
+ var doc = document;
+ //function to be called onready or onerror:
+ var loadAll = function() {
+
+
+ //get the current script path (this file name is timeside.js?... or simplt timeside.js)
+ var scripts = $J('script');
+ var thisScriptPath = '';
+ scripts.each(function(i,s){
+ var src = $J(s).attr('src');
+ if(src){
+ var srcName = src.split(/\//);
+ if(srcName.length){
+ srcName = srcName[srcName.length-1];
+ //is this script ? consider the case here we are loading timeside.js?....
+ if(srcName.replace(/\.js(?:\?[^\?]*)*$/,'.js') == 'timeside.js'){
+ src[src.length-1] = '';
+ thisScriptPath = src.replace(/\/[^\/]+$/, '');
+ }
+ }
+ }
+ });
+
+ var ts = Timeside;
+ var ts_scripts = ts.config.timesideScripts;
+ //detect SVG support and load Raphael in case. Copied from Raphael code v 1.5.2:
+ var svg = (win.SVGAngle || doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"));
+ if(!svg){
+ //add the raphael path. Raphael will be loaded in Timeside.load (see below)
+ ts_scripts.splice(0,0,ts.config.vml.raphaelScript);
+ //populate the vml object with methods to be used in ruler and rulermarker:
+
+ //global private variable:
+ //map to store each class name to the relative dictionary for raphael attr function (VML only)
+ var classToRaphaelAttr = {};
+ //get the raphael attributes for which a conversion css -> raphael_attribute is possible:
+ var availableAttrs = ts.config.vml.raphaelAttributes;
+ //here below we store Raphael paper objects. var paper = Raphael(htmlElement) is the raphel method to build
+ //a new paper object. Internally, the method builds a div embedding vmls inside htmlElement, retriavable via the
+ //paper.node property.
+ //However, calling again var paper = Raphael(htmlElement) does not use the already created paper,
+ //but creates a new paper with a new paper.node (div). Too bad. The possibility to wrap existing paper node
+ //into a Raphael paper would be a nice and almost necessary feature, which however is not even
+ //planned to be implemented according to raphael developers (see raphael forums).
+ //In case of markers lines, we want to draw a new marker
+ //on the same raphael paper. Therefore, we store here raphael papers in a map htmlElement -> paper
+ var raphael_papers = {};
+ ts.utils.vml = {
+ getVmlAttr: function(className){
+
+ if(classToRaphaelAttr.hasOwnProperty(className)){
+ //if(className in classToRaphaelAttr){
+ return classToRaphaelAttr[className];
+ }
+ var d = document;
+ var dottedclassName = className.replace(/^\.*/,'.'); //add a dot if not present
+ var ssheets = d.styleSheets;
+ var len = ssheets.length-1;
+
+ var attr = {};
+ for(var i=0; i<len; i++){
+ var rules = ssheets[i].rules;
+ var l = rules.length;
+ for(var j=0; j <l; j++){
+ var rule = rules[j];
+
+ if(rule.selectorText === dottedclassName){
+
+ var style = rule.style;
+ for(var k =0; k<availableAttrs.length; k++){
+ var val = style[availableAttrs[k]];
+ if(val){
+ attr[availableAttrs[k]] = val;
+ }
+ }
+ }
+ }
+ }
+ classToRaphaelAttr[className] = attr;
+ return attr;
+ },
+
+ Raphael: function(element,w,h){
+ //pass jQueryElm.get(0) as first argument, in case)
+ if(raphael_papers[element]){
+ return raphael_papers[element];
+ }
+ var paper = Raphael(element,w,h);
+ raphael_papers[element] = paper;
+ //paper canvas is a div with weird dimensions. You can check it by printing paper.canvas.outerHTML in IE.
+ //We set them to 100% so we dont have clipping regions when resizing (maximizing)
+ paper.canvas.style.width='100%';
+ paper.canvas.style.height='100%';
+ paper.canvas.width='100%';
+ paper.canvas.height='100%';
+ //apparently, there is also a clip style declaration made by raphael. The following code trhows an error in IE7:
+ //paper.canvas.style.clip = 'auto';
+ //however, even leaving the clip style declaration as it is, it seems to work (the div spans the whole width)
+ return paper;
+ }
+
+ };
+ }
+
+ ts.player = undefined;
+ if(config.onReady && typeof config.onReady === 'function'){
+ var oR = config.onReady;
+ config.onReady = function(player){
+ ts.player = player;
+ oR(player);
+ };
+ }else{
+ config.onReady = function(player){
+ ts.player = player;
+ };
+ }
+
+ //finally,define the error function
+ ts.utils.loadScripts(thisScriptPath,ts_scripts, function() {
+ new ts.classes.Player(config); //do not assign it to any variable, we do it only onready
+ },config.onError);
+ };
+
+
+
+
+ $J(win).ready(function(){
+ var s = soundManager;
+ //grab the case of soundManager init errors:
+ s.onerror = function() {
+ Timeside.utils.flashFailed = true;
+ //end('SoundManager error. If your browser does not support HTML5, Flash player (version '+soundManager.flashVersion+'+) must be installed.\nIf flash is installed, try to:\n - Reload the page\n - Empty the cache (see browser preferences/options/tools) and reload the page\n - Restart the browser');
+
+ //and load all anyway:
+ loadAll();
+ };
+
+ //if soundmanager is ready, the callback is executed immetiately
+ //onready is executed BEFORE onload, it basically queues several onload events.
+ //It it is executed immetiately if soundmanager has already been loaded
+ s.onready(function(){loadAll();});
+ });
+};
+
+/**
+* Loads scripts asynchronously
+* can take up to four arguments:
+* scriptsOptionalRoot (optional): a string specifying the root (such as '/usr/local/'). IF IT IS A NONEMPTY STRING AND
+* DOES NOT END WITH A SLASH, A SLASH WILL B APPENDED
+* scriptArray: a string array of js script filenames, such as ['script1.js','script2.js']
+* optionalOnOkCallback (optional): callback to be executed when ALL scripts are succesfully loaded
+* optionalOnErrorCallback (optional) a callback receiving a string as argument to be called if some script is not found
+* optionalSynchroLoad (optional): if true scripts are loaded in synchronously, ie each script is loaded only once the
+* previous has been loaded. Otherise (including missing argument) an asynchronous load is performed
+* and the optional onOkCallback is executed once ALL scripts are loaded
+*/
+Timeside.utils.loadScripts = function(scriptsOptionalRoot,scriptArray, optionalOnOkCallback, optionalOnErrorCallback, optionalSynchroLoad){
+ //var optionalRoot='', callback=undefined, loadInSeries=false;
+ if(!optionalOnOkCallback || typeof optionalOnOkCallback !== 'function'){
+ optionalOnOkCallback = function(){};
+ }
+ if(!optionalOnErrorCallback || typeof optionalOnErrorCallback !== 'function'){
+ optionalOnErrorCallback = function(msg){};
+ }
+
+ if(!scriptArray || !scriptArray.length){
+ optionalOnOkCallback();
+ return;
+ }
+ var len = scriptArray.length;
+ var i=0;
+ if(scriptsOptionalRoot){
+ scriptsOptionalRoot = scriptsOptionalRoot.replace(/\/*$/,"/"); //add slash at end if not present
+ for(i =0; i<len; i++){
+ scriptArray[i] = scriptsOptionalRoot+scriptArray[i];
+ }
+ }
+
+ var $J = jQuery;
+ //there is a handy getScript function in jQuery, which however does NOT manage the onError case (script load error)
+ //looking at jQuery doc, getScript is the same as the followig ajax request,
+ //to which we added the error property to manage errors:
+ var loadScript = function(url,onSuccess,onError){
+ $J.ajax({
+ url: url,
+ dataType: 'script',
+ success: onSuccess,
+ error: function(a,b,errorThrown){
+ onError('file "'+url+'" error: '+errorThrown);
+ }
+ });
+ };
+ if(optionalSynchroLoad){
+ var load = function(index){
+ if(index<len){
+ loadScript(scriptArray[index],function(){
+ load(index+1);
+ }, function(msg){
+ optionalOnErrorCallback(msg);
+ });
+ }else if(index==len){
+ optionalOnOkCallback();
+ }
+ };
+ load(0);
+ }else{
+ var count=0;
+ var s;
+ for(i=0; i <len; i++){
+ s = scriptArray[i];
+ //this means that onError all scripts will be loaded.
+ //However, if everything works fine, asynchornous load (here) should be faster
+ loadScript(s, function(){
+ count++;
+ if(count===len){
+ optionalOnOkCallback();
+ }
+ },function(msg){
+ count = len+1; //avoid calling optionalOkOnCallback
+ optionalOnErrorCallback(msg);
+ });
+ }
+ }
+};
--- /dev/null
+/*
+* Style for the timeside player. The player div is supposed to be of class .ts-player. Change if needed
+* For details, see http://code.google.com/p/timeside/wiki/UiGuide?ts=1308677096&updated=UiGuide#CSS_and_skins
+*/
+
+.ts-player {
+ padding: 0;
+ border: solid 1px #ADADAD;
+ margin-top: 2px;
+}
+
+
+.ts-player .ts-ruler{
+ color: #ADADAD;
+ background-color: #F2F2F2;
+ font-size: 10px;
+ line-height: 13px;
+}
+/*svg style, MUST BE A SINGLE SELECTOR. FOR INSTANCE, THIS DOES NOT WORK WHEN SVG IS NOT SUPPORTED:
+ ".ts-player .ts-ruler .ts-svg-ruler-upper-rect" */
+.ts-svg-ruler-upper-rect{
+ fill: #FFFFFF;
+ stroke-width:0;
+ stroke: #FFFFFF; /*to be sure...*/
+}
+/*svg style, MUST BE A SINGLE SELECTOR. FOR INSTANCE, THIS DOES NOT WORK WHEN SVG IS NOT SUPPORTED:
+ ".ts-player .ts-ruler .ts-svg-ruler-lines"*/
+.ts-svg-ruler-lines{
+ stroke-width:1;
+ stroke: #ADADAD;
+}
+
+/*wave:*/
+.ts-player .ts-wave {
+ height: 130px;
+}
+
+/*.ts-player .ts-viewer .ts-marker {*/
+.ts-player .ts-ruler .ts-marker {
+ padding: 0 0.5em;
+ background: #fff;
+ border: 1px solid #92bdd4;
+ color: #92bdd4;
+ text-decoration: none;
+}
+/*svg style, MUST BE A SINGLE SELECTOR. FOR INSTANCE, THIS DOES NOT WORK WHEN SVG IS NOT SUPPORTED:
+ ".ts-player .ts-wave .ts-image-canvas .ts-svg-marker-line" */
+.ts-svg-marker-line {
+ fill: #92bdd4;
+ stroke-width:0;
+}
+
+/*.ts-player .ts-viewer a.ts-pointer {*/
+.ts-player .ts-ruler a.ts-pointer {
+ color: white ;
+ background-color: #92bde4;
+ padding: 0 0.5em;
+ /*border: solid 1px #92bde4;*/
+
+ text-decoration: none;
+ -moz-border-radius: .3em;
+ -webkit-border-radius: .3em;
+ border-radius: .3em;
+ /*color: #3c4251; #6A0307 !important;*/
+}
+/*svg style, MUST BE A SINGLE SELECTOR. FOR INSTANCE, THIS DOES NOT WORK WHEN SVG IS NOT SUPPORTED:
+ ".ts-player .ts-wave .ts-image-canvas .ts-svg-pointer-line" */
+.ts-svg-pointer-line {
+ fill: #92bde4;
+ stroke-width:0;
+}
+
+.ts-player .ts-wave .ts-image {
+ background: #090e0d ;
+}
+
+.ts-player .ts-control {
+ background: url('img/player_controlbg.png');
+}
+
+ /** display (inline-block) and overflow of a is set inside javascript*/
+.ts-player .ts-control .ts-button {
+ background-repeat: no-repeat;
+ margin:4px;
+ height:21px;
+ width:21px;
+ /* background-position: 0px 0px;*/
+}
+.ts-player .ts-control .ts-button:hover {
+ background-position: 0px -21px;
+}
+.ts-player .ts-control .ts-play {
+ background-image: url('img/play.png');
+}
+
+.ts-player .ts-control .ts-pause {
+ background-image: url('img/pause.png');
+}
+
+.ts-player .ts-control .ts-rewind {
+ background-image: url('img/rewind.png');
+}
+
+.ts-player .ts-control .ts-forward {
+ background-image: url('img/forward.png');
+}
+
+.ts-player .ts-control .ts-set-marker {
+ background-image: url('img/setmarker.png');
+}
+
+.ts-player .ts-control .ts-volume-speaker-on {
+ background-image: url('img/volumeon.png');
+ width:24px;
+}
+.ts-player .ts-control .ts-volume-speaker-off {
+ background-image: url('img/volumeoff.png');
+ width:24px;
+}
+.ts-player .ts-control .ts-volume-bar-container {
+ /*background: url('img/controlbg-inverted.png');
+ background-position: -3px left;
+ background-repeat: repeat-x;*/
+ border: 1px solid #a3a4a7;
+ height:10px;
+ width:42px;
+ margin-top:9px;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+
+}
+.ts-player .ts-control .ts-volume-bar { /*width will be changed inside the code*/
+ background-color: #ccc;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+}
+/*position is set to absolute inside javascript*/
+.ts-player .ts-control .ts-wait {
+ background-repeat: no-repeat;
+ background-image: url('img/wait.gif');
+ text-align: right;
+ right:0;
+ height:28px;
+ line-height:28px;
+ top:0;
+ background-position: right center;
+ padding-right: 30px;
+ font-size: 80%;
+ color: #000;
+}
--- /dev/null
+/*
+* Style for the timeside player. The player div is supposed to be of class .ts-player. Change if needed
+* For details, see http://code.google.com/p/timeside/wiki/UiGuide?ts=1308677096&updated=UiGuide#CSS_and_skins
+*/
+
+.ts-player {
+ padding: 0;
+ border: solid 1px #ADADAD;
+ margin-top: 2px;
+}
+
+
+.ts-player .ts-ruler{
+ color: white;
+ background-color: #2E2E2E;
+ font-size: 10px;
+ line-height: 13px;
+}
+/*svg style, MUST BE A SINGLE SELECTOR. FOR INSTANCE, THIS DOES NOT WORK WHEN SVG IS NOT SUPPORTED:
+ ".ts-player .ts-ruler .ts-svg-ruler-upper-rect" */
+.ts-svg-ruler-upper-rect{
+ fill: #595959;
+ stroke-width:0;
+ stroke: #595959; /*to be sure...*/
+}
+/*svg style, MUST BE A SINGLE SELECTOR. FOR INSTANCE, THIS DOES NOT WORK WHEN SVG IS NOT SUPPORTED:
+ ".ts-player .ts-ruler .ts-svg-ruler-lines"*/
+.ts-svg-ruler-lines{
+ stroke-width:1;
+ stroke: #ADADAD;
+}
+
+/*wave:*/
+.ts-player .ts-wave {
+ height: 130px;
+}
+
+/*.ts-player .ts-viewer .ts-marker {*/
+.ts-player .ts-ruler .ts-marker {
+ padding: 0 0.5em;
+ background: #e65911;
+ color: #FFF;
+ text-decoration: none;
+}
+/*svg style, MUST BE A SINGLE SELECTOR. FOR INSTANCE, THIS DOES NOT WORK WHEN SVG IS NOT SUPPORTED:
+ ".ts-player .ts-wave .ts-image-canvas .ts-svg-marker-line" */
+.ts-svg-marker-line {
+ fill: #e65911;
+ stroke-width:0;
+}
+
+/*.ts-player .ts-viewer a.ts-pointer {*/
+.ts-player .ts-ruler a.ts-pointer {
+ color: #BB0000;
+ background-color: white;
+ padding: 0 0.5em;
+ border: solid 1px #BB0000;
+
+ text-decoration: none;
+ -moz-border-radius: .3em;
+ -webkit-border-radius: .3em;
+ border-radius: .3em;
+ /*color: #3c4251; #6A0307 !important;*/
+}
+/*svg style, MUST BE A SINGLE SELECTOR. FOR INSTANCE, THIS DOES NOT WORK WHEN SVG IS NOT SUPPORTED:
+ ".ts-player .ts-wave .ts-image-canvas .ts-svg-pointer-line" */
+.ts-svg-pointer-line {
+ fill: #BB0000;
+ stroke-width:0;
+}
+
+.ts-player .ts-wave .ts-image {
+ background: #090e0d ;
+}
+
+.ts-player .ts-control {
+ background: url('img/controlbg.png');
+}
+
+ /** display (inline-block) and overflow of a is set inside javascript*/
+.ts-player .ts-control .ts-button {
+ background-repeat: no-repeat;
+ height:28px;
+ width:28px;
+}
+.ts-player .ts-control .ts-play {
+ background-image: url('img/play.png');
+}
+
+.ts-player .ts-control .ts-pause {
+ background-image: url('img/pause.png');
+}
+
+.ts-player .ts-control .ts-rewind {
+ background-image: url('img/rewind.png');
+}
+
+.ts-player .ts-control .ts-forward {
+ background-image: url('img/forward.png');
+}
+
+.ts-player .ts-control .ts-set-marker {
+ background-image: url('img/setmarker.png');
+}
+
+.ts-player .ts-control .ts-volume-speaker-on {
+ background-image: url('img/volumeon.png');
+ width:24px;
+}
+.ts-player .ts-control .ts-volume-speaker-off {
+ background-image: url('img/volumeoff.png');
+ width:24px;
+}
+.ts-player .ts-control .ts-volume-bar-container {
+ background: url('img/controlbg-inverted.png');
+ background-position: -3px left;
+ background-repeat: repeat-x;
+ height:10px;
+ width:42px;
+ margin-top:9px;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+
+}
+.ts-player .ts-control .ts-volume-bar { /*width will be changed inside the code*/
+ background-color: #e4eaf1;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+}
+/*position is set to absolute inside javascript*/
+.ts-player .ts-control .ts-wait {
+ background-repeat: no-repeat;
+ background-image: url('img/wait3.gif');
+ text-align: right;
+ right:0;
+ height:28px;
+ line-height:28px;
+ top:0;
+ background-position: right center;
+ padding-right: 60px;
+ font-size: 80%;
+ color:white;
+}
\ No newline at end of file
--- /dev/null
+/*
+VideoJS Default Styles (http://videojs.com)
+Version GENERATED_AT_BUILD
+*/
+
+/*
+REQUIRED STYLES (be careful overriding)
+================================================================================ */
+/* When loading the player, the video tag is replaced with a DIV,
+ that will hold the video tag or object tag for other playback methods.
+ The div contains the video playback element (Flash or HTML5) and controls, and sets the width and height of the video.
+
+ ** If you want to add some kind of border/padding (e.g. a frame), or special positioning, use another containing element.
+ Otherwise you risk messing up control positioning and full window mode. **
+*/
+.video-js {
+ background-color: #000; position: relative; padding: 0;
+
+ /* Start with 10px for base font size so other dimensions can be em based and easily calculable. */
+ font-size: 10px;
+
+ /* Allow poster to be vertially aligned. */
+ vertical-align: middle;
+ /* display: table-cell; */ /*This works in Safari but not Firefox.*/
+}
+
+/* Playback technology elements expand to the width/height of the containing div. <video> or <object> */
+.video-js .vjs-tech { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
+
+/* Fix for Firefox 9 fullscreen (only if it is enabled). Not needed when checking fullScreenEnabled. */
+.video-js:-moz-full-screen { position: absolute; }
+
+/* Fullscreen Styles */
+body.vjs-full-window {
+ padding: 0; margin: 0;
+ height: 100%; overflow-y: auto; /* Fix for IE6 full-window. http://www.cssplay.co.uk/layouts/fixed.html */
+}
+.video-js.vjs-fullscreen {
+ position: fixed; overflow: hidden; z-index: 1000; left: 0; top: 0; bottom: 0; right: 0; width: 100% !important; height: 100% !important;
+ _position: absolute; /* IE6 Full-window (underscore hack) */
+}
+.video-js:-webkit-full-screen {
+ width: 100% !important; height: 100% !important;
+}
+
+/* Poster Styles */
+.vjs-poster {
+ margin: 0 auto; padding: 0; cursor: pointer;
+
+ /* Scale with the size of the player div. Works when poster is vertically shorter, but stretches when it's less wide. */
+ position: relative; width: 100%; max-height: 100%;
+}
+
+/* Text Track Styles */
+/* Overall track holder for both captions and subtitles */
+.video-js .vjs-text-track-display { text-align: center; position: absolute; bottom: 4em; left: 1em; right: 1em; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; }
+/* Individual tracks */
+.video-js .vjs-text-track {
+ display: none; color: #fff; font-size: 1.4em; text-align: center; margin-bottom: 0.1em;
+ /* Transparent black background, or fallback to all black (IE6) */
+ background: rgb(0, 0, 0); background: rgba(0, 0, 0, 0.50);
+}
+.video-js .vjs-subtitles { color: #fff; }
+.video-js .vjs-captions { color: #fc6; }
+.vjs-tt-cue { display: block; }
+
+/* Fading sytles, used to fade control bar. */
+.vjs-fade-in {
+ visibility: visible !important; /* Needed to make sure things hide in older browsers too. */
+ opacity: 1 !important;
+
+ -webkit-transition: visibility 0s linear 0s, opacity 0.3s linear;
+ -moz-transition: visibility 0s linear 0s, opacity 0.3s linear;
+ -ms-transition: visibility 0s linear 0s, opacity 0.3s linear;
+ -o-transition: visibility 0s linear 0s, opacity 0.3s linear;
+ transition: visibility 0s linear 0s, opacity 0.3s linear;
+}
+.vjs-fade-out {
+ visibility: hidden !important;
+ opacity: 0 !important;
+
+ -webkit-transition: visibility 0s linear 1.5s,opacity 1.5s linear;
+ -moz-transition: visibility 0s linear 1.5s,opacity 1.5s linear;
+ -ms-transition: visibility 0s linear 1.5s,opacity 1.5s linear;
+ -o-transition: visibility 0s linear 1.5s,opacity 1.5s linear;
+ transition: visibility 0s linear 1.5s,opacity 1.5s linear;
+}
+
+/* DEFAULT SKIN (override in another file to create new skins)
+================================================================================
+Instead of editing this file, I recommend creating your own skin CSS file to be included after this file,
+so you can upgrade to newer versions easier. You can remove all these styles by removing the 'vjs-default-skin' class from the tag. */
+
+/* The default control bar. Created by bar.js */
+.vjs-default-skin .vjs-controls {
+ position: absolute;
+ bottom: 0; /* Distance from the bottom of the box/video. Keep 0. Use height to add more bottom margin. */
+ left: 0; right: 0; /* 100% width of div */
+ margin: 0; padding: 0; /* Controls are absolutely position, so no padding necessary */
+ height: 2.6em; /* Including any margin you want above or below control items */
+ color: #fff; border-top: 1px solid #404040;
+
+ /* CSS Gradient */
+ /* Can use the Ultimate CSS Gradient Generator: http://www.colorzilla.com/gradient-editor/ */
+ background: #242424; /* Old browsers */
+ background: -moz-linear-gradient(top, #242424 50%, #1f1f1f 50%, #171717 100%); /* FF3.6+ */
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(50%,#242424), color-stop(50%,#1f1f1f), color-stop(100%,#171717)); /* Chrome,Safari4+ */
+ background: -webkit-linear-gradient(top, #242424 50%,#1f1f1f 50%,#171717 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #242424 50%,#1f1f1f 50%,#171717 100%); /* Opera11.10+ */
+ background: -ms-linear-gradient(top, #242424 50%,#1f1f1f 50%,#171717 100%); /* IE10+ */
+ /* Filter was causing a lot of weird issues in IE. Elements would stop showing up, or other styles would break. */
+ /*filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#242424', endColorstr='#171717',GradientType=0 );*/ /* IE6-9 */
+ background: linear-gradient(top, #242424 50%,#1f1f1f 50%,#171717 100%); /* W3C */
+
+ /* Start hidden and with 0 opacity. Opacity is used to fade in modern browsers. */
+ /* Can't use display block to hide initially because widths of slider handles aren't calculated and avaialbe for positioning correctly. */
+ visibility: hidden;
+ opacity: 0;
+}
+
+/* General styles for individual controls. */
+.vjs-default-skin .vjs-control {
+ position: relative; float: left;
+ text-align: center; margin: 0; padding: 0;
+ height: 2.6em; width: 2.6em;
+}
+
+.vjs-default-skin .vjs-control:focus {
+ outline: 0;
+/* background-color: #555;*/
+}
+
+/* Hide control text visually, but have it available for screenreaders: h5bp.com/v */
+.vjs-default-skin .vjs-control-text { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
+
+
+/* Play/Pause
+-------------------------------------------------------------------------------- */
+.vjs-default-skin .vjs-play-control { width: 5em; cursor: pointer !important; }
+/* Play Icon */
+.vjs-default-skin.vjs-paused .vjs-play-control div { width: 15px; height: 17px; background: url('video-js.png'); margin: 0.5em auto 0; }
+.vjs-default-skin.vjs-playing .vjs-play-control div { width: 15px; height: 17px; background: url('video-js.png') -25px 0; margin: 0.5em auto 0; }
+
+/* Rewind
+-------------------------------------------------------------------------------- */
+.vjs-default-skin .vjs-rewind-control { width: 5em; cursor: pointer !important; }
+.vjs-default-skin .vjs-rewind-control div { width: 19px; height: 16px; background: url('video-js.png'); margin: 0.5em auto 0; }
+
+/* Volume/Mute
+-------------------------------------------------------------------------------- */
+.vjs-default-skin .vjs-mute-control { width: 3.8em; cursor: pointer !important; float: right; }
+.vjs-default-skin .vjs-mute-control div { width: 22px; height: 16px; background: url('video-js.png') -75px -25px; margin: 0.5em auto 0; }
+.vjs-default-skin .vjs-mute-control.vjs-vol-0 div { background: url('video-js.png') 0 -25px; }
+.vjs-default-skin .vjs-mute-control.vjs-vol-1 div { background: url('video-js.png') -25px -25px; }
+.vjs-default-skin .vjs-mute-control.vjs-vol-2 div { background: url('video-js.png') -50px -25px; }
+
+
+.vjs-default-skin .vjs-volume-control { width: 5em; float: right; }
+.vjs-default-skin .vjs-volume-bar {
+ position: relative; width: 5em; height: 0.6em; margin: 1em auto 0; cursor: pointer !important;
+
+ -moz-border-radius: 0.3em; -webkit-border-radius: 0.3em; border-radius: 0.3em;
+
+ background: #666;
+ background: -moz-linear-gradient(top, #333, #666);
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#333), to(#666));
+ background: -webkit-linear-gradient(top, #333, #666);
+ background: -o-linear-gradient(top, #333, #666);
+ background: -ms-linear-gradient(top, #333, #666);
+ background: linear-gradient(top, #333, #666);
+}
+.vjs-default-skin .vjs-volume-level {
+ position: absolute; top: 0; left: 0; height: 0.6em;
+
+ -moz-border-radius: 0.3em; -webkit-border-radius: 0.3em; border-radius: 0.3em;
+
+ background: #fff;
+ background: -moz-linear-gradient(top, #fff, #ccc);
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#fff), to(#ccc));
+ background: -webkit-linear-gradient(top, #fff, #ccc);
+ background: -o-linear-gradient(top, #fff, #ccc);
+ background: -ms-linear-gradient(top, #fff, #ccc);
+ background: linear-gradient(top, #fff, #ccc);
+}
+.vjs-default-skin .vjs-volume-handle {
+ position: absolute; top: -0.2em; width: 0.8em; height: 0.8em; background: #ccc; left: 0;
+ border: 1px solid #fff;
+ -moz-border-radius: 0.6em; -webkit-border-radius: 0.6em; border-radius: 0.6em;
+}
+
+/* Progress
+-------------------------------------------------------------------------------- */
+.vjs-default-skin div.vjs-progress-control {
+ position: absolute;
+ left: 4.8em; right: 4.8em; /* Leave room for time displays. */
+ height: 1.0em; width: auto;
+ top: -1.3em; /* Set above the rest of the controls. And leave room for 2px of borders (progress bottom and controls top). */
+ border-bottom: 1px solid #1F1F1F;
+ border-top: 1px solid #222;
+
+ /* CSS Gradient */
+ background: #333;
+ background: -moz-linear-gradient(top, #222, #333);
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#222), to(#333));
+ background: -webkit-linear-gradient(top, #222, #333);
+ background: -o-linear-gradient(top, #333, #222);
+ background: -ms-linear-gradient(top, #333, #222);
+ background: linear-gradient(top, #333, #222);
+
+
+ /* 1px top shadow */
+/* -webkit-box-shadow: 0px -1px 0px 0px rgba(0, 0, 0, 0.15); -moz-box-shadow: 0px -1px 0px 0px rgba(0, 0, 0, 0.15); box-shadow: 0px -1px 0px 0px rgba(0, 0, 0, 0.15);*/
+}
+
+/* Box containing play and load progresses. Also acts as seek scrubber. */
+.vjs-default-skin .vjs-progress-holder {
+ position: relative; cursor: pointer !important; /*overflow: hidden;*/
+ padding: 0; margin: 0; /* Placement within the progress control item */
+ height: 1.0em;
+ -moz-border-radius: 0.6em; -webkit-border-radius: 0.6em; border-radius: 0.6em;
+
+ /* CSS Gradient */
+ background: #111;
+ background: -moz-linear-gradient(top, #111, #262626);
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#111), to(#262626));
+ background: -webkit-linear-gradient(top, #111, #262626);
+ background: -o-linear-gradient(top, #111, #262626);
+ background: -ms-linear-gradient(top, #111, #262626);
+ background: linear-gradient(top, #111, #262626);
+}
+.vjs-default-skin .vjs-progress-holder .vjs-play-progress,
+.vjs-default-skin .vjs-progress-holder .vjs-load-progress { /* Progress Bars */
+ position: absolute; display: block; height: 1.0em; margin: 0; padding: 0;
+ left: 0; top: 0; /*Needed for IE6*/
+ -moz-border-radius: 0.6em; -webkit-border-radius: 0.6em; border-radius: 0.6em;
+
+ /*width: 0;*/
+}
+
+.vjs-default-skin .vjs-play-progress {
+ /* CSS Gradient. */
+ background: #fff; /* Old browsers */
+ background: -moz-linear-gradient(top, #fff 0%, #d6d6d6 50%, #fff 100%);
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%,#fff), color-stop(50%,#d6d6d6), color-stop(100%,#fff));
+ background: -webkit-linear-gradient(top, #fff 0%,#d6d6d6 50%,#fff 100%);
+ background: -o-linear-gradient(top, #fff 0%,#d6d6d6 50%,#fff 100%);
+ background: -ms-linear-gradient(top, #fff 0%,#d6d6d6 50%,#fff 100%);
+ background: linear-gradient(top, #fff 0%,#d6d6d6 50%,#fff 100%);
+
+ background: #efefef;
+ background: -moz-linear-gradient(top, #efefef 0%, #f5f5f5 50%, #dbdbdb 50%, #f1f1f1 100%);
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%,#efefef), color-stop(50%,#f5f5f5), color-stop(50%,#dbdbdb), color-stop(100%,#f1f1f1));
+ background: -webkit-linear-gradient(top, #efefef 0%,#f5f5f5 50%,#dbdbdb 50%,#f1f1f1 100%);
+ background: -o-linear-gradient(top, #efefef 0%,#f5f5f5 50%,#dbdbdb 50%,#f1f1f1 100%);
+ background: -ms-linear-gradient(top, #efefef 0%,#f5f5f5 50%,#dbdbdb 50%,#f1f1f1 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#efefef', endColorstr='#f1f1f1',GradientType=0 );
+ background: linear-gradient(top, #efefef 0%,#f5f5f5 50%,#dbdbdb 50%,#f1f1f1 100%);
+}
+.vjs-default-skin .vjs-load-progress {
+ opacity: 0.8;
+
+ /* CSS Gradient */
+ background: #666;
+ background: -moz-linear-gradient(top, #666, #333);
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#666), to(#333));
+ background: -webkit-linear-gradient(top, #666, #333);
+ background: -o-linear-gradient(top, #666, #333);
+ background: -ms-linear-gradient(top, #666, #333);
+ background: linear-gradient(top, #666, #333);
+}
+
+.vjs-default-skin div.vjs-seek-handle {
+ position: absolute;
+ width: 16px; height: 16px; /* Match img pixles */
+ margin-top: -0.3em;
+ left: 0; top: 0; /*Needed for IE6*/
+
+ background: url('video-js.png') 0 -50px;
+ /* CSS Curved Corners. Needed to make shadows curved. */
+ -moz-border-radius: 0.8em; -webkit-border-radius: 0.8em; border-radius: 0.8em;
+ /* CSS Shadows */
+ -webkit-box-shadow: 0 2px 4px 0 #000; -moz-box-shadow: 0 2px 4px 0 #000; box-shadow: 0 2px 4px 0 #000;
+}
+/* Time Display
+-------------------------------------------------------------------------------- */
+.vjs-default-skin .vjs-time-controls {
+ position: absolute;
+ right: 0;
+ height: 1.0em; width: 4.8em;
+ top: -1.3em;
+ border-bottom: 1px solid #1F1F1F;
+ border-top: 1px solid #222;
+ background-color: #333;
+
+ font-size: 1em; line-height: 1.0em; font-weight: normal; font-family: Helvetica, Arial, sans-serif;
+
+ background: #333;
+ background: -moz-linear-gradient(top, #222, #333);
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#222), to(#333));
+ background: -webkit-linear-gradient(top, #222, #333);
+ background: -o-linear-gradient(top, #333, #222);
+ background: -ms-linear-gradient(top, #333, #222);
+ background: linear-gradient(top, #333, #222);
+
+ /* 1px top shadow */
+/* -webkit-box-shadow: 0px -1px 0px 0px rgba(0, 0, 0, 0.15); -moz-box-shadow: 0px -1px 0px 0px rgba(0, 0, 0, 0.15); box-shadow: 0px -1px 0px 0px rgba(0, 0, 0, 0.15);*/
+}
+
+.vjs-default-skin .vjs-current-time { left: 0; }
+
+.vjs-default-skin .vjs-duration { right: 0; display: none; }
+.vjs-default-skin .vjs-remaining-time { right: 0; }
+
+.vjs-time-divider { display:none; }
+
+.vjs-default-skin .vjs-time-control { font-size: 1em; line-height: 1; font-weight: normal; font-family: Helvetica, Arial, sans-serif; }
+.vjs-default-skin .vjs-time-control span { line-height: 25px; /* Centering vertically */ }
+
+/* Fullscreen
+-------------------------------------------------------------------------------- */
+.vjs-secondary-controls { float: right; }
+
+.vjs-default-skin .vjs-fullscreen-control { width: 3.8em; cursor: pointer !important; float: right; }
+.vjs-default-skin .vjs-fullscreen-control div { width: 16px; height: 16px; background: url('video-js.png') -50px 0; margin: 0.5em auto 0; }
+
+.vjs-default-skin.vjs-fullscreen .vjs-fullscreen-control div { background: url('video-js.png') -75px 0; }
+
+
+/* Big Play Button (at start)
+---------------------------------------------------------*/
+.vjs-default-skin .vjs-big-play-button {
+ display: block; /* Start hidden */ z-index: 2;
+ position: absolute; top: 50%; left: 50%; width: 8.0em; height: 8.0em; margin: -42px 0 0 -42px; text-align: center; vertical-align: center; cursor: pointer !important;
+ border: 0.2em solid #fff; opacity: 0.95;
+ -webkit-border-radius: 25px; -moz-border-radius: 25px; border-radius: 25px;
+
+ background: #454545;
+ background: -moz-linear-gradient(top, #454545 0%, #232323 50%, #161616 50%, #3f3f3f 100%);
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%,#454545), color-stop(50%,#232323), color-stop(50%,#161616), color-stop(100%,#3f3f3f));
+ background: -webkit-linear-gradient(top, #454545 0%,#232323 50%,#161616 50%,#3f3f3f 100%);
+ background: -o-linear-gradient(top, #454545 0%,#232323 50%,#161616 50%,#3f3f3f 100%);
+ background: -ms-linear-gradient(top, #454545 0%,#232323 50%,#161616 50%,#3f3f3f 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#454545', endColorstr='#3f3f3f',GradientType=0 );
+ background: linear-gradient(top, #454545 0%,#232323 50%,#161616 50%,#3f3f3f 100%);
+
+ /* CSS Shadows */
+ -webkit-box-shadow: 4px 4px 8px #000; -moz-box-shadow: 4px 4px 8px #000; box-shadow: 4px 4px 8px #000;
+}
+
+.vjs-default-skin div.vjs-big-play-button:hover {
+ -webkit-box-shadow: 0 0 80px #fff; -moz-box-shadow: 0 0 80px #fff; box-shadow: 0 0 80px #fff;
+}
+
+.vjs-default-skin div.vjs-big-play-button span {
+ position: absolute; top: 50%; left: 50%;
+ display: block; width: 35px; height: 42px;
+ margin: -20px 0 0 -15px; /* Using negative margin to center image. */
+ background: url('video-js.png') -100px 0;
+}
+
+/* Loading Spinner
+---------------------------------------------------------*/
+/* CSS Spinners by Kilian Valkhof - http://kilianvalkhof.com/2010/css-xhtml/css3-loading-spinners-without-images/ */
+.vjs-loading-spinner {
+ display: none;
+ position: absolute; top: 50%; left: 50%; width: 55px; height: 55px;
+ margin: -28px 0 0 -28px;
+ -webkit-animation-name: rotatethis;
+ -webkit-animation-duration:1s;
+ -webkit-animation-iteration-count:infinite;
+ -webkit-animation-timing-function:linear;
+ -moz-animation-name: rotatethis;
+ -moz-animation-duration:1s;
+ -moz-animation-iteration-count:infinite;
+ -moz-animation-timing-function:linear;
+}
+
+@-webkit-keyframes rotatethis {
+ 0% {-webkit-transform:scale(0.6) rotate(0deg); }
+ 12.5% {-webkit-transform:scale(0.6) rotate(0deg); }
+ 12.51% {-webkit-transform:scale(0.6) rotate(45deg); }
+ 25% {-webkit-transform:scale(0.6) rotate(45deg); }
+ 25.01% {-webkit-transform:scale(0.6) rotate(90deg);}
+ 37.5% {-webkit-transform:scale(0.6) rotate(90deg);}
+ 37.51% {-webkit-transform:scale(0.6) rotate(135deg);}
+ 50% {-webkit-transform:scale(0.6) rotate(135deg);}
+ 50.01% {-webkit-transform:scale(0.6) rotate(180deg);}
+ 62.5% {-webkit-transform:scale(0.6) rotate(180deg);}
+ 62.51% {-webkit-transform:scale(0.6) rotate(225deg);}
+ 75% {-webkit-transform:scale(0.6) rotate(225deg);}
+ 75.01% {-webkit-transform:scale(0.6) rotate(270deg);}
+ 87.5% {-webkit-transform:scale(0.6) rotate(270deg);}
+ 87.51% {-webkit-transform:scale(0.6) rotate(315deg);}
+ 100% {-webkit-transform:scale(0.6) rotate(315deg);}
+}
+
+@-moz-keyframes rotatethis {
+ 0% {-moz-transform:scale(0.6) rotate(0deg);}
+ 12.5% {-moz-transform:scale(0.6) rotate(0deg);}
+ 12.51% {-moz-transform:scale(0.6) rotate(45deg);}
+ 25% {-moz-transform:scale(0.6) rotate(45deg);}
+ 25.01% {-moz-transform:scale(0.6) rotate(90deg);}
+ 37.5% {-moz-transform:scale(0.6) rotate(90deg);}
+ 37.51% {-moz-transform:scale(0.6) rotate(135deg);}
+ 50% {-moz-transform:scale(0.6) rotate(135deg);}
+ 50.01% {-moz-transform:scale(0.6) rotate(180deg);}
+ 62.5% {-moz-transform:scale(0.6) rotate(180deg);}
+ 62.51% {-moz-transform:scale(0.6) rotate(225deg);}
+ 75% {-moz-transform:scale(0.6) rotate(225deg);}
+ 75.01% {-moz-transform:scale(0.6) rotate(270deg);}
+ 87.5% {-moz-transform:scale(0.6) rotate(270deg);}
+ 87.51% {-moz-transform:scale(0.6) rotate(315deg);}
+ 100% {-moz-transform:scale(0.6) rotate(315deg);}
+}
+/* Each circle */
+div.vjs-loading-spinner .ball1 { opacity: 0.12; position:absolute; left: 20px; top: 0px; width: 13px; height: 13px; background: #fff;
+ border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
+
+div.vjs-loading-spinner .ball2 { opacity: 0.25; position:absolute; left: 34px; top: 6px; width: 13px; height: 13px; background: #fff;
+ border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
+
+div.vjs-loading-spinner .ball3 { opacity: 0.37; position:absolute; left: 40px; top: 20px; width: 13px; height: 13px; background: #fff;
+ border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
+
+div.vjs-loading-spinner .ball4 { opacity: 0.50; position:absolute; left: 34px; top: 34px; width: 13px; height: 13px; background: #fff;
+ border-radius: 10px; -webkit-border-radius: 10px; -moz-border-radius: 15px; border: 1px solid #ccc; }
+
+div.vjs-loading-spinner .ball5 { opacity: 0.62; position:absolute; left: 20px; top: 40px; width: 13px; height: 13px; background: #fff;
+ border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
+
+div.vjs-loading-spinner .ball6 { opacity: 0.75; position:absolute; left: 6px; top: 34px; width: 13px; height: 13px; background: #fff;
+ border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
+
+div.vjs-loading-spinner .ball7 { opacity: 0.87; position:absolute; left: 0px; top: 20px; width: 13px; height: 13px; background: #fff;
+ border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
+
+div.vjs-loading-spinner .ball8 { opacity: 1.00; position:absolute; left: 6px; top: 6px; width: 13px; height: 13px; background: #fff;
+ border-radius: 13px; -webkit-border-radius: 13px; -moz-border-radius: 13px; border: 1px solid #ccc; }
+
+/* Menu Buttons (Captions/Subtitles/etc.)
+-------------------------------------------------------------------------------- */
+.vjs-default-skin .vjs-menu-button {
+ float: right; margin: 0.2em 0.5em 0 0; padding: 0; width: 3em; height: 2em; cursor: pointer !important;
+
+ border: 1px solid #111; -moz-border-radius: 0.3em; -webkit-border-radius: 0.3em; border-radius: 0.3em;
+
+ background: #4d4d4d;
+ background: -moz-linear-gradient(top, #4d4d4d 0%, #3f3f3f 50%, #333333 50%, #252525 100%);
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#4d4d4d), color-stop(50%,#3f3f3f), color-stop(50%,#333333), color-stop(100%,#252525));
+ background: -webkit-linear-gradient(top, #4d4d4d 0%,#3f3f3f 50%,#333333 50%,#252525 100%);
+ background: -o-linear-gradient(top, #4d4d4d 0%,#3f3f3f 50%,#333333 50%,#252525 100%);
+ background: -ms-linear-gradient(top, #4d4d4d 0%,#3f3f3f 50%,#333333 50%,#252525 100%);
+ background: linear-gradient(top, #4d4d4d 0%,#3f3f3f 50%,#333333 50%,#252525 100%);
+}
+/* Button Icon */
+.vjs-default-skin .vjs-menu-button div { background: url('video-js.png') 0px -75px no-repeat; width: 16px; height: 16px; margin: 0.2em auto 0; padding: 0; }
+
+/* Button Pop-up Menu */
+.vjs-default-skin .vjs-menu-button ul {
+ display: none; /* Start hidden. Hover will show. */
+ opacity: 0.8;
+ padding: 0; margin: 0;
+ position: absolute; width: 10em; bottom: 2em; max-height: 15em;
+ left: -3.5em; /* Width of menu - width of button / 2 */
+ background-color: #111;
+ border: 2px solid #333;
+ -moz-border-radius: 0.7em; -webkit-border-radius: 1em; border-radius: .5em;
+ -webkit-box-shadow: 0 2px 4px 0 #000; -moz-box-shadow: 0 2px 4px 0 #000; box-shadow: 0 2px 4px 0 #000;
+ overflow: auto;
+}
+
+.vjs-default-skin .vjs-menu-button:focus ul,
+.vjs-default-skin .vjs-menu-button:hover ul { display: block; list-style: none; }
+.vjs-default-skin .vjs-menu-button ul li { list-style: none; margin: 0; padding: 0.3em 0 0.3em 20px; line-height: 1.4em; font-size: 1.2em; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; text-align: left; }
+.vjs-default-skin .vjs-menu-button ul li.vjs-selected { text-decoration: underline; background: url('video-js.png') -125px -50px no-repeat; }
+.vjs-default-skin .vjs-menu-button ul li:focus,
+.vjs-default-skin .vjs-menu-button ul li:hover,
+.vjs-default-skin .vjs-menu-button ul li.vjs-selected:focus,
+.vjs-default-skin .vjs-menu-button ul li.vjs-selected:hover { background-color: #ccc; color: #111; outline: 0; }
+.vjs-default-skin .vjs-menu-button ul li.vjs-menu-title {
+ text-align: center; text-transform: uppercase; font-size: 1em; line-height: 2em; padding: 0; margin: 0 0 0.3em 0;
+
+ color: #fff; font-weight: bold;
+
+ cursor: default;
+
+ background: #4d4d4d;
+ background: -moz-linear-gradient(top, #4d4d4d 0%, #3f3f3f 50%, #333333 50%, #252525 100%);
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#4d4d4d), color-stop(50%,#3f3f3f), color-stop(50%,#333333), color-stop(100%,#252525));
+ background: -webkit-linear-gradient(top, #4d4d4d 0%,#3f3f3f 50%,#333333 50%,#252525 100%);
+ background: -o-linear-gradient(top, #4d4d4d 0%,#3f3f3f 50%,#333333 50%,#252525 100%);
+ background: -ms-linear-gradient(top, #4d4d4d 0%,#3f3f3f 50%,#333333 50%,#252525 100%);
+ background: linear-gradient(top, #4d4d4d 0%,#3f3f3f 50%,#333333 50%,#252525 100%);
+}
+
+/* Subtitles Button */
+.vjs-default-skin .vjs-captions-button div { background-position: -25px -75px; }
+.vjs-default-skin .vjs-chapters-button div { background-position: -100px -75px; }
+.vjs-default-skin .vjs-chapters-button ul { width: 20em; left: -8.5em; /* Width of menu - width of button / 2 */ }
\ No newline at end of file
--- /dev/null
+.video-js{background-color:#000;position:relative;padding:0;font-size:10px;vertical-align:middle}.video-js .vjs-tech{position:absolute;top:0;left:0;width:100%;height:100%}.video-js:-moz-full-screen{position:absolute}body.vjs-full-window{padding:0;margin:0;height:100%;overflow-y:auto}.video-js.vjs-fullscreen{position:fixed;overflow:hidden;z-index:1000;left:0;top:0;bottom:0;right:0;width:100%!important;height:100%!important;_position:absolute}.video-js:-webkit-full-screen{width:100%!important;height:100%!important}.vjs-poster{margin:0 auto;padding:0;cursor:pointer;position:relative;width:100%;max-height:100%}.video-js .vjs-text-track-display{text-align:center;position:absolute;bottom:4em;left:1em;right:1em;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}.video-js .vjs-text-track{display:none;color:#fff;font-size:1.4em;text-align:center;margin-bottom:.1em;background:#000;background:rgba(0,0,0,0.50)}.video-js .vjs-subtitles{color:#fff}.video-js .vjs-captions{color:#fc6}.vjs-tt-cue{display:block}.vjs-fade-in{visibility:visible!important;opacity:1!important;-webkit-transition:visibility 0s linear 0s,opacity .3s linear;-moz-transition:visibility 0s linear 0s,opacity .3s linear;-ms-transition:visibility 0s linear 0s,opacity .3s linear;-o-transition:visibility 0s linear 0s,opacity .3s linear;transition:visibility 0s linear 0s,opacity .3s linear}.vjs-fade-out{visibility:hidden!important;opacity:0!important;-webkit-transition:visibility 0s linear 1.5s,opacity 1.5s linear;-moz-transition:visibility 0s linear 1.5s,opacity 1.5s linear;-ms-transition:visibility 0s linear 1.5s,opacity 1.5s linear;-o-transition:visibility 0s linear 1.5s,opacity 1.5s linear;transition:visibility 0s linear 1.5s,opacity 1.5s linear}.vjs-default-skin .vjs-controls{position:absolute;bottom:0;left:0;right:0;margin:0;padding:0;height:2.6em;color:#fff;border-top:1px solid #404040;background:#242424;background:-moz-linear-gradient(top,#242424 50%,#1f1f1f 50%,#171717 100%);background:-webkit-gradient(linear,0% 0,0% 100%,color-stop(50%,#242424),color-stop(50%,#1f1f1f),color-stop(100%,#171717));background:-webkit-linear-gradient(top,#242424 50%,#1f1f1f 50%,#171717 100%);background:-o-linear-gradient(top,#242424 50%,#1f1f1f 50%,#171717 100%);background:-ms-linear-gradient(top,#242424 50%,#1f1f1f 50%,#171717 100%);background:linear-gradient(top,#242424 50%,#1f1f1f 50%,#171717 100%);visibility:hidden;opacity:0}.vjs-default-skin .vjs-control{position:relative;float:left;text-align:center;margin:0;padding:0;height:2.6em;width:2.6em}.vjs-default-skin .vjs-control:focus{outline:0}.vjs-default-skin .vjs-control-text{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.vjs-default-skin .vjs-play-control{width:5em;cursor:pointer!important}.vjs-default-skin.vjs-paused .vjs-play-control div{width:15px;height:17px;background:url('video-js.png');margin:.5em auto 0}.vjs-default-skin.vjs-playing .vjs-play-control div{width:15px;height:17px;background:url('video-js.png') -25px 0;margin:.5em auto 0}.vjs-default-skin .vjs-rewind-control{width:5em;cursor:pointer!important}.vjs-default-skin .vjs-rewind-control div{width:19px;height:16px;background:url('video-js.png');margin:.5em auto 0}.vjs-default-skin .vjs-mute-control{width:3.8em;cursor:pointer!important;float:right}.vjs-default-skin .vjs-mute-control div{width:22px;height:16px;background:url('video-js.png') -75px -25px;margin:.5em auto 0}.vjs-default-skin .vjs-mute-control.vjs-vol-0 div{background:url('video-js.png') 0 -25px}.vjs-default-skin .vjs-mute-control.vjs-vol-1 div{background:url('video-js.png') -25px -25px}.vjs-default-skin .vjs-mute-control.vjs-vol-2 div{background:url('video-js.png') -50px -25px}.vjs-default-skin .vjs-volume-control{width:5em;float:right}.vjs-default-skin .vjs-volume-bar{position:relative;width:5em;height:.6em;margin:1em auto 0;cursor:pointer!important;-moz-border-radius:.3em;-webkit-border-radius:.3em;border-radius:.3em;background:#666;background:-moz-linear-gradient(top,#333,#666);background:-webkit-gradient(linear,0% 0,0% 100%,from(#333),to(#666));background:-webkit-linear-gradient(top,#333,#666);background:-o-linear-gradient(top,#333,#666);background:-ms-linear-gradient(top,#333,#666);background:linear-gradient(top,#333,#666)}.vjs-default-skin .vjs-volume-level{position:absolute;top:0;left:0;height:.6em;-moz-border-radius:.3em;-webkit-border-radius:.3em;border-radius:.3em;background:#fff;background:-moz-linear-gradient(top,#fff,#ccc);background:-webkit-gradient(linear,0% 0,0% 100%,from(#fff),to(#ccc));background:-webkit-linear-gradient(top,#fff,#ccc);background:-o-linear-gradient(top,#fff,#ccc);background:-ms-linear-gradient(top,#fff,#ccc);background:linear-gradient(top,#fff,#ccc)}.vjs-default-skin .vjs-volume-handle{position:absolute;top:-0.2em;width:.8em;height:.8em;background:#ccc;left:0;border:1px solid #fff;-moz-border-radius:.6em;-webkit-border-radius:.6em;border-radius:.6em}.vjs-default-skin div.vjs-progress-control{position:absolute;left:4.8em;right:4.8em;height:1.0em;width:auto;top:-1.3em;border-bottom:1px solid #1f1f1f;border-top:1px solid #222;background:#333;background:-moz-linear-gradient(top,#222,#333);background:-webkit-gradient(linear,0% 0,0% 100%,from(#222),to(#333));background:-webkit-linear-gradient(top,#222,#333);background:-o-linear-gradient(top,#333,#222);background:-ms-linear-gradient(top,#333,#222);background:linear-gradient(top,#333,#222)}.vjs-default-skin .vjs-progress-holder{position:relative;cursor:pointer!important;padding:0;margin:0;height:1.0em;-moz-border-radius:.6em;-webkit-border-radius:.6em;border-radius:.6em;background:#111;background:-moz-linear-gradient(top,#111,#262626);background:-webkit-gradient(linear,0% 0,0% 100%,from(#111),to(#262626));background:-webkit-linear-gradient(top,#111,#262626);background:-o-linear-gradient(top,#111,#262626);background:-ms-linear-gradient(top,#111,#262626);background:linear-gradient(top,#111,#262626)}.vjs-default-skin .vjs-progress-holder .vjs-play-progress,.vjs-default-skin .vjs-progress-holder .vjs-load-progress{position:absolute;display:block;height:1.0em;margin:0;padding:0;left:0;top:0;-moz-border-radius:.6em;-webkit-border-radius:.6em;border-radius:.6em}.vjs-default-skin .vjs-play-progress{background:#fff;background:-moz-linear-gradient(top,#fff 0,#d6d6d6 50%,#fff 100%);background:-webkit-gradient(linear,0% 0,0% 100%,color-stop(0%,#fff),color-stop(50%,#d6d6d6),color-stop(100%,#fff));background:-webkit-linear-gradient(top,#fff 0,#d6d6d6 50%,#fff 100%);background:-o-linear-gradient(top,#fff 0,#d6d6d6 50%,#fff 100%);background:-ms-linear-gradient(top,#fff 0,#d6d6d6 50%,#fff 100%);background:linear-gradient(top,#fff 0,#d6d6d6 50%,#fff 100%);background:#efefef;background:-moz-linear-gradient(top,#efefef 0,#f5f5f5 50%,#dbdbdb 50%,#f1f1f1 100%);background:-webkit-gradient(linear,0% 0,0% 100%,color-stop(0%,#efefef),color-stop(50%,#f5f5f5),color-stop(50%,#dbdbdb),color-stop(100%,#f1f1f1));background:-webkit-linear-gradient(top,#efefef 0,#f5f5f5 50%,#dbdbdb 50%,#f1f1f1 100%);background:-o-linear-gradient(top,#efefef 0,#f5f5f5 50%,#dbdbdb 50%,#f1f1f1 100%);background:-ms-linear-gradient(top,#efefef 0,#f5f5f5 50%,#dbdbdb 50%,#f1f1f1 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#efefef',endColorstr='#f1f1f1',GradientType=0);background:linear-gradient(top,#efefef 0,#f5f5f5 50%,#dbdbdb 50%,#f1f1f1 100%)}.vjs-default-skin .vjs-load-progress{opacity:.8;background:#666;background:-moz-linear-gradient(top,#666,#333);background:-webkit-gradient(linear,0% 0,0% 100%,from(#666),to(#333));background:-webkit-linear-gradient(top,#666,#333);background:-o-linear-gradient(top,#666,#333);background:-ms-linear-gradient(top,#666,#333);background:linear-gradient(top,#666,#333)}.vjs-default-skin div.vjs-seek-handle{position:absolute;width:16px;height:16px;margin-top:-0.3em;left:0;top:0;background:url('video-js.png') 0 -50px;-moz-border-radius:.8em;-webkit-border-radius:.8em;border-radius:.8em;-webkit-box-shadow:0 2px 4px 0 #000;-moz-box-shadow:0 2px 4px 0 #000;box-shadow:0 2px 4px 0 #000}.vjs-default-skin .vjs-time-controls{position:absolute;right:0;height:1.0em;width:4.8em;top:-1.3em;border-bottom:1px solid #1f1f1f;border-top:1px solid #222;background-color:#333;font-size:1em;line-height:1.0em;font-weight:normal;font-family:Helvetica,Arial,sans-serif;background:#333;background:-moz-linear-gradient(top,#222,#333);background:-webkit-gradient(linear,0% 0,0% 100%,from(#222),to(#333));background:-webkit-linear-gradient(top,#222,#333);background:-o-linear-gradient(top,#333,#222);background:-ms-linear-gradient(top,#333,#222);background:linear-gradient(top,#333,#222)}.vjs-default-skin .vjs-current-time{left:0}.vjs-default-skin .vjs-duration{right:0;display:none}.vjs-default-skin .vjs-remaining-time{right:0}.vjs-time-divider{display:none}.vjs-default-skin .vjs-time-control{font-size:1em;line-height:1;font-weight:normal;font-family:Helvetica,Arial,sans-serif}.vjs-default-skin .vjs-time-control span{line-height:25px}.vjs-secondary-controls{float:right}.vjs-default-skin .vjs-fullscreen-control{width:3.8em;cursor:pointer!important;float:right}.vjs-default-skin .vjs-fullscreen-control div{width:16px;height:16px;background:url('video-js.png') -50px 0;margin:.5em auto 0}.vjs-default-skin.vjs-fullscreen .vjs-fullscreen-control div{background:url('video-js.png') -75px 0}.vjs-default-skin .vjs-big-play-button{display:block;z-index:2;position:absolute;top:50%;left:50%;width:8.0em;height:8.0em;margin:-42px 0 0 -42px;text-align:center;vertical-align:center;cursor:pointer!important;border:.2em solid #fff;opacity:.95;-webkit-border-radius:25px;-moz-border-radius:25px;border-radius:25px;background:#454545;background:-moz-linear-gradient(top,#454545 0,#232323 50%,#161616 50%,#3f3f3f 100%);background:-webkit-gradient(linear,0% 0,0% 100%,color-stop(0%,#454545),color-stop(50%,#232323),color-stop(50%,#161616),color-stop(100%,#3f3f3f));background:-webkit-linear-gradient(top,#454545 0,#232323 50%,#161616 50%,#3f3f3f 100%);background:-o-linear-gradient(top,#454545 0,#232323 50%,#161616 50%,#3f3f3f 100%);background:-ms-linear-gradient(top,#454545 0,#232323 50%,#161616 50%,#3f3f3f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#454545',endColorstr='#3f3f3f',GradientType=0);background:linear-gradient(top,#454545 0,#232323 50%,#161616 50%,#3f3f3f 100%);-webkit-box-shadow:4px 4px 8px #000;-moz-box-shadow:4px 4px 8px #000;box-shadow:4px 4px 8px #000}.vjs-default-skin div.vjs-big-play-button:hover{-webkit-box-shadow:0 0 80px #fff;-moz-box-shadow:0 0 80px #fff;box-shadow:0 0 80px #fff}.vjs-default-skin div.vjs-big-play-button span{position:absolute;top:50%;left:50%;display:block;width:35px;height:42px;margin:-20px 0 0 -15px;background:url('video-js.png') -100px 0}.vjs-loading-spinner{display:none;position:absolute;top:50%;left:50%;width:55px;height:55px;margin:-28px 0 0 -28px;-webkit-animation-name:rotatethis;-webkit-animation-duration:1s;-webkit-animation-iteration-count:infinite;-webkit-animation-timing-function:linear;-moz-animation-name:rotatethis;-moz-animation-duration:1s;-moz-animation-iteration-count:infinite;-moz-animation-timing-function:linear}@-webkit-keyframes rotatethis{0%{-webkit-transform:scale(0.6) rotate(0deg)}12.5%{-webkit-transform:scale(0.6) rotate(0deg)}12.51%{-webkit-transform:scale(0.6) rotate(45deg)}25%{-webkit-transform:scale(0.6) rotate(45deg)}25.01%{-webkit-transform:scale(0.6) rotate(90deg)}37.5%{-webkit-transform:scale(0.6) rotate(90deg)}37.51%{-webkit-transform:scale(0.6) rotate(135deg)}50%{-webkit-transform:scale(0.6) rotate(135deg)}50.01%{-webkit-transform:scale(0.6) rotate(180deg)}62.5%{-webkit-transform:scale(0.6) rotate(180deg)}62.51%{-webkit-transform:scale(0.6) rotate(225deg)}75%{-webkit-transform:scale(0.6) rotate(225deg)}75.01%{-webkit-transform:scale(0.6) rotate(270deg)}87.5%{-webkit-transform:scale(0.6) rotate(270deg)}87.51%{-webkit-transform:scale(0.6) rotate(315deg)}100%{-webkit-transform:scale(0.6) rotate(315deg)}}@-moz-keyframes rotatethis{0%{-moz-transform:scale(0.6) rotate(0deg)}12.5%{-moz-transform:scale(0.6) rotate(0deg)}12.51%{-moz-transform:scale(0.6) rotate(45deg)}25%{-moz-transform:scale(0.6) rotate(45deg)}25.01%{-moz-transform:scale(0.6) rotate(90deg)}37.5%{-moz-transform:scale(0.6) rotate(90deg)}37.51%{-moz-transform:scale(0.6) rotate(135deg)}50%{-moz-transform:scale(0.6) rotate(135deg)}50.01%{-moz-transform:scale(0.6) rotate(180deg)}62.5%{-moz-transform:scale(0.6) rotate(180deg)}62.51%{-moz-transform:scale(0.6) rotate(225deg)}75%{-moz-transform:scale(0.6) rotate(225deg)}75.01%{-moz-transform:scale(0.6) rotate(270deg)}87.5%{-moz-transform:scale(0.6) rotate(270deg)}87.51%{-moz-transform:scale(0.6) rotate(315deg)}100%{-moz-transform:scale(0.6) rotate(315deg)}}div.vjs-loading-spinner .ball1{opacity:.12;position:absolute;left:20px;top:0;width:13px;height:13px;background:#fff;border-radius:13px;-webkit-border-radius:13px;-moz-border-radius:13px;border:1px solid #ccc}div.vjs-loading-spinner .ball2{opacity:.25;position:absolute;left:34px;top:6px;width:13px;height:13px;background:#fff;border-radius:13px;-webkit-border-radius:13px;-moz-border-radius:13px;border:1px solid #ccc}div.vjs-loading-spinner .ball3{opacity:.37;position:absolute;left:40px;top:20px;width:13px;height:13px;background:#fff;border-radius:13px;-webkit-border-radius:13px;-moz-border-radius:13px;border:1px solid #ccc}div.vjs-loading-spinner .ball4{opacity:.50;position:absolute;left:34px;top:34px;width:13px;height:13px;background:#fff;border-radius:10px;-webkit-border-radius:10px;-moz-border-radius:15px;border:1px solid #ccc}div.vjs-loading-spinner .ball5{opacity:.62;position:absolute;left:20px;top:40px;width:13px;height:13px;background:#fff;border-radius:13px;-webkit-border-radius:13px;-moz-border-radius:13px;border:1px solid #ccc}div.vjs-loading-spinner .ball6{opacity:.75;position:absolute;left:6px;top:34px;width:13px;height:13px;background:#fff;border-radius:13px;-webkit-border-radius:13px;-moz-border-radius:13px;border:1px solid #ccc}div.vjs-loading-spinner .ball7{opacity:.87;position:absolute;left:0;top:20px;width:13px;height:13px;background:#fff;border-radius:13px;-webkit-border-radius:13px;-moz-border-radius:13px;border:1px solid #ccc}div.vjs-loading-spinner .ball8{opacity:1.00;position:absolute;left:6px;top:6px;width:13px;height:13px;background:#fff;border-radius:13px;-webkit-border-radius:13px;-moz-border-radius:13px;border:1px solid #ccc}.vjs-default-skin .vjs-menu-button{float:right;margin:.2em .5em 0 0;padding:0;width:3em;height:2em;cursor:pointer!important;border:1px solid #111;-moz-border-radius:.3em;-webkit-border-radius:.3em;border-radius:.3em;background:#4d4d4d;background:-moz-linear-gradient(top,#4d4d4d 0,#3f3f3f 50%,#333 50%,#252525 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#4d4d4d),color-stop(50%,#3f3f3f),color-stop(50%,#333),color-stop(100%,#252525));background:-webkit-linear-gradient(top,#4d4d4d 0,#3f3f3f 50%,#333 50%,#252525 100%);background:-o-linear-gradient(top,#4d4d4d 0,#3f3f3f 50%,#333 50%,#252525 100%);background:-ms-linear-gradient(top,#4d4d4d 0,#3f3f3f 50%,#333 50%,#252525 100%);background:linear-gradient(top,#4d4d4d 0,#3f3f3f 50%,#333 50%,#252525 100%)}.vjs-default-skin .vjs-menu-button div{background:url('video-js.png') 0 -75px no-repeat;width:16px;height:16px;margin:.2em auto 0;padding:0}.vjs-default-skin .vjs-menu-button ul{display:none;opacity:.8;padding:0;margin:0;position:absolute;width:10em;bottom:2em;max-height:15em;left:-3.5em;background-color:#111;border:2px solid #333;-moz-border-radius:.7em;-webkit-border-radius:1em;border-radius:.5em;-webkit-box-shadow:0 2px 4px 0 #000;-moz-box-shadow:0 2px 4px 0 #000;box-shadow:0 2px 4px 0 #000;overflow:auto}.vjs-default-skin .vjs-menu-button:focus ul,.vjs-default-skin .vjs-menu-button:hover ul{display:block;list-style:none}.vjs-default-skin .vjs-menu-button ul li{list-style:none;margin:0;padding:.3em 0 .3em 20px;line-height:1.4em;font-size:1.2em;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;text-align:left}.vjs-default-skin .vjs-menu-button ul li.vjs-selected{text-decoration:underline;background:url('video-js.png') -125px -50px no-repeat}.vjs-default-skin .vjs-menu-button ul li:focus,.vjs-default-skin .vjs-menu-button ul li:hover,.vjs-default-skin .vjs-menu-button ul li.vjs-selected:focus,.vjs-default-skin .vjs-menu-button ul li.vjs-selected:hover{background-color:#ccc;color:#111;outline:0}.vjs-default-skin .vjs-menu-button ul li.vjs-menu-title{text-align:center;text-transform:uppercase;font-size:1em;line-height:2em;padding:0;margin:0 0 .3em 0;color:#fff;font-weight:bold;cursor:default;background:#4d4d4d;background:-moz-linear-gradient(top,#4d4d4d 0,#3f3f3f 50%,#333 50%,#252525 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#4d4d4d),color-stop(50%,#3f3f3f),color-stop(50%,#333),color-stop(100%,#252525));background:-webkit-linear-gradient(top,#4d4d4d 0,#3f3f3f 50%,#333 50%,#252525 100%);background:-o-linear-gradient(top,#4d4d4d 0,#3f3f3f 50%,#333 50%,#252525 100%);background:-ms-linear-gradient(top,#4d4d4d 0,#3f3f3f 50%,#333 50%,#252525 100%);background:linear-gradient(top,#4d4d4d 0,#3f3f3f 50%,#333 50%,#252525 100%)}.vjs-default-skin .vjs-captions-button div{background-position:-25px -75px}.vjs-default-skin .vjs-chapters-button div{background-position:-100px -75px}.vjs-default-skin .vjs-chapters-button ul{width:20em;left:-8.5em}
\ No newline at end of file
--- /dev/null
+/*!
+Video.js - HTML5 Video Player
+Version GENERATED_AT_BUILD
+
+LGPL v3 LICENSE INFO
+This file is part of Video.js. Copyright 2011 Zencoder, Inc.
+
+Video.js is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Video.js is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with Video.js. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+// Self-executing function to prevent global vars and help with minification
+;(function(window, undefined){
+ var document = window.document;// HTML5 Shiv. Must be in <head> to support older browsers.
+document.createElement("video");document.createElement("audio");
+
+var VideoJS = function(id, addOptions, ready){
+ var tag; // Element of ID
+
+ // Allow for element or ID to be passed in
+ // String ID
+ if (typeof id == "string") {
+
+ // Adjust for jQuery ID syntax
+ if (id.indexOf("#") === 0) {
+ id = id.slice(1);
+ }
+
+ // If a player instance has already been created for this ID return it.
+ if (_V_.players[id]) {
+ return _V_.players[id];
+
+ // Otherwise get element for ID
+ } else {
+ tag = _V_.el(id)
+ }
+
+ // ID is a media element
+ } else {
+ tag = id;
+ }
+
+ // Check for a useable element
+ if (!tag || !tag.nodeName) { // re: nodeName, could be a box div also
+ throw new TypeError("The element or ID supplied is not valid. (VideoJS)"); // Returns
+ }
+
+ // Element may have a player attr referring to an already created player instance.
+ // If not, set up a new player and return the instance.
+ return tag.player || new _V_.Player(tag, addOptions, ready);
+},
+
+// Shortcut
+_V_ = VideoJS,
+
+// CDN Version. Used to target right flash swf.
+CDN_VERSION = "GENERATED_CDN_VSN";
+
+VideoJS.players = {};
+
+VideoJS.options = {
+
+ // Default order of fallback technology
+ techOrder: ["html5","flash"],
+ // techOrder: ["flash","html5"],
+
+ html5: {},
+ flash: { swf: "http://vjs.zencdn.net/c/video-js.swf" },
+
+ // Default of web browser is 300x150. Should rely on source width/height.
+ width: 300,
+ height: 150,
+
+ // defaultVolume: 0.85,
+ defaultVolume: 0.00, // The freakin seaguls are driving me crazy!
+
+ // Included control sets
+ components: {
+ "posterImage": {},
+ "textTrackDisplay": {},
+ "loadingSpinner": {},
+ "bigPlayButton": {},
+ "controlBar": {}
+ }
+
+ // components: [
+ // "poster",
+ // "loadingSpinner",
+ // "bigPlayButton",
+ // { name: "controlBar", options: {
+ // components: [
+ // "playToggle",
+ // "fullscreenToggle",
+ // "currentTimeDisplay",
+ // "timeDivider",
+ // "durationDisplay",
+ // "remainingTimeDisplay",
+ // { name: "progressControl", options: {
+ // components: [
+ // { name: "seekBar", options: {
+ // components: [
+ // "loadProgressBar",
+ // "playProgressBar",
+ // "seekHandle"
+ // ]}
+ // }
+ // ]}
+ // },
+ // { name: "volumeControl", options: {
+ // components: [
+ // { name: "volumeBar", options: {
+ // components: [
+ // "volumeLevel",
+ // "volumeHandle"
+ // ]}
+ // }
+ // ]}
+ // },
+ // "muteToggle"
+ // ]
+ // }},
+ // "subtitlesDisplay"/*, "replay"*/
+ // ]
+};
+
+// Set CDN Version of swf
+if (CDN_VERSION != "GENERATED_CDN_VSN") {
+ _V_.options.flash.swf = "http://vjs.zencdn.net/"+CDN_VERSION+"/video-js.swf"
+}_V_.merge = function(obj1, obj2, safe){
+ // Make sure second object exists
+ if (!obj2) { obj2 = {}; };
+
+ for (var attrname in obj2){
+ if (obj2.hasOwnProperty(attrname) && (!safe || !obj1.hasOwnProperty(attrname))) { obj1[attrname]=obj2[attrname]; }
+ }
+ return obj1;
+};
+_V_.extend = function(obj){ this.merge(this, obj, true); };
+
+_V_.extend({
+ tech: {}, // Holder for playback technology settings
+ controlSets: {}, // Holder for control set definitions
+
+ // Device Checks
+ isIE: function(){ return !+"\v1"; },
+ isFF: function(){ return !!_V_.ua.match("Firefox") },
+ isIPad: function(){ return navigator.userAgent.match(/iPad/i) !== null; },
+ isIPhone: function(){ return navigator.userAgent.match(/iPhone/i) !== null; },
+ isIOS: function(){ return VideoJS.isIPhone() || VideoJS.isIPad(); },
+ iOSVersion: function() {
+ var match = navigator.userAgent.match(/OS (\d+)_/i);
+ if (match && match[1]) { return match[1]; }
+ },
+ isAndroid: function(){ return navigator.userAgent.match(/Android.*AppleWebKit/i) !== null; },
+ androidVersion: function() {
+ var match = navigator.userAgent.match(/Android (\d+)\./i);
+ if (match && match[1]) { return match[1]; }
+ },
+
+ testVid: document.createElement("video"),
+ ua: navigator.userAgent,
+ support: {},
+
+ each: function(arr, fn){
+ if (!arr || arr.length === 0) { return; }
+ for (var i=0,j=arr.length; i<j; i++) {
+ fn.call(this, arr[i], i);
+ }
+ },
+
+ eachProp: function(obj, fn){
+ if (!obj) { return; }
+ for (var name in obj) {
+ if (obj.hasOwnProperty(name)) {
+ fn.call(this, name, obj[name]);
+ }
+ }
+ },
+
+ el: function(id){ return document.getElementById(id); },
+ createElement: function(tagName, attributes){
+ var el = document.createElement(tagName),
+ attrname;
+ for (attrname in attributes){
+ if (attributes.hasOwnProperty(attrname)) {
+ if (attrname.indexOf("-") !== -1) {
+ el.setAttribute(attrname, attributes[attrname]);
+ } else {
+ el[attrname] = attributes[attrname];
+ }
+ }
+ }
+ return el;
+ },
+
+ insertFirst: function(node, parent){
+ if (parent.firstChild) {
+ parent.insertBefore(node, parent.firstChild);
+ } else {
+ parent.appendChild(node);
+ }
+ },
+
+ addClass: function(element, classToAdd){
+ if ((" "+element.className+" ").indexOf(" "+classToAdd+" ") == -1) {
+ element.className = element.className === "" ? classToAdd : element.className + " " + classToAdd;
+ }
+ },
+
+ removeClass: function(element, classToRemove){
+ if (element.className.indexOf(classToRemove) == -1) { return; }
+ var classNames = element.className.split(" ");
+ classNames.splice(classNames.indexOf(classToRemove),1);
+ element.className = classNames.join(" ");
+ },
+
+ // Attempt to block the ability to select text while dragging controls
+ blockTextSelection: function(){
+ document.body.focus();
+ document.onselectstart = function () { return false; };
+ },
+ // Turn off text selection blocking
+ unblockTextSelection: function(){ document.onselectstart = function () { return true; }; },
+
+ // Return seconds as H:MM:SS or M:SS
+ // Supplying a guide (in seconds) will include enough leading zeros to cover the length of the guide
+ formatTime: function(seconds, guide) {
+ guide = guide || seconds; // Default to using seconds as guide
+ var s = Math.floor(seconds % 60),
+ m = Math.floor(seconds / 60 % 60),
+ h = Math.floor(seconds / 3600),
+ gm = Math.floor(guide / 60 % 60),
+ gh = Math.floor(guide / 3600);
+
+ // Check if we need to show hours
+ h = (h > 0 || gh > 0) ? h + ":" : "";
+
+ // If hours are showing, we may need to add a leading zero.
+ // Always show at least one digit of minutes.
+ m = (((h || gm >= 10) && m < 10) ? "0" + m : m) + ":";
+
+ // Check if leading zero is need for seconds
+ s = (s < 10) ? "0" + s : s;
+
+ return h + m + s;
+ },
+
+ uc: function(string){
+ return string.charAt(0).toUpperCase() + string.slice(1);
+ },
+
+ // Return the relative horizonal position of an event as a value from 0-1
+ getRelativePosition: function(x, relativeElement){
+ return Math.max(0, Math.min(1, (x - _V_.findPosX(relativeElement)) / relativeElement.offsetWidth));
+ },
+
+ getComputedStyleValue: function(element, style){
+ return window.getComputedStyle(element, null).getPropertyValue(style);
+ },
+
+ trim: function(string){ return string.toString().replace(/^\s+/, "").replace(/\s+$/, ""); },
+ round: function(num, dec) {
+ if (!dec) { dec = 0; }
+ return Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
+ },
+
+ isEmpty: function(object) {
+ for (var prop in object) {
+ return false;
+ }
+ return true;
+ },
+
+ // Mimic HTML5 TimeRange Spec.
+ createTimeRange: function(start, end){
+ return {
+ length: 1,
+ start: function() { return start; },
+ end: function() { return end; }
+ };
+ },
+
+ /* Element Data Store. Allows for binding data to an element without putting it directly on the element.
+ Ex. Event listneres are stored here.
+ (also from jsninja.com)
+ ================================================================================ */
+ cache: {}, // Where the data is stored
+ guid: 1, // Unique ID for the element
+ expando: "vdata" + (new Date).getTime(), // Unique attribute to store element's guid in
+
+ // Returns the cache object where data for the element is stored
+ getData: function(elem){
+ var id = elem[_V_.expando];
+ if (!id) {
+ id = elem[_V_.expando] = _V_.guid++;
+ _V_.cache[id] = {};
+ }
+ return _V_.cache[id];
+ },
+ // Delete data for the element from the cache and the guid attr from element
+ removeData: function(elem){
+ var id = elem[_V_.expando];
+ if (!id) { return; }
+ // Remove all stored data
+ delete _V_.cache[id];
+ // Remove the expando property from the DOM node
+ try {
+ delete elem[_V_.expando];
+ } catch(e) {
+ if (elem.removeAttribute) {
+ elem.removeAttribute(_V_.expando);
+ } else {
+ // IE doesn't appear to support removeAttribute on the document element
+ elem[_V_.expando] = null;
+ }
+ }
+ },
+
+ /* Proxy (a.k.a Bind or Context). A simple method for changing the context of a function
+ It also stores a unique id on the function so it can be easily removed from events
+ ================================================================================ */
+ proxy: function(context, fn, uid) {
+ // Make sure the function has a unique ID
+ if (!fn.guid) { fn.guid = _V_.guid++; }
+
+ // Create the new function that changes the context
+ var ret = function() {
+ return fn.apply(context, arguments);
+ }
+
+ // Allow for the ability to individualize this function
+ // Needed in the case where multiple objects might share the same prototype
+ // IF both items add an event listener with the same function, then you try to remove just one
+ // it will remove both because they both have the same guid.
+ // when using this, you need to use the proxy method when you remove the listener as well.
+ ret.guid = (uid) ? uid + "_" + fn.guid : fn.guid;
+
+ return ret;
+ },
+
+ get: function(url, onSuccess, onError){
+ // if (netscape.security.PrivilegeManager.enablePrivilege) {
+ // netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
+ // }
+
+ var local = (url.indexOf("file:") == 0 || (window.location.href.indexOf("file:") == 0 && url.indexOf("http:") == -1));
+
+ if (typeof XMLHttpRequest == "undefined") {
+ XMLHttpRequest = function () {
+ try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e) {}
+ try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (f) {}
+ try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (g) {}
+ throw new Error("This browser does not support XMLHttpRequest.");
+ };
+ }
+
+ var request = new XMLHttpRequest();
+
+ try {
+ request.open("GET", url);
+ } catch(e) {
+ _V_.log("VideoJS XMLHttpRequest (open)", e);
+ // onError(e);
+ return false;
+ }
+
+ request.onreadystatechange = _V_.proxy(this, function() {
+ if (request.readyState == 4) {
+ if (request.status == 200 || local && request.status == 0) {
+ onSuccess(request.responseText);
+ } else {
+ if (onError) {
+ onError();
+ }
+ }
+ }
+ });
+
+ try {
+ request.send();
+ } catch(e) {
+ _V_.log("VideoJS XMLHttpRequest (send)", e);
+ if (onError) {
+ onError(e);
+ }
+ }
+ },
+
+ /* Local Storage
+ ================================================================================ */
+ setLocalStorage: function(key, value){
+ // IE was throwing errors referencing the var anywhere without this
+ var localStorage = window.localStorage || false;
+ if (!localStorage) { return; }
+ try {
+ localStorage[key] = value;
+ } catch(e) {
+ if (e.code == 22 || e.code == 1014) { // Webkit == 22 / Firefox == 1014
+ _V_.log("LocalStorage Full (VideoJS)", e);
+ } else {
+ _V_.log("LocalStorage Error (VideoJS)", e);
+ }
+ }
+ },
+
+ // Get abosolute version of relative URL. Used to tell flash correct URL.
+ // http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue
+ getAbsoluteURL: function(url){
+
+ // Check if absolute URL
+ if (!url.match(/^https?:\/\//)) {
+ // Convert to absolute URL. Flash hosted off-site needs an absolute URL.
+ url = _V_.createElement('div', {
+ innerHTML: '<a href="'+url+'">x</a>'
+ }).firstChild.href;
+ }
+
+ return url;
+ }
+
+});
+
+// usage: log('inside coolFunc', this, arguments);
+// paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
+_V_.log = function(){
+ _V_.log.history = _V_.log.history || [];// store logs to an array for reference
+ _V_.log.history.push(arguments);
+ if(window.console) {
+ arguments.callee = arguments.callee.caller;
+ var newarr = [].slice.call(arguments);
+ (typeof console.log === 'object' ? _V_.log.apply.call(console.log, console, newarr) : console.log.apply(console, newarr));
+ }
+};
+
+// make it safe to use console.log always
+(function(b){function c(){}for(var d="assert,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,timeStamp,profile,profileEnd,time,timeEnd,trace,warn".split(","),a;a=d.pop();){b[a]=b[a]||c}})((function(){try
+{console.log();return window.console;}catch(err){return window.console={};}})());
+
+// Offset Left
+// getBoundingClientRect technique from John Resig http://ejohn.org/blog/getboundingclientrect-is-awesome/
+if ("getBoundingClientRect" in document.documentElement) {
+ _V_.findPosX = function(el) {
+ var box;
+
+ try {
+ box = el.getBoundingClientRect();
+ } catch(e) {}
+
+ if (!box) { return 0; }
+
+ var docEl = document.documentElement,
+ body = document.body,
+ clientLeft = docEl.clientLeft || body.clientLeft || 0,
+ scrollLeft = window.pageXOffset || body.scrollLeft,
+ left = box.left + scrollLeft - clientLeft;
+
+ return left;
+ };
+} else {
+ _V_.findPosX = function(el) {
+ var curleft = el.offsetLeft;
+ // _V_.log(obj.className, obj.offsetLeft)
+ while(el = obj.offsetParent) {
+ if (el.className.indexOf("video-js") == -1) {
+ // _V_.log(el.offsetParent, "OFFSETLEFT", el.offsetLeft)
+ // _V_.log("-webkit-full-screen", el.webkitMatchesSelector("-webkit-full-screen"));
+ // _V_.log("-webkit-full-screen", el.querySelectorAll(".video-js:-webkit-full-screen"));
+ } else {
+ }
+ curleft += el.offsetLeft;
+ }
+ return curleft;
+ };
+}// Javascript JSON implementation
+// (Parse Method Only)
+// https://github.com/douglascrockford/JSON-js/blob/master/json2.js
+
+var JSON;
+if (!JSON) { JSON = {}; }
+
+(function(){
+ var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
+
+ if (typeof JSON.parse !== 'function') {
+ JSON.parse = function (text, reviver) {
+ var j;
+
+ function walk(holder, key) {
+ var k, v, value = holder[key];
+ if (value && typeof value === 'object') {
+ for (k in value) {
+ if (Object.prototype.hasOwnProperty.call(value, k)) {
+ v = walk(value, k);
+ if (v !== undefined) {
+ value[k] = v;
+ } else {
+ delete value[k];
+ }
+ }
+ }
+ }
+ return reviver.call(holder, key, value);
+ }
+ text = String(text);
+ cx.lastIndex = 0;
+ if (cx.test(text)) {
+ text = text.replace(cx, function (a) {
+ return '\\u' +
+ ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+ });
+ }
+
+ if (/^[\],:{}\s]*$/
+ .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
+ .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
+ .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
+
+ j = eval('(' + text + ')');
+
+ return typeof reviver === 'function' ?
+ walk({'': j}, '') : j;
+ }
+
+ throw new SyntaxError('JSON.parse');
+ };
+ }
+}());
+// Event System (J.Resig - Secrets of a JS Ninja http://jsninja.com/ [Go read it, really])
+// (Book version isn't completely usable, so fixed some things and borrowed from jQuery where it's working)
+//
+// This should work very similarly to jQuery's events, however it's based off the book version which isn't as
+// robust as jquery's, so there's probably some differences.
+//
+// When you add an event listener using _V_.addEvent,
+// it stores the handler function in seperate cache object,
+// and adds a generic handler to the element's event,
+// along with a unique id (guid) to the element.
+
+_V_.extend({
+
+ // Add an event listener to element
+ // It stores the handler function in a separate cache object
+ // and adds a generic handler to the element's event,
+ // along with a unique id (guid) to the element.
+ on: function(elem, type, fn){
+ var data = _V_.getData(elem), handlers;
+
+ // We only need to generate one handler per element
+ if (data && !data.handler) {
+ // Our new meta-handler that fixes the event object and the context
+ data.handler = function(event){
+ event = _V_.fixEvent(event);
+ var handlers = _V_.getData(elem).events[event.type];
+ // Go through and call all the real bound handlers
+ if (handlers) {
+
+ // Copy handlers so if handlers are added/removed during the process it doesn't throw everything off.
+ var handlersCopy = [];
+ _V_.each(handlers, function(handler, i){
+ handlersCopy[i] = handler;
+ })
+
+ for (var i = 0, l = handlersCopy.length; i < l; i++) {
+ handlersCopy[i].call(elem, event);
+ }
+ }
+ };
+ }
+
+ // We need a place to store all our event data
+ if (!data.events) { data.events = {}; }
+
+ // And a place to store the handlers for this event type
+ handlers = data.events[type];
+
+ if (!handlers) {
+ handlers = data.events[ type ] = [];
+
+ // Attach our meta-handler to the element, since one doesn't exist
+ if (document.addEventListener) {
+ elem.addEventListener(type, data.handler, false);
+ } else if (document.attachEvent) {
+ elem.attachEvent("on" + type, data.handler);
+ }
+ }
+
+ if (!fn.guid) { fn.guid = _V_.guid++; }
+
+ handlers.push(fn);
+ },
+ // Deprecated name for 'on' function
+ addEvent: function(){ return _V_.on.apply(this, arguments); },
+
+ off: function(elem, type, fn) {
+ var data = _V_.getData(elem), handlers;
+ // If no events exist, nothing to unbind
+ if (!data.events) { return; }
+
+ // Are we removing all bound events?
+ if (!type) {
+ for (type in data.events) {
+ _V_.cleanUpEvents(elem, type);
+ }
+ return;
+ }
+
+ // And a place to store the handlers for this event type
+ handlers = data.events[type];
+
+ // If no handlers exist, nothing to unbind
+ if (!handlers) { return; }
+
+ // See if we're only removing a single handler
+ if (fn && fn.guid) {
+ for (var i = 0; i < handlers.length; i++) {
+ // We found a match (don't stop here, there could be a couple bound)
+ if (handlers[i].guid === fn.guid) {
+ // Remove the handler from the array of handlers
+ handlers.splice(i--, 1);
+ }
+ }
+ }
+
+ _V_.cleanUpEvents(elem, type);
+ },
+ // Deprecated name for 'on' function
+ removeEvent: function(){ return _V_.off.apply(this, arguments); },
+
+ cleanUpEvents: function(elem, type) {
+ var data = _V_.getData(elem);
+ // Remove the events of a particular type if there are none left
+
+ if (data.events[type].length === 0) {
+ delete data.events[type];
+
+ // Remove the meta-handler from the element
+ if (document.removeEventListener) {
+ elem.removeEventListener(type, data.handler, false);
+ } else if (document.detachEvent) {
+ elem.detachEvent("on" + type, data.handler);
+ }
+ }
+
+ // Remove the events object if there are no types left
+ if (_V_.isEmpty(data.events)) {
+ delete data.events;
+ delete data.handler;
+ }
+
+ // Finally remove the expando if there is no data left
+ if (_V_.isEmpty(data)) {
+ _V_.removeData(elem);
+ }
+ },
+
+ fixEvent: function(event) {
+ if (event[_V_.expando]) { return event; }
+ // store a copy of the original event object
+ // and "clone" to set read-only properties
+ var originalEvent = event;
+ event = new _V_.Event(originalEvent);
+
+ for ( var i = _V_.Event.props.length, prop; i; ) {
+ prop = _V_.Event.props[ --i ];
+ event[prop] = originalEvent[prop];
+ }
+
+ // Fix target property, if necessary
+ if (!event.target) { event.target = event.srcElement || document; }
+
+ // check if target is a textnode (safari)
+ if (event.target.nodeType === 3) { event.target = event.target.parentNode; }
+
+ // Add relatedTarget, if necessary
+ if (!event.relatedTarget && event.fromElement) {
+ event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
+ }
+
+ // Calculate pageX/Y if missing and clientX/Y available
+ if ( event.pageX == null && event.clientX != null ) {
+ var eventDocument = event.target.ownerDocument || document,
+ doc = eventDocument.documentElement,
+ body = eventDocument.body;
+
+ event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
+ event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
+ }
+
+ // Add which for key events
+ if (event.which == null && (event.charCode != null || event.keyCode != null)) {
+ event.which = event.charCode != null ? event.charCode : event.keyCode;
+ }
+
+ // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+ if ( !event.metaKey && event.ctrlKey ) {
+ event.metaKey = event.ctrlKey;
+ }
+
+ // Add which for click: 1 === left; 2 === middle; 3 === right
+ // Note: button is not normalized, so don't use it
+ if ( !event.which && event.button !== undefined ) {
+ event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+ }
+
+ return event;
+ },
+
+ trigger: function(elem, event) {
+ var data = _V_.getData(elem),
+ parent = elem.parentNode || elem.ownerDocument,
+ type = event.type || event,
+ handler;
+
+ if (data) { handler = data.handler }
+
+ // Added in attion to book. Book code was broke.
+ event = typeof event === "object" ?
+ event[_V_.expando] ?
+ event :
+ new _V_.Event(type, event) :
+ new _V_.Event(type);
+
+ event.type = type;
+ if (handler) {
+ handler.call(elem, event);
+ }
+
+ // Clean up the event in case it is being reused
+ event.result = undefined;
+ event.target = elem;
+
+ // Bubble the event up the tree to the document,
+ // Unless it's been explicitly stopped
+ // if (parent && !event.isPropagationStopped()) {
+ // _V_.triggerEvent(parent, event);
+ //
+ // // We're at the top document so trigger the default action
+ // } else if (!parent && !event.isDefaultPrevented()) {
+ // // log(type);
+ // var targetData = _V_.getData(event.target);
+ // // log(targetData);
+ // var targetHandler = targetData.handler;
+ // // log("2");
+ // if (event.target[event.type]) {
+ // // Temporarily disable the bound handler,
+ // // don't want to execute it twice
+ // if (targetHandler) {
+ // targetData.handler = function(){};
+ // }
+ //
+ // // Trigger the native event (click, focus, blur)
+ // event.target[event.type]();
+ //
+ // // Restore the handler
+ // if (targetHandler) {
+ // targetData.handler = targetHandler;
+ // }
+ // }
+ // }
+ },
+ // Deprecated name for 'on' function
+ triggerEvent: function(){ return _V_.trigger.apply(this, arguments); },
+
+ one: function(elem, type, fn) {
+ _V_.on(elem, type, function(){
+ _V_.off(elem, type, arguments.callee)
+ fn.apply(this, arguments);
+ });
+ }
+});
+
+// Custom Event object for standardizing event objects between browsers.
+_V_.Event = function(src, props){
+ // Event object
+ if (src && src.type) {
+ this.originalEvent = src;
+ this.type = src.type;
+
+ // Events bubbling up the document may have been marked as prevented
+ // by a handler lower down the tree; reflect the correct value.
+ this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
+ src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
+
+ // Event type
+ } else {
+ this.type = src;
+ }
+
+ // Put explicitly provided properties onto the event object
+ if (props) { _V_.merge(this, props); }
+
+ this.timeStamp = (new Date).getTime();
+
+ // Mark it as fixed
+ this[_V_.expando] = true;
+};
+
+_V_.Event.prototype = {
+ preventDefault: function() {
+ this.isDefaultPrevented = returnTrue;
+
+ var e = this.originalEvent;
+ if (!e) { return; }
+
+ // if preventDefault exists run it on the original event
+ if (e.preventDefault) {
+ e.preventDefault();
+ // otherwise set the returnValue property of the original event to false (IE)
+ } else {
+ e.returnValue = false;
+ }
+ },
+ stopPropagation: function() {
+ this.isPropagationStopped = returnTrue;
+
+ var e = this.originalEvent;
+ if (!e) { return; }
+ // if stopPropagation exists run it on the original event
+ if (e.stopPropagation) { e.stopPropagation(); }
+ // otherwise set the cancelBubble property of the original event to true (IE)
+ e.cancelBubble = true;
+ },
+ stopImmediatePropagation: function() {
+ this.isImmediatePropagationStopped = returnTrue;
+ this.stopPropagation();
+ },
+ isDefaultPrevented: returnFalse,
+ isPropagationStopped: returnFalse,
+ isImmediatePropagationStopped: returnFalse
+};
+_V_.Event.props = "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" ");
+
+function returnTrue(){ return true; }
+function returnFalse(){ return false; }
+
+// Using John Resig's Class implementation http://ejohn.org/blog/simple-javascript-inheritance/
+// (function(){var initializing=false, fnTest=/xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; _V_.Class = function(){}; _V_.Class.extend = function(prop) { var _super = this.prototype; initializing = true; var prototype = new this(); initializing = false; for (var name in prop) { prototype[name] = typeof prop[name] == "function" && typeof _super[name] == "function" && fnTest.test(prop[name]) ? (function(name, fn){ return function() { var tmp = this._super; this._super = _super[name]; var ret = fn.apply(this, arguments); this._super = tmp; return ret; }; })(name, prop[name]) : prop[name]; } function Class() { if ( !initializing && this.init ) this.init.apply(this, arguments); } Class.prototype = prototype; Class.constructor = Class; Class.extend = arguments.callee; return Class;};})();
+(function(){
+ var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
+ _V_.Class = function(){};
+ _V_.Class.extend = function(prop) {
+ var _super = this.prototype;
+ initializing = true;
+ var prototype = new this();
+ initializing = false;
+ for (var name in prop) {
+ prototype[name] = typeof prop[name] == "function" &&
+ typeof _super[name] == "function" && fnTest.test(prop[name]) ?
+ (function(name, fn){
+ return function() {
+ var tmp = this._super;
+ this._super = _super[name];
+ var ret = fn.apply(this, arguments);
+ this._super = tmp;
+ return ret;
+ };
+ })(name, prop[name]) :
+ prop[name];
+ }
+ function Class() {
+ if ( !initializing && this.init ) {
+ return this.init.apply(this, arguments);
+
+ // Attempting to recreate accessing function form of class.
+ } else if (!initializing) {
+ return arguments.callee.prototype.init()
+ }
+ }
+ Class.prototype = prototype;
+ Class.constructor = Class;
+ Class.extend = arguments.callee;
+ return Class;
+ };
+})();
+
+/* Player Component- Base class for all UI objects
+================================================================================ */
+_V_.Component = _V_.Class.extend({
+
+ init: function(player, options){
+ this.player = player;
+
+ // Allow for overridding default component options
+ options = this.options = _V_.merge(this.options || {}, options);
+
+ // Create element if one wasn't provided in options
+ if (options.el) {
+ this.el = options.el;
+ } else {
+ this.el = this.createElement();
+ }
+
+ // Add any components in options
+ this.initComponents();
+ },
+
+ destroy: function(){},
+
+ createElement: function(type, attrs){
+ return _V_.createElement(type || "div", attrs);
+ },
+
+ buildCSSClass: function(){
+ // Child classes can include a function that does:
+ // return "CLASS NAME" + this._super();
+ return "";
+ },
+
+ initComponents: function(){
+ var options = this.options;
+ if (options && options.components) {
+ // Loop through components and add them to the player
+ this.eachProp(options.components, function(name, opts){
+
+ // Allow waiting to add components until a specific event is called
+ var tempAdd = this.proxy(function(){
+ // Set property name on player. Could cause conflicts with other prop names, but it's worth making refs easy.
+ this[name] = this.addComponent(name, opts);
+ });
+
+ if (opts.loadEvent) {
+ this.one(opts.loadEvent, tempAdd)
+ } else {
+ tempAdd();
+ }
+ });
+ }
+ },
+
+ // Add child components to this component.
+ // Will generate a new child component and then append child component's element to this component's element.
+ // Takes either the name of the UI component class, or an object that contains a name, UI Class, and options.
+ addComponent: function(name, options){
+ var component, componentClass;
+
+ // If string, create new component with options
+ if (typeof name == "string") {
+
+ // Make sure options is at least an empty object to protect against errors
+ options = options || {};
+
+ // Assume name of set is a lowercased name of the UI Class (PlayButton, etc.)
+ componentClass = options.componentClass || _V_.uc(name);
+
+ // Create a new object & element for this controls set
+ // If there's no .player, this is a player
+ component = new _V_[componentClass](this.player || this, options);
+
+ } else {
+ component = name;
+ }
+
+ // Add the UI object's element to the container div (box)
+ this.el.appendChild(component.el);
+
+ // Return so it can stored on parent object if desired.
+ return component;
+ },
+
+ removeComponent: function(component){
+ this.el.removeChild(component.el);
+ },
+
+ /* Display
+ ================================================================================ */
+ show: function(){
+ this.el.style.display = "block";
+ },
+
+ hide: function(){
+ this.el.style.display = "none";
+ },
+
+ fadeIn: function(){
+ this.removeClass("vjs-fade-out");
+ this.addClass("vjs-fade-in");
+ },
+
+ fadeOut: function(){
+ this.removeClass("vjs-fade-in");
+ this.addClass("vjs-fade-out");
+ },
+
+ lockShowing: function(){
+ var style = this.el.style;
+ style.display = "block";
+ style.opacity = 1;
+ style.visiblity = "visible";
+ },
+
+ unlockShowing: function(){
+ var style = this.el.style;
+ style.display = "";
+ style.opacity = "";
+ style.visiblity = "";
+ },
+
+ addClass: function(classToAdd){
+ _V_.addClass(this.el, classToAdd);
+ },
+
+ removeClass: function(classToRemove){
+ _V_.removeClass(this.el, classToRemove);
+ },
+
+ /* Events
+ ================================================================================ */
+ on: function(type, fn, uid){
+ return _V_.on(this.el, type, _V_.proxy(this, fn));
+ },
+ // Deprecated name for 'on' function
+ addEvent: function(){ return this.on.apply(this, arguments); },
+
+ off: function(type, fn){
+ return _V_.off(this.el, type, fn);
+ },
+ // Deprecated name for 'off' function
+ removeEvent: function(){ return this.off.apply(this, arguments); },
+
+ trigger: function(type, e){
+ return _V_.trigger(this.el, type, e);
+ },
+ // Deprecated name for 'off' function
+ triggerEvent: function(){ return this.trigger.apply(this, arguments); },
+
+ one: function(type, fn) {
+ _V_.one(this.el, type, _V_.proxy(this, fn));
+ },
+
+ /* Ready - Trigger functions when component is ready
+ ================================================================================ */
+ ready: function(fn){
+ if (!fn) return this;
+
+ if (this.isReady) {
+ fn.call(this);
+ } else {
+ if (this.readyQueue === undefined) {
+ this.readyQueue = [];
+ }
+ this.readyQueue.push(fn);
+ }
+
+ return this;
+ },
+
+ triggerReady: function(){
+ this.isReady = true;
+ if (this.readyQueue && this.readyQueue.length > 0) {
+ // Call all functions in ready queue
+ this.each(this.readyQueue, function(fn){
+ fn.call(this);
+ });
+
+ // Reset Ready Queue
+ this.readyQueue = [];
+
+ // Allow for using event listeners also, in case you want to do something everytime a source is ready.
+ this.trigger("ready");
+ }
+ },
+
+ /* Utility
+ ================================================================================ */
+ each: function(arr, fn){ _V_.each.call(this, arr, fn); },
+
+ eachProp: function(obj, fn){ _V_.eachProp.call(this, obj, fn); },
+
+ extend: function(obj){ _V_.merge(this, obj) },
+
+ // More easily attach 'this' to functions
+ proxy: function(fn, uid){ return _V_.proxy(this, fn, uid); }
+
+});/* UI Component- Base class for all UI objects
+================================================================================ */
+_V_.Player = _V_.Component.extend({
+
+ init: function(tag, addOptions, ready){
+
+ this.tag = tag; // Store the original tag used to set options
+
+ var el = this.el = _V_.createElement("div"), // Div to contain video and controls
+ options = this.options = {};
+
+ // Set Options
+ _V_.merge(options, _V_.options); // Copy Global Defaults
+ _V_.merge(options, this.getVideoTagSettings()); // Override with Video Tag Options
+ _V_.merge(options, addOptions); // Override/extend with options from setup call
+
+ // Add callback to ready queue
+ this.ready(ready);
+
+ // Store controls setting, and then remove immediately so native controls don't flash.
+ tag.removeAttribute("controls");
+
+ // Poster will be handled by a manual <img>
+ tag.removeAttribute("poster");
+
+ // Make player findable on elements
+ tag.player = el.player = this;
+
+ // Make sure tag ID exists
+ tag.id = tag.id || "vjs_video_" + _V_.guid++;
+
+ // Give video tag properties to box
+ // ID will now reference box, not the video tag
+ this.id = el.id = tag.id;
+ el.className = tag.className;
+
+ // Make player easily findable by ID
+ _V_.players[el.id] = this;
+
+ // Make box use width/height of tag, or default 300x150
+ el.setAttribute("width", options.width);
+ el.setAttribute("height", options.height);
+
+ // Enforce with CSS since width/height attrs don't work on divs
+ el.style.width = options.width+"px";
+ el.style.height = options.height+"px";
+
+ // Update tag id/class for use as HTML5 playback tech
+ // Might think we should do this after embedding in container so .vjs-tech class
+ // doesn't flash 100% width/height, but class only applies with .video-js parent
+ tag.id += "_html5_api";
+ tag.className = "vjs-tech";
+
+ // Remove width/height attrs from tag so CSS can make it 100% width/height
+ tag.removeAttribute("width");
+ tag.removeAttribute("height");
+
+ // Wrap video tag in div (el/box) container
+ tag.parentNode.insertBefore(el, tag);
+ el.appendChild(tag); // Breaks iPhone, fixed in HTML5 setup.
+
+ // Empty video tag sources and tracks so the built-in player doesn't use them also.
+ if (tag.hasChildNodes()) {
+ var nrOfChildNodes = tag.childNodes.length;
+ for (var i=0,j=tag.childNodes;i<nrOfChildNodes;i++) {
+ if (j[0].nodeName.toLowerCase() == "source" || j[0].nodeName.toLowerCase() == "track") {
+ tag.removeChild(j[0]);
+ }
+ }
+ }
+
+ // Cache for video property values.
+ this.values = {};
+
+ this.addClass("vjs-paused");
+
+ this.on("ended", this.onEnded);
+ this.on("play", this.onPlay);
+ this.on("pause", this.onPause);
+ this.on("progress", this.onProgress);
+ this.on("error", this.onError);
+
+ // When the API is ready, loop through the components and add to the player.
+ if (options.controls) {
+ this.ready(function(){
+ this.initComponents();
+ });
+ }
+
+ // Tracks defined in tracks.js
+ this.textTracks = [];
+ if (options.tracks && options.tracks.length > 0) {
+ this.addTextTracks(options.tracks);
+ }
+
+ // If there are no sources when the player is initialized,
+ // load the first supported playback technology.
+ if (!options.sources || options.sources.length == 0) {
+ for (var i=0,j=options.techOrder; i<j.length; i++) {
+ var techName = j[i],
+ tech = _V_[techName];
+
+ // Check if the browser supports this technology
+ if (tech.isSupported()) {
+ this.loadTech(techName);
+ break;
+ }
+ }
+ } else {
+ // Loop through playback technologies (HTML5, Flash) and check for support. Then load the best source.
+ // A few assumptions here:
+ // All playback technologies respect preload false.
+ this.src(options.sources);
+ }
+ },
+
+ destroy: function(){
+ // Ensure that tracking progress and time progress will stop and plater deleted
+ this.stopTrackingProgress();
+ this.stopTrackingCurrentTime();
+ _V_.players[this.id] = null;
+ delete _V_.players[this.id];
+ this.tech.destroy();
+ this.el.parentNode.removeChild(this.el);
+ },
+
+ createElement: function(type, options){},
+
+ getVideoTagSettings: function(){
+ var options = {
+ sources: [],
+ tracks: []
+ },
+ tag = this.tag,
+ getAttribute = "getAttribute"; // For better minification
+
+ options.src = tag[getAttribute]("src");
+ options.controls = tag[getAttribute]("controls") !== null;
+ options.poster = tag[getAttribute]("poster");
+ options.preload = tag[getAttribute]("preload");
+ options.autoplay = tag[getAttribute]("autoplay") !== null; // hasAttribute not IE <8 compatible
+ options.loop = tag[getAttribute]("loop") !== null;
+ options.muted = tag[getAttribute]("muted") !== null;
+
+ options.width = tag[getAttribute]("width");
+ options.height = tag[getAttribute]("height");
+
+ if (this.tag.hasChildNodes()) {
+ for (var c,i=0,j=this.tag.childNodes;i<j.length;i++) {
+ c = j[i];
+ if (c.nodeName.toLowerCase() == "source") {
+ options.sources.push({
+ src: c[getAttribute]('src'),
+ type: c[getAttribute]('type'),
+ media: c[getAttribute]('media'),
+ title: c[getAttribute]('title')
+ });
+ }
+ if (c.nodeName.toLowerCase() == "track") {
+ options.tracks.push({
+ src: c[getAttribute]("src"),
+ kind: c[getAttribute]("kind"),
+ srclang: c[getAttribute]("srclang"),
+ label: c[getAttribute]("label"),
+ 'default': c[getAttribute]("default") !== null,
+ title: c[getAttribute]("title")
+ });
+ }
+ }
+ }
+ return options;
+ },
+
+ /* PLayback Technology (tech)
+ ================================================================================ */
+ // Load/Create an instance of playback technlogy including element and API methods
+ // And append playback element in player div.
+ loadTech: function(techName, source){
+
+ // Pause and remove current playback technology
+ if (this.tech) {
+ this.unloadTech();
+
+ // If the first time loading, HTML5 tag will exist but won't be initialized
+ // So we need to remove it if we're not loading HTML5
+ } else if (techName != "html5" && this.tag) {
+ this.el.removeChild(this.tag);
+ this.tag = false;
+ }
+
+ this.techName = techName;
+
+ // Turn off API access because we're loading a new tech that might load asynchronously
+ this.isReady = false;
+
+ var techReady = function(){
+ this.player.triggerReady();
+
+ // Manually track progress in cases where the browser/flash player doesn't report it.
+ if (!this.support.progressEvent) {
+ this.player.manualProgressOn();
+ }
+
+ // Manually track timeudpates in cases where the browser/flash player doesn't report it.
+ if (!this.support.timeupdateEvent) {
+ this.player.manualTimeUpdatesOn();
+ }
+ }
+
+ // Grab tech-specific options from player options and add source and parent element to use.
+ var techOptions = _V_.merge({ source: source, parentEl: this.el }, this.options[techName])
+
+ if (source) {
+ if (source.src == this.values.src && this.values.currentTime > 0) {
+ techOptions.startTime = this.values.currentTime;
+ }
+
+ this.values.src = source.src;
+ }
+
+ // Initialize tech instance
+ this.tech = new _V_[techName](this, techOptions);
+ this.tech.ready(techReady);
+ },
+
+ unloadTech: function(){
+ this.tech.destroy();
+
+ // Turn off any manual progress or timeupdate tracking
+ if (this.manualProgress) { this.manualProgressOff(); }
+
+ if (this.manualTimeUpdates) { this.manualTimeUpdatesOff(); }
+
+ this.tech = false;
+ },
+
+ // There's many issues around changing the size of a Flash (or other plugin) object.
+ // First is a plugin reload issue in Firefox that has been around for 11 years: https://bugzilla.mozilla.org/show_bug.cgi?id=90268
+ // Then with the new fullscreen API, Mozilla and webkit browsers will reload the flash object after going to fullscreen.
+ // To get around this, we're unloading the tech, caching source and currentTime values, and reloading the tech once the plugin is resized.
+ // reloadTech: function(betweenFn){
+ // _V_.log("unloadingTech")
+ // this.unloadTech();
+ // _V_.log("unloadedTech")
+ // if (betweenFn) { betweenFn.call(); }
+ // _V_.log("LoadingTech")
+ // this.loadTech(this.techName, { src: this.values.src })
+ // _V_.log("loadedTech")
+ // },
+
+ /* Fallbacks for unsupported event types
+ ================================================================================ */
+ // Manually trigger progress events based on changes to the buffered amount
+ // Many flash players and older HTML5 browsers don't send progress or progress-like events
+ manualProgressOn: function(){
+ this.manualProgress = true;
+
+ // Trigger progress watching when a source begins loading
+ this.trackProgress();
+
+ // Watch for a native progress event call on the tech element
+ // In HTML5, some older versions don't support the progress event
+ // So we're assuming they don't, and turning off manual progress if they do.
+ this.tech.on("progress", function(){
+
+ // Remove this listener from the element
+ this.removeEvent("progress", arguments.callee);
+
+ // Update known progress support for this playback technology
+ this.support.progressEvent = true;
+
+ // Turn off manual progress tracking
+ this.player.manualProgressOff();
+ });
+ },
+
+ manualProgressOff: function(){
+ this.manualProgress = false;
+ this.stopTrackingProgress();
+ },
+
+ trackProgress: function(){
+ this.progressInterval = setInterval(_V_.proxy(this, function(){
+ // Don't trigger unless buffered amount is greater than last time
+ // log(this.values.bufferEnd, this.buffered().end(0), this.duration())
+ /* TODO: update for multiple buffered regions */
+ if (this.values.bufferEnd < this.buffered().end(0)) {
+ this.trigger("progress");
+ } else if (this.bufferedPercent() == 1) {
+ this.stopTrackingProgress();
+ this.trigger("progress"); // Last update
+ }
+ }), 500);
+ },
+ stopTrackingProgress: function(){ clearInterval(this.progressInterval); },
+
+ /* Time Tracking -------------------------------------------------------------- */
+ manualTimeUpdatesOn: function(){
+ this.manualTimeUpdates = true;
+
+ this.on("play", this.trackCurrentTime);
+ this.on("pause", this.stopTrackingCurrentTime);
+ // timeupdate is also called by .currentTime whenever current time is set
+
+ // Watch for native timeupdate event
+ this.tech.on("timeupdate", function(){
+
+ // Remove this listener from the element
+ this.removeEvent("timeupdate", arguments.callee);
+
+ // Update known progress support for this playback technology
+ this.support.timeupdateEvent = true;
+
+ // Turn off manual progress tracking
+ this.player.manualTimeUpdatesOff();
+ });
+ },
+
+ manualTimeUpdatesOff: function(){
+ this.manualTimeUpdates = false;
+ this.stopTrackingCurrentTime();
+ this.removeEvent("play", this.trackCurrentTime);
+ this.removeEvent("pause", this.stopTrackingCurrentTime);
+ },
+
+ trackCurrentTime: function(){
+ if (this.currentTimeInterval) { this.stopTrackingCurrentTime(); }
+ this.currentTimeInterval = setInterval(_V_.proxy(this, function(){
+ this.trigger("timeupdate");
+ }), 250); // 42 = 24 fps // 250 is what Webkit uses // FF uses 15
+ },
+
+ // Turn off play progress tracking (when paused or dragging)
+ stopTrackingCurrentTime: function(){ clearInterval(this.currentTimeInterval); },
+
+ /* Player event handlers (how the player reacts to certain events)
+ ================================================================================ */
+ onEnded: function(){
+ if (this.options.loop) {
+ this.currentTime(0);
+ this.play();
+ } else {
+ this.pause();
+ this.currentTime(0);
+ this.pause();
+ }
+ },
+
+ onPlay: function(){
+ _V_.removeClass(this.el, "vjs-paused");
+ _V_.addClass(this.el, "vjs-playing");
+ },
+
+ onPause: function(){
+ _V_.removeClass(this.el, "vjs-playing");
+ _V_.addClass(this.el, "vjs-paused");
+ },
+
+ onProgress: function(){
+ // Add custom event for when source is finished downloading.
+ if (this.bufferedPercent() == 1) {
+ this.trigger("loadedalldata");
+ }
+ },
+
+ onError: function(e) {
+ _V_.log("Video Error", e);
+ },
+
+/* Player API
+================================================================================ */
+
+ // Pass values to the playback tech
+ techCall: function(method, arg){
+
+ // If it's not ready yet, call method when it is
+ if (!this.tech.isReady) {
+ this.tech.ready(function(){
+ this[method](arg);
+ });
+
+ // Otherwise call method now
+ } else {
+ try {
+ this.tech[method](arg);
+ } catch(e) {
+ _V_.log(e);
+ }
+ }
+ },
+
+ // Get calls can't wait for the tech, and sometimes don't need to.
+ techGet: function(method){
+
+ // Make sure tech is ready
+ if (this.tech.isReady) {
+
+ // Flash likes to die and reload when you hide or reposition it.
+ // In these cases the object methods go away and we get errors.
+ // When that happens we'll catch the errors and inform tech that it's not ready any more.
+ try {
+ return this.tech[method]();
+ } catch(e) {
+
+ // When building additional tech libs, an expected method may not be defined yet
+ if (this.tech[method] === undefined) {
+ _V_.log("Video.js: " + method + " method not defined for "+this.techName+" playback technology.", e);
+
+ } else {
+
+ // When a method isn't available on the object it throws a TypeError
+ if (e.name == "TypeError") {
+ _V_.log("Video.js: " + method + " unavailable on "+this.techName+" playback technology element.", e);
+ this.tech.isReady = false;
+
+ } else {
+ _V_.log(e);
+ }
+ }
+ }
+ }
+
+ return;
+ },
+
+ // Method for calling methods on the current playback technology
+ // techCall: function(method, arg){
+ //
+ // // if (this.isReady) {
+ // //
+ // // } else {
+ // // _V_.log("The playback technology API is not ready yet. Use player.ready(myFunction)."+" ["+method+"]", arguments.callee.caller.arguments.callee.caller.arguments.callee.caller)
+ // // return false;
+ // // // throw new Error("The playback technology API is not ready yet. Use player.ready(myFunction)."+" ["+method+"]");
+ // // }
+ // },
+
+ // http://dev.w3.org/html5/spec/video.html#dom-media-play
+ play: function(){
+ this.techCall("play");
+ return this;
+ },
+
+ // http://dev.w3.org/html5/spec/video.html#dom-media-pause
+ pause: function(){
+ this.techCall("pause");
+ return this;
+ },
+
+ // http://dev.w3.org/html5/spec/video.html#dom-media-paused
+ // The initial state of paused should be true (in Safari it's actually false)
+ paused: function(){
+ return (this.techGet("paused") === false) ? false : true;
+ },
+
+ // http://dev.w3.org/html5/spec/video.html#dom-media-currenttime
+ currentTime: function(seconds){
+ if (seconds !== undefined) {
+
+ // Cache the last set value for smoother scrubbing.
+ this.values.lastSetCurrentTime = seconds;
+
+ this.techCall("setCurrentTime", seconds);
+
+ // Improve the accuracy of manual timeupdates
+ if (this.manualTimeUpdates) { this.trigger("timeupdate"); }
+
+ return this;
+ }
+
+ // Cache last currentTime and return
+ // Default to 0 seconds
+ return this.values.currentTime = (this.techGet("currentTime") || 0);
+ },
+
+ // http://dev.w3.org/html5/spec/video.html#dom-media-duration
+ // Duration should return NaN if not available. ParseFloat will turn false-ish values to NaN.
+ duration: function(){
+ return parseFloat(this.techGet("duration"));
+ },
+
+ // Calculates how much time is left. Not in spec, but useful.
+ remainingTime: function(){
+ return this.duration() - this.currentTime();
+ },
+
+ // http://dev.w3.org/html5/spec/video.html#dom-media-buffered
+ // Buffered returns a timerange object. Kind of like an array of portions of the video that have been downloaded.
+ // So far no browsers return more than one range (portion)
+ buffered: function(){
+ var buffered = this.techGet("buffered"),
+ start = 0,
+ end = this.values.bufferEnd = this.values.bufferEnd || 0, // Default end to 0 and store in values
+ timeRange;
+
+ if (buffered && buffered.length > 0 && buffered.end(0) !== end) {
+ end = buffered.end(0);
+ // Storing values allows them be overridden by setBufferedFromProgress
+ this.values.bufferEnd = end;
+ }
+
+ return _V_.createTimeRange(start, end);
+ },
+
+ // Calculates amount of buffer is full. Not in spec but useful.
+ bufferedPercent: function(){
+ return (this.duration()) ? this.buffered().end(0) / this.duration() : 0;
+ },
+
+ // http://dev.w3.org/html5/spec/video.html#dom-media-volume
+ volume: function(percentAsDecimal){
+ var vol;
+
+ if (percentAsDecimal !== undefined) {
+ vol = Math.max(0, Math.min(1, parseFloat(percentAsDecimal))); // Force value to between 0 and 1
+ this.values.volume = vol;
+ this.techCall("setVolume", vol);
+ _V_.setLocalStorage("volume", vol);
+ return this;
+ }
+
+ // Default to 1 when returning current volume.
+ vol = parseFloat(this.techGet("volume"));
+ return (isNaN(vol)) ? 1 : vol;
+ },
+
+ // http://dev.w3.org/html5/spec/video.html#attr-media-muted
+ muted: function(muted){
+ if (muted !== undefined) {
+ this.techCall("setMuted", muted);
+ return this;
+ }
+ return this.techGet("muted") || false; // Default to false
+ },
+
+ // http://dev.w3.org/html5/spec/dimension-attributes.html#attr-dim-height
+ // Video tag width/height only work in pixels. No percents.
+ // We could potentially allow percents but won't for now until we can do testing around it.
+ width: function(width, skipListeners){
+ if (width !== undefined) {
+ this.el.width = width;
+ this.el.style.width = width+"px";
+
+ // skipListeners allows us to avoid triggering the resize event when setting both width and height
+ if (!skipListeners) { this.trigger("resize"); }
+ return this;
+ }
+ return parseInt(this.el.getAttribute("width"));
+ },
+ height: function(height){
+ if (height !== undefined) {
+ this.el.height = height;
+ this.el.style.height = height+"px";
+ this.trigger("resize");
+ return this;
+ }
+ return parseInt(this.el.getAttribute("height"));
+ },
+ // Set both width and height at the same time.
+ size: function(width, height){
+ // Skip resize listeners on width for optimization
+ return this.width(width, true).height(height);
+ },
+
+ // Check if current tech can support native fullscreen (e.g. with built in controls lik iOS, so not our flash swf)
+ supportsFullScreen: function(){ return this.techGet("supportsFullScreen") || false; },
+
+ // Turn on fullscreen (or window) mode
+ requestFullScreen: function(){
+ var requestFullScreen = _V_.support.requestFullScreen;
+
+ this.isFullScreen = true;
+
+ // Check for browser element fullscreen support
+ if (requestFullScreen) {
+
+ // Trigger fullscreenchange event after change
+ _V_.on(document, requestFullScreen.eventName, this.proxy(function(){
+ this.isFullScreen = document[requestFullScreen.isFullScreen];
+
+ // If cancelling fullscreen, remove event listener.
+ if (this.isFullScreen == false) {
+ _V_.removeEvent(document, requestFullScreen.eventName, arguments.callee);
+ }
+
+ this.trigger("fullscreenchange");
+ }));
+
+ // Flash and other plugins get reloaded when you take their parent to fullscreen.
+ // To fix that we'll remove the tech, and reload it after the resize has finished.
+ if (this.tech.support.fullscreenResize === false && this.options.flash.iFrameMode != true) {
+
+ this.pause();
+ this.unloadTech();
+
+ _V_.on(document, requestFullScreen.eventName, this.proxy(function(){
+ _V_.removeEvent(document, requestFullScreen.eventName, arguments.callee);
+ this.loadTech(this.techName, { src: this.values.src });
+ }));
+
+ this.el[requestFullScreen.requestFn]();
+
+ } else {
+ this.el[requestFullScreen.requestFn]();
+ }
+
+ } else if (this.tech.supportsFullScreen()) {
+ this.trigger("fullscreenchange");
+ this.techCall("enterFullScreen");
+
+ } else {
+ this.trigger("fullscreenchange");
+ this.enterFullWindow();
+ }
+
+ return this;
+ },
+
+ cancelFullScreen: function(){
+ var requestFullScreen = _V_.support.requestFullScreen;
+
+ this.isFullScreen = false;
+
+ // Check for browser element fullscreen support
+ if (requestFullScreen) {
+
+ // Flash and other plugins get reloaded when you take their parent to fullscreen.
+ // To fix that we'll remove the tech, and reload it after the resize has finished.
+ if (this.tech.support.fullscreenResize === false && this.options.flash.iFrameMode != true) {
+
+ this.pause();
+ this.unloadTech();
+
+ _V_.on(document, requestFullScreen.eventName, this.proxy(function(){
+ _V_.removeEvent(document, requestFullScreen.eventName, arguments.callee);
+ this.loadTech(this.techName, { src: this.values.src })
+ }));
+
+ document[requestFullScreen.cancelFn]();
+
+ } else {
+ document[requestFullScreen.cancelFn]();
+ }
+
+ } else if (this.tech.supportsFullScreen()) {
+ this.techCall("exitFullScreen");
+ this.trigger("fullscreenchange");
+
+ } else {
+ this.exitFullWindow();
+ this.trigger("fullscreenchange");
+ }
+
+ return this;
+ },
+
+ // When fullscreen isn't supported we can stretch the video container to as wide as the browser will let us.
+ enterFullWindow: function(){
+ this.isFullWindow = true;
+
+ // Storing original doc overflow value to return to when fullscreen is off
+ this.docOrigOverflow = document.documentElement.style.overflow;
+
+ // Add listener for esc key to exit fullscreen
+ _V_.on(document, "keydown", _V_.proxy(this, this.fullWindowOnEscKey));
+
+ // Hide any scroll bars
+ document.documentElement.style.overflow = 'hidden';
+
+ // Apply fullscreen styles
+ _V_.addClass(document.body, "vjs-full-window");
+ _V_.addClass(this.el, "vjs-fullscreen");
+
+ this.trigger("enterFullWindow");
+ },
+ fullWindowOnEscKey: function(event){
+ if (event.keyCode == 27) {
+ if (this.isFullScreen == true) {
+ this.cancelFullScreen();
+ } else {
+ this.exitFullWindow();
+ }
+ }
+ },
+
+ exitFullWindow: function(){
+ this.isFullWindow = false;
+ _V_.removeEvent(document, "keydown", this.fullWindowOnEscKey);
+
+ // Unhide scroll bars.
+ document.documentElement.style.overflow = this.docOrigOverflow;
+
+ // Remove fullscreen styles
+ _V_.removeClass(document.body, "vjs-full-window");
+ _V_.removeClass(this.el, "vjs-fullscreen");
+
+ // Resize the box, controller, and poster to original sizes
+ // this.positionAll();
+ this.trigger("exitFullWindow");
+ },
+
+ selectSource: function(sources){
+
+ // Loop through each playback technology in the options order
+ for (var i=0,j=this.options.techOrder;i<j.length;i++) {
+ var techName = j[i],
+ tech = _V_[techName];
+ // tech = _V_.tech[techName];
+
+ // Check if the browser supports this technology
+ if (tech.isSupported()) {
+
+ // Loop through each source object
+ for (var a=0,b=sources;a<b.length;a++) {
+ var source = b[a];
+
+ // Check if source can be played with this technology
+ if (tech.canPlaySource.call(this, source)) {
+
+ return { source: source, tech: techName };
+
+ }
+ }
+ }
+ }
+
+ return false;
+ },
+
+ // src is a pretty powerful function
+ // If you pass it an array of source objects, it will find the best source to play and use that object.src
+ // If the new source requires a new playback technology, it will switch to that.
+ // If you pass it an object, it will set the source to object.src
+ // If you pass it anything else (url string) it will set the video source to that
+ src: function(source){
+ // Case: Array of source objects to choose from and pick the best to play
+ if (source instanceof Array) {
+
+ var sourceTech = this.selectSource(source),
+ source,
+ techName;
+
+ if (sourceTech) {
+ source = sourceTech.source;
+ techName = sourceTech.tech;
+
+ // If this technology is already loaded, set source
+ if (techName == this.techName) {
+ this.src(source); // Passing the source object
+
+ // Otherwise load this technology with chosen source
+ } else {
+ this.loadTech(techName, source);
+ }
+ } else {
+ _V_.log("No compatible source and playback technology were found.")
+ }
+
+ // Case: Source object { src: "", type: "" ... }
+ } else if (source instanceof Object) {
+
+ if (_V_[this.techName].canPlaySource(source)) {
+ this.src(source.src);
+ } else {
+ // Send through tech loop to check for a compatible technology.
+ this.src([source]);
+ }
+
+ // Case: URL String (http://myvideo...)
+ } else {
+ // Cache for getting last set source
+ this.values.src = source;
+
+ if (!this.isReady) {
+ this.ready(function(){
+ this.src(source);
+ });
+ } else {
+ this.techCall("src", source);
+ if (this.options.preload == "auto") {
+ this.load();
+ }
+ if (this.options.autoplay) {
+ this.play();
+ }
+ }
+ }
+ return this;
+ },
+
+ // Begin loading the src data
+ // http://dev.w3.org/html5/spec/video.html#dom-media-load
+ load: function(){
+ this.techCall("load");
+ return this;
+ },
+
+ // http://dev.w3.org/html5/spec/video.html#dom-media-currentsrc
+ currentSrc: function(){
+ return this.techGet("currentSrc") || this.values.src || "";
+ },
+
+ // Attributes/Options
+ preload: function(value){
+ if (value !== undefined) {
+ this.techCall("setPreload", value);
+ this.options.preload = value;
+ return this;
+ }
+ return this.techGet("preload");
+ },
+ autoplay: function(value){
+ if (value !== undefined) {
+ this.techCall("setAutoplay", value);
+ this.options.autoplay = value;
+ return this;
+ }
+ return this.techGet("autoplay", value);
+ },
+ loop: function(value){
+ if (value !== undefined) {
+ this.techCall("setLoop", value);
+ this.options.loop = value;
+ return this;
+ }
+ return this.techGet("loop");
+ },
+
+ controls: function(){ return this.options.controls; },
+ poster: function(){ return this.techGet("poster"); },
+ error: function(){ return this.techGet("error"); },
+ ended: function(){ return this.techGet("ended"); }
+
+ // Methods to add support for
+ // networkState: function(){ return this.techCall("networkState"); },
+ // readyState: function(){ return this.techCall("readyState"); },
+ // seeking: function(){ return this.techCall("seeking"); },
+ // initialTime: function(){ return this.techCall("initialTime"); },
+ // startOffsetTime: function(){ return this.techCall("startOffsetTime"); },
+ // played: function(){ return this.techCall("played"); },
+ // seekable: function(){ return this.techCall("seekable"); },
+ // videoTracks: function(){ return this.techCall("videoTracks"); },
+ // audioTracks: function(){ return this.techCall("audioTracks"); },
+ // videoWidth: function(){ return this.techCall("videoWidth"); },
+ // videoHeight: function(){ return this.techCall("videoHeight"); },
+ // defaultPlaybackRate: function(){ return this.techCall("defaultPlaybackRate"); },
+ // playbackRate: function(){ return this.techCall("playbackRate"); },
+ // mediaGroup: function(){ return this.techCall("mediaGroup"); },
+ // controller: function(){ return this.techCall("controller"); },
+ // defaultMuted: function(){ return this.techCall("defaultMuted"); }
+});
+
+// RequestFullscreen API
+(function(){
+ var requestFn,
+ cancelFn,
+ eventName,
+ isFullScreen,
+ playerProto = _V_.Player.prototype;
+
+ // Current W3C Spec
+ // http://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#api
+ // Mozilla Draft: https://wiki.mozilla.org/Gecko:FullScreenAPI#fullscreenchange_event
+ if (document.cancelFullscreen !== undefined) {
+ requestFn = "requestFullscreen";
+ cancelFn = "exitFullscreen";
+ eventName = "fullscreenchange";
+ isFullScreen = "fullScreen";
+
+ // Webkit (Chrome/Safari) and Mozilla (Firefox) have working implementaitons
+ // that use prefixes and vary slightly from the new W3C spec. Specifically, using 'exit' instead of 'cancel',
+ // and lowercasing the 'S' in Fullscreen.
+ // Other browsers don't have any hints of which version they might follow yet, so not going to try to predict by loopeing through all prefixes.
+ } else {
+
+ _V_.each(["moz", "webkit"], function(prefix){
+
+ // https://github.com/zencoder/video-js/pull/128
+ if ((prefix != "moz" || document.mozFullScreenEnabled) && document[prefix + "CancelFullScreen"] !== undefined) {
+ requestFn = prefix + "RequestFullScreen";
+ cancelFn = prefix + "CancelFullScreen";
+ eventName = prefix + "fullscreenchange";
+
+ if (prefix == "webkit") {
+ isFullScreen = prefix + "IsFullScreen";
+ } else {
+ isFullScreen = prefix + "FullScreen";
+ }
+ }
+
+ });
+
+ }
+
+ if (requestFn) {
+ _V_.support.requestFullScreen = {
+ requestFn: requestFn,
+ cancelFn: cancelFn,
+ eventName: eventName,
+ isFullScreen: isFullScreen
+ };
+ }
+
+})();/* Playback Technology - Base class for playback technologies
+================================================================================ */
+_V_.PlaybackTech = _V_.Component.extend({
+ init: function(player, options){
+ // this._super(player, options);
+
+ // Make playback element clickable
+ // _V_.addEvent(this.el, "click", _V_.proxy(this, _V_.PlayToggle.prototype.onClick));
+
+ // this.addEvent("click", this.proxy(this.onClick));
+
+ // player.triggerEvent("techready");
+ },
+ // destroy: function(){},
+ // createElement: function(){},
+ onClick: function(){
+ if (this.player.options.controls) {
+ _V_.PlayToggle.prototype.onClick.call(this);
+ }
+ }
+});
+
+// Create placeholder methods for each that warn when a method isn't supported by the current playback technology
+_V_.apiMethods = "play,pause,paused,currentTime,setCurrentTime,duration,buffered,volume,setVolume,muted,setMuted,width,height,supportsFullScreen,enterFullScreen,src,load,currentSrc,preload,setPreload,autoplay,setAutoplay,loop,setLoop,error,networkState,readyState,seeking,initialTime,startOffsetTime,played,seekable,ended,videoTracks,audioTracks,videoWidth,videoHeight,textTracks,defaultPlaybackRate,playbackRate,mediaGroup,controller,controls,defaultMuted".split(",");
+_V_.each(_V_.apiMethods, function(methodName){
+ _V_.PlaybackTech.prototype[methodName] = function(){
+ throw new Error("The '"+methodName+"' method is not available on the playback technology's API");
+ }
+});
+
+/* HTML5 Playback Technology - Wrapper for HTML5 Media API
+================================================================================ */
+_V_.html5 = _V_.PlaybackTech.extend({
+
+ init: function(player, options, ready){
+ this.player = player;
+ this.el = this.createElement();
+ this.ready(ready);
+
+ this.addEvent("click", this.proxy(this.onClick));
+
+ var source = options.source;
+
+ // If the element source is already set, we may have missed the loadstart event, and want to trigger it.
+ // We don't want to set the source again and interrupt playback.
+ if (source && this.el.currentSrc == source.src) {
+ player.triggerEvent("loadstart");
+
+ // Otherwise set the source if one was provided.
+ } else if (source) {
+ this.el.src = source.src;
+ }
+
+ // Chrome and Safari both have issues with autoplay.
+ // In Safari (5.1.1), when we move the video element into the container div, autoplay doesn't work.
+ // In Chrome (15), if you have autoplay + a poster + no controls, the video gets hidden (but audio plays)
+ // This fixes both issues. Need to wait for API, so it updates displays correctly
+ player.ready(function(){
+ if (this.options.autoplay && this.paused()) {
+ this.tag.poster = null; // Chrome Fix. Fixed in Chrome v16.
+ this.play();
+ }
+ });
+
+ this.setupTriggers();
+
+ this.triggerReady();
+ },
+
+ destroy: function(){
+ this.player.tag = false;
+ this.removeTriggers();
+ this.el.parentNode.removeChild(this.el);
+ },
+
+ createElement: function(){
+ var html5 = _V_.html5,
+ player = this.player,
+
+ // If possible, reuse original tag for HTML5 playback technology element
+ el = player.tag,
+ newEl;
+
+ // Check if this browser supports moving the element into the box.
+ // On the iPhone video will break if you move the element,
+ // So we have to create a brand new element.
+ if (!el || this.support.movingElementInDOM === false) {
+
+ // If the original tag is still there, remove it.
+ if (el) {
+ player.el.removeChild(el);
+ }
+
+ newEl = _V_.createElement("video", {
+ id: el.id || player.el.id + "_html5_api",
+ className: el.className || "vjs-tech"
+ });
+
+ el = newEl;
+ _V_.insertFirst(el, player.el);
+ }
+
+ // Update tag settings, in case they were overridden
+ _V_.each(["autoplay","preload","loop","muted"], function(attr){ // ,"poster"
+ if (player.options[attr] !== null) {
+ el[attr] = player.options[attr];
+ }
+ }, this);
+
+ return el;
+ },
+
+ // Make video events trigger player events
+ // May seem verbose here, but makes other APIs possible.
+ setupTriggers: function(){
+ _V_.each.call(this, _V_.html5.events, function(type){
+ _V_.addEvent(this.el, type, _V_.proxy(this.player, this.eventHandler));
+ });
+ },
+ removeTriggers: function(){
+ _V_.each.call(this, _V_.html5.events, function(type){
+ _V_.removeEvent(this.el, type, _V_.proxy(this.player, this.eventHandler));
+ });
+ },
+ eventHandler: function(e){
+ e.stopPropagation();
+ this.triggerEvent(e);
+ },
+
+ play: function(){ this.el.play(); },
+ pause: function(){ this.el.pause(); },
+ paused: function(){ return this.el.paused; },
+
+ currentTime: function(){ return this.el.currentTime; },
+ setCurrentTime: function(seconds){
+ try {
+ this.el.currentTime = seconds;
+ } catch(e) {
+ _V_.log(e, "Video isn't ready. (VideoJS)");
+ // this.warning(VideoJS.warnings.videoNotReady);
+ }
+ },
+
+ duration: function(){ return this.el.duration || 0; },
+ buffered: function(){ return this.el.buffered; },
+
+ volume: function(){ return this.el.volume; },
+ setVolume: function(percentAsDecimal){ this.el.volume = percentAsDecimal; },
+ muted: function(){ return this.el.muted; },
+ setMuted: function(muted){ this.el.muted = muted },
+
+ width: function(){ return this.el.offsetWidth; },
+ height: function(){ return this.el.offsetHeight; },
+
+ supportsFullScreen: function(){
+ if (typeof this.el.webkitEnterFullScreen == 'function') {
+
+ // Seems to be broken in Chromium/Chrome && Safari in Leopard
+ if (!navigator.userAgent.match("Chrome") && !navigator.userAgent.match("Mac OS X 10.5")) {
+ return true;
+ }
+ }
+ return false;
+ },
+
+ enterFullScreen: function(){
+ try {
+ this.el.webkitEnterFullScreen();
+ } catch (e) {
+ if (e.code == 11) {
+ // this.warning(VideoJS.warnings.videoNotReady);
+ _V_.log("VideoJS: Video not ready.")
+ }
+ }
+ },
+ exitFullScreen: function(){
+ try {
+ this.el.webkitExitFullScreen();
+ } catch (e) {
+ if (e.code == 11) {
+ // this.warning(VideoJS.warnings.videoNotReady);
+ _V_.log("VideoJS: Video not ready.")
+ }
+ }
+ },
+ src: function(src){ this.el.src = src; },
+ load: function(){ this.el.load(); },
+ currentSrc: function(){ return this.el.currentSrc; },
+
+ preload: function(){ return this.el.preload; },
+ setPreload: function(val){ this.el.preload = val; },
+ autoplay: function(){ return this.el.autoplay; },
+ setAutoplay: function(val){ this.el.autoplay = val; },
+ loop: function(){ return this.el.loop; },
+ setLoop: function(val){ this.el.loop = val; },
+
+ error: function(){ return this.el.error; },
+ // networkState: function(){ return this.el.networkState; },
+ // readyState: function(){ return this.el.readyState; },
+ seeking: function(){ return this.el.seeking; },
+ // initialTime: function(){ return this.el.initialTime; },
+ // startOffsetTime: function(){ return this.el.startOffsetTime; },
+ // played: function(){ return this.el.played; },
+ // seekable: function(){ return this.el.seekable; },
+ ended: function(){ return this.el.ended; },
+ // videoTracks: function(){ return this.el.videoTracks; },
+ // audioTracks: function(){ return this.el.audioTracks; },
+ // videoWidth: function(){ return this.el.videoWidth; },
+ // videoHeight: function(){ return this.el.videoHeight; },
+ // textTracks: function(){ return this.el.textTracks; },
+ // defaultPlaybackRate: function(){ return this.el.defaultPlaybackRate; },
+ // playbackRate: function(){ return this.el.playbackRate; },
+ // mediaGroup: function(){ return this.el.mediaGroup; },
+ // controller: function(){ return this.el.controller; },
+ controls: function(){ return this.player.options.controls; },
+ defaultMuted: function(){ return this.el.defaultMuted; }
+});
+
+/* HTML5 Support Testing -------------------------------------------------------- */
+
+_V_.html5.isSupported = function(){
+ return !!document.createElement("video").canPlayType;
+};
+
+_V_.html5.canPlaySource = function(srcObj){
+ return !!document.createElement("video").canPlayType(srcObj.type);
+ // TODO: Check Type
+ // If no Type, check ext
+ // Check Media Type
+};
+
+// List of all HTML5 events (various uses).
+_V_.html5.events = "loadstart,suspend,abort,error,emptied,stalled,loadedmetadata,loadeddata,canplay,canplaythrough,playing,waiting,seeking,seeked,ended,durationchange,timeupdate,progress,play,pause,ratechange,volumechange".split(",");
+
+/* HTML5 Device Fixes ---------------------------------------------------------- */
+
+_V_.html5.prototype.support = {
+
+ // Support for tech specific full screen. (webkitEnterFullScreen, not requestFullscreen)
+ // http://developer.apple.com/library/safari/#documentation/AudioVideo/Reference/HTMLVideoElementClassReference/HTMLVideoElement/HTMLVideoElement.html
+ // Seems to be broken in Chromium/Chrome && Safari in Leopard
+ fullscreen: (typeof _V_.testVid.webkitEnterFullScreen !== undefined) ? (!_V_.ua.match("Chrome") && !_V_.ua.match("Mac OS X 10.5") ? true : false) : false,
+
+ // In iOS, if you move a video element in the DOM, it breaks video playback.
+ movingElementInDOM: !_V_.isIOS()
+
+};
+
+// Android
+if (_V_.isAndroid()) {
+
+ // Override Android 2.2 and less canPlayType method which is broken
+ if (_V_.androidVersion() < 3) {
+ document.createElement("video").constructor.prototype.canPlayType = function(type){
+ return (type && type.toLowerCase().indexOf("video/mp4") != -1) ? "maybe" : "";
+ };
+ }
+}
+
+
+/* VideoJS-SWF - Custom Flash Player with HTML5-ish API - https://github.com/zencoder/video-js-swf
+================================================================================ */
+_V_.flash = _V_.PlaybackTech.extend({
+
+ init: function(player, options){
+ this.player = player;
+
+ var source = options.source,
+
+ // Which element to embed in
+ parentEl = options.parentEl,
+
+ // Create a temporary element to be replaced by swf object
+ placeHolder = this.el = _V_.createElement("div", { id: parentEl.id + "_temp_flash" }),
+
+ // Generate ID for swf object
+ objId = player.el.id+"_flash_api",
+
+ // Store player options in local var for optimization
+ playerOptions = player.options,
+
+ // Merge default flashvars with ones passed in to init
+ flashVars = _V_.merge({
+
+ // SWF Callback Functions
+ readyFunction: "_V_.flash.onReady",
+ eventProxyFunction: "_V_.flash.onEvent",
+ errorEventProxyFunction: "_V_.flash.onError",
+
+ // Player Settings
+ autoplay: playerOptions.autoplay,
+ preload: playerOptions.preload,
+ loop: playerOptions.loop,
+ muted: playerOptions.muted
+
+ }, options.flashVars),
+
+ // Merge default parames with ones passed in
+ params = _V_.merge({
+ wmode: "opaque", // Opaque is needed to overlay controls, but can affect playback performance
+ bgcolor: "#000000" // Using bgcolor prevents a white flash when the object is loading
+ }, options.params),
+
+ // Merge default attributes with ones passed in
+ attributes = _V_.merge({
+ id: objId,
+ name: objId, // Both ID and Name needed or swf to identifty itself
+ 'class': 'vjs-tech'
+ }, options.attributes)
+ ;
+
+ // If source was supplied pass as a flash var.
+ if (source) {
+ flashVars.src = encodeURIComponent(_V_.getAbsoluteURL(source.src));
+ }
+
+ // Add placeholder to player div
+ _V_.insertFirst(placeHolder, parentEl);
+
+ // Having issues with Flash reloading on certain page actions (hide/resize/fullscreen) in certain browsers
+ // This allows resetting the playhead when we catch the reload
+ if (options.startTime) {
+ this.ready(function(){
+ this.load();
+ this.play();
+ this.currentTime(options.startTime);
+ });
+ }
+
+ // Flash iFrame Mode
+ // In web browsers there are multiple instances where changing the parent element or visibility of a plugin causes the plugin to reload.
+ // - Firefox just about always. https://bugzilla.mozilla.org/show_bug.cgi?id=90268 (might be fixed by version 13)
+ // - Webkit when hiding the plugin
+ // - Webkit and Firefox when using requestFullScreen on a parent element
+ // Loading the flash plugin into a dynamically generated iFrame gets around most of these issues.
+ // Issues that remain include hiding the element and requestFullScreen in Firefox specifically
+
+ // There's on particularly annoying issue with this method which is that Firefox throws a security error on an offsite Flash object loaded into a dynamically created iFrame.
+ // Even though the iframe was inserted into a page on the web, Firefox + Flash considers it a local app trying to access an internet file.
+ // I tried mulitple ways of setting the iframe src attribute but couldn't find a src that worked well. Tried a real/fake source, in/out of domain.
+ // Also tried a method from stackoverflow that caused a security error in all browsers. http://stackoverflow.com/questions/2486901/how-to-set-document-domain-for-a-dynamically-generated-iframe
+ // In the end the solution I found to work was setting the iframe window.location.href right before doing a document.write of the Flash object.
+ // The only downside of this it seems to trigger another http request to the original page (no matter what's put in the href). Not sure why that is.
+
+ // NOTE (2012-01-29): Cannot get Firefox to load the remote hosted SWF into a dynamically created iFrame
+ // Firefox 9 throws a security error, unleess you call location.href right before doc.write.
+ // Not sure why that even works, but it causes the browser to look like it's continuously trying to load the page.
+ // Firefox 3.6 keeps calling the iframe onload function anytime I write to it, causing an endless loop.
+
+ if (options.iFrameMode == true && !_V_.isFF) {
+
+ // Create iFrame with vjs-tech class so it's 100% width/height
+ var iFrm = _V_.createElement("iframe", {
+ id: objId + "_iframe",
+ name: objId + "_iframe",
+ className: "vjs-tech",
+ scrolling: "no",
+ marginWidth: 0,
+ marginHeight: 0,
+ frameBorder: 0
+ });
+
+ // Update ready function names in flash vars for iframe window
+ flashVars.readyFunction = "ready";
+ flashVars.eventProxyFunction = "events";
+ flashVars.errorEventProxyFunction = "errors";
+
+ // Tried multiple methods to get this to work in all browsers
+
+ // Tried embedding the flash object in the page first, and then adding a place holder to the iframe, then replacing the placeholder with the page object.
+ // The goal here was to try to load the swf URL in the parent page first and hope that got around the firefox security error
+ // var newObj = _V_.flash.embed(options.swf, placeHolder, flashVars, params, attributes);
+ // (in onload)
+ // var temp = _V_.createElement("a", { id:"asdf", innerHTML: "asdf" } );
+ // iDoc.body.appendChild(temp);
+
+ // Tried embedding the flash object through javascript in the iframe source.
+ // This works in webkit but still triggers the firefox security error
+ // iFrm.src = "javascript: document.write('"+_V_.flash.getEmbedCode(options.swf, flashVars, params, attributes)+"');";
+
+ // Tried an actual local iframe just to make sure that works, but it kills the easiness of the CDN version if you require the user to host an iframe
+ // We should add an option to host the iframe locally though, because it could help a lot of issues.
+ // iFrm.src = "iframe.html";
+
+ // Wait until iFrame has loaded to write into it.
+ _V_.addEvent(iFrm, "load", _V_.proxy(this, function(){
+
+ var iDoc, objTag, swfLoc,
+ iWin = iFrm.contentWindow,
+ varString = "";
+
+
+ // The one working method I found was to use the iframe's document.write() to create the swf object
+ // This got around the security issue in all browsers except firefox.
+ // I did find a hack where if I call the iframe's window.location.href="", it would get around the security error
+ // However, the main page would look like it was loading indefinitely (URL bar loading spinner would never stop)
+ // Plus Firefox 3.6 didn't work no matter what I tried.
+ // if (_V_.ua.match("Firefox")) {
+ // iWin.location.href = "";
+ // }
+
+ // Get the iFrame's document depending on what the browser supports
+ iDoc = iFrm.contentDocument ? iFrm.contentDocument : iFrm.contentWindow.document;
+
+ // Tried ensuring both document domains were the same, but they already were, so that wasn't the issue.
+ // Even tried adding /. that was mentioned in a browser security writeup
+ // document.domain = document.domain+"/.";
+ // iDoc.domain = document.domain+"/.";
+
+ // Tried adding the object to the iframe doc's innerHTML. Security error in all browsers.
+ // iDoc.body.innerHTML = swfObjectHTML;
+
+ // Tried appending the object to the iframe doc's body. Security error in all browsers.
+ // iDoc.body.appendChild(swfObject);
+
+ // Using document.write actually got around the security error that browsers were throwing.
+ // Again, it's a dynamically generated (same domain) iframe, loading an external Flash swf.
+ // Not sure why that's a security issue, but apparently it is.
+ iDoc.write(_V_.flash.getEmbedCode(options.swf, flashVars, params, attributes));
+
+ // Setting variables on the window needs to come after the doc write because otherwise they can get reset in some browsers
+ // So far no issues with swf ready event being called before it's set on the window.
+ iWin.player = this.player;
+
+ // Create swf ready function for iFrame window
+ iWin.ready = _V_.proxy(this.player, function(currSwf){
+ var el = iDoc.getElementById(currSwf),
+ player = this,
+ tech = player.tech;
+
+ // Update reference to playback technology element
+ tech.el = el;
+
+ // Now that the element is ready, make a click on the swf play the video
+ _V_.addEvent(el, "click", tech.proxy(tech.onClick));
+
+ // Make sure swf is actually ready. Sometimes the API isn't actually yet.
+ _V_.flash.checkReady(tech);
+ });
+
+ // Create event listener for all swf events
+ iWin.events = _V_.proxy(this.player, function(swfID, eventName, other){
+ var player = this;
+ if (player && player.techName == "flash") {
+ player.triggerEvent(eventName);
+ }
+ });
+
+ // Create error listener for all swf errors
+ iWin.errors = _V_.proxy(this.player, function(swfID, eventName){
+ _V_.log("Flash Error", eventName);
+ });
+
+ }));
+
+ // Replace placeholder with iFrame (it will load now)
+ placeHolder.parentNode.replaceChild(iFrm, placeHolder);
+
+ // If not using iFrame mode, embed as normal object
+ } else {
+ _V_.flash.embed(options.swf, placeHolder, flashVars, params, attributes);
+ }
+ },
+
+ destroy: function(){
+ this.el.parentNode.removeChild(this.el);
+ },
+
+ // setupTriggers: function(){}, // Using global onEvent func to distribute events
+
+ play: function(){ this.el.vjs_play(); },
+ pause: function(){ this.el.vjs_pause(); },
+ src: function(src){
+ // Make sure source URL is abosolute.
+ src = _V_.getAbsoluteURL(src);
+
+ this.el.vjs_src(src);
+
+ // Currently the SWF doesn't autoplay if you load a source later.
+ // e.g. Load player w/ no source, wait 2s, set src.
+ if (this.player.autoplay()) {
+ var tech = this;
+ setTimeout(function(){ tech.play(); }, 0);
+ }
+ },
+ load: function(){ this.el.vjs_load(); },
+ poster: function(){ this.el.vjs_getProperty("poster"); },
+
+ buffered: function(){
+ return _V_.createTimeRange(0, this.el.vjs_getProperty("buffered"));
+ },
+
+ supportsFullScreen: function(){
+ return false; // Flash does not allow fullscreen through javascript
+ },
+ enterFullScreen: function(){
+ return false;
+ }
+});
+
+// Create setters and getters for attributes
+(function(){
+
+ var api = _V_.flash.prototype,
+ readWrite = "preload,currentTime,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted".split(","),
+ readOnly = "error,currentSrc,networkState,readyState,seeking,initialTime,duration,startOffsetTime,paused,played,seekable,ended,videoTracks,audioTracks,videoWidth,videoHeight,textTracks".split(","),
+ callOnly = "load,play,pause".split(",");
+ // Overridden: buffered
+
+ createSetter = function(attr){
+ var attrUpper = attr.charAt(0).toUpperCase() + attr.slice(1);
+ api["set"+attrUpper] = function(val){ return this.el.vjs_setProperty(attr, val); };
+ },
+
+ createGetter = function(attr){
+ api[attr] = function(){ return this.el.vjs_getProperty(attr); };
+ }
+ ;
+
+ // Create getter and setters for all read/write attributes
+ _V_.each(readWrite, function(attr){
+ createGetter(attr);
+ createSetter(attr);
+ });
+
+ // Create getters for read-only attributes
+ _V_.each(readOnly, function(attr){
+ createGetter(attr);
+ });
+
+})();
+
+/* Flash Support Testing -------------------------------------------------------- */
+
+_V_.flash.isSupported = function(){
+ return _V_.flash.version()[0] >= 10;
+ // return swfobject.hasFlashPlayerVersion("10");
+};
+
+_V_.flash.canPlaySource = function(srcObj){
+ if (srcObj.type in _V_.flash.prototype.support.formats) { return "maybe"; }
+};
+
+_V_.flash.prototype.support = {
+ formats: {
+ "video/flv": "FLV",
+ "video/x-flv": "FLV",
+ "video/mp4": "MP4",
+ "video/m4v": "MP4"
+ },
+
+ // Optional events that we can manually mimic with timers
+ progressEvent: false,
+ timeupdateEvent: false,
+
+ // Resizing plugins using request fullscreen reloads the plugin
+ fullscreenResize: false,
+
+ // Resizing plugins in Firefox always reloads the plugin (e.g. full window mode)
+ parentResize: !(_V_.ua.match("Firefox"))
+};
+
+_V_.flash.onReady = function(currSwf){
+
+ var el = _V_.el(currSwf);
+
+ // Get player from box
+ // On firefox reloads, el might already have a player
+ var player = el.player || el.parentNode.player,
+ tech = player.tech;
+
+ // Reference player on tech element
+ el.player = player;
+
+ // Update reference to playback technology element
+ tech.el = el;
+
+ // Now that the element is ready, make a click on the swf play the video
+ tech.addEvent("click", tech.onClick);
+
+ _V_.flash.checkReady(tech);
+};
+
+// The SWF isn't alwasy ready when it says it is. Sometimes the API functions still need to be added to the object.
+// If it's not ready, we set a timeout to check again shortly.
+_V_.flash.checkReady = function(tech){
+
+ // Check if API property exists
+ if (tech.el.vjs_getProperty) {
+
+ // If so, tell tech it's ready
+ tech.triggerReady();
+
+ // Otherwise wait longer.
+ } else {
+
+ setTimeout(function(){
+ _V_.flash.checkReady(tech);
+ }, 50);
+
+ }
+};
+
+// Trigger events from the swf on the player
+_V_.flash.onEvent = function(swfID, eventName){
+ var player = _V_.el(swfID).player;
+ player.triggerEvent(eventName);
+};
+
+// Log errors from the swf
+_V_.flash.onError = function(swfID, err){
+ var player = _V_.el(swfID).player;
+ player.triggerEvent("error");
+ _V_.log("Flash Error", err, swfID);
+};
+
+// Flash Version Check
+_V_.flash.version = function(){
+ var version = '0,0,0'
+
+ // IE
+ try {
+ version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
+
+ // other browsers
+ } catch(e) {
+ try {
+ if (navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin){
+ version = (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]).description.replace(/\D+/g, ",").match(/^,?(.+),?$/)[1];
+ }
+ } catch(e) {}
+ }
+ return version.split(",");
+}
+
+// Flash embedding method. Only used in non-iframe mode
+_V_.flash.embed = function(swf, placeHolder, flashVars, params, attributes){
+ var code = _V_.flash.getEmbedCode(swf, flashVars, params, attributes),
+
+ // Get element by embedding code and retrieving created element
+ obj = _V_.createElement("div", { innerHTML: code }).childNodes[0],
+
+ par = placeHolder.parentNode
+ ;
+
+ placeHolder.parentNode.replaceChild(obj, placeHolder);
+
+ // IE6 seems to have an issue where it won't initialize the swf object after injecting it.
+ // This is a dumb temporary fix
+ if (_V_.isIE()) {
+ var newObj = par.childNodes[0];
+ setTimeout(function(){
+ newObj.style.display = "block";
+ }, 1000);
+ }
+
+ return obj;
+
+};
+
+_V_.flash.getEmbedCode = function(swf, flashVars, params, attributes){
+
+ var objTag = '<object type="application/x-shockwave-flash"',
+ flashVarsString = '',
+ paramsString = ''
+ attrsString = '';
+
+ // Convert flash vars to string
+ if (flashVars) {
+ _V_.eachProp(flashVars, function(key, val){
+ flashVarsString += (key + "=" + val + "&");
+ });
+ }
+
+ // Add swf, flashVars, and other default params
+ params = _V_.merge({
+ movie: swf,
+ flashvars: flashVarsString,
+ allowScriptAccess: "always", // Required to talk to swf
+ allowNetworking: "all" // All should be default, but having security issues.
+ }, params);
+
+ // Create param tags string
+ _V_.eachProp(params, function(key, val){
+ paramsString += '<param name="'+key+'" value="'+val+'" />';
+ });
+
+ attributes = _V_.merge({
+ // Add swf to attributes (need both for IE and Others to work)
+ data: swf,
+
+ // Default to 100% width/height
+ width: "100%",
+ height: "100%"
+
+ }, attributes);
+
+ // Create Attributes string
+ _V_.eachProp(attributes, function(key, val){
+ attrsString += (key + '="' + val + '" ');
+ });
+
+ return objTag + attrsString + '>' + paramsString + '</object>';
+}
+/* Control - Base class for all control elements
+================================================================================ */
+_V_.Control = _V_.Component.extend({
+
+ buildCSSClass: function(){
+ return "vjs-control " + this._super();
+ }
+
+});
+
+/* Control Bar
+================================================================================ */
+_V_.ControlBar = _V_.Component.extend({
+
+ options: {
+ loadEvent: "play",
+ components: {
+ "playToggle": {},
+ "fullscreenToggle": {},
+ "currentTimeDisplay": {},
+ "timeDivider": {},
+ "durationDisplay": {},
+ "remainingTimeDisplay": {},
+ "progressControl": {},
+ "volumeControl": {},
+ "muteToggle": {}
+ }
+ },
+
+ init: function(player, options){
+ this._super(player, options);
+
+ player.on("play", this.proxy(function(){
+ this.fadeIn();
+ this.player.on("mouseover", this.proxy(this.fadeIn));
+ this.player.on("mouseout", this.proxy(this.fadeOut));
+ }));
+
+ },
+
+ createElement: function(){
+ return _V_.createElement("div", {
+ className: "vjs-controls"
+ });
+ },
+
+ fadeIn: function(){
+ this._super();
+ this.player.trigger("controlsvisible");
+ },
+
+ fadeOut: function(){
+ this._super();
+ this.player.trigger("controlshidden");
+ },
+
+ lockShowing: function(){
+ this.el.style.opacity = "1";
+ }
+
+});
+
+/* Button - Base class for all buttons
+================================================================================ */
+_V_.Button = _V_.Control.extend({
+
+ init: function(player, options){
+ this._super(player, options);
+
+ this.on("click", this.onClick);
+ this.on("focus", this.onFocus);
+ this.on("blur", this.onBlur);
+ },
+
+ createElement: function(type, attrs){
+ // Add standard Aria and Tabindex info
+ attrs = _V_.merge({
+ className: this.buildCSSClass(),
+ innerHTML: '<div><span class="vjs-control-text">' + (this.buttonText || "Need Text") + '</span></div>',
+ role: "button",
+ tabIndex: 0
+ }, attrs);
+
+ return this._super(type, attrs);
+ },
+
+ // Click - Override with specific functionality for button
+ onClick: function(){},
+
+ // Focus - Add keyboard functionality to element
+ onFocus: function(){
+ _V_.on(document, "keyup", _V_.proxy(this, this.onKeyPress));
+ },
+
+ // KeyPress (document level) - Trigger click when keys are pressed
+ onKeyPress: function(event){
+ // Check for space bar (32) or enter (13) keys
+ if (event.which == 32 || event.which == 13) {
+ event.preventDefault();
+ this.onClick();
+ }
+ },
+
+ // Blur - Remove keyboard triggers
+ onBlur: function(){
+ _V_.off(document, "keyup", _V_.proxy(this, this.onKeyPress));
+ }
+
+});
+
+/* Play Button
+================================================================================ */
+_V_.PlayButton = _V_.Button.extend({
+
+ buttonText: "Play",
+
+ buildCSSClass: function(){
+ return "vjs-play-button " + this._super();
+ },
+
+ onClick: function(){
+ this.player.play();
+ }
+
+});
+
+/* Pause Button
+================================================================================ */
+_V_.PauseButton = _V_.Button.extend({
+
+ buttonText: "Pause",
+
+ buildCSSClass: function(){
+ return "vjs-pause-button " + this._super();
+ },
+
+ onClick: function(){
+ this.player.pause();
+ }
+
+});
+
+/* Play Toggle - Play or Pause Media
+================================================================================ */
+_V_.PlayToggle = _V_.Button.extend({
+
+ buttonText: "Play",
+
+ init: function(player, options){
+ this._super(player, options);
+
+ player.on("play", _V_.proxy(this, this.onPlay));
+ player.on("pause", _V_.proxy(this, this.onPause));
+ },
+
+ buildCSSClass: function(){
+ return "vjs-play-control " + this._super();
+ },
+
+ // OnClick - Toggle between play and pause
+ onClick: function(){
+ if (this.player.paused()) {
+ this.player.play();
+ } else {
+ this.player.pause();
+ }
+ },
+
+ // OnPlay - Add the vjs-playing class to the element so it can change appearance
+ onPlay: function(){
+ _V_.removeClass(this.el, "vjs-paused");
+ _V_.addClass(this.el, "vjs-playing");
+ },
+
+ // OnPause - Add the vjs-paused class to the element so it can change appearance
+ onPause: function(){
+ _V_.removeClass(this.el, "vjs-playing");
+ _V_.addClass(this.el, "vjs-paused");
+ }
+
+});
+
+
+/* Fullscreen Toggle Behaviors
+================================================================================ */
+_V_.FullscreenToggle = _V_.Button.extend({
+
+ buttonText: "Fullscreen",
+
+ buildCSSClass: function(){
+ return "vjs-fullscreen-control " + this._super();
+ },
+
+ onClick: function(){
+ if (!this.player.isFullScreen) {
+ this.player.requestFullScreen();
+ } else {
+ this.player.cancelFullScreen();
+ }
+ }
+
+});
+
+/* Big Play Button
+================================================================================ */
+_V_.BigPlayButton = _V_.Button.extend({
+ init: function(player, options){
+ this._super(player, options);
+
+ player.on("play", _V_.proxy(this, this.hide));
+ player.on("ended", _V_.proxy(this, this.show));
+ },
+
+ createElement: function(){
+ return this._super("div", {
+ className: "vjs-big-play-button",
+ innerHTML: "<span></span>"
+ });
+ },
+
+ onClick: function(){
+ // Go back to the beginning if big play button is showing at the end.
+ // Have to check for current time otherwise it might throw a 'not ready' error.
+ if(this.player.currentTime()) {
+ this.player.currentTime(0);
+ }
+ this.player.play();
+ }
+});
+
+/* Loading Spinner
+================================================================================ */
+_V_.LoadingSpinner = _V_.Component.extend({
+ init: function(player, options){
+ this._super(player, options);
+
+ player.on("canplay", _V_.proxy(this, this.hide));
+ player.on("canplaythrough", _V_.proxy(this, this.hide));
+ player.on("playing", _V_.proxy(this, this.hide));
+
+ player.on("seeking", _V_.proxy(this, this.show));
+ player.on("error", _V_.proxy(this, this.show));
+
+ // Not showing spinner on stalled any more. Browsers may stall and then not trigger any events that would remove the spinner.
+ // Checked in Chrome 16 and Safari 5.1.2. http://help.videojs.com/discussions/problems/883-why-is-the-download-progress-showing
+ // player.on("stalled", _V_.proxy(this, this.show));
+
+ player.on("waiting", _V_.proxy(this, this.show));
+ },
+
+ createElement: function(){
+
+ var classNameSpinner, innerHtmlSpinner;
+
+ if ( typeof this.player.el.style.WebkitBorderRadius == "string"
+ || typeof this.player.el.style.MozBorderRadius == "string"
+ || typeof this.player.el.style.KhtmlBorderRadius == "string"
+ || typeof this.player.el.style.borderRadius == "string")
+ {
+ classNameSpinner = "vjs-loading-spinner";
+ innerHtmlSpinner = "<div class='ball1'></div><div class='ball2'></div><div class='ball3'></div><div class='ball4'></div><div class='ball5'></div><div class='ball6'></div><div class='ball7'></div><div class='ball8'></div>";
+ } else {
+ classNameSpinner = "vjs-loading-spinner-fallback";
+ innerHtmlSpinner = "";
+ }
+
+ return this._super("div", {
+ className: classNameSpinner,
+ innerHTML: innerHtmlSpinner
+ });
+ }
+});
+
+/* Time
+================================================================================ */
+_V_.CurrentTimeDisplay = _V_.Component.extend({
+
+ init: function(player, options){
+ this._super(player, options);
+
+ player.on("timeupdate", _V_.proxy(this, this.updateContent));
+ },
+
+ createElement: function(){
+ var el = this._super("div", {
+ className: "vjs-current-time vjs-time-controls vjs-control"
+ });
+
+ this.content = _V_.createElement("div", {
+ className: "vjs-current-time-display",
+ innerHTML: '0:00'
+ });
+
+ el.appendChild(_V_.createElement("div").appendChild(this.content));
+ return el;
+ },
+
+ updateContent: function(){
+ // Allows for smooth scrubbing, when player can't keep up.
+ var time = (this.player.scrubbing) ? this.player.values.currentTime : this.player.currentTime();
+ this.content.innerHTML = _V_.formatTime(time, this.player.duration());
+ }
+
+});
+
+_V_.DurationDisplay = _V_.Component.extend({
+
+ init: function(player, options){
+ this._super(player, options);
+
+ player.on("timeupdate", _V_.proxy(this, this.updateContent));
+ },
+
+ createElement: function(){
+ var el = this._super("div", {
+ className: "vjs-duration vjs-time-controls vjs-control"
+ });
+
+ this.content = _V_.createElement("div", {
+ className: "vjs-duration-display",
+ innerHTML: '0:00'
+ });
+
+ el.appendChild(_V_.createElement("div").appendChild(this.content));
+ return el;
+ },
+
+ updateContent: function(){
+ if (this.player.duration()) { this.content.innerHTML = _V_.formatTime(this.player.duration()); }
+ }
+
+});
+
+// Time Separator (Not used in main skin, but still available, and could be used as a 'spare element')
+_V_.TimeDivider = _V_.Component.extend({
+
+ createElement: function(){
+ return this._super("div", {
+ className: "vjs-time-divider",
+ innerHTML: '<div><span>/</span></div>'
+ });
+ }
+
+});
+
+_V_.RemainingTimeDisplay = _V_.Component.extend({
+
+ init: function(player, options){
+ this._super(player, options);
+
+ player.on("timeupdate", _V_.proxy(this, this.updateContent));
+ },
+
+ createElement: function(){
+ var el = this._super("div", {
+ className: "vjs-remaining-time vjs-time-controls vjs-control"
+ });
+
+ this.content = _V_.createElement("div", {
+ className: "vjs-remaining-time-display",
+ innerHTML: '-0:00'
+ });
+
+ el.appendChild(_V_.createElement("div").appendChild(this.content));
+ return el;
+ },
+
+ updateContent: function(){
+ if (this.player.duration()) { this.content.innerHTML = "-"+_V_.formatTime(this.player.remainingTime()); }
+
+ // Allows for smooth scrubbing, when player can't keep up.
+ // var time = (this.player.scrubbing) ? this.player.values.currentTime : this.player.currentTime();
+ // this.content.innerHTML = _V_.formatTime(time, this.player.duration());
+ }
+
+});
+
+/* Slider - Parent for seek bar and volume slider
+================================================================================ */
+_V_.Slider = _V_.Component.extend({
+
+ init: function(player, options){
+ this._super(player, options);
+
+ player.on(this.playerEvent, _V_.proxy(this, this.update));
+
+ this.on("mousedown", this.onMouseDown);
+ this.on("focus", this.onFocus);
+ this.on("blur", this.onBlur);
+
+ this.player.on("controlsvisible", this.proxy(this.update));
+
+ // This is actually to fix the volume handle position. http://twitter.com/#!/gerritvanaaken/status/159046254519787520
+ // this.player.one("timeupdate", this.proxy(this.update));
+
+ this.update();
+ },
+
+ createElement: function(type, attrs) {
+ attrs = _V_.merge({
+ role: "slider",
+ "aria-valuenow": 0,
+ "aria-valuemin": 0,
+ "aria-valuemax": 100,
+ tabIndex: 0
+ }, attrs);
+
+ return this._super(type, attrs);
+ },
+
+ onMouseDown: function(event){
+ event.preventDefault();
+ _V_.blockTextSelection();
+
+ _V_.on(document, "mousemove", _V_.proxy(this, this.onMouseMove));
+ _V_.on(document, "mouseup", _V_.proxy(this, this.onMouseUp));
+
+ this.onMouseMove(event);
+ },
+
+ onMouseUp: function(event) {
+ _V_.unblockTextSelection();
+ _V_.off(document, "mousemove", this.onMouseMove, false);
+ _V_.off(document, "mouseup", this.onMouseUp, false);
+
+ this.update();
+ },
+
+ update: function(){
+ // If scrubbing, we could use a cached value to make the handle keep up with the user's mouse.
+ // On HTML5 browsers scrubbing is really smooth, but some flash players are slow, so we might want to utilize this later.
+ // var progress = (this.player.scrubbing) ? this.player.values.currentTime / this.player.duration() : this.player.currentTime() / this.player.duration();
+
+ var barProgress,
+ progress = this.getPercent();
+ handle = this.handle,
+ bar = this.bar;
+
+ // Protect against no duration and other division issues
+ if (isNaN(progress)) { progress = 0; }
+
+ barProgress = progress;
+
+ // If there is a handle, we need to account for the handle in our calculation for progress bar
+ // so that it doesn't fall short of or extend past the handle.
+ if (handle) {
+
+ var box = this.el,
+ boxWidth = box.offsetWidth,
+
+ handleWidth = handle.el.offsetWidth,
+
+ // The width of the handle in percent of the containing box
+ // In IE, widths may not be ready yet causing NaN
+ handlePercent = (handleWidth) ? handleWidth / boxWidth : 0,
+
+ // Get the adjusted size of the box, considering that the handle's center never touches the left or right side.
+ // There is a margin of half the handle's width on both sides.
+ boxAdjustedPercent = 1 - handlePercent;
+
+ // Adjust the progress that we'll use to set widths to the new adjusted box width
+ adjustedProgress = progress * boxAdjustedPercent,
+
+ // The bar does reach the left side, so we need to account for this in the bar's width
+ barProgress = adjustedProgress + (handlePercent / 2);
+
+ // Move the handle from the left based on the adjected progress
+ handle.el.style.left = _V_.round(adjustedProgress * 100, 2) + "%";
+ }
+
+ // Set the new bar width
+ bar.el.style.width = _V_.round(barProgress * 100, 2) + "%";
+ },
+
+ calculateDistance: function(event){
+ var box = this.el,
+ boxX = _V_.findPosX(box),
+ boxW = box.offsetWidth,
+ handle = this.handle;
+
+ if (handle) {
+ var handleW = handle.el.offsetWidth;
+
+ // Adjusted X and Width, so handle doesn't go outside the bar
+ boxX = boxX + (handleW / 2);
+ boxW = boxW - handleW;
+ }
+
+ // Percent that the click is through the adjusted area
+ return Math.max(0, Math.min(1, (event.pageX - boxX) / boxW));
+ },
+
+ onFocus: function(event){
+ _V_.on(document, "keyup", _V_.proxy(this, this.onKeyPress));
+ },
+
+ onKeyPress: function(event){
+ if (event.which == 37) { // Left Arrow
+ event.preventDefault();
+ this.stepBack();
+ } else if (event.which == 39) { // Right Arrow
+ event.preventDefault();
+ this.stepForward();
+ }
+ },
+
+ onBlur: function(event){
+ _V_.off(document, "keyup", _V_.proxy(this, this.onKeyPress));
+ }
+});
+
+
+/* Progress
+================================================================================ */
+
+// Progress Control: Seek, Load Progress, and Play Progress
+_V_.ProgressControl = _V_.Component.extend({
+
+ options: {
+ components: {
+ "seekBar": {}
+ }
+ },
+
+ createElement: function(){
+ return this._super("div", {
+ className: "vjs-progress-control vjs-control"
+ });
+ }
+
+});
+
+// Seek Bar and holder for the progress bars
+_V_.SeekBar = _V_.Slider.extend({
+
+ options: {
+ components: {
+ "loadProgressBar": {},
+
+ // Set property names to bar and handle to match with the parent Slider class is looking for
+ "bar": { componentClass: "PlayProgressBar" },
+ "handle": { componentClass: "SeekHandle" }
+ }
+ },
+
+ playerEvent: "timeupdate",
+
+ init: function(player, options){
+ this._super(player, options);
+ },
+
+ createElement: function(){
+ return this._super("div", {
+ className: "vjs-progress-holder"
+ });
+ },
+
+ getPercent: function(){
+ return this.player.currentTime() / this.player.duration();
+ },
+
+ onMouseDown: function(event){
+ this._super(event);
+
+ this.player.scrubbing = true;
+
+ this.videoWasPlaying = !this.player.paused();
+ this.player.pause();
+ },
+
+ onMouseMove: function(event){
+ var newTime = this.calculateDistance(event) * this.player.duration();
+
+ // Don't let video end while scrubbing.
+ if (newTime == this.player.duration()) { newTime = newTime - 0.1; }
+
+ // Set new time (tell player to seek to new time)
+ this.player.currentTime(newTime);
+ },
+
+ onMouseUp: function(event){
+ this._super(event);
+
+ this.player.scrubbing = false;
+ if (this.videoWasPlaying) {
+ this.player.play();
+ }
+ },
+
+ stepForward: function(){
+ this.player.currentTime(this.player.currentTime() + 1);
+ },
+
+ stepBack: function(){
+ this.player.currentTime(this.player.currentTime() - 1);
+ }
+
+});
+
+// Load Progress Bar
+_V_.LoadProgressBar = _V_.Component.extend({
+
+ init: function(player, options){
+ this._super(player, options);
+ player.on("progress", _V_.proxy(this, this.update));
+ },
+
+ createElement: function(){
+ return this._super("div", {
+ className: "vjs-load-progress",
+ innerHTML: '<span class="vjs-control-text">Loaded: 0%</span>'
+ });
+ },
+
+ update: function(){
+ if (this.el.style) { this.el.style.width = _V_.round(this.player.bufferedPercent() * 100, 2) + "%"; }
+ }
+
+});
+
+// Play Progress Bar
+_V_.PlayProgressBar = _V_.Component.extend({
+
+ createElement: function(){
+ return this._super("div", {
+ className: "vjs-play-progress",
+ innerHTML: '<span class="vjs-control-text">Progress: 0%</span>'
+ });
+ }
+
+});
+
+// Seek Handle
+// SeekBar Behavior includes play progress bar, and seek handle
+// Needed so it can determine seek position based on handle position/size
+_V_.SeekHandle = _V_.Component.extend({
+
+ createElement: function(){
+ return this._super("div", {
+ className: "vjs-seek-handle",
+ innerHTML: '<span class="vjs-control-text">00:00</span>'
+ });
+ }
+
+});
+
+/* Volume Scrubber
+================================================================================ */
+// Progress Control: Seek, Load Progress, and Play Progress
+_V_.VolumeControl = _V_.Component.extend({
+
+ options: {
+ components: {
+ "volumeBar": {}
+ }
+ },
+
+ createElement: function(){
+ return this._super("div", {
+ className: "vjs-volume-control vjs-control"
+ });
+ }
+
+});
+
+_V_.VolumeBar = _V_.Slider.extend({
+
+ options: {
+ components: {
+ "bar": { componentClass: "VolumeLevel" },
+ "handle": { componentClass: "VolumeHandle" }
+ }
+ },
+
+ playerEvent: "volumechange",
+
+ createElement: function(){
+ return this._super("div", {
+ className: "vjs-volume-bar"
+ });
+ },
+
+ onMouseMove: function(event) {
+ this.player.volume(this.calculateDistance(event));
+ },
+
+ getPercent: function(){
+ return this.player.volume();
+ },
+
+ stepForward: function(){
+ this.player.volume(this.player.volume() + 0.1);
+ },
+
+ stepBack: function(){
+ this.player.volume(this.player.volume() - 0.1);
+ }
+});
+
+_V_.VolumeLevel = _V_.Component.extend({
+
+ createElement: function(){
+ return this._super("div", {
+ className: "vjs-volume-level",
+ innerHTML: '<span class="vjs-control-text"></span>'
+ });
+ }
+
+});
+
+_V_.VolumeHandle = _V_.Component.extend({
+
+ createElement: function(){
+ return this._super("div", {
+ className: "vjs-volume-handle",
+ innerHTML: '<span class="vjs-control-text"></span>'
+ // tabindex: 0,
+ // role: "slider", "aria-valuenow": 0, "aria-valuemin": 0, "aria-valuemax": 100
+ });
+ }
+
+});
+
+_V_.MuteToggle = _V_.Button.extend({
+
+ init: function(player, options){
+ this._super(player, options);
+
+ player.on("volumechange", _V_.proxy(this, this.update));
+ },
+
+ createElement: function(){
+ return this._super("div", {
+ className: "vjs-mute-control vjs-control",
+ innerHTML: '<div><span class="vjs-control-text">Mute</span></div>'
+ });
+ },
+
+ onClick: function(event){
+ this.player.muted( this.player.muted() ? false : true );
+ },
+
+ update: function(event){
+ var vol = this.player.volume(),
+ level = 3;
+
+ if (vol == 0 || this.player.muted()) {
+ level = 0;
+ } else if (vol < 0.33) {
+ level = 1;
+ } else if (vol < 0.67) {
+ level = 2;
+ }
+
+ /* TODO improve muted icon classes */
+ _V_.each.call(this, [0,1,2,3], function(i){
+ _V_.removeClass(this.el, "vjs-vol-"+i);
+ });
+ _V_.addClass(this.el, "vjs-vol-"+level);
+ }
+
+});
+
+
+/* Poster Image
+================================================================================ */
+_V_.PosterImage = _V_.Button.extend({
+ init: function(player, options){
+ this._super(player, options);
+
+ if (!this.player.options.poster) {
+ this.hide();
+ }
+
+ player.on("play", _V_.proxy(this, this.hide));
+ },
+
+ createElement: function(){
+ return _V_.createElement("img", {
+ className: "vjs-poster",
+ src: this.player.options.poster,
+
+ // Don't want poster to be tabbable.
+ tabIndex: -1
+ });
+ },
+
+ onClick: function(){
+ this.player.play();
+ }
+});
+
+/* Menu
+================================================================================ */
+// The base for text track and settings menu buttons.
+_V_.Menu = _V_.Component.extend({
+
+ init: function(player, options){
+ this._super(player, options);
+ },
+
+ addItem: function(component){
+ this.addComponent(component);
+ component.on("click", this.proxy(function(){
+ this.unlockShowing();
+ }));
+ },
+
+ createElement: function(){
+ return this._super("ul", {
+ className: "vjs-menu"
+ });
+ }
+
+});
+
+_V_.MenuItem = _V_.Button.extend({
+
+ init: function(player, options){
+ this._super(player, options);
+
+ if (options.selected) {
+ this.addClass("vjs-selected");
+ }
+ },
+
+ createElement: function(type, attrs){
+ return this._super("li", _V_.merge({
+ className: "vjs-menu-item",
+ innerHTML: this.options.label
+ }, attrs));
+ },
+
+ onClick: function(){
+ this.selected(true);
+ },
+
+ selected: function(selected){
+ if (selected) {
+ this.addClass("vjs-selected");
+ } else {
+ this.removeClass("vjs-selected")
+ }
+ }
+
+});// TEXT TRACKS
+// Text tracks are tracks of timed text events.
+// Captions - text displayed over the video for the hearing impared
+// Subtitles - text displayed over the video for those who don't understand langauge in the video
+// Chapters - text displayed in a menu allowing the user to jump to particular points (chapters) in the video
+// Descriptions (not supported yet) - audio descriptions that are read back to the user by a screen reading device
+
+// Player Track Functions - Functions add to the player object for easier access to tracks
+_V_.merge(_V_.Player.prototype, {
+
+ // Add an array of text tracks. captions, subtitles, chapters, descriptions
+ // Track objects will be stored in the player.textTracks array
+ addTextTracks: function(trackObjects){
+ var tracks = this.textTracks = (this.textTracks) ? this.textTracks : [],
+ i = 0, j = trackObjects.length, track, Kind;
+
+ for (;i<j;i++) {
+ // HTML5 Spec says default to subtitles.
+ // Uppercase (uc) first letter to match class names
+ Kind = _V_.uc(trackObjects[i].kind || "subtitles");
+
+ // Create correct texttrack class. CaptionsTrack, etc.
+ track = new _V_[Kind + "Track"](this, trackObjects[i]);
+
+ tracks.push(track);
+
+ // If track.default is set, start showing immediately
+ // TODO: Add a process to deterime the best track to show for the specific kind
+ // Incase there are mulitple defaulted tracks of the same kind
+ // Or the user has a set preference of a specific language that should override the default
+ if (track['default']) {
+ this.ready(_V_.proxy(track, track.show));
+ }
+ }
+
+ // Return the track so it can be appended to the display component
+ return this;
+ },
+
+ // Show a text track
+ // disableSameKind: disable all other tracks of the same kind. Value should be a track kind (captions, etc.)
+ showTextTrack: function(id, disableSameKind){
+ var tracks = this.textTracks,
+ i = 0,
+ j = tracks.length,
+ track, showTrack, kind;
+
+ // Find Track with same ID
+ for (;i<j;i++) {
+ track = tracks[i];
+ if (track.id === id) {
+ track.show();
+ showTrack = track;
+
+ // Disable tracks of the same kind
+ } else if (disableSameKind && track.kind == disableSameKind && track.mode > 0) {
+ track.disable();
+ }
+ }
+
+ // Get track kind from shown track or disableSameKind
+ kind = (showTrack) ? showTrack.kind : ((disableSameKind) ? disableSameKind : false);
+
+ // Trigger trackchange event, captionstrackchange, subtitlestrackchange, etc.
+ if (kind) {
+ this.trigger(kind+"trackchange");
+ }
+
+ return this;
+ }
+
+});
+
+// Track Class
+// Contains track methods for loading, showing, parsing cues of tracks
+_V_.Track = _V_.Component.extend({
+
+ init: function(player, options){
+ this._super(player, options);
+
+ // Apply track info to track object
+ // Options will often be a track element
+ _V_.merge(this, {
+ // Build ID if one doesn't exist
+ id: options.id || ("vjs_" + options.kind + "_" + options.language + "_" + _V_.guid++),
+
+ src: options.src,
+
+ // If default is used, subtitles/captions to start showing
+ "default": options["default"], // 'default' is reserved-ish
+ title: options.title,
+
+ // Language - two letter string to represent track language, e.g. "en" for English
+ // readonly attribute DOMString language;
+ language: options.srclang,
+
+ // Track label e.g. "English"
+ // readonly attribute DOMString label;
+ label: options.label,
+
+ // All cues of the track. Cues have a startTime, endTime, text, and other properties.
+ // readonly attribute TextTrackCueList cues;
+ cues: [],
+
+ // ActiveCues is all cues that are currently showing
+ // readonly attribute TextTrackCueList activeCues;
+ activeCues: [],
+
+ // ReadyState describes if the text file has been loaded
+ // const unsigned short NONE = 0;
+ // const unsigned short LOADING = 1;
+ // const unsigned short LOADED = 2;
+ // const unsigned short ERROR = 3;
+ // readonly attribute unsigned short readyState;
+ readyState: 0,
+
+ // Mode describes if the track is showing, hidden, or disabled
+ // const unsigned short OFF = 0;
+ // const unsigned short HIDDEN = 1; (still triggering cuechange events, but not visible)
+ // const unsigned short SHOWING = 2;
+ // attribute unsigned short mode;
+ mode: 0
+ });
+ },
+
+ // Create basic div to hold cue text
+ createElement: function(){
+ return this._super("div", {
+ className: "vjs-" + this.kind + " vjs-text-track"
+ });
+ },
+
+ // Show: Mode Showing (2)
+ // Indicates that the text track is active. If no attempt has yet been made to obtain the track's cues, the user agent will perform such an attempt momentarily.
+ // The user agent is maintaining a list of which cues are active, and events are being fired accordingly.
+ // In addition, for text tracks whose kind is subtitles or captions, the cues are being displayed over the video as appropriate;
+ // for text tracks whose kind is descriptions, the user agent is making the cues available to the user in a non-visual fashion;
+ // and for text tracks whose kind is chapters, the user agent is making available to the user a mechanism by which the user can navigate to any point in the media resource by selecting a cue.
+ // The showing by default state is used in conjunction with the default attribute on track elements to indicate that the text track was enabled due to that attribute.
+ // This allows the user agent to override the state if a later track is discovered that is more appropriate per the user's preferences.
+ show: function(){
+ this.activate();
+
+ this.mode = 2;
+
+ // Show element.
+ this._super();
+ },
+
+ // Hide: Mode Hidden (1)
+ // Indicates that the text track is active, but that the user agent is not actively displaying the cues.
+ // If no attempt has yet been made to obtain the track's cues, the user agent will perform such an attempt momentarily.
+ // The user agent is maintaining a list of which cues are active, and events are being fired accordingly.
+ hide: function(){
+ // When hidden, cues are still triggered. Disable to stop triggering.
+ this.activate();
+
+ this.mode = 1;
+
+ // Hide element.
+ this._super();
+ },
+
+ // Disable: Mode Off/Disable (0)
+ // Indicates that the text track is not active. Other than for the purposes of exposing the track in the DOM, the user agent is ignoring the text track.
+ // No cues are active, no events are fired, and the user agent will not attempt to obtain the track's cues.
+ disable: function(){
+ // If showing, hide.
+ if (this.mode == 2) { this.hide(); }
+
+ // Stop triggering cues
+ this.deactivate();
+
+ // Switch Mode to Off
+ this.mode = 0;
+ },
+
+ // Turn on cue tracking. Tracks that are showing OR hidden are active.
+ activate: function(){
+ // Load text file if it hasn't been yet.
+ if (this.readyState == 0) { this.load(); }
+
+ // Only activate if not already active.
+ if (this.mode == 0) {
+ // Update current cue on timeupdate
+ // Using unique ID for proxy function so other tracks don't remove listener
+ this.player.on("timeupdate", this.proxy(this.update, this.id));
+
+ // Reset cue time on media end
+ this.player.on("ended", this.proxy(this.reset, this.id));
+
+ // Add to display
+ if (this.kind == "captions" || this.kind == "subtitles") {
+ this.player.textTrackDisplay.addComponent(this);
+ }
+ }
+ },
+
+ // Turn off cue tracking.
+ deactivate: function(){
+ // Using unique ID for proxy function so other tracks don't remove listener
+ this.player.off("timeupdate", this.proxy(this.update, this.id));
+ this.player.off("ended", this.proxy(this.reset, this.id));
+ this.reset(); // Reset
+
+ // Remove from display
+ this.player.textTrackDisplay.removeComponent(this);
+ },
+
+ // A readiness state
+ // One of the following:
+ //
+ // Not loaded
+ // Indicates that the text track is known to exist (e.g. it has been declared with a track element), but its cues have not been obtained.
+ //
+ // Loading
+ // Indicates that the text track is loading and there have been no fatal errors encountered so far. Further cues might still be added to the track.
+ //
+ // Loaded
+ // Indicates that the text track has been loaded with no fatal errors. No new cues will be added to the track except if the text track corresponds to a MutableTextTrack object.
+ //
+ // Failed to load
+ // Indicates that the text track was enabled, but when the user agent attempted to obtain it, this failed in some way (e.g. URL could not be resolved, network error, unknown text track format). Some or all of the cues are likely missing and will not be obtained.
+ load: function(){
+
+ // Only load if not loaded yet.
+ if (this.readyState == 0) {
+ this.readyState = 1;
+ _V_.get(this.src, this.proxy(this.parseCues), this.proxy(this.onError));
+ }
+
+ },
+
+ onError: function(err){
+ this.error = err;
+ this.readyState = 3;
+ this.trigger("error");
+ },
+
+ // Parse the WebVTT text format for cue times.
+ // TODO: Separate parser into own class so alternative timed text formats can be used. (TTML, DFXP)
+ parseCues: function(srcContent) {
+ var cue, time, text,
+ lines = srcContent.split("\n"),
+ line = "", id;
+
+ for (var i=1, j=lines.length; i<j; i++) {
+ // Line 0 should be 'WEBVTT', so skipping i=0
+
+ line = _V_.trim(lines[i]); // Trim whitespace and linebreaks
+
+ if (line) { // Loop until a line with content
+
+ // First line could be an optional cue ID
+ // Check if line has the time separator
+ if (line.indexOf("-->") == -1) {
+ id = line;
+ // Advance to next line for timing.
+ line = _V_.trim(lines[++i]);
+ } else {
+ id = this.cues.length;
+ }
+
+ // First line - Number
+ cue = {
+ id: id, // Cue Number
+ index: this.cues.length // Position in Array
+ };
+
+ // Timing line
+ time = line.split(" --> ");
+ cue.startTime = this.parseCueTime(time[0]);
+ cue.endTime = this.parseCueTime(time[1]);
+
+ // Additional lines - Cue Text
+ text = [];
+
+ // Loop until a blank line or end of lines
+ // Assumeing trim("") returns false for blank lines
+ while (lines[++i] && (line = _V_.trim(lines[i]))) {
+ text.push(line);
+ }
+
+ cue.text = text.join('<br/>');
+
+ // Add this cue
+ this.cues.push(cue);
+ }
+ }
+
+ this.readyState = 2;
+ this.trigger("loaded");
+ },
+
+ parseCueTime: function(timeText) {
+ var parts = timeText.split(':'),
+ time = 0,
+ hours, minutes, other, seconds, ms, flags;
+
+ // Check if optional hours place is included
+ // 00:00:00.000 vs. 00:00.000
+ if (parts.length == 3) {
+ hours = parts[0];
+ minutes = parts[1];
+ other = parts[2];
+ } else {
+ hours = 0;
+ minutes = parts[0];
+ other = parts[1];
+ }
+
+ // Break other (seconds, milliseconds, and flags) by spaces
+ // TODO: Make additional cue layout settings work with flags
+ other = other.split(/\s+/)
+ // Remove seconds. Seconds is the first part before any spaces.
+ seconds = other.splice(0,1)[0];
+ // Could use either . or , for decimal
+ seconds = seconds.split(/\.|,/);
+ // Get milliseconds
+ ms = parseFloat(seconds[1]);
+ seconds = seconds[0];
+
+ // hours => seconds
+ time += parseFloat(hours) * 3600;
+ // minutes => seconds
+ time += parseFloat(minutes) * 60;
+ // Add seconds
+ time += parseFloat(seconds);
+ // Add milliseconds
+ if (ms) { time += ms/1000; }
+
+ return time;
+ },
+
+ // Update active cues whenever timeupdate events are triggered on the player.
+ update: function(){
+ if (this.cues.length > 0) {
+
+ // Get curent player time
+ var time = this.player.currentTime();
+
+ // Check if the new time is outside the time box created by the the last update.
+ if (this.prevChange === undefined || time < this.prevChange || this.nextChange <= time) {
+ var cues = this.cues,
+
+ // Create a new time box for this state.
+ newNextChange = this.player.duration(), // Start at beginning of the timeline
+ newPrevChange = 0, // Start at end
+
+ reverse = false, // Set the direction of the loop through the cues. Optimized the cue check.
+ newCues = [], // Store new active cues.
+
+ // Store where in the loop the current active cues are, to provide a smart starting point for the next loop.
+ firstActiveIndex, lastActiveIndex,
+
+ html = "", // Create cue text HTML to add to the display
+ cue, i, j; // Loop vars
+
+ // Check if time is going forwards or backwards (scrubbing/rewinding)
+ // If we know the direction we can optimize the starting position and direction of the loop through the cues array.
+ if (time >= this.nextChange || this.nextChange === undefined) { // NextChange should happen
+ // Forwards, so start at the index of the first active cue and loop forward
+ i = (this.firstActiveIndex !== undefined) ? this.firstActiveIndex : 0;
+ } else {
+ // Backwards, so start at the index of the last active cue and loop backward
+ reverse = true;
+ i = (this.lastActiveIndex !== undefined) ? this.lastActiveIndex : cues.length - 1;
+ }
+
+ while (true) { // Loop until broken
+ cue = cues[i];
+
+ // Cue ended at this point
+ if (cue.endTime <= time) {
+ newPrevChange = Math.max(newPrevChange, cue.endTime);
+
+ if (cue.active) {
+ cue.active = false;
+ }
+
+ // No earlier cues should have an active start time.
+ // Nevermind. Assume first cue could have a duration the same as the video.
+ // In that case we need to loop all the way back to the beginning.
+ // if (reverse && cue.startTime) { break; }
+
+ // Cue hasn't started
+ } else if (time < cue.startTime) {
+ newNextChange = Math.min(newNextChange, cue.startTime);
+
+ if (cue.active) {
+ cue.active = false;
+ }
+
+ // No later cues should have an active start time.
+ if (!reverse) { break; }
+
+ // Cue is current
+ } else {
+
+ if (reverse) {
+ // Add cue to front of array to keep in time order
+ newCues.splice(0,0,cue);
+
+ // If in reverse, the first current cue is our lastActiveCue
+ if (lastActiveIndex === undefined) { lastActiveIndex = i; }
+ firstActiveIndex = i;
+ } else {
+ // Add cue to end of array
+ newCues.push(cue);
+
+ // If forward, the first current cue is our firstActiveIndex
+ if (firstActiveIndex === undefined) { firstActiveIndex = i; }
+ lastActiveIndex = i;
+ }
+
+ newNextChange = Math.min(newNextChange, cue.endTime);
+ newPrevChange = Math.max(newPrevChange, cue.startTime);
+
+ cue.active = true;
+ }
+
+ if (reverse) {
+ // Reverse down the array of cues, break if at first
+ if (i === 0) { break; } else { i--; }
+ } else {
+ // Walk up the array fo cues, break if at last
+ if (i === cues.length - 1) { break; } else { i++; }
+ }
+
+ }
+
+ this.activeCues = newCues;
+ this.nextChange = newNextChange;
+ this.prevChange = newPrevChange;
+ this.firstActiveIndex = firstActiveIndex;
+ this.lastActiveIndex = lastActiveIndex;
+
+ this.updateDisplay();
+
+ this.trigger("cuechange");
+ }
+ }
+ },
+
+ // Add cue HTML to display
+ updateDisplay: function(){
+ var cues = this.activeCues,
+ html = "",
+ i=0,j=cues.length;
+
+ for (;i<j;i++) {
+ html += "<span class='vjs-tt-cue'>"+cues[i].text+"</span>";
+ }
+
+ this.el.innerHTML = html;
+ },
+
+ // Set all loop helper values back
+ reset: function(){
+ this.nextChange = 0;
+ this.prevChange = this.player.duration();
+ this.firstActiveIndex = 0;
+ this.lastActiveIndex = 0;
+ }
+
+});
+
+// Create specific track types
+_V_.CaptionsTrack = _V_.Track.extend({
+ kind: "captions"
+});
+
+_V_.SubtitlesTrack = _V_.Track.extend({
+ kind: "subtitles"
+});
+
+_V_.ChaptersTrack = _V_.Track.extend({
+ kind: "chapters"
+});
+
+
+/* Text Track Display
+================================================================================ */
+// Global container for both subtitle and captions text. Simple div container.
+_V_.TextTrackDisplay = _V_.Component.extend({
+
+ createElement: function(){
+ return this._super("div", {
+ className: "vjs-text-track-display"
+ });
+ }
+
+});
+
+/* Text Track Menu Items
+================================================================================ */
+_V_.TextTrackMenuItem = _V_.MenuItem.extend({
+
+ init: function(player, options){
+ var track = this.track = options.track;
+
+ // Modify options for parent MenuItem class's init.
+ options.label = track.label;
+ options.selected = track["default"];
+ this._super(player, options);
+
+ this.player.on(track.kind + "trackchange", _V_.proxy(this, this.update));
+ },
+
+ onClick: function(){
+ this._super();
+ this.player.showTextTrack(this.track.id, this.track.kind);
+ },
+
+ update: function(){
+ if (this.track.mode == 2) {
+ this.selected(true);
+ } else {
+ this.selected(false);
+ }
+ }
+
+});
+
+_V_.OffTextTrackMenuItem = _V_.TextTrackMenuItem.extend({
+
+ init: function(player, options){
+ // Create pseudo track info
+ // Requires options.kind
+ options.track = { kind: options.kind, player: player, label: "Off" }
+ this._super(player, options);
+ },
+
+ onClick: function(){
+ this._super();
+ this.player.showTextTrack(this.track.id, this.track.kind);
+ },
+
+ update: function(){
+ var tracks = this.player.textTracks,
+ i=0, j=tracks.length, track,
+ off = true;
+
+ for (;i<j;i++) {
+ track = tracks[i];
+ if (track.kind == this.track.kind && track.mode == 2) {
+ off = false;
+ }
+ }
+
+ if (off) {
+ this.selected(true);
+ } else {
+ this.selected(false);
+ }
+ }
+
+});
+
+/* Captions Button
+================================================================================ */
+_V_.TextTrackButton = _V_.Button.extend({
+
+ init: function(player, options){
+ this._super(player, options);
+
+ this.menu = this.createMenu();
+
+ if (this.items.length === 0) {
+ this.hide();
+ }
+ },
+
+ createMenu: function(){
+ var menu = new _V_.Menu(this.player);
+
+ // Add a title list item to the top
+ menu.el.appendChild(_V_.createElement("li", {
+ className: "vjs-menu-title",
+ innerHTML: _V_.uc(this.kind)
+ }));
+
+ // Add an OFF menu item to turn all tracks off
+ menu.addItem(new _V_.OffTextTrackMenuItem(this.player, { kind: this.kind }))
+
+ this.items = this.createItems();
+
+ // Add menu items to the menu
+ this.each(this.items, function(item){
+ menu.addItem(item);
+ });
+
+ // Add list to element
+ this.addComponent(menu);
+
+ return menu;
+ },
+
+ // Create a menu item for each text track
+ createItems: function(){
+ var items = [];
+ this.each(this.player.textTracks, function(track){
+ if (track.kind === this.kind) {
+ items.push(new _V_.TextTrackMenuItem(this.player, {
+ track: track
+ }));
+ }
+ });
+ return items;
+ },
+
+ buildCSSClass: function(){
+ return this.className + " vjs-menu-button " + this._super();
+ },
+
+ // Focus - Add keyboard functionality to element
+ onFocus: function(){
+ // Show the menu, and keep showing when the menu items are in focus
+ this.menu.lockShowing();
+ // this.menu.el.style.display = "block";
+
+ // When tabbing through, the menu should hide when focus goes from the last menu item to the next tabbed element.
+ _V_.one(this.menu.el.childNodes[this.menu.el.childNodes.length - 1], "blur", this.proxy(function(){
+ this.menu.unlockShowing();
+ }));
+ },
+ // Can't turn off list display that we turned on with focus, because list would go away.
+ onBlur: function(){},
+
+ onClick: function(){
+ // When you click the button it adds focus, which will show the menu indefinitely.
+ // So we'll remove focus when the mouse leaves the button.
+ // Focus is needed for tab navigation.
+ this.one("mouseout", this.proxy(function(){
+ this.menu.unlockShowing();
+ this.el.blur();
+ }));
+ }
+
+});
+
+_V_.CaptionsButton = _V_.TextTrackButton.extend({
+ kind: "captions",
+ buttonText: "Captions",
+ className: "vjs-captions-button"
+});
+
+_V_.SubtitlesButton = _V_.TextTrackButton.extend({
+ kind: "subtitles",
+ buttonText: "Subtitles",
+ className: "vjs-subtitles-button"
+});
+
+// Chapters act much differently than other text tracks
+// Cues are navigation vs. other tracks of alternative languages
+_V_.ChaptersButton = _V_.TextTrackButton.extend({
+ kind: "chapters",
+ buttonText: "Chapters",
+ className: "vjs-chapters-button",
+
+ // Create a menu item for each text track
+ createItems: function(chaptersTrack){
+ var items = [];
+
+ this.each(this.player.textTracks, function(track){
+ if (track.kind === this.kind) {
+ items.push(new _V_.TextTrackMenuItem(this.player, {
+ track: track
+ }));
+ }
+ });
+
+ return items;
+ },
+
+ createMenu: function(){
+ var tracks = this.player.textTracks,
+ i = 0,
+ j = tracks.length,
+ track, chaptersTrack,
+ items = this.items = [];
+
+ for (;i<j;i++) {
+ track = tracks[i];
+ if (track.kind == this.kind && track["default"]) {
+ if (track.readyState < 2) {
+ this.chaptersTrack = track;
+ track.on("loaded", this.proxy(this.createMenu));
+ return;
+ } else {
+ chaptersTrack = track;
+ break;
+ }
+ }
+ }
+
+ var menu = this.menu = new _V_.Menu(this.player);
+
+ menu.el.appendChild(_V_.createElement("li", {
+ className: "vjs-menu-title",
+ innerHTML: _V_.uc(this.kind)
+ }));
+
+ if (chaptersTrack) {
+ var cues = chaptersTrack.cues,
+ i = 0, j = cues.length, cue, mi;
+
+ for (;i<j;i++) {
+ cue = cues[i];
+
+ mi = new _V_.ChaptersTrackMenuItem(this.player, {
+ track: chaptersTrack,
+ cue: cue
+ });
+
+ items.push(mi);
+
+ menu.addComponent(mi);
+ }
+ }
+
+ // Add list to element
+ this.addComponent(menu);
+
+ if (this.items.length > 0) {
+ this.show();
+ }
+
+ return menu;
+ }
+
+});
+
+_V_.ChaptersTrackMenuItem = _V_.MenuItem.extend({
+
+ init: function(player, options){
+ var track = this.track = options.track,
+ cue = this.cue = options.cue,
+ currentTime = player.currentTime();
+
+ // Modify options for parent MenuItem class's init.
+ options.label = cue.text;
+ options.selected = (cue.startTime <= currentTime && currentTime < cue.endTime);
+ this._super(player, options);
+
+ track.on("cuechange", _V_.proxy(this, this.update));
+ },
+
+ onClick: function(){
+ this._super();
+ this.player.currentTime(this.cue.startTime);
+ this.update(this.cue.startTime);
+ },
+
+ update: function(time){
+ var cue = this.cue,
+ currentTime = this.player.currentTime();
+
+ // _V_.log(currentTime, cue.startTime);
+ if (cue.startTime <= currentTime && currentTime < cue.endTime) {
+ this.selected(true);
+ } else {
+ this.selected(false);
+ }
+ }
+
+});
+
+// Add Buttons to controlBar
+_V_.merge(_V_.ControlBar.prototype.options.components, {
+ "subtitlesButton": {},
+ "captionsButton": {},
+ "chaptersButton": {}
+});
+
+// _V_.Cue = _V_.Component.extend({
+// init: function(player, options){
+// this._super(player, options);
+// }
+// });// Automatically set up any tags that have a data-setup attribute
+_V_.autoSetup = function(){
+ var options, vid, player,
+ vids = document.getElementsByTagName("video");
+
+ // Check if any media elements exist
+ if (vids && vids.length > 0) {
+
+ for (var i=0,j=vids.length; i<j; i++) {
+ vid = vids[i];
+
+ // Check if element exists, has getAttribute func.
+ // IE seems to consider typeof el.getAttribute == "object" instead of "function" like expected, at least when loading the player immediately.
+ if (vid && vid.getAttribute) {
+
+ // Make sure this player hasn't already been set up.
+ if (vid.player === undefined) {
+ options = vid.getAttribute("data-setup");
+
+ // Check if data-setup attr exists.
+ // We only auto-setup if they've added the data-setup attr.
+ if (options !== null) {
+
+ // Parse options JSON
+ // If empty string, make it a parsable json object.
+ options = JSON.parse(options || "{}");
+
+ // Create new video.js instance.
+ player = _V_(vid, options);
+ }
+ }
+
+ // If getAttribute isn't defined, we need to wait for the DOM.
+ } else {
+ _V_.autoSetupTimeout(1);
+ break;
+ }
+ }
+
+ // No videos were found, so keep looping unless page is finisehd loading.
+ } else if (!_V_.windowLoaded) {
+ _V_.autoSetupTimeout(1);
+ }
+};
+
+// Pause to let the DOM keep processing
+_V_.autoSetupTimeout = function(wait){
+ setTimeout(_V_.autoSetup, wait);
+};
+
+_V_.addEvent(window, "load", function(){
+ _V_.windowLoaded = true;
+});
+
+// Run Auto-load players
+_V_.autoSetup();
+// Expose to global
+window.VideoJS = window._V_ = VideoJS;
+
+// End self-executing function
+})(window);
\ No newline at end of file
--- /dev/null
+/*!
+Video.js - HTML5 Video Player
+Version GENERATED_AT_BUILD
+
+LGPL v3 LICENSE INFO
+This file is part of Video.js. Copyright 2011 Zencoder, Inc.
+
+Video.js is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Video.js is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with Video.js. If not, see <http://www.gnu.org/licenses/>.
+*/
+(function(window,undefined){var document=window.document;document.createElement("video");document.createElement("audio");var VideoJS=function(id,addOptions,ready){var tag;if(typeof id=="string"){if(id.indexOf("#")===0){id=id.slice(1)}if(_V_.players[id]){return _V_.players[id]}else{tag=_V_.el(id)}}else{tag=id}if(!tag||!tag.nodeName){throw new TypeError("The element or ID supplied is not valid. (VideoJS)")}return tag.player||new _V_.Player(tag,addOptions,ready)},_V_=VideoJS,CDN_VERSION="GENERATED_CDN_VSN";VideoJS.players={};VideoJS.options={techOrder:["html5","flash"],html5:{},flash:{swf:"http://vjs.zencdn.net/c/video-js.swf"},width:300,height:150,defaultVolume:0,components:{posterImage:{},textTrackDisplay:{},loadingSpinner:{},bigPlayButton:{},controlBar:{}}};if(CDN_VERSION!="GENERATED_CDN_VSN"){_V_.options.flash.swf="http://vjs.zencdn.net/"+CDN_VERSION+"/video-js.swf"}_V_.merge=function(obj1,obj2,safe){if(!obj2){obj2={}}for(var attrname in obj2){if(obj2.hasOwnProperty(attrname)&&(!safe||!obj1.hasOwnProperty(attrname))){obj1[attrname]=obj2[attrname]}}return obj1};_V_.extend=function(obj){this.merge(this,obj,true)};_V_.extend({tech:{},controlSets:{},isIE:function(){return !+"\v1"},isFF:function(){return !!_V_.ua.match("Firefox")},isIPad:function(){return navigator.userAgent.match(/iPad/i)!==null},isIPhone:function(){return navigator.userAgent.match(/iPhone/i)!==null},isIOS:function(){return VideoJS.isIPhone()||VideoJS.isIPad()},iOSVersion:function(){var match=navigator.userAgent.match(/OS (\d+)_/i);if(match&&match[1]){return match[1]}},isAndroid:function(){return navigator.userAgent.match(/Android.*AppleWebKit/i)!==null},androidVersion:function(){var match=navigator.userAgent.match(/Android (\d+)\./i);if(match&&match[1]){return match[1]}},testVid:document.createElement("video"),ua:navigator.userAgent,support:{},each:function(arr,fn){if(!arr||arr.length===0){return}for(var i=0,j=arr.length;i<j;i++){fn.call(this,arr[i],i)}},eachProp:function(obj,fn){if(!obj){return}for(var name in obj){if(obj.hasOwnProperty(name)){fn.call(this,name,obj[name])}}},el:function(id){return document.getElementById(id)},createElement:function(tagName,attributes){var el=document.createElement(tagName),attrname;for(attrname in attributes){if(attributes.hasOwnProperty(attrname)){if(attrname.indexOf("-")!==-1){el.setAttribute(attrname,attributes[attrname])}else{el[attrname]=attributes[attrname]}}}return el},insertFirst:function(node,parent){if(parent.firstChild){parent.insertBefore(node,parent.firstChild)}else{parent.appendChild(node)}},addClass:function(element,classToAdd){if((" "+element.className+" ").indexOf(" "+classToAdd+" ")==-1){element.className=element.className===""?classToAdd:element.className+" "+classToAdd}},removeClass:function(element,classToRemove){if(element.className.indexOf(classToRemove)==-1){return}var classNames=element.className.split(" ");classNames.splice(classNames.indexOf(classToRemove),1);element.className=classNames.join(" ")},blockTextSelection:function(){document.body.focus();document.onselectstart=function(){return false}},unblockTextSelection:function(){document.onselectstart=function(){return true}},formatTime:function(seconds,guide){guide=guide||seconds;var s=Math.floor(seconds%60),m=Math.floor(seconds/60%60),h=Math.floor(seconds/3600),gm=Math.floor(guide/60%60),gh=Math.floor(guide/3600);h=(h>0||gh>0)?h+":":"";m=(((h||gm>=10)&&m<10)?"0"+m:m)+":";s=(s<10)?"0"+s:s;return h+m+s},uc:function(string){return string.charAt(0).toUpperCase()+string.slice(1)},getRelativePosition:function(x,relativeElement){return Math.max(0,Math.min(1,(x-_V_.findPosX(relativeElement))/relativeElement.offsetWidth))},getComputedStyleValue:function(element,style){return window.getComputedStyle(element,null).getPropertyValue(style)},trim:function(string){return string.toString().replace(/^\s+/,"").replace(/\s+$/,"")},round:function(num,dec){if(!dec){dec=0}return Math.round(num*Math.pow(10,dec))/Math.pow(10,dec)},isEmpty:function(object){for(var prop in object){return false}return true},createTimeRange:function(start,end){return{length:1,start:function(){return start},end:function(){return end}}},cache:{},guid:1,expando:"vdata"+(new Date).getTime(),getData:function(elem){var id=elem[_V_.expando];if(!id){id=elem[_V_.expando]=_V_.guid++;_V_.cache[id]={}}return _V_.cache[id]},removeData:function(elem){var id=elem[_V_.expando];if(!id){return}delete _V_.cache[id];try{delete elem[_V_.expando]}catch(e){if(elem.removeAttribute){elem.removeAttribute(_V_.expando)}else{elem[_V_.expando]=null}}},proxy:function(context,fn,uid){if(!fn.guid){fn.guid=_V_.guid++}var ret=function(){return fn.apply(context,arguments)};ret.guid=(uid)?uid+"_"+fn.guid:fn.guid;return ret},get:function(url,onSuccess,onError){var local=(url.indexOf("file:")==0||(window.location.href.indexOf("file:")==0&&url.indexOf("http:")==-1));if(typeof XMLHttpRequest=="undefined"){XMLHttpRequest=function(){try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(f){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(g){}throw new Error("This browser does not support XMLHttpRequest.")}}var request=new XMLHttpRequest();try{request.open("GET",url)}catch(e){_V_.log("VideoJS XMLHttpRequest (open)",e);return false}request.onreadystatechange=_V_.proxy(this,function(){if(request.readyState==4){if(request.status==200||local&&request.status==0){onSuccess(request.responseText)}else{if(onError){onError()}}}});try{request.send()}catch(e){_V_.log("VideoJS XMLHttpRequest (send)",e);if(onError){onError(e)}}},setLocalStorage:function(key,value){var localStorage=window.localStorage||false;if(!localStorage){return}try{localStorage[key]=value}catch(e){if(e.code==22||e.code==1014){_V_.log("LocalStorage Full (VideoJS)",e)}else{_V_.log("LocalStorage Error (VideoJS)",e)}}},getAbsoluteURL:function(url){if(!url.match(/^https?:\/\//)){url=_V_.createElement("div",{innerHTML:'<a href="'+url+'">x</a>'}).firstChild.href}return url}});_V_.log=function(){_V_.log.history=_V_.log.history||[];_V_.log.history.push(arguments);if(window.console){arguments.callee=arguments.callee.caller;var newarr=[].slice.call(arguments);(typeof console.log==="object"?_V_.log.apply.call(console.log,console,newarr):console.log.apply(console,newarr))}};(function(b){function c(){}for(var d="assert,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,timeStamp,profile,profileEnd,time,timeEnd,trace,warn".split(","),a;a=d.pop();){b[a]=b[a]||c}})((function(){try{console.log();return window.console}catch(err){return window.console={}}})());if("getBoundingClientRect" in document.documentElement){_V_.findPosX=function(el){var box;try{box=el.getBoundingClientRect()}catch(e){}if(!box){return 0}var docEl=document.documentElement,body=document.body,clientLeft=docEl.clientLeft||body.clientLeft||0,scrollLeft=window.pageXOffset||body.scrollLeft,left=box.left+scrollLeft-clientLeft;return left}}else{_V_.findPosX=function(el){var curleft=el.offsetLeft;while(el=obj.offsetParent){if(el.className.indexOf("video-js")==-1){}else{}curleft+=el.offsetLeft}return curleft}}var JSON;if(!JSON){JSON={}}(function(){var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;if(typeof JSON.parse!=="function"){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==="object"){for(k in value){if(Object.prototype.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v}else{delete value[k]}}}}return reviver.call(holder,key,value)}text=String(text);cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})}if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))){j=eval("("+text+")");return typeof reviver==="function"?walk({"":j},""):j}throw new SyntaxError("JSON.parse")}}}());_V_.extend({on:function(elem,type,fn){var data=_V_.getData(elem),handlers;if(data&&!data.handler){data.handler=function(event){event=_V_.fixEvent(event);var handlers=_V_.getData(elem).events[event.type];if(handlers){var handlersCopy=[];_V_.each(handlers,function(handler,i){handlersCopy[i]=handler});for(var i=0,l=handlersCopy.length;i<l;i++){handlersCopy[i].call(elem,event)}}}}if(!data.events){data.events={}}handlers=data.events[type];if(!handlers){handlers=data.events[type]=[];if(document.addEventListener){elem.addEventListener(type,data.handler,false)}else{if(document.attachEvent){elem.attachEvent("on"+type,data.handler)}}}if(!fn.guid){fn.guid=_V_.guid++}handlers.push(fn)},addEvent:function(){return _V_.on.apply(this,arguments)},off:function(elem,type,fn){var data=_V_.getData(elem),handlers;if(!data.events){return}if(!type){for(type in data.events){_V_.cleanUpEvents(elem,type)}return}handlers=data.events[type];if(!handlers){return}if(fn&&fn.guid){for(var i=0;i<handlers.length;i++){if(handlers[i].guid===fn.guid){handlers.splice(i--,1)}}}_V_.cleanUpEvents(elem,type)},removeEvent:function(){return _V_.off.apply(this,arguments)},cleanUpEvents:function(elem,type){var data=_V_.getData(elem);if(data.events[type].length===0){delete data.events[type];if(document.removeEventListener){elem.removeEventListener(type,data.handler,false)}else{if(document.detachEvent){elem.detachEvent("on"+type,data.handler)}}}if(_V_.isEmpty(data.events)){delete data.events;delete data.handler}if(_V_.isEmpty(data)){_V_.removeData(elem)}},fixEvent:function(event){if(event[_V_.expando]){return event}var originalEvent=event;event=new _V_.Event(originalEvent);for(var i=_V_.Event.props.length,prop;i;){prop=_V_.Event.props[--i];event[prop]=originalEvent[prop]}if(!event.target){event.target=event.srcElement||document}if(event.target.nodeType===3){event.target=event.target.parentNode}if(!event.relatedTarget&&event.fromElement){event.relatedTarget=event.fromElement===event.target?event.toElement:event.fromElement}if(event.pageX==null&&event.clientX!=null){var eventDocument=event.target.ownerDocument||document,doc=eventDocument.documentElement,body=eventDocument.body;event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc&&doc.clientLeft||body&&body.clientLeft||0);event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc&&doc.clientTop||body&&body.clientTop||0)}if(event.which==null&&(event.charCode!=null||event.keyCode!=null)){event.which=event.charCode!=null?event.charCode:event.keyCode}if(!event.metaKey&&event.ctrlKey){event.metaKey=event.ctrlKey}if(!event.which&&event.button!==undefined){event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)))}return event},trigger:function(elem,event){var data=_V_.getData(elem),parent=elem.parentNode||elem.ownerDocument,type=event.type||event,handler;if(data){handler=data.handler}event=typeof event==="object"?event[_V_.expando]?event:new _V_.Event(type,event):new _V_.Event(type);event.type=type;if(handler){handler.call(elem,event)}event.result=undefined;event.target=elem},triggerEvent:function(){return _V_.trigger.apply(this,arguments)},one:function(elem,type,fn){_V_.on(elem,type,function(){_V_.off(elem,type,arguments.callee);fn.apply(this,arguments)})}});_V_.Event=function(src,props){if(src&&src.type){this.originalEvent=src;this.type=src.type;this.isDefaultPrevented=(src.defaultPrevented||src.returnValue===false||src.getPreventDefault&&src.getPreventDefault())?returnTrue:returnFalse}else{this.type=src}if(props){_V_.merge(this,props)}this.timeStamp=(new Date).getTime();this[_V_.expando]=true};_V_.Event.prototype={preventDefault:function(){this.isDefaultPrevented=returnTrue;var e=this.originalEvent;if(!e){return}if(e.preventDefault){e.preventDefault()}else{e.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=returnTrue;var e=this.originalEvent;if(!e){return}if(e.stopPropagation){e.stopPropagation()}e.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=returnTrue;this.stopPropagation()},isDefaultPrevented:returnFalse,isPropagationStopped:returnFalse,isImmediatePropagationStopped:returnFalse};_V_.Event.props="altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" ");function returnTrue(){return true}function returnFalse(){return false}(function(){var initializing=false,fnTest=/xyz/.test(function(){xyz})?/\b_super\b/:/.*/;_V_.Class=function(){};_V_.Class.extend=function(prop){var _super=this.prototype;initializing=true;var prototype=new this();initializing=false;for(var name in prop){prototype[name]=typeof prop[name]=="function"&&typeof _super[name]=="function"&&fnTest.test(prop[name])?(function(name,fn){return function(){var tmp=this._super;this._super=_super[name];var ret=fn.apply(this,arguments);this._super=tmp;return ret}})(name,prop[name]):prop[name]}function Class(){if(!initializing&&this.init){return this.init.apply(this,arguments)}else{if(!initializing){return arguments.callee.prototype.init()}}}Class.prototype=prototype;Class.constructor=Class;Class.extend=arguments.callee;return Class}})();_V_.Component=_V_.Class.extend({init:function(player,options){this.player=player;options=this.options=_V_.merge(this.options||{},options);if(options.el){this.el=options.el}else{this.el=this.createElement()}this.initComponents()},destroy:function(){},createElement:function(type,attrs){return _V_.createElement(type||"div",attrs)},buildCSSClass:function(){return""},initComponents:function(){var options=this.options;if(options&&options.components){this.eachProp(options.components,function(name,opts){var tempAdd=this.proxy(function(){this[name]=this.addComponent(name,opts)});if(opts.loadEvent){this.one(opts.loadEvent,tempAdd)}else{tempAdd()}})}},addComponent:function(name,options){var component,componentClass;if(typeof name=="string"){options=options||{};componentClass=options.componentClass||_V_.uc(name);component=new _V_[componentClass](this.player||this,options)}else{component=name}this.el.appendChild(component.el);return component},removeComponent:function(component){this.el.removeChild(component.el)},show:function(){this.el.style.display="block"},hide:function(){this.el.style.display="none"},fadeIn:function(){this.removeClass("vjs-fade-out");this.addClass("vjs-fade-in")},fadeOut:function(){this.removeClass("vjs-fade-in");this.addClass("vjs-fade-out")},lockShowing:function(){var style=this.el.style;style.display="block";style.opacity=1;style.visiblity="visible"},unlockShowing:function(){var style=this.el.style;style.display="";style.opacity="";style.visiblity=""},addClass:function(classToAdd){_V_.addClass(this.el,classToAdd)},removeClass:function(classToRemove){_V_.removeClass(this.el,classToRemove)},on:function(type,fn,uid){return _V_.on(this.el,type,_V_.proxy(this,fn))},addEvent:function(){return this.on.apply(this,arguments)},off:function(type,fn){return _V_.off(this.el,type,fn)},removeEvent:function(){return this.off.apply(this,arguments)},trigger:function(type,e){return _V_.trigger(this.el,type,e)},triggerEvent:function(){return this.trigger.apply(this,arguments)},one:function(type,fn){_V_.one(this.el,type,_V_.proxy(this,fn))},ready:function(fn){if(!fn){return this}if(this.isReady){fn.call(this)}else{if(this.readyQueue===undefined){this.readyQueue=[]}this.readyQueue.push(fn)}return this},triggerReady:function(){this.isReady=true;if(this.readyQueue&&this.readyQueue.length>0){this.each(this.readyQueue,function(fn){fn.call(this)});this.readyQueue=[];this.trigger("ready")}},each:function(arr,fn){_V_.each.call(this,arr,fn)},eachProp:function(obj,fn){_V_.eachProp.call(this,obj,fn)},extend:function(obj){_V_.merge(this,obj)},proxy:function(fn,uid){return _V_.proxy(this,fn,uid)}});_V_.Player=_V_.Component.extend({init:function(tag,addOptions,ready){this.tag=tag;var el=this.el=_V_.createElement("div"),options=this.options={};_V_.merge(options,_V_.options);_V_.merge(options,this.getVideoTagSettings());_V_.merge(options,addOptions);this.ready(ready);tag.removeAttribute("controls");tag.removeAttribute("poster");tag.player=el.player=this;tag.id=tag.id||"vjs_video_"+_V_.guid++;this.id=el.id=tag.id;el.className=tag.className;_V_.players[el.id]=this;el.setAttribute("width",options.width);el.setAttribute("height",options.height);el.style.width=options.width+"px";el.style.height=options.height+"px";tag.id+="_html5_api";tag.className="vjs-tech";tag.removeAttribute("width");tag.removeAttribute("height");tag.parentNode.insertBefore(el,tag);el.appendChild(tag);if(tag.hasChildNodes()){var nrOfChildNodes=tag.childNodes.length;for(var i=0,j=tag.childNodes;i<nrOfChildNodes;i++){if(j[0].nodeName.toLowerCase()=="source"||j[0].nodeName.toLowerCase()=="track"){tag.removeChild(j[0])}}}this.values={};this.addClass("vjs-paused");this.on("ended",this.onEnded);this.on("play",this.onPlay);this.on("pause",this.onPause);this.on("progress",this.onProgress);this.on("error",this.onError);if(options.controls){this.ready(function(){this.initComponents()})}this.textTracks=[];if(options.tracks&&options.tracks.length>0){this.addTextTracks(options.tracks)}if(!options.sources||options.sources.length==0){for(var i=0,j=options.techOrder;i<j.length;i++){var techName=j[i],tech=_V_[techName];if(tech.isSupported()){this.loadTech(techName);break}}}else{this.src(options.sources)}},destroy:function(){this.stopTrackingProgress();this.stopTrackingCurrentTime();_V_.players[this.id]=null;delete _V_.players[this.id];this.tech.destroy();this.el.parentNode.removeChild(this.el)},createElement:function(type,options){},getVideoTagSettings:function(){var options={sources:[],tracks:[]},tag=this.tag,getAttribute="getAttribute";options.src=tag[getAttribute]("src");options.controls=tag[getAttribute]("controls")!==null;options.poster=tag[getAttribute]("poster");options.preload=tag[getAttribute]("preload");options.autoplay=tag[getAttribute]("autoplay")!==null;options.loop=tag[getAttribute]("loop")!==null;options.muted=tag[getAttribute]("muted")!==null;options.width=tag[getAttribute]("width");options.height=tag[getAttribute]("height");if(this.tag.hasChildNodes()){for(var c,i=0,j=this.tag.childNodes;i<j.length;i++){c=j[i];if(c.nodeName.toLowerCase()=="source"){options.sources.push({src:c[getAttribute]("src"),type:c[getAttribute]("type"),media:c[getAttribute]("media"),title:c[getAttribute]("title")})}if(c.nodeName.toLowerCase()=="track"){options.tracks.push({src:c[getAttribute]("src"),kind:c[getAttribute]("kind"),srclang:c[getAttribute]("srclang"),label:c[getAttribute]("label"),"default":c[getAttribute]("default")!==null,title:c[getAttribute]("title")})}}}return options},loadTech:function(techName,source){if(this.tech){this.unloadTech()}else{if(techName!="html5"&&this.tag){this.el.removeChild(this.tag);this.tag=false}}this.techName=techName;this.isReady=false;var techReady=function(){this.player.triggerReady();if(!this.support.progressEvent){this.player.manualProgressOn()}if(!this.support.timeupdateEvent){this.player.manualTimeUpdatesOn()}};var techOptions=_V_.merge({source:source,parentEl:this.el},this.options[techName]);if(source){if(source.src==this.values.src&&this.values.currentTime>0){techOptions.startTime=this.values.currentTime}this.values.src=source.src}this.tech=new _V_[techName](this,techOptions);this.tech.ready(techReady)},unloadTech:function(){this.tech.destroy();if(this.manualProgress){this.manualProgressOff()}if(this.manualTimeUpdates){this.manualTimeUpdatesOff()}this.tech=false},manualProgressOn:function(){this.manualProgress=true;this.trackProgress();this.tech.on("progress",function(){this.removeEvent("progress",arguments.callee);this.support.progressEvent=true;this.player.manualProgressOff()})},manualProgressOff:function(){this.manualProgress=false;this.stopTrackingProgress()},trackProgress:function(){this.progressInterval=setInterval(_V_.proxy(this,function(){if(this.values.bufferEnd<this.buffered().end(0)){this.trigger("progress")}else{if(this.bufferedPercent()==1){this.stopTrackingProgress();this.trigger("progress")}}}),500)},stopTrackingProgress:function(){clearInterval(this.progressInterval)},manualTimeUpdatesOn:function(){this.manualTimeUpdates=true;this.on("play",this.trackCurrentTime);this.on("pause",this.stopTrackingCurrentTime);this.tech.on("timeupdate",function(){this.removeEvent("timeupdate",arguments.callee);this.support.timeupdateEvent=true;this.player.manualTimeUpdatesOff()})},manualTimeUpdatesOff:function(){this.manualTimeUpdates=false;this.stopTrackingCurrentTime();this.removeEvent("play",this.trackCurrentTime);this.removeEvent("pause",this.stopTrackingCurrentTime)},trackCurrentTime:function(){if(this.currentTimeInterval){this.stopTrackingCurrentTime()}this.currentTimeInterval=setInterval(_V_.proxy(this,function(){this.trigger("timeupdate")}),250)},stopTrackingCurrentTime:function(){clearInterval(this.currentTimeInterval)},onEnded:function(){if(this.options.loop){this.currentTime(0);this.play()}else{this.pause();this.currentTime(0);this.pause()}},onPlay:function(){_V_.removeClass(this.el,"vjs-paused");_V_.addClass(this.el,"vjs-playing")},onPause:function(){_V_.removeClass(this.el,"vjs-playing");_V_.addClass(this.el,"vjs-paused")},onProgress:function(){if(this.bufferedPercent()==1){this.trigger("loadedalldata")}},onError:function(e){_V_.log("Video Error",e)},techCall:function(method,arg){if(!this.tech.isReady){this.tech.ready(function(){this[method](arg)})}else{try{this.tech[method](arg)}catch(e){_V_.log(e)}}},techGet:function(method){if(this.tech.isReady){try{return this.tech[method]()}catch(e){if(this.tech[method]===undefined){_V_.log("Video.js: "+method+" method not defined for "+this.techName+" playback technology.",e)}else{if(e.name=="TypeError"){_V_.log("Video.js: "+method+" unavailable on "+this.techName+" playback technology element.",e);this.tech.isReady=false}else{_V_.log(e)}}}}return},play:function(){this.techCall("play");return this},pause:function(){this.techCall("pause");return this},paused:function(){return(this.techGet("paused")===false)?false:true},currentTime:function(seconds){if(seconds!==undefined){this.values.lastSetCurrentTime=seconds;this.techCall("setCurrentTime",seconds);if(this.manualTimeUpdates){this.trigger("timeupdate")}return this}return this.values.currentTime=(this.techGet("currentTime")||0)},duration:function(){return parseFloat(this.techGet("duration"))},remainingTime:function(){return this.duration()-this.currentTime()},buffered:function(){var buffered=this.techGet("buffered"),start=0,end=this.values.bufferEnd=this.values.bufferEnd||0,timeRange;if(buffered&&buffered.length>0&&buffered.end(0)!==end){end=buffered.end(0);this.values.bufferEnd=end}return _V_.createTimeRange(start,end)},bufferedPercent:function(){return(this.duration())?this.buffered().end(0)/this.duration():0},volume:function(percentAsDecimal){var vol;if(percentAsDecimal!==undefined){vol=Math.max(0,Math.min(1,parseFloat(percentAsDecimal)));this.values.volume=vol;this.techCall("setVolume",vol);_V_.setLocalStorage("volume",vol);return this}vol=parseFloat(this.techGet("volume"));return(isNaN(vol))?1:vol},muted:function(muted){if(muted!==undefined){this.techCall("setMuted",muted);return this}return this.techGet("muted")||false},width:function(width,skipListeners){if(width!==undefined){this.el.width=width;this.el.style.width=width+"px";if(!skipListeners){this.trigger("resize")}return this}return parseInt(this.el.getAttribute("width"))},height:function(height){if(height!==undefined){this.el.height=height;this.el.style.height=height+"px";this.trigger("resize");return this}return parseInt(this.el.getAttribute("height"))},size:function(width,height){return this.width(width,true).height(height)},supportsFullScreen:function(){return this.techGet("supportsFullScreen")||false},requestFullScreen:function(){var requestFullScreen=_V_.support.requestFullScreen;this.isFullScreen=true;if(requestFullScreen){_V_.on(document,requestFullScreen.eventName,this.proxy(function(){this.isFullScreen=document[requestFullScreen.isFullScreen];if(this.isFullScreen==false){_V_.removeEvent(document,requestFullScreen.eventName,arguments.callee)}this.trigger("fullscreenchange")}));if(this.tech.support.fullscreenResize===false&&this.options.flash.iFrameMode!=true){this.pause();this.unloadTech();_V_.on(document,requestFullScreen.eventName,this.proxy(function(){_V_.removeEvent(document,requestFullScreen.eventName,arguments.callee);this.loadTech(this.techName,{src:this.values.src})}));this.el[requestFullScreen.requestFn]()}else{this.el[requestFullScreen.requestFn]()}}else{if(this.tech.supportsFullScreen()){this.trigger("fullscreenchange");this.techCall("enterFullScreen")}else{this.trigger("fullscreenchange");this.enterFullWindow()}}return this},cancelFullScreen:function(){var requestFullScreen=_V_.support.requestFullScreen;this.isFullScreen=false;if(requestFullScreen){if(this.tech.support.fullscreenResize===false&&this.options.flash.iFrameMode!=true){this.pause();this.unloadTech();_V_.on(document,requestFullScreen.eventName,this.proxy(function(){_V_.removeEvent(document,requestFullScreen.eventName,arguments.callee);this.loadTech(this.techName,{src:this.values.src})}));document[requestFullScreen.cancelFn]()}else{document[requestFullScreen.cancelFn]()}}else{if(this.tech.supportsFullScreen()){this.techCall("exitFullScreen");this.trigger("fullscreenchange")}else{this.exitFullWindow();this.trigger("fullscreenchange")}}return this},enterFullWindow:function(){this.isFullWindow=true;this.docOrigOverflow=document.documentElement.style.overflow;_V_.on(document,"keydown",_V_.proxy(this,this.fullWindowOnEscKey));document.documentElement.style.overflow="hidden";_V_.addClass(document.body,"vjs-full-window");_V_.addClass(this.el,"vjs-fullscreen");this.trigger("enterFullWindow")},fullWindowOnEscKey:function(event){if(event.keyCode==27){if(this.isFullScreen==true){this.cancelFullScreen()}else{this.exitFullWindow()}}},exitFullWindow:function(){this.isFullWindow=false;_V_.removeEvent(document,"keydown",this.fullWindowOnEscKey);document.documentElement.style.overflow=this.docOrigOverflow;_V_.removeClass(document.body,"vjs-full-window");_V_.removeClass(this.el,"vjs-fullscreen");this.trigger("exitFullWindow")},selectSource:function(sources){for(var i=0,j=this.options.techOrder;i<j.length;i++){var techName=j[i],tech=_V_[techName];if(tech.isSupported()){for(var a=0,b=sources;a<b.length;a++){var source=b[a];if(tech.canPlaySource.call(this,source)){return{source:source,tech:techName}}}}}return false},src:function(source){if(source instanceof Array){var sourceTech=this.selectSource(source),source,techName;if(sourceTech){source=sourceTech.source;techName=sourceTech.tech;if(techName==this.techName){this.src(source)}else{this.loadTech(techName,source)}}else{_V_.log("No compatible source and playback technology were found.")}}else{if(source instanceof Object){if(_V_[this.techName].canPlaySource(source)){this.src(source.src)}else{this.src([source])}}else{this.values.src=source;if(!this.isReady){this.ready(function(){this.src(source)})}else{this.techCall("src",source);if(this.options.preload=="auto"){this.load()}if(this.options.autoplay){this.play()}}}}return this},load:function(){this.techCall("load");return this},currentSrc:function(){return this.techGet("currentSrc")||this.values.src||""},preload:function(value){if(value!==undefined){this.techCall("setPreload",value);this.options.preload=value;return this}return this.techGet("preload")},autoplay:function(value){if(value!==undefined){this.techCall("setAutoplay",value);this.options.autoplay=value;return this}return this.techGet("autoplay",value)},loop:function(value){if(value!==undefined){this.techCall("setLoop",value);this.options.loop=value;return this}return this.techGet("loop")},controls:function(){return this.options.controls},poster:function(){return this.techGet("poster")},error:function(){return this.techGet("error")},ended:function(){return this.techGet("ended")}});(function(){var requestFn,cancelFn,eventName,isFullScreen,playerProto=_V_.Player.prototype;if(document.cancelFullscreen!==undefined){requestFn="requestFullscreen";cancelFn="exitFullscreen";eventName="fullscreenchange";isFullScreen="fullScreen"}else{_V_.each(["moz","webkit"],function(prefix){if((prefix!="moz"||document.mozFullScreenEnabled)&&document[prefix+"CancelFullScreen"]!==undefined){requestFn=prefix+"RequestFullScreen";cancelFn=prefix+"CancelFullScreen";eventName=prefix+"fullscreenchange";if(prefix=="webkit"){isFullScreen=prefix+"IsFullScreen"}else{isFullScreen=prefix+"FullScreen"}}})}if(requestFn){_V_.support.requestFullScreen={requestFn:requestFn,cancelFn:cancelFn,eventName:eventName,isFullScreen:isFullScreen}}})();_V_.PlaybackTech=_V_.Component.extend({init:function(player,options){},onClick:function(){if(this.player.options.controls){_V_.PlayToggle.prototype.onClick.call(this)}}});_V_.apiMethods="play,pause,paused,currentTime,setCurrentTime,duration,buffered,volume,setVolume,muted,setMuted,width,height,supportsFullScreen,enterFullScreen,src,load,currentSrc,preload,setPreload,autoplay,setAutoplay,loop,setLoop,error,networkState,readyState,seeking,initialTime,startOffsetTime,played,seekable,ended,videoTracks,audioTracks,videoWidth,videoHeight,textTracks,defaultPlaybackRate,playbackRate,mediaGroup,controller,controls,defaultMuted".split(",");_V_.each(_V_.apiMethods,function(methodName){_V_.PlaybackTech.prototype[methodName]=function(){throw new Error("The '"+methodName+"' method is not available on the playback technology's API")}});_V_.html5=_V_.PlaybackTech.extend({init:function(player,options,ready){this.player=player;this.el=this.createElement();this.ready(ready);this.addEvent("click",this.proxy(this.onClick));var source=options.source;if(source&&this.el.currentSrc==source.src){player.triggerEvent("loadstart")}else{if(source){this.el.src=source.src}}player.ready(function(){if(this.options.autoplay&&this.paused()){this.tag.poster=null;this.play()}});this.setupTriggers();this.triggerReady()},destroy:function(){this.player.tag=false;this.removeTriggers();this.el.parentNode.removeChild(this.el)},createElement:function(){var html5=_V_.html5,player=this.player,el=player.tag,newEl;if(!el||this.support.movingElementInDOM===false){if(el){player.el.removeChild(el)}newEl=_V_.createElement("video",{id:el.id||player.el.id+"_html5_api",className:el.className||"vjs-tech"});el=newEl;_V_.insertFirst(el,player.el)}_V_.each(["autoplay","preload","loop","muted"],function(attr){if(player.options[attr]!==null){el[attr]=player.options[attr]}},this);return el},setupTriggers:function(){_V_.each.call(this,_V_.html5.events,function(type){_V_.addEvent(this.el,type,_V_.proxy(this.player,this.eventHandler))})},removeTriggers:function(){_V_.each.call(this,_V_.html5.events,function(type){_V_.removeEvent(this.el,type,_V_.proxy(this.player,this.eventHandler))})},eventHandler:function(e){e.stopPropagation();this.triggerEvent(e)},play:function(){this.el.play()},pause:function(){this.el.pause()},paused:function(){return this.el.paused},currentTime:function(){return this.el.currentTime},setCurrentTime:function(seconds){try{this.el.currentTime=seconds}catch(e){_V_.log(e,"Video isn't ready. (VideoJS)")}},duration:function(){return this.el.duration||0},buffered:function(){return this.el.buffered},volume:function(){return this.el.volume},setVolume:function(percentAsDecimal){this.el.volume=percentAsDecimal},muted:function(){return this.el.muted},setMuted:function(muted){this.el.muted=muted},width:function(){return this.el.offsetWidth},height:function(){return this.el.offsetHeight},supportsFullScreen:function(){if(typeof this.el.webkitEnterFullScreen=="function"){if(!navigator.userAgent.match("Chrome")&&!navigator.userAgent.match("Mac OS X 10.5")){return true}}return false},enterFullScreen:function(){try{this.el.webkitEnterFullScreen()}catch(e){if(e.code==11){_V_.log("VideoJS: Video not ready.")}}},exitFullScreen:function(){try{this.el.webkitExitFullScreen()}catch(e){if(e.code==11){_V_.log("VideoJS: Video not ready.")}}},src:function(src){this.el.src=src},load:function(){this.el.load()},currentSrc:function(){return this.el.currentSrc},preload:function(){return this.el.preload},setPreload:function(val){this.el.preload=val},autoplay:function(){return this.el.autoplay},setAutoplay:function(val){this.el.autoplay=val},loop:function(){return this.el.loop},setLoop:function(val){this.el.loop=val},error:function(){return this.el.error},seeking:function(){return this.el.seeking},ended:function(){return this.el.ended},controls:function(){return this.player.options.controls},defaultMuted:function(){return this.el.defaultMuted}});_V_.html5.isSupported=function(){return !!document.createElement("video").canPlayType};_V_.html5.canPlaySource=function(srcObj){return !!document.createElement("video").canPlayType(srcObj.type)};_V_.html5.events="loadstart,suspend,abort,error,emptied,stalled,loadedmetadata,loadeddata,canplay,canplaythrough,playing,waiting,seeking,seeked,ended,durationchange,timeupdate,progress,play,pause,ratechange,volumechange".split(",");_V_.html5.prototype.support={fullscreen:(typeof _V_.testVid.webkitEnterFullScreen!==undefined)?(!_V_.ua.match("Chrome")&&!_V_.ua.match("Mac OS X 10.5")?true:false):false,movingElementInDOM:!_V_.isIOS()};if(_V_.isAndroid()){if(_V_.androidVersion()<3){document.createElement("video").constructor.prototype.canPlayType=function(type){return(type&&type.toLowerCase().indexOf("video/mp4")!=-1)?"maybe":""}}}_V_.flash=_V_.PlaybackTech.extend({init:function(player,options){this.player=player;var source=options.source,parentEl=options.parentEl,placeHolder=this.el=_V_.createElement("div",{id:parentEl.id+"_temp_flash"}),objId=player.el.id+"_flash_api",playerOptions=player.options,flashVars=_V_.merge({readyFunction:"_V_.flash.onReady",eventProxyFunction:"_V_.flash.onEvent",errorEventProxyFunction:"_V_.flash.onError",autoplay:playerOptions.autoplay,preload:playerOptions.preload,loop:playerOptions.loop,muted:playerOptions.muted},options.flashVars),params=_V_.merge({wmode:"opaque",bgcolor:"#000000"},options.params),attributes=_V_.merge({id:objId,name:objId,"class":"vjs-tech"},options.attributes);if(source){flashVars.src=encodeURIComponent(_V_.getAbsoluteURL(source.src))}_V_.insertFirst(placeHolder,parentEl);if(options.startTime){this.ready(function(){this.load();this.play();this.currentTime(options.startTime)})}if(options.iFrameMode==true&&!_V_.isFF){var iFrm=_V_.createElement("iframe",{id:objId+"_iframe",name:objId+"_iframe",className:"vjs-tech",scrolling:"no",marginWidth:0,marginHeight:0,frameBorder:0});flashVars.readyFunction="ready";flashVars.eventProxyFunction="events";flashVars.errorEventProxyFunction="errors";_V_.addEvent(iFrm,"load",_V_.proxy(this,function(){var iDoc,objTag,swfLoc,iWin=iFrm.contentWindow,varString="";iDoc=iFrm.contentDocument?iFrm.contentDocument:iFrm.contentWindow.document;iDoc.write(_V_.flash.getEmbedCode(options.swf,flashVars,params,attributes));iWin.player=this.player;iWin.ready=_V_.proxy(this.player,function(currSwf){var el=iDoc.getElementById(currSwf),player=this,tech=player.tech;tech.el=el;_V_.addEvent(el,"click",tech.proxy(tech.onClick));_V_.flash.checkReady(tech)});iWin.events=_V_.proxy(this.player,function(swfID,eventName,other){var player=this;if(player&&player.techName=="flash"){player.triggerEvent(eventName)}});iWin.errors=_V_.proxy(this.player,function(swfID,eventName){_V_.log("Flash Error",eventName)})}));placeHolder.parentNode.replaceChild(iFrm,placeHolder)}else{_V_.flash.embed(options.swf,placeHolder,flashVars,params,attributes)}},destroy:function(){this.el.parentNode.removeChild(this.el)},play:function(){this.el.vjs_play()},pause:function(){this.el.vjs_pause()},src:function(src){src=_V_.getAbsoluteURL(src);this.el.vjs_src(src);if(this.player.autoplay()){var tech=this;setTimeout(function(){tech.play()},0)}},load:function(){this.el.vjs_load()},poster:function(){this.el.vjs_getProperty("poster")},buffered:function(){return _V_.createTimeRange(0,this.el.vjs_getProperty("buffered"))},supportsFullScreen:function(){return false},enterFullScreen:function(){return false}});(function(){var api=_V_.flash.prototype,readWrite="preload,currentTime,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted".split(","),readOnly="error,currentSrc,networkState,readyState,seeking,initialTime,duration,startOffsetTime,paused,played,seekable,ended,videoTracks,audioTracks,videoWidth,videoHeight,textTracks".split(","),callOnly="load,play,pause".split(",");createSetter=function(attr){var attrUpper=attr.charAt(0).toUpperCase()+attr.slice(1);api["set"+attrUpper]=function(val){return this.el.vjs_setProperty(attr,val)}},createGetter=function(attr){api[attr]=function(){return this.el.vjs_getProperty(attr)}};_V_.each(readWrite,function(attr){createGetter(attr);createSetter(attr)});_V_.each(readOnly,function(attr){createGetter(attr)})})();_V_.flash.isSupported=function(){return _V_.flash.version()[0]>=10};_V_.flash.canPlaySource=function(srcObj){if(srcObj.type in _V_.flash.prototype.support.formats){return"maybe"}};_V_.flash.prototype.support={formats:{"video/flv":"FLV","video/x-flv":"FLV","video/mp4":"MP4","video/m4v":"MP4"},progressEvent:false,timeupdateEvent:false,fullscreenResize:false,parentResize:!(_V_.ua.match("Firefox"))};_V_.flash.onReady=function(currSwf){var el=_V_.el(currSwf);var player=el.player||el.parentNode.player,tech=player.tech;el.player=player;tech.el=el;tech.addEvent("click",tech.onClick);_V_.flash.checkReady(tech)};_V_.flash.checkReady=function(tech){if(tech.el.vjs_getProperty){tech.triggerReady()}else{setTimeout(function(){_V_.flash.checkReady(tech)},50)}};_V_.flash.onEvent=function(swfID,eventName){var player=_V_.el(swfID).player;player.triggerEvent(eventName)};_V_.flash.onError=function(swfID,err){var player=_V_.el(swfID).player;player.triggerEvent("error");_V_.log("Flash Error",err,swfID)};_V_.flash.version=function(){var version="0,0,0";try{version=new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version").replace(/\D+/g,",").match(/^,?(.+),?$/)[1]}catch(e){try{if(navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin){version=(navigator.plugins["Shockwave Flash 2.0"]||navigator.plugins["Shockwave Flash"]).description.replace(/\D+/g,",").match(/^,?(.+),?$/)[1]}}catch(e){}}return version.split(",")};_V_.flash.embed=function(swf,placeHolder,flashVars,params,attributes){var code=_V_.flash.getEmbedCode(swf,flashVars,params,attributes),obj=_V_.createElement("div",{innerHTML:code}).childNodes[0],par=placeHolder.parentNode;placeHolder.parentNode.replaceChild(obj,placeHolder);if(_V_.isIE()){var newObj=par.childNodes[0];setTimeout(function(){newObj.style.display="block"},1000)}return obj};_V_.flash.getEmbedCode=function(swf,flashVars,params,attributes){var objTag='<object type="application/x-shockwave-flash"',flashVarsString="",paramsString="";attrsString="";if(flashVars){_V_.eachProp(flashVars,function(key,val){flashVarsString+=(key+"="+val+"&")})}params=_V_.merge({movie:swf,flashvars:flashVarsString,allowScriptAccess:"always",allowNetworking:"all"},params);_V_.eachProp(params,function(key,val){paramsString+='<param name="'+key+'" value="'+val+'" />'});attributes=_V_.merge({data:swf,width:"100%",height:"100%"},attributes);_V_.eachProp(attributes,function(key,val){attrsString+=(key+'="'+val+'" ')});return objTag+attrsString+">"+paramsString+"</object>"};_V_.Control=_V_.Component.extend({buildCSSClass:function(){return"vjs-control "+this._super()}});_V_.ControlBar=_V_.Component.extend({options:{loadEvent:"play",components:{playToggle:{},fullscreenToggle:{},currentTimeDisplay:{},timeDivider:{},durationDisplay:{},remainingTimeDisplay:{},progressControl:{},volumeControl:{},muteToggle:{}}},init:function(player,options){this._super(player,options);player.on("play",this.proxy(function(){this.fadeIn();this.player.on("mouseover",this.proxy(this.fadeIn));this.player.on("mouseout",this.proxy(this.fadeOut))}))},createElement:function(){return _V_.createElement("div",{className:"vjs-controls"})},fadeIn:function(){this._super();this.player.trigger("controlsvisible")},fadeOut:function(){this._super();this.player.trigger("controlshidden")},lockShowing:function(){this.el.style.opacity="1"}});_V_.Button=_V_.Control.extend({init:function(player,options){this._super(player,options);this.on("click",this.onClick);this.on("focus",this.onFocus);this.on("blur",this.onBlur)},createElement:function(type,attrs){attrs=_V_.merge({className:this.buildCSSClass(),innerHTML:'<div><span class="vjs-control-text">'+(this.buttonText||"Need Text")+"</span></div>",role:"button",tabIndex:0},attrs);return this._super(type,attrs)},onClick:function(){},onFocus:function(){_V_.on(document,"keyup",_V_.proxy(this,this.onKeyPress))},onKeyPress:function(event){if(event.which==32||event.which==13){event.preventDefault();this.onClick()}},onBlur:function(){_V_.off(document,"keyup",_V_.proxy(this,this.onKeyPress))}});_V_.PlayButton=_V_.Button.extend({buttonText:"Play",buildCSSClass:function(){return"vjs-play-button "+this._super()},onClick:function(){this.player.play()}});_V_.PauseButton=_V_.Button.extend({buttonText:"Pause",buildCSSClass:function(){return"vjs-pause-button "+this._super()},onClick:function(){this.player.pause()}});_V_.PlayToggle=_V_.Button.extend({buttonText:"Play",init:function(player,options){this._super(player,options);player.on("play",_V_.proxy(this,this.onPlay));player.on("pause",_V_.proxy(this,this.onPause))},buildCSSClass:function(){return"vjs-play-control "+this._super()},onClick:function(){if(this.player.paused()){this.player.play()}else{this.player.pause()}},onPlay:function(){_V_.removeClass(this.el,"vjs-paused");_V_.addClass(this.el,"vjs-playing")},onPause:function(){_V_.removeClass(this.el,"vjs-playing");_V_.addClass(this.el,"vjs-paused")}});_V_.FullscreenToggle=_V_.Button.extend({buttonText:"Fullscreen",buildCSSClass:function(){return"vjs-fullscreen-control "+this._super()},onClick:function(){if(!this.player.isFullScreen){this.player.requestFullScreen()}else{this.player.cancelFullScreen()}}});_V_.BigPlayButton=_V_.Button.extend({init:function(player,options){this._super(player,options);player.on("play",_V_.proxy(this,this.hide));player.on("ended",_V_.proxy(this,this.show))},createElement:function(){return this._super("div",{className:"vjs-big-play-button",innerHTML:"<span></span>"})},onClick:function(){if(this.player.currentTime()){this.player.currentTime(0)}this.player.play()}});_V_.LoadingSpinner=_V_.Component.extend({init:function(player,options){this._super(player,options);player.on("canplay",_V_.proxy(this,this.hide));player.on("canplaythrough",_V_.proxy(this,this.hide));player.on("playing",_V_.proxy(this,this.hide));player.on("seeking",_V_.proxy(this,this.show));player.on("error",_V_.proxy(this,this.show));player.on("waiting",_V_.proxy(this,this.show))},createElement:function(){var classNameSpinner,innerHtmlSpinner;if(typeof this.player.el.style.WebkitBorderRadius=="string"||typeof this.player.el.style.MozBorderRadius=="string"||typeof this.player.el.style.KhtmlBorderRadius=="string"||typeof this.player.el.style.borderRadius=="string"){classNameSpinner="vjs-loading-spinner";innerHtmlSpinner="<div class='ball1'></div><div class='ball2'></div><div class='ball3'></div><div class='ball4'></div><div class='ball5'></div><div class='ball6'></div><div class='ball7'></div><div class='ball8'></div>"}else{classNameSpinner="vjs-loading-spinner-fallback";innerHtmlSpinner=""}return this._super("div",{className:classNameSpinner,innerHTML:innerHtmlSpinner})}});_V_.CurrentTimeDisplay=_V_.Component.extend({init:function(player,options){this._super(player,options);player.on("timeupdate",_V_.proxy(this,this.updateContent))},createElement:function(){var el=this._super("div",{className:"vjs-current-time vjs-time-controls vjs-control"});this.content=_V_.createElement("div",{className:"vjs-current-time-display",innerHTML:"0:00"});el.appendChild(_V_.createElement("div").appendChild(this.content));return el},updateContent:function(){var time=(this.player.scrubbing)?this.player.values.currentTime:this.player.currentTime();this.content.innerHTML=_V_.formatTime(time,this.player.duration())}});_V_.DurationDisplay=_V_.Component.extend({init:function(player,options){this._super(player,options);player.on("timeupdate",_V_.proxy(this,this.updateContent))},createElement:function(){var el=this._super("div",{className:"vjs-duration vjs-time-controls vjs-control"});this.content=_V_.createElement("div",{className:"vjs-duration-display",innerHTML:"0:00"});el.appendChild(_V_.createElement("div").appendChild(this.content));return el},updateContent:function(){if(this.player.duration()){this.content.innerHTML=_V_.formatTime(this.player.duration())}}});_V_.TimeDivider=_V_.Component.extend({createElement:function(){return this._super("div",{className:"vjs-time-divider",innerHTML:"<div><span>/</span></div>"})}});_V_.RemainingTimeDisplay=_V_.Component.extend({init:function(player,options){this._super(player,options);player.on("timeupdate",_V_.proxy(this,this.updateContent))},createElement:function(){var el=this._super("div",{className:"vjs-remaining-time vjs-time-controls vjs-control"});this.content=_V_.createElement("div",{className:"vjs-remaining-time-display",innerHTML:"-0:00"});el.appendChild(_V_.createElement("div").appendChild(this.content));return el},updateContent:function(){if(this.player.duration()){this.content.innerHTML="-"+_V_.formatTime(this.player.remainingTime())}}});_V_.Slider=_V_.Component.extend({init:function(player,options){this._super(player,options);player.on(this.playerEvent,_V_.proxy(this,this.update));this.on("mousedown",this.onMouseDown);this.on("focus",this.onFocus);this.on("blur",this.onBlur);this.player.on("controlsvisible",this.proxy(this.update));this.update()},createElement:function(type,attrs){attrs=_V_.merge({role:"slider","aria-valuenow":0,"aria-valuemin":0,"aria-valuemax":100,tabIndex:0},attrs);return this._super(type,attrs)},onMouseDown:function(event){event.preventDefault();_V_.blockTextSelection();_V_.on(document,"mousemove",_V_.proxy(this,this.onMouseMove));_V_.on(document,"mouseup",_V_.proxy(this,this.onMouseUp));this.onMouseMove(event)},onMouseUp:function(event){_V_.unblockTextSelection();_V_.off(document,"mousemove",this.onMouseMove,false);_V_.off(document,"mouseup",this.onMouseUp,false);this.update()},update:function(){var barProgress,progress=this.getPercent();handle=this.handle,bar=this.bar;if(isNaN(progress)){progress=0}barProgress=progress;if(handle){var box=this.el,boxWidth=box.offsetWidth,handleWidth=handle.el.offsetWidth,handlePercent=(handleWidth)?handleWidth/boxWidth:0,boxAdjustedPercent=1-handlePercent;adjustedProgress=progress*boxAdjustedPercent,barProgress=adjustedProgress+(handlePercent/2);handle.el.style.left=_V_.round(adjustedProgress*100,2)+"%"}bar.el.style.width=_V_.round(barProgress*100,2)+"%"},calculateDistance:function(event){var box=this.el,boxX=_V_.findPosX(box),boxW=box.offsetWidth,handle=this.handle;if(handle){var handleW=handle.el.offsetWidth;boxX=boxX+(handleW/2);boxW=boxW-handleW}return Math.max(0,Math.min(1,(event.pageX-boxX)/boxW))},onFocus:function(event){_V_.on(document,"keyup",_V_.proxy(this,this.onKeyPress))},onKeyPress:function(event){if(event.which==37){event.preventDefault();this.stepBack()}else{if(event.which==39){event.preventDefault();this.stepForward()}}},onBlur:function(event){_V_.off(document,"keyup",_V_.proxy(this,this.onKeyPress))}});_V_.ProgressControl=_V_.Component.extend({options:{components:{seekBar:{}}},createElement:function(){return this._super("div",{className:"vjs-progress-control vjs-control"})}});_V_.SeekBar=_V_.Slider.extend({options:{components:{loadProgressBar:{},bar:{componentClass:"PlayProgressBar"},handle:{componentClass:"SeekHandle"}}},playerEvent:"timeupdate",init:function(player,options){this._super(player,options)},createElement:function(){return this._super("div",{className:"vjs-progress-holder"})},getPercent:function(){return this.player.currentTime()/this.player.duration()},onMouseDown:function(event){this._super(event);this.player.scrubbing=true;this.videoWasPlaying=!this.player.paused();this.player.pause()},onMouseMove:function(event){var newTime=this.calculateDistance(event)*this.player.duration();if(newTime==this.player.duration()){newTime=newTime-0.1}this.player.currentTime(newTime)},onMouseUp:function(event){this._super(event);this.player.scrubbing=false;if(this.videoWasPlaying){this.player.play()}},stepForward:function(){this.player.currentTime(this.player.currentTime()+1)},stepBack:function(){this.player.currentTime(this.player.currentTime()-1)}});_V_.LoadProgressBar=_V_.Component.extend({init:function(player,options){this._super(player,options);player.on("progress",_V_.proxy(this,this.update))},createElement:function(){return this._super("div",{className:"vjs-load-progress",innerHTML:'<span class="vjs-control-text">Loaded: 0%</span>'})},update:function(){if(this.el.style){this.el.style.width=_V_.round(this.player.bufferedPercent()*100,2)+"%"}}});_V_.PlayProgressBar=_V_.Component.extend({createElement:function(){return this._super("div",{className:"vjs-play-progress",innerHTML:'<span class="vjs-control-text">Progress: 0%</span>'})}});_V_.SeekHandle=_V_.Component.extend({createElement:function(){return this._super("div",{className:"vjs-seek-handle",innerHTML:'<span class="vjs-control-text">00:00</span>'})}});_V_.VolumeControl=_V_.Component.extend({options:{components:{volumeBar:{}}},createElement:function(){return this._super("div",{className:"vjs-volume-control vjs-control"})}});_V_.VolumeBar=_V_.Slider.extend({options:{components:{bar:{componentClass:"VolumeLevel"},handle:{componentClass:"VolumeHandle"}}},playerEvent:"volumechange",createElement:function(){return this._super("div",{className:"vjs-volume-bar"})},onMouseMove:function(event){this.player.volume(this.calculateDistance(event))},getPercent:function(){return this.player.volume()},stepForward:function(){this.player.volume(this.player.volume()+0.1)},stepBack:function(){this.player.volume(this.player.volume()-0.1)}});_V_.VolumeLevel=_V_.Component.extend({createElement:function(){return this._super("div",{className:"vjs-volume-level",innerHTML:'<span class="vjs-control-text"></span>'})}});_V_.VolumeHandle=_V_.Component.extend({createElement:function(){return this._super("div",{className:"vjs-volume-handle",innerHTML:'<span class="vjs-control-text"></span>'})}});_V_.MuteToggle=_V_.Button.extend({init:function(player,options){this._super(player,options);player.on("volumechange",_V_.proxy(this,this.update))},createElement:function(){return this._super("div",{className:"vjs-mute-control vjs-control",innerHTML:'<div><span class="vjs-control-text">Mute</span></div>'})},onClick:function(event){this.player.muted(this.player.muted()?false:true)},update:function(event){var vol=this.player.volume(),level=3;if(vol==0||this.player.muted()){level=0}else{if(vol<0.33){level=1}else{if(vol<0.67){level=2}}}_V_.each.call(this,[0,1,2,3],function(i){_V_.removeClass(this.el,"vjs-vol-"+i)});_V_.addClass(this.el,"vjs-vol-"+level)}});_V_.PosterImage=_V_.Button.extend({init:function(player,options){this._super(player,options);if(!this.player.options.poster){this.hide()}player.on("play",_V_.proxy(this,this.hide))},createElement:function(){return _V_.createElement("img",{className:"vjs-poster",src:this.player.options.poster,tabIndex:-1})},onClick:function(){this.player.play()}});_V_.Menu=_V_.Component.extend({init:function(player,options){this._super(player,options)},addItem:function(component){this.addComponent(component);component.on("click",this.proxy(function(){this.unlockShowing()}))},createElement:function(){return this._super("ul",{className:"vjs-menu"})}});_V_.MenuItem=_V_.Button.extend({init:function(player,options){this._super(player,options);if(options.selected){this.addClass("vjs-selected")}},createElement:function(type,attrs){return this._super("li",_V_.merge({className:"vjs-menu-item",innerHTML:this.options.label},attrs))},onClick:function(){this.selected(true)},selected:function(selected){if(selected){this.addClass("vjs-selected")}else{this.removeClass("vjs-selected")}}});_V_.merge(_V_.Player.prototype,{addTextTracks:function(trackObjects){var tracks=this.textTracks=(this.textTracks)?this.textTracks:[],i=0,j=trackObjects.length,track,Kind;for(;i<j;i++){Kind=_V_.uc(trackObjects[i].kind||"subtitles");track=new _V_[Kind+"Track"](this,trackObjects[i]);tracks.push(track);if(track["default"]){this.ready(_V_.proxy(track,track.show))}}return this},showTextTrack:function(id,disableSameKind){var tracks=this.textTracks,i=0,j=tracks.length,track,showTrack,kind;for(;i<j;i++){track=tracks[i];if(track.id===id){track.show();showTrack=track}else{if(disableSameKind&&track.kind==disableSameKind&&track.mode>0){track.disable()}}}kind=(showTrack)?showTrack.kind:((disableSameKind)?disableSameKind:false);if(kind){this.trigger(kind+"trackchange")}return this}});_V_.Track=_V_.Component.extend({init:function(player,options){this._super(player,options);_V_.merge(this,{id:options.id||("vjs_"+options.kind+"_"+options.language+"_"+_V_.guid++),src:options.src,"default":options["default"],title:options.title,language:options.srclang,label:options.label,cues:[],activeCues:[],readyState:0,mode:0})},createElement:function(){return this._super("div",{className:"vjs-"+this.kind+" vjs-text-track"})},show:function(){this.activate();this.mode=2;this._super()},hide:function(){this.activate();this.mode=1;this._super()},disable:function(){if(this.mode==2){this.hide()}this.deactivate();this.mode=0},activate:function(){if(this.readyState==0){this.load()}if(this.mode==0){this.player.on("timeupdate",this.proxy(this.update,this.id));this.player.on("ended",this.proxy(this.reset,this.id));if(this.kind=="captions"||this.kind=="subtitles"){this.player.textTrackDisplay.addComponent(this)}}},deactivate:function(){this.player.off("timeupdate",this.proxy(this.update,this.id));this.player.off("ended",this.proxy(this.reset,this.id));this.reset();this.player.textTrackDisplay.removeComponent(this)},load:function(){if(this.readyState==0){this.readyState=1;_V_.get(this.src,this.proxy(this.parseCues),this.proxy(this.onError))}},onError:function(err){this.error=err;this.readyState=3;this.trigger("error")},parseCues:function(srcContent){var cue,time,text,lines=srcContent.split("\n"),line="",id;for(var i=1,j=lines.length;i<j;i++){line=_V_.trim(lines[i]);if(line){if(line.indexOf("-->")==-1){id=line;line=_V_.trim(lines[++i])}else{id=this.cues.length}cue={id:id,index:this.cues.length};time=line.split(" --> ");cue.startTime=this.parseCueTime(time[0]);cue.endTime=this.parseCueTime(time[1]);text=[];while(lines[++i]&&(line=_V_.trim(lines[i]))){text.push(line)}cue.text=text.join("<br/>");this.cues.push(cue)}}this.readyState=2;this.trigger("loaded")},parseCueTime:function(timeText){var parts=timeText.split(":"),time=0,hours,minutes,other,seconds,ms,flags;if(parts.length==3){hours=parts[0];minutes=parts[1];other=parts[2]}else{hours=0;minutes=parts[0];other=parts[1]}other=other.split(/\s+/);seconds=other.splice(0,1)[0];seconds=seconds.split(/\.|,/);ms=parseFloat(seconds[1]);seconds=seconds[0];time+=parseFloat(hours)*3600;time+=parseFloat(minutes)*60;time+=parseFloat(seconds);if(ms){time+=ms/1000}return time},update:function(){if(this.cues.length>0){var time=this.player.currentTime();if(this.prevChange===undefined||time<this.prevChange||this.nextChange<=time){var cues=this.cues,newNextChange=this.player.duration(),newPrevChange=0,reverse=false,newCues=[],firstActiveIndex,lastActiveIndex,html="",cue,i,j;if(time>=this.nextChange||this.nextChange===undefined){i=(this.firstActiveIndex!==undefined)?this.firstActiveIndex:0}else{reverse=true;i=(this.lastActiveIndex!==undefined)?this.lastActiveIndex:cues.length-1}while(true){cue=cues[i];if(cue.endTime<=time){newPrevChange=Math.max(newPrevChange,cue.endTime);if(cue.active){cue.active=false}}else{if(time<cue.startTime){newNextChange=Math.min(newNextChange,cue.startTime);if(cue.active){cue.active=false}if(!reverse){break}}else{if(reverse){newCues.splice(0,0,cue);if(lastActiveIndex===undefined){lastActiveIndex=i}firstActiveIndex=i}else{newCues.push(cue);if(firstActiveIndex===undefined){firstActiveIndex=i}lastActiveIndex=i}newNextChange=Math.min(newNextChange,cue.endTime);newPrevChange=Math.max(newPrevChange,cue.startTime);cue.active=true}}if(reverse){if(i===0){break}else{i--}}else{if(i===cues.length-1){break}else{i++}}}this.activeCues=newCues;this.nextChange=newNextChange;this.prevChange=newPrevChange;this.firstActiveIndex=firstActiveIndex;this.lastActiveIndex=lastActiveIndex;this.updateDisplay();this.trigger("cuechange")}}},updateDisplay:function(){var cues=this.activeCues,html="",i=0,j=cues.length;for(;i<j;i++){html+="<span class='vjs-tt-cue'>"+cues[i].text+"</span>"}this.el.innerHTML=html},reset:function(){this.nextChange=0;this.prevChange=this.player.duration();this.firstActiveIndex=0;this.lastActiveIndex=0}});_V_.CaptionsTrack=_V_.Track.extend({kind:"captions"});_V_.SubtitlesTrack=_V_.Track.extend({kind:"subtitles"});_V_.ChaptersTrack=_V_.Track.extend({kind:"chapters"});_V_.TextTrackDisplay=_V_.Component.extend({createElement:function(){return this._super("div",{className:"vjs-text-track-display"})}});_V_.TextTrackMenuItem=_V_.MenuItem.extend({init:function(player,options){var track=this.track=options.track;options.label=track.label;options.selected=track["default"];this._super(player,options);this.player.on(track.kind+"trackchange",_V_.proxy(this,this.update))},onClick:function(){this._super();this.player.showTextTrack(this.track.id,this.track.kind)},update:function(){if(this.track.mode==2){this.selected(true)}else{this.selected(false)}}});_V_.OffTextTrackMenuItem=_V_.TextTrackMenuItem.extend({init:function(player,options){options.track={kind:options.kind,player:player,label:"Off"};this._super(player,options)},onClick:function(){this._super();this.player.showTextTrack(this.track.id,this.track.kind)},update:function(){var tracks=this.player.textTracks,i=0,j=tracks.length,track,off=true;for(;i<j;i++){track=tracks[i];if(track.kind==this.track.kind&&track.mode==2){off=false}}if(off){this.selected(true)}else{this.selected(false)}}});_V_.TextTrackButton=_V_.Button.extend({init:function(player,options){this._super(player,options);this.menu=this.createMenu();if(this.items.length===0){this.hide()}},createMenu:function(){var menu=new _V_.Menu(this.player);menu.el.appendChild(_V_.createElement("li",{className:"vjs-menu-title",innerHTML:_V_.uc(this.kind)}));menu.addItem(new _V_.OffTextTrackMenuItem(this.player,{kind:this.kind}));this.items=this.createItems();this.each(this.items,function(item){menu.addItem(item)});this.addComponent(menu);return menu},createItems:function(){var items=[];this.each(this.player.textTracks,function(track){if(track.kind===this.kind){items.push(new _V_.TextTrackMenuItem(this.player,{track:track}))}});return items},buildCSSClass:function(){return this.className+" vjs-menu-button "+this._super()},onFocus:function(){this.menu.lockShowing();_V_.one(this.menu.el.childNodes[this.menu.el.childNodes.length-1],"blur",this.proxy(function(){this.menu.unlockShowing()}))},onBlur:function(){},onClick:function(){this.one("mouseout",this.proxy(function(){this.menu.unlockShowing();this.el.blur()}))}});_V_.CaptionsButton=_V_.TextTrackButton.extend({kind:"captions",buttonText:"Captions",className:"vjs-captions-button"});_V_.SubtitlesButton=_V_.TextTrackButton.extend({kind:"subtitles",buttonText:"Subtitles",className:"vjs-subtitles-button"});_V_.ChaptersButton=_V_.TextTrackButton.extend({kind:"chapters",buttonText:"Chapters",className:"vjs-chapters-button",createItems:function(chaptersTrack){var items=[];this.each(this.player.textTracks,function(track){if(track.kind===this.kind){items.push(new _V_.TextTrackMenuItem(this.player,{track:track}))}});return items},createMenu:function(){var tracks=this.player.textTracks,i=0,j=tracks.length,track,chaptersTrack,items=this.items=[];for(;i<j;i++){track=tracks[i];if(track.kind==this.kind&&track["default"]){if(track.readyState<2){this.chaptersTrack=track;track.on("loaded",this.proxy(this.createMenu));return}else{chaptersTrack=track;break}}}var menu=this.menu=new _V_.Menu(this.player);menu.el.appendChild(_V_.createElement("li",{className:"vjs-menu-title",innerHTML:_V_.uc(this.kind)}));if(chaptersTrack){var cues=chaptersTrack.cues,i=0,j=cues.length,cue,mi;for(;i<j;i++){cue=cues[i];mi=new _V_.ChaptersTrackMenuItem(this.player,{track:chaptersTrack,cue:cue});items.push(mi);menu.addComponent(mi)}}this.addComponent(menu);if(this.items.length>0){this.show()}return menu}});_V_.ChaptersTrackMenuItem=_V_.MenuItem.extend({init:function(player,options){var track=this.track=options.track,cue=this.cue=options.cue,currentTime=player.currentTime();options.label=cue.text;options.selected=(cue.startTime<=currentTime&¤tTime<cue.endTime);this._super(player,options);track.on("cuechange",_V_.proxy(this,this.update))},onClick:function(){this._super();this.player.currentTime(this.cue.startTime);this.update(this.cue.startTime)},update:function(time){var cue=this.cue,currentTime=this.player.currentTime();if(cue.startTime<=currentTime&¤tTime<cue.endTime){this.selected(true)}else{this.selected(false)}}});_V_.merge(_V_.ControlBar.prototype.options.components,{subtitlesButton:{},captionsButton:{},chaptersButton:{}});_V_.autoSetup=function(){var options,vid,player,vids=document.getElementsByTagName("video");if(vids&&vids.length>0){for(var i=0,j=vids.length;i<j;i++){vid=vids[i];if(vid&&vid.getAttribute){if(vid.player===undefined){options=vid.getAttribute("data-setup");if(options!==null){options=JSON.parse(options||"{}");player=_V_(vid,options)}}}else{_V_.autoSetupTimeout(1);break}}}else{if(!_V_.windowLoaded){_V_.autoSetupTimeout(1)}}};_V_.autoSetupTimeout=function(wait){setTimeout(_V_.autoSetup,wait)};_V_.addEvent(window,"load",function(){_V_.windowLoaded=true});_V_.autoSetup();window.VideoJS=window._V_=VideoJS})(window);
\ No newline at end of file
{{ block.super }}
<div id="module" class="module">
- <h3><img src="/images/module_playlist.png" style="vertical-align:middle" />
+ <h3><img src="{{ STATIC_URL }}telemeta/images/module_playlist.png" style="vertical-align:middle" />
Partenaires</h3><br />
<div style="background-color: white; padding: 1ex;" align="center">
<a href="http://www.cnrs.fr"><img class="image-link" src="{{ STATIC_URL }}telemeta/images/logo-CNRS.png" alt="CNRS"></a>
{% block stylesheets %}
{{ block.super }}
- <link rel="stylesheet" type="text/css" href="{% url telemeta-timeside "skins/lab/style.css" %}" />
- <link rel="stylesheet" type="text/css" href="{% url telemeta-css "player.css" %}" />
+ <link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}timeside/skins/lab/style.css" />
+ <link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}telemeta/css/player.css" />
{% endblock %}
{% block extra_javascript %}
{% if item.file %}
{% if public_access or perms.telemeta.can_play_all_items %}
-<script src="{% url telemeta-timeside "js/libs/soundmanager2-nodebug-jsmin.js" %}" type="text/javascript"></script>
-<script src="{% url telemeta-timeside "js/timeside.js" %}" type="text/javascript"></script>
+<script src="{{ STATIC_URL }}timeside/js/libs/soundmanager2-nodebug-jsmin.js" type="text/javascript"></script>
+<script src="{{ STATIC_URL }}timeside/js/timeside.js" type="text/javascript"></script>
{% endif %}
{% endif %}
-<script src="{% url telemeta-js "popupdiv-min.js" %}" type="text/javascript"></script>
-<script src="{% url telemeta-js "playlist.js" %}" type="text/javascript"></script>
+<script src="{{ STATIC_URL }}telemeta/js/popupdiv-min.js" type="text/javascript"></script>
+<script src="{{ STATIC_URL }}telemeta/js/playlist.js" type="text/javascript"></script>
{% if item.file %}
{% if public_access or perms.telemeta.can_play_all_items %}
-<script src="{% url telemeta-js "playerLoader.js" %}" type="text/javascript"></script>
-<script src="{% url telemeta-js "divmarker.js" %}" type="text/javascript"></script>
+<script src="{{ STATIC_URL }}telemeta/js/playerLoader.js" type="text/javascript"></script>
+<script src="{{ STATIC_URL }}telemeta/js/divmarker.js" type="text/javascript"></script>
{% endif %}
{% endif %}
</script>
{% if "video" in mime_type %}
-<script src="{% url telemeta-video-js "video.js" %}"></script>
-<link href="{% url telemeta-video-js "video-js.css" %}" rel="stylesheet">
+<script src="{{ STATIC_URL }}telemeta/video-js/video.js" ></script>
+<link href="{{ STATIC_URL }}telemeta/video-js/video-js.css" rel="stylesheet">
{% endif %}
{% endif %}
{% if item %}
{% block title %}
-<img src="{% url telemeta-images "item.png" %}" alt="item" style="vertical-align:middle" />
+<img src="{{ STATIC_URL }}telemeta/images/item.png" alt="item" style="vertical-align:middle" />
Item : <a href="{% url telemeta-item-detail item.public_id %}">{{ item }}</a>
{% endblock %}