PageSourceSearch

https://imoci.ru/js/xplayer.js

js imoci.ru collected 2026-09-30 02:51:46 UTC 61,540 bytes, 1,725 lines download raw bytes

1function addHandler(object, event, handler) {
2   if (object.addEventListener) {
3      object.addEventListener(event, handler, false);
4   }
5   else if (object.attachEvent) {
6      object.attachEvent('on' + event, handler);
7   }
8   else alert("Îáðàáîò÷èê íå ïîääåðæèâàåòñÿ");
9}
10
11function addWheelHandler(obj) {
12   addHandler(obj, 'DOMMouseScroll', wheel);
13   addHandler(obj, 'mousewheel', wheel);
14}
15
16function wheel(event) {
17   var delta;
18   event = event || window.event;
19
20   if (event.wheelDelta) { // Â Opera è IE
21      delta = -event.wheelDelta / 120;
22   }
23   else if (event.detail) { // Äëÿ Gecko
24       delta = event.detail / 3;
25   }
26   // Çàïðåùàåì îáðàáîòêó ñîáûòèÿ áðàóçåðîì ïî óìîë÷àíèþ
27   if (event.preventDefault) event.preventDefault();
28   event.returnValue = false;
29   var el = event.target || event.srcElement
30   if (el.className != 'trackItem') return
31   
32   var pl_c = el.parentNode
33   var pl = el.parentNode.parentNode
34   var b = getElementsByClass('scrollBar', pl, 'div')[0]
35   if (b.style.display == 'none') return
36   var t = parseInt(pl_c.style.top) - (delta * 30)
37   if (t > 0) t = 0
38   if (t < - pl_c.clientHeight + pl.clientHeight) t = - pl_c.clientHeight + pl.clientHeight
39   pl_c.style.top = t + 'px'
40   
41   var sbh = (pl.clientHeight / pl_c.clientHeight) * pl.clientHeight
42   var sbt = -parseInt(pl_c.style.top) / (pl_c.clientHeight - pl.clientHeight) * (pl.clientHeight - sbh)
43   if (sbt == 0) sbt = 2
44   if (sbt == pl.clientHeight - sbh) sbt = pl.clientHeight - sbh - 1
45   b.style.height = sbh + 'px'
46   b.style.top = sbt + 'px'
47}
48
49function getOffsetSum(elem) {
50    var top = 0, left = 0
51    while(elem) {
52        top = top + parseFloat(elem.offsetTop)
53        left = left + parseFloat(elem.offsetLeft)
54        elem = elem.offsetParent
55    }
56
57    return {top: Math.round(top), left: Math.round(left)}
58}
59
60function getOffsetRect(elem) {
61
62    var ua = navigator.userAgent.toLowerCase()
63    if (ua.indexOf('msie') && parseFloat(ua.slice(ua.indexOf('msie') + 5)) <= 7) {
64       return getOffsetSum(elem)
65    }
66
67    var box = elem.getBoundingClientRect()
68
69    var body = document.body
70    var docElem = document.documentElement
71
72    var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop
73    var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft
74
75    var clientTop = docElem.clientTop || body.clientTop || 0
76    var clientLeft = docElem.clientLeft || body.clientLeft || 0
77
78    var top  = box.top +  scrollTop - clientTop
79    var left = box.left + scrollLeft - clientLeft
80
81    return { top: Math.round(top), left: Math.round(left) }
82}
83
84function getBodyScrollLeft() {
85  return self.pageXOffset || (document.documentElement && document.documentElement.scrollLeft) || (document.body && document.body.scrollLeft);
86}
87
88function getElementsByClass(searchClass, node, tag) {
89   var classElements = new Array();
90   if ( node == null )
91      node = document;
92   if ( tag == null )
93      tag = '*';
94   var els = node.getElementsByTagName(tag);
95   var elsLen = els.length;
96
97   var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
98   for (i = 0, j = 0; i < elsLen; i++) {
99      if ( pattern.test(els[i].className) ) {
100         classElements[j] = els[i];
101         j++;
102      }
103   }
104   return classElements;
105}
106
107function getBackgroundColor(obj) {
108   var style = obj.currentStyle || getComputedStyle(obj, '')
109   var bgcol = style.backgroundColor
110   if (bgcol != 'transparent') return bgcol
111   else if (obj.tagName.toLowerCase() != 'body') return getBackgroundColor(obj.parentNode)
112   else return '#fff'
113}
114
115function hexToDec(n) {
116   return Number(parseInt(n+'',16)).toString(10)
117}
118
119function decToHex(n) {
120   return Number(parseInt(n+'',10)).toString(16)
121}
122
123function highlight(color) {
124   var red = color.substring(1,3)
125   var green = color.substring(3,5)
126   var blue = color.substring(5,7)
127   red = decToHex(255 - (255 - parseInt(hexToDec(red))) / 3.8)
128   green = decToHex(255 - (255 - parseInt(hexToDec(green))) / 4.2)
129   blue = decToHex(255 - (255 - parseInt(hexToDec(blue))) / 3.6)
130   return '#' + red + green + blue
131}
132
133function embedSWF(swfUrlStr, replaceElemIdStr, widthStr, heightStr, flashvarsObj, parObj, attObj) {
134
135   document.getElementById(replaceElemIdStr).style.visibility = 'hidden';
136   widthStr += "";
137   heightStr += "";
138   var att = {};
139   if (attObj && typeof attObj === "object") {
140      for (var i in attObj) { // copy object to avoid the use of references, because web authors often reuse attObj for multiple SWFs
141         att[i] = attObj[i];
142      }
143   }
144   att.data = swfUrlStr;
145   att.width = widthStr;
146   att.height = heightStr;
147   var par = {};
148   if (parObj && typeof parObj === "object") {
149      for (var j in parObj) { // copy object to avoid the use of references, because web authors often reuse parObj for multiple SWFs
150         par[j] = parObj[j];
151      }
152   }
153   if (flashvarsObj && typeof flashvarsObj === "object") {
154      for (var k in flashvarsObj) { // copy object to avoid the use of references, because web authors often reuse flashvarsObj for multiple SWFs
155         if (typeof par.flashvars != "undefined") {
156            par.flashvars += "&" + k + "=" + flashvarsObj[k];
157         }
158         else {
159            par.flashvars = k + "=" + flashvarsObj[k];
160         }
161      }
162   }
163
164   var obj = createSWF(att, par, replaceElemIdStr);
165
166}
167
168function createSWF(attObj, parObj, id) {
169   var r, el = document.getElementById(id);
170
171   if (document.all && !window.opera) { // Internet Explorer
172
173      var att = "";
174      for (var i in attObj) {
175         if (i.toLowerCase() == "data") {
176            parObj.movie = attObj[i];
177         }
178         else if (i.toLowerCase() == "styleclass") { // 'class' is an ECMA4 reserved keyword
179            att += ' class="' + attObj[i] + '"';
180         }
181         else if (i.toLowerCase() != "classid") {
182            att += ' ' + i + '="' + attObj[i] + '"';
183         }
184      }
185
186      var par = "";
187      for (var j in parObj) {
188         par += '<param name="' + j + '" value="' + parObj[j] + '" />';
189      }
190
191      el.outerHTML = '<object id="' + id + '" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + att + '>' + par + '<embed name="audio_' + attObj.id + '" src="' + parObj.movie + '" width="' + attObj.width + '" height="' + attObj.height + '"' + att + '></embed></object>';
192      el = document.getElementById(id);
193      if (el.getElementsByTagName('embed')[0]) {
194         for (var i in parObj) {
195            el.getElementsByTagName('embed')[0].setAttribute(i, parOb
195j[i])
196         }
197      }
198      r = document.getElementById(attObj.id);
199
200   } else { // well-behaving browsers
201
202      var o = document.createElement("object");
203      o.id = id
204      o.setAttribute("type", "application/x-shockwave-flash");
205      for (var m in attObj) {
206         if (m.toLowerCase() == "styleclass") { // 'class' is an ECMA4 reserved keyword
207            o.setAttribute("class", attObj[m]);
208         }
209         else if (m.toLowerCase() != "classid") { // filter out IE specific attribute
210            o.setAttribute(m, attObj[m]);
211         }
212      }
213      for (var n in parObj) {
214         if (n.toLowerCase() != "movie") { // filter out IE specific param element
215            var p = document.createElement("param");
216            p.setAttribute("name", n);
217            p.setAttribute("value", parObj[n]);
218            o.appendChild(p);
219         }
220      }
221      el.parentNode.replaceChild(o, el);
222      r = o;
223   }
224
225   return r;
226}
227
228function shuffle(array) {
229   for(var j, x, i = array.length; i; j = parseInt(Math.random() * i), x = array[--i], array[i] = array[j], array[j] = x);
230}
231
232var xPlayer = {
233
234setMainColor : function(col, obj) {
235   var _play = getElementsByClass('play', obj, 'div')[0]
236   var _pause = getElementsByClass('pause', obj, 'div')[0]
237   var _stop = getElementsByClass('stop', obj, 'div')[0]
238
239
240   _play.style.borderLeft = '14px solid ' + col
241   _stop.style.background = col
242   _pause.style.borderLeft = '4px solid ' + col
243   _pause.style.borderRight = '4px solid ' + col
244   getElementsByClass('progress', obj, 'div')[0].style.background = col
245   getElementsByClass('volume', obj, 'div')[0].style.background = col
246   getElementsByClass('progresstip', obj, 'div')[0].style.border = '1px solid ' + col
247   getElementsByClass('progresstip', obj, 'div')[0].style.color = col
248   getElementsByClass('volumetip', obj, 'div')[0].style.border = '1px solid ' + col
249   getElementsByClass('volumetip', obj, 'div')[0].style.color = col
250   
251   if (obj.playlist && obj.getAttribute('noplaylist') == null && obj.getAttribute('playliststyle') == null) {
252      getElementsByClass('playlistView', obj, 'div')[0].style.color = col
253      getElementsByClass('playlistView', obj, 'div')[0].style.border = '1px solid ' + col
254      getElementsByClass('scrollBar', obj, 'div')[0].style.background = col
255      getElementsByClass('nowPlaying', obj, 'div')[0].style.borderLeft = '6px solid ' + col
256   }
257   
258
259   var bgcol = getBackgroundColor(obj)
260   
261   var _play = getElementsByClass('play', obj, 'div')[0]
262   _play.style.borderBottom = '7px solid ' + bgcol
263   _play.style.borderTop = '7px solid ' + bgcol
264
265   if (obj.playlist && obj.getAttribute('noplaylist') == null && obj.getAttribute('pointercolor') == null) {
266      var els = getElementsByClass('nowPlaying', obj, 'div')
267      for (var i = 0; i < els.length; i++) {
268         els[i].style.borderLeft = '6px solid ' + col
269         els[i].style.borderTop = '3px solid transparent'
270         els[i].style.borderBottom = '3px solid transparent'
271      }
272   }
273
274   if (obj.playlist && obj.getAttribute('noplaylist') == null && obj.getAttribute('scrollbarcolor') == null) {
275      this.setScrollbarColor(col, obj)
276   }
277   
278   if (!obj.getAttribute('tooltipcolor')) this.setTooltipColor(col, '#fff', obj)
279   else this.setTooltipColor(col, obj.getAttribute('tooltipcolor'), obj)
280   
281},
282
283setScaleColor : function(col, obj) {
284   var ps = getElementsByClass('progressScale', obj, 'div')[0]
285   var vs = getElementsByClass('volumeScale', obj, 'div')[0]
286
287   ps.style.background = col
288   vs.style.background = col
289},
290
291setTooltipColor : function(maincol, col, obj) {
292   getElementsByClass('progresstip', obj, 'div')[0].style.color = maincol
293   getElementsByClass('volumetip', obj, 'div')[0].style.color = maincol
294   getElementsByClass('progresstip', obj, 'div')[0].style.border = '1px solid '+ maincol
295   getElementsByClass('volumetip', obj, 'div')[0].style.border = '1px solid '+ maincol
296   getElementsByClass('progresstip', obj, 'div')[0].style.backgroundColor = col
297   getElementsByClass('volumetip', obj, 'div')[0].style.backgroundColor = col
298   
299   if (!document.all || window.opera) {
300      var obj = document.head.getElementsByTagName('style')
301      obj = obj[obj.length - 1]
302      var str = obj.innerHTML
303   } else {
304      var str = document.styleSheets[0].cssText
305   }
306   var new_rules = '.xt1:before,\r\n\
307.xt1:after {\r\n\
308    content: "\\2666";\r\n\
309    font-family: monospace;\r\n\
310    font-size: 10px;\r\n\
311    line-height: 12px;\r\n\
312    text-align: center;\r\n\
313\r\n\
314    position: absolute;\r\n\
315    overflow: hidden;\r\n\
316    width: 10px;\r\n\
317    height: 10px;\r\n\
318\r\n\
319    -moz-user-select: -moz-none;\r\n\
320    -khtml-user-select: none;\r\n\
321    -webkit-user-select: none;\r\n\
322    user-select: none;\r\n\
323}\r\n\
324.xt1:before {\r\n\
325    color: ' + maincol + ';\r\n\
326}\r\n\
327.xt1:after {\r\n\
328    color: ' + maincol + ';\r\n\
329}\r\n\
330.xbottomArrow:before,\r\n\
331.xbottomArrow:after {\r\n\
332    left: 50%;\r\n\
333    bottom: -6px;\r\n\
334    margin-left: -5px;\r\n\
335    clip: rect(5px, 10px, 10px, 0px);\r\n\
336}\r\n\
337.xbottomArrow:after {\r\n\
338    bottom: -4px;\r\n\
339    color: ' + col + ';\r\n\
340}\r\n'
341   if (str.indexOf('.xt1') != -1) str = str.slice(0, str.indexOf('.xt1')) + new_rules
342   else str = str + new_rules
343   if (!document.all || window.opera) obj.innerHTML = str
344   else document.styleSheets[0].cssText = str
345},
346
347setPointerColor: function(col, obj) {
348   var els = getElementsByClass('nowPlaying', obj, 'div')
349   for (var i = 0; i < els.length; i++) {
350      els[i].style.borderLeft = '6px solid ' + col
351   }
352},
353
354setScrollbarColor: function(col, obj) {
355   getElementsByClass('scrollBar', obj, 'div')[0].style.background = col
356},
357
358disableOtherSources : function(player) {
359   var audios = document.getElementsByTagName('audio')
360   for (var i = 0; i < audios.length; i++) {
361      audios[i].pause()
362      if (audios[i].parentNode.hasAttribute('source') && audios[i].parentNode != player) {
363         var b1 = getElementsByClass('play', audios[i].parentNode, 'div')[0]
364         var b2 = getElementsByClass('pause', audios[i].parentNode, 'div')[0]
365         b2.style.display = 'none'
366         b1.style.display = 'inline-block'
367      }
368   }
369   var uppods = document.getElementsByTagName('object')
370   for (var i = 0; i < uppods.length; i++) {
371      if (uppods[i].id.indexOf('audio_') == 0) {
372         if (uppods[i].parentNode.isPlaying != undefined) this.stop(uppods[i].parentNode)
373      }
374   }
375},
376
377MODE_NORMAL : 0,
378MODE_CONT : 1,
379MODE_REPEAT : 2,
380MODE_CONT_REPEAT: 3,
381
382changeMode : function(mode, player) {
383   if (mode < 0 || mode > 3) return false;
384   player.mode = mode
385   return true;
386},
387
388setShuffling : function(value, player) {
389   if (value == null) return false
390   if (!player.shuffle && value) {
391      var pos = player.plPos+1 < player.playlist.length ? player.plPos+1 : 0
392      player.playlist_shuffled = player.playlist.slice(pos)
393      shuffle(player.playlist_shuffled)
394   }
395   player.shuffle = !!value
396   return true;
397},
398
399loadFile : function(src, player, startPlaying) {
400   if (player.isPlaying) this.stop(player)
401   
402   var p = getElementsByClass('progressScale', player, 'div')[0]
403   clearInterval(p.timer)
404   
405   var volume = 0.5
406   if (!player.flash) {
407      volume = player.getElementsByTagName('audio')[0].volume
408   } else {
409      var v = uppodGet('audio_' + player.id, 'getv')
410      if (v != null) volume = v / 100
411   }
412   
413   player.setAttribute('source', src)
414   var re = /\s*;\s*/
415   var sources = src.split(re)
416   var str = ''
417   var mp3file = ''
418   var audio = document.createElement("audio");
419   if (audio == null && !audio.canPlayType) {
420      player.flash = true
421   }
422   var supported = false
423   for (var i = 0; i < sources.length; i++) {
424      str += '<source src="' + sources[i] + '" />\r\n'
425      var type = sources[i].slice(sources[i].lastIndexOf('.') + 1)
426      if (audio.canPlayType && audio.canPlayType('audio/' + type)) supported = true
427      if (type == 'mp3') mp3file = sources[i]
428   }
429   if (player.flash) {
430      var obj = player.getElementsByTagName('object')[0]
431      if (obj) player.removeChild(obj)
432   } else {
433      var obj = player.getElementsByTagName('audio')[0]
434      if (obj) player.removeChild(obj)
435   }
436   if (!supported || player.getAttribute('flash') != null) {
437      if (mp3file == '') {
438         if (!supported) return false;
439         else player.flash = false
440      } else {
441         player.flash = true
442      }
443   } else {
444      player.flash = false
445   }
446   if (!player.flash) {
447      var a = document.createElement('audio')
448      a.innerHTML = str
449      player.appendChild(a)
450   }
451   else {
452      var a = document.createElement('div')
453      a.id = 'audio_' + player.id
454      player.appendChild(a)
455      var attributes = {"style":"position: absolute; top: -999px"}
456      var flashvars = {"uid":"audio_" + player.id,"m":"audio","file":mp3file};
457      var params = {"id":"audio_" + player.id,"bgcolor":"#ffffff","allowScriptAccess":"always"};
458      var url = "http://popov654.pp.ru/xplayer/uppod.swf"
459      embedSWF(url, "audio_" + player.id, "0", "0", flashvars, params, attributes);
460   }
461   this.setVolume(volume, player)
462   if (startPlaying) this.play(player)
463   return true;
464},
465
466loadPlaylist : function(pl, player, startPlaying) {
467   player.playlist = []
468   for (var i = 0; i < pl.length; i++) {
469      if (pl[i].title && pl[i].source) {
470         player.playlist.push({"title":pl[i].title, "source": pl[i].source})
471      }
472   }
473   if (player.shuffle) {
474      var n = Math.floor(Math.random() * pl.length)
475      player.plPos = n
476      this.loadFile(pl[n].source, player, startPlaying)
477   } else {
478      player.plPos = 0
479      this.loadFile(pl[0].source, player, startPlaying)
480   }
481   if (player.titleId && document.getElementById(player.titleId)) {
482      document.getElementById(player.titleId).innerHTML = player.playlist[player.plPos].title
483   }
484},
485
486loadPlaylistJSON : function(obj, player) {
487   try {
488      eval('player.playlist = ' + obj.innerHTML)
489   } catch(ex) { alert(ex); return false; }
490   return true;
491},
492
493loadPlaylistXML : function(obj, player) {
494   var children = obj.childNodes
495   var elements = []
496   for (var i = 0; i < children.length; i++) {
497      if (children[i].nodeType == 1) elements.push(children[i])
498   }
499   if (elements.length % 2 == 1) return false;
500   player.playlist = []
501   if (document.all && !window.opera && children[2].tagName.charAt(0) == '/') {
502      if (children[0].tagName == children[4].tagName) {
503         if (children[children.length / 2 - 4].tagName != children[0].tagName ||
504             children[children.length / 2].tagName == children[0].tagName) return false;
505         for (var i = 0; i < children.length / 2; i+=4) {
506            player.playlist.push({"title" : children[i+1].nodeValue, "source" : children[children.length / 2 + i + 1].nodeValue})
507         }
508      } else {
509         for (var i = 0; i < children.length; i+=8) {
510            player.playlist.push({"title" : children[i+1].nodeValue, "source" : children[i+5].nodeValue})
511         }
512      }
513      return true;
514   }
515   if (elements[0].tagName == elements[1].tagName) {
516      if (elements[elements.length / 2 - 1].tagName != elements[0].tagName ||
517          elements[elements.length / 2].tagName == elements[0].tagName) return false;
518      for (var i = 0; i < elements.length / 2; i++) {
519         player.playlist.push({"title" : elements[i].innerHTML, "source" : elements[elements.length / 2 + i].innerHTML})
520      }
521   } else {
522      for (var i = 0; i < elements.length; i+=2) {
523         player.playlist.push({"title" : elements[i].innerHTML, "source" : elements[i+1].innerHTML})
524      }
525   }
526   return true;
527},
528
529prevSong : function(player) {
530   if (!player.playlist || player.playlist.length == 1) return
531   player.plPos--
532   if (player.plPos < 0) {
533      player.plPos = player.playlist.length - 1
534      if (player.shuffle) {
535         player.playlist_shuffled = player.playlist.slice()
536         shuffle(player.playlist_shuffled)
537      }
538   }
539   var title = player.shuffle ? player.playlist_shuffled[player.plPos].title : player.playlist[player.plPos].title
540   var source = player.shuffle ? player.playlist_shuffled[player.plPos].source : player.playlist[player.plPos].source
541   if (player.titleId && document.getElementById(player.titleId)) {
542      document.getElementById(player.titleId).innerHTML = title
543   }
544   var p = player.isPlaying
545   this.loadFile(source, player, p)
546   this.fireEvent(player, 'prev', title, source)
547},
548
549nextSong : function(player) {
550   if (!player.playlist || player.playlist.length == 1) return
551   else if (player.getAttribute('noplaylist') == null) getElementsByClass('nowPlaying', null, 'div')[player.plPos].style.visibility = 'hidden'
552   player.plPos++
553   if (player.plPos == player.playlist.length) {
554      player.plPos = 0
555      if (player.shuffle) {
556         player.playlist_shuffled = player.playlist.slice()
557         shuffle(player.playlist_shuffled)
558      }
559   }
560   var title = player.shuffle ? player.playlist_shuffled[player.plPos].title : player.playlist[player.plPos].title
561   var source = player.shuffle ? player.playlist_shuffled[player.plPos].source : player.playlist[player.plPos].source
562   if (player.titleId && document.getElementById(player.titleId)) {
563      document.getElementById(player.titleId).innerHTML = title
564   }
565   var p = player.isPlaying
566   this.loadFile(source, player, p)
567   this.fireEvent(player, 'next', title, source)
568},
569
570play : function(player) {
571
572   if (player.isPlaying && getElementsByClass('play', player, 'div')[0].style.display == 'none') return
573   if (player.playlist && player.titleId && document.getElementById(player.titleId)) {
574      document.getElementById(player.titleId).innerHTML = player.playlist[player.plPos].title
575   }
576   
577   xPlayer.disableOtherSources(player)
578   
579   player.isPlaying = true
580
581   var t = getElementsByClass('play', player, 'div')[0]
582   if (t.style.display != 'none') {
583      t.style.display = 'none'
584      while (t.className != 'pause') t = t.nextSibling
585      t.style.display = 'inline-block'
586   }
587   
588   var title = ''
589   if (player.playlist && player.playlist.length > 0) {
590      title = player.shuffle ? player.playlist_shuffled[player.plPos].title : player.playlist[player.plPos].title
591      if (player.getAttribute('noplaylist') == null) {
592         var pos = player.plPos
593         if (player.shuffle) {
594            for (var i = 0; i < player.playlist.length; i++) {
595               if (player.playlist[i].title == player.playlist_shuffled[pos].title && player.playlist[i].source == player.playlist_shuffled[pos].source) {
596                  break;
597               }
598            }
599            var pos = i
600         }
601         getElementsByClass('nowPlaying', null, 'div')[pos].style.visibility = 'visible'
602      }
603   } else {
604      if (player.getAttribute('songtitle') != null) title = player.getAttribute('songtitle')
605   }
606   var source = player.getAttribute('source')
607   this.fireEvent(player, 'play', title, source)
608   
609   var t = getElementsByClass('progressScale', player, 'div')[0]
610   t.timer = setInterval(function(obj) {
611      return function() {
612         xPlayer.updatePosition(obj)
613      }
614   } (t.firstChild), t.parentNode.delay)
615   
616   if (player.flash) {
617      uppodSend('audio_' + player.id, 'play')
618      var pos = parseFloat(t.firstChild.style.width) / 100
619      xPlayer.setPosition(pos, t.parentNode)
620      return;
621   }
622   var audio = player.getElementsByTagName('audio')[0]
623   audio.play()
624},
625
626pause : function(player) {
627
628   var t = getElementsByClass('pause', player, 'div')[0]
629   if (t.style.display != 'none') {
630      t.style.display = 'none'
631      while (t.className != 'play') t = t.previousSibling
632      t.style.display = 'inline-block'
633   } else {
634      return
635   }
636   var p = getElementsByClass('progressScale', player, 'div')[0]
637   clearInterval(p.timer)
638
639   this.fireEvent(player, 'pause')
640   if (player.flash) {
641      uppodSend('audio_' + player.id, 'pause')
642      return;
643   }
644   var audio = player.getElementsByTagName('audio')[0]
645   audio.pause()
646},
647
648stop : function(player) {
649
650   if (!player.isPlaying) return
651   var t = getElementsByClass('pause', player, 'div')[0]
652   if (t.style.display != 'none') {
653      t.style.display = 'none'
654      while (t.className != 'play') t = t.previousSibling
655      t.style.display = 'inline-block'
656   }
657   if (player.playlist && player.getAttribute('noplaylist') == null) {
658      if (player.shuffle) {
659         var a = getElementsByClass('nowPlaying', null, 'div')
660         for (var i = 0; i < a.length; i++) {
661            a[i].style.visibility = 'hidden'
662         }
663      } else {
664         getElementsByClass('nowPlaying', null, 'div')[player.plPos].style.visibility = 'hidden'
665      }
666   }
667
668   getElementsByClass('progress', player, 'div')[0].style.width = '0%'
669   var p = getElementsByClass('progressScale', player, 'div')[0]
670   clearInterval(p.timer)
671
672   player.isPlaying = false
673   this.fireEvent(player, 'stop')
674   if (player.flash) {
675      uppodSend('audio_' + player.id, 'stop')
676      uppodSend('audio_' + player.id, 'time0')
677      xPlayer.storage.ticker = 0
678      return;
679   }
680   var audio = player.getElementsByTagName('audio')[0]
681   audio.pause()
682   audio.currentTime = 0
683},
684
685setPosition : function(pos, player) {
686   if (player.flash) {
687      var time = uppodGet('audio_' + player.id, 'getimed')
688      uppodSend('audio_' + player.id, 'seek:' + time * pos)
689      if (player.clockId && document.getElementById(player.clockId)) {
690         var time = Math.round(time * pos)
691         var secs = (time % 60 < 10) ? ('0' + time % 60) : (time % 60)
692         document.getElementById(player.clockId).innerHTML = Math.floor(time / 60) + ':' + secs
693      }
694      return;
695   }
696   var audio = player.getElementsByTagName('audio')[0]
697   audio.currentTime = audio.duration * pos
698   if (player.clockId && document.getElementById(player.clockId)) {
699      var time = Math.round(audio.duration * pos)
700      var secs = (time % 60 < 10) ? ('0' + time % 60) : (time % 60)
701      document.getElementById(player.clockId).innerHTML = Math.floor(time / 60) + ':' + secs
702   }
703},
704
705setVolume : function(volume, player) {
706
707   player.volume = volume
708
709   getElementsByClass('volume', player, 'div')[0].style.width = Number(volume * 100).toPrecision(4) + '%'
710
711   if (player.flash) {
712      uppodSend('audio_' + player.id, 'v' + Math.round(volume * 100))
713      return;
714   }
715   var audio = player.getElementsByTagName('audio')[0]
716   audio.volume = volume
717},
718
719updatePosition : function(obj) {
720   var player = obj.parentNode.parentNode
721   
722   var currentTime = 0
723   var duration = 0
724   
725   if (!player.flash) {
726      var audio = player.getElementsByTagName('audio')[0]
727      currentTime = audio.currentTime
728      duration = audio.duration
729   } else {
730      currentTime = uppodGet('audio_' + player.id, 'getime')
731      duration = uppodGet('audio_' + player.id, 'getimed')
732      if (currentTime == 0) xPlayer.storage.ticker++
733      if (document.all && !window.opera) xPlayer.storage.ticker++
734      var limit = (player.delay == 1000) ? 2 : 40
735      if (currentTime == 0 && xPlayer.storage.ticker > limit) currentTime = duration
736   }
737
738   if (duration == 0 || isNaN(duration) || isNaN(currentTime) || !player.isPlaying) return
739   
740   if (player.getAttribute('smoothrefresh') == null) {
741      obj.style.width = Number(currentTime / duration * 100).toPrecision(3) + '%'
742   } else {
743      obj.style.width = Math.round(currentTime / duration * parseInt(obj.parentNode.clientWidth)) + 'px'
744   }
745
746   if (xPlayer.storage.follow) {
747      var tooltip = getElementsByClass('progresstip', obj.parentNode.parentNode, 'div')[0]
748      var time = Math.round(currentTime)
749      var secs = (time % 60 < 10) ? ('0' + time % 60) : (time % 60)
750      tooltip.innerHTML = Math.floor(time / 60) + ':' + secs
751      tooltip.style.left = (obj.parentNode.offsetLeft + obj.clientWidth - tooltip.clientWidth / 2) + 'px'
752   }
753   
754   if (player.clockId && document.getElementById(player.clockId)) {
755      if (xPlayer.storage.follow) {
756         var tooltip = getElementsByClass('progresstip', obj.parentNode.parentNode, 'div')[0]
757         document.getElementById(player.clockId).innerHTML = tooltip.innerHTML
758      } else {
759         var time = Math.round(currentTime)
760         var secs = (time % 60 < 10) ? ('0' + time % 60) : (time % 60)
761         document.getElementById(player.clockId).innerHTML = Math.floor(time / 60) + ':' + secs
762      }
763   }
764   
765   var title = ''
766   if (player.playlist && player.playlist.length > 0) {
767      title = player.playlist[player.plPos].title
768   } else {
769      if (player.getAttribute('songtitle') != null) title = player.getAttribute('songtitle')
770   }
771   var source = player.getAttribute('source')
772   
773   if (player.delay == 50) {
774      xPlayer.storage.ticker2++
775      if (xPlayer.storage.ticker2 == 20) {
776         this.fireEvent(player, 'progress', currentTime, duration, title, source)
777         xPlayer.storage.ticker2 = 0
778      }
779   } else {
780      this.fireEvent(player, 'progress', currentTime, duration, title, source)
781   }
782
783   if (currentTime == duration) {
784      if (player.mode == this.MODE_CONT && player.plPos < player.playlist.length - 1
785       || player.mode == this.MODE_CONT_REPEAT) {
786         obj.style.width = '0%'
787         this.nextSong(player)
788         return
789      }
790      if (player.mode == this.MODE_REPEAT) {
791         obj.style.width = '0%'
792         this.stop(player)
793         this.play(player)
794         return
795      }
796      obj.style.borderRadius = '3px'
797      setTimeout(function() {
798         xPlayer.stop(player)
799         obj.style.width = '0%'
800         var play = getElementsByClass('play', player, 'div')[0]
801         var pause = getElementsByClass('pause', player, 'div')[0]
802         pause.style.display = 'none'
803         play.style.display = 'inline-block'
804         obj.style.borderRadius = '3px 0px 0px 3px'
805      }, 400)
806   }
807},
808
809seek: function(time, player) {
810
811   var duration = this.getTrackDuration(player)
812   
813   if (time < 0 || time > duration) return false
814   
815   var pos = time / duration
816   getElementsByClass('progress', player, 'div')[0].style.width = Number(pos * 100).toPrecision(4) + '%'
817   this.setPosition(pos, player)
818   return true
819},
820
821getTrackDuration: function(player) {
822
823   var duration = 0
824
825   if (!player.flash) {
826      var audio = player.getElementsByTagName('audio')[0]
827      duration = audio.duration
828   } else {
829      duration = uppodGet('audio_' + player.id, 'getimed')
830   }
831   return duration;
832   
833},
834
835getVolume: function(player) {
836   return player.volume
837},
838
839getKey: function() {
840   var result = ''
841   for (var i = 0; i < 16; i++) {
842      var n = Math.floor(Math.random() * 62)
843      if (n < 26) {
844          result += String.fromCharCode(n + 65)
845      }
846      if (n >= 26 && n < 52) {
847         result += String.fromCharCode(n + 71)
848      }
849      if (n >= 52) {
850         result += String.fromCharCode(n - 4)
851      }
852   }
853   return result
854},
855
856addListener: function(player, type, listener, obj) {
857   var c
858   if (!player) c = this.storage.listeners
859   else c = player.listeners
860   switch(type) {
861      case 'play':
862         if (c[type] == undefined) c[type] = []
863         var key = this.getKey()
864         var fn = function(title, source) { listener.call(obj, title, source) }
865         c[type].push({"key": key, "listener": fn})
866         break;
867      case 'pause':
868      case 'stop':
869         if (c[type] == undefined) c[type] = []
870         var key = this.getKey()
871         var fn = function() { listener.call(obj) }
872         c[type].push({"key": key, "listener": fn})
873         break;
874      
874case 'prev':
875      case 'next':
876         if (c[type] == undefined) c[type] = []
877         var key = this.getKey()
878         var fn = function(title, source) { listener.call(obj, title, source) }
879         c[type].push({"key": key, "listener": fn})
880         break;
881      case 'progress':
882         if (c[type] == undefined) c[type] = []
883         var key = this.getKey()
884         var fn = function(time, duration, title, source) { listener.call(obj, time, duration, title, source) }
885         c[type].push({"key": key, "listener": fn})
886         break;
887   }
888   return key
889},
890
891removeListener: function(player, key, type) {
892   if (key == null) return false;
893   var c
894   if (!player) c = this.storage.listeners
895   else c = player.listeners
896   if (type == null) {
897      for (var type in c) {
898         for (var i = 0; i < c[type].length; i++) {
899            if (c[type][i] == null) continue;
900            if (c[type][i].key == key) {
901               c[type][i] = null;
902               return true;
903            }
904         }
905      }
906   } else {
907      for (var i = 0; i < c[type].length; i++) {
908         if (c[type][i] == null) continue;
909         if (c[type][i].key == key) {
910            c[type][i] = null;
911            return true;
912         }
913      }
914   }
915   return false;
916},
917
918fireEvent: function(player, type) {
919   var args = Array.prototype.slice.call(arguments, 2)
920
921   c = player.listeners
922   if (c[type] != undefined) {
923      for (var i = 0; i < c[type].length; i++) {
924         if (c[type][i] == null) continue;
925         c[type][i].listener.apply(null, args)
926      }
927   }
928
929   c = this.storage.listeners
930   if (c[type] != undefined) {
931      for (var i = 0; i < c[type].length; i++) {
932         if (c[type][i] == null) continue;
933         c[type][i].listener.apply(null, args)
934      }
935   }
936},
937
938
939createPlayer : function(obj) {
940
941   if (obj.getAttribute('shuffle') != null) obj.shuffle = true
942
943   if (getElementsByClass('playlist', obj, null).length > 0) {
944      var playlist = getElementsByClass('playlist', obj, null)[0]
945      if (playlist.getAttribute('type') == "xml") this.loadPlaylistXML(playlist, obj)
946      else if (playlist.getAttribute('type') == "json") this.loadPlaylistJSON(playlist, obj)
947      if (obj.playlist && obj.playlist.length > 0) {
948         obj.plPos = 0
949         if (obj.shuffle) {
950            obj.playlist_shuffled = obj.playlist.slice()
951            shuffle(player.playlist_shuffled)
952            obj.setAttribute('source', obj.playlist_shuffled[obj.plPos].source)
953         } else {
954            obj.setAttribute('source', obj.playlist[obj.plPos].source)
955         }
956      }
957   }
958   var playlists = getElementsByClass('playlist', obj, null)
959   for (var i = 0; i < playlists.length; i++) obj.removeChild(playlists[i])
960
961   var re = /\s*;\s*/
962   var sources = obj.getAttribute('source').split(re)
963   var str = ''
964   var mp3file = ''
965   var audio = document.createElement("audio");
966   if (audio == null && !audio.canPlayType) obj.flash = true
967   var supported = false
968   for (var i = 0; i < sources.length; i++) {
969      str += '<source src="' + sources[i] + '" />\r\n'
970      var type = sources[i].slice(sources[i].lastIndexOf('.') + 1)
971      if (audio.canPlayType && audio.canPlayType('audio/' + type)) supported = true
972      if (type == 'mp3') mp3file = sources[i]
973   }
974   if (!supported || obj.getAttribute('flash') != null) {
975      if (mp3file == '') {
976         if (!supported) return false;
977         else obj.flash = false
978      } else {
979         obj.flash = true
980      }
981   } else {
982      obj.flash = false
983   }
984   obj.style.height = '32px'
985   obj.innerHTML = '<div class="play"></div>\r\n\
986   <div class="pause"></div>\r\n\
987   <div class="stop"></div>\r\n\
988   <div class="progressScale"><div class="progress"></div></div>\r\n\
989   <div class="volumeScale"><div class="volume"></div></div>\r\n\
990   <div class="progresstip xt1 xbottomArrow">0:00</div>\r\n\
991   <div class="volumetip xt1 xbottomArrow">50%</div>\r\n'
992   if (!obj.flash) obj.innerHTML += '<audio>' + str + '</audio>'
993   else {
994      obj.innerHTML += '<div id="audio_' + obj.id + '"></div>'
995      var attributes = {"style":"position: absolute; top: -999px"}
996      var flashvars = {"uid":"audio_" + obj.id,"m":"audio","file":mp3file};
997      var params = {"id":"audio_" + obj.id,"bgcolor":"#ffffff","allowScriptAccess":"always"};
998      var url = "http://xplayer.su/uppod.swf"
999      embedSWF(url, "audio_" + obj.id, "0", "0", flashvars, params, attributes);
1000   }
1001   obj.mode = this.MODE_NORMAL
1002   obj.isPlaying = false
1003
1004   obj.playlistHeight = 0
1005
1006   if (obj.playlist && obj.getAttribute('noplaylist') == null) {
1007      var pl = document.createElement('div')
1008      var pl_c = document.createElement('div')
1009      var b = document.createElement('div')
1010      b.className = 'scrollBar'
1011      pl.className = 'playlistView'
1012      pl_c.className = 'playlistContents'
1013      for (var i = 0; i < obj.playlist.length; i++) {
1014         var pl_el = document.createElement('div')
1015         pl_el.className = 'trackItem'
1016         pl_el.innerHTML = '<div class="nowPlaying"></div>' + obj.playlist[i].title
1017         pl_c.appendChild(pl_el)
1018         pl_el.onclick = function(player, pos) {
1019            return function() {
1020               getElementsByClass('nowPlaying', null, 'div')[player.plPos].style.visibility = 'hidden'
1021               if (player.shuffle) {
1022                  for (var i = 0; i < player.playlist.length; i++) {
1023                     if (player.playlist_shuffled[i].title == player.playlist[pos].title && player.playlist_shuffled[i].source == player.playlist[pos].source) {
1024                        break;
1025                     }
1026                  }
1027                  player.plPos = i
1028               } else {
1029                  player.plPos = pos
1030               }
1031               xPlayer.loadFile(player.playlist[pos].source, player, true)
1032            }
1033         } (obj, i)
1034      }
1035
1036      function setPlaylistHeight() {
1037         var height = obj.playlist.length * getElementsByClass('trackItem', obj, 'div')[0].clientHeight
1038         if (!isNaN(parseInt(obj.getAttribute('height')))) {
1039            obj.playlistHeight = parseInt(obj.getAttribute('height')) - 48
1040         } else if (obj.getAttribute('height') == 'auto') {
1041            obj.playlistHeight = height
1042            obj.style.height = height + 48 + 'px'
1043         }
1044         if (obj.playlistHeight > 78 && !obj.getAttribute('height')) {
1045            obj.playlistHeight = 78
1046         }
1047         pl.style.height = obj.playlistHeight - 4 + 'px'
1048         if (obj.playlistHeight < height) {
1049            pl_c.style.right = '3px'
1050         } else {
1051            pl_c.style.right = '0px'
1052            b.style.display = 'none'
1053         }
1054      }
1055
1056      pl.appendChild(pl_c)
1057      pl_c.style.top = '0px'
1058      pl.appendChild(b)
1059      obj.appendChild(pl)
1060      setPlaylistHeight()
1061      addWheelHandler(pl)
1062      
1063      var sbh = (pl.clientHeight / pl_c.clientHeight) * (pl.clientHeight - 4)
1064      var sbt = 2
1065      b.style.height = sbh + 'px'
1066      b.style.top = sbt + 'px'
1067   }
1068   
1069   obj.delay = (obj.getAttribute('smoothrefresh') != null) ? 50 : 1000
1070   
1071   obj.listeners = {}
1072   
1073   if (obj.getAttribute('titleid')) obj.titleId = obj.getAttribute('titleid')
1074   if (obj.getAttribute('clockid')) obj.clockId = obj.getAttribute('clockid')
1075   
1076   if (obj.getAttribute('maincolor')) this.setMainColor(obj.getAttribute('maincolor'), obj)
1077   if (obj.getAttribute('scalecolor')) this.setScaleColor(obj.getAttribute('scalecolor'), obj)
1078   
1079   if (!obj.getAttribute('maincolor')) {
1080      if (obj.getAttribute('tooltipcolor')) {
1081         this.setTooltipColor('#5873A3', obj.getAttribute('tooltipcolor'), obj)
1082      } else {
1083         this.setTooltipColor('#5873A3', '#fff', obj)
1084      }
1085   }
1086   
1087   
1088   var _play = getElementsByClass('play', obj, 'div')[0]
1089   var _pause = getElementsByClass('pause', obj, 'div')[0]
1090   var _stop = getElementsByClass('stop', obj, 'div')[0]
1091   var ps = getElementsByClass('progressScale', obj, 'div')[0]
1092   var vs = getElementsByClass('volumeScale', obj, 'div')[0]
1093   
1094   
1095   var st = obj.currentStyle || getComputedStyle(obj, '')
1096   if (st.position == 'absolute' || st.position == 'fixed') {
1097      _play.style.position = 'absolute'
1098      _play.style.top = '8px'
1099      _play.style.marginTop = '0px'
1100      _pause.style.position = 'absolute'
1101      _pause.style.top = '9px'
1102      _pause.style.marginTop = '0px'
1103      _stop.style.position = 'absolute'
1104      _stop.style.left = '41px'
1105      _stop.style.top = '9px'
1106      _stop.style.marginTop = '0px'
1107
1108      if (obj.playlist && obj.getAttribute('noplaylist') == null) {
1109         _play.style.top = '9px'
1110         _pause.style.top = '10px'
1111         _stop.style.top = '10px'
1112         ps.style.top = vs.style.top = '14px'
1113      }
1114   } else if (st.position != 'relative') {
1115      obj.style.position = 'relative'
1116      if (obj.playlist && obj.getAttribute('noplaylist') == null) {
1117         _play.style.marginTop = '9px'
1118         _pause.style.marginTop = '9px'
1119         _stop.style.marginTop = '9px'
1120         ps.style.top = vs.style.top = '14px'
1121      }
1122   }
1123   
1124   if (obj.getAttribute('playliststyle')) {
1125      var rules = obj.getAttribute('playliststyle').split(',')
1126      var pl = getElementsByClass('playlistView', obj, 'div')[0]
1127      for (var i = 0; i < rules.length; i++) {
1128         pl.style[rules[i].split(':')[0]] = rules[i].split(':')[1]
1129      }
1130   }
1131   if (obj.getAttribute('trackstyle')) {
1132      var rules = obj.getAttribute('trackstyle').split(',')
1133      var pl = getElementsByClass('playlistView', obj, 'div')[0]
1134      var els = getElementsByClass('trackItem', pl, 'div')
1135      for (var j = 0; j < els.length; j++) {
1136         var f = function() {}
1137         var g = function() {}
1138         for (var i = 0; i < rules.length; i++) {
1139            if (rules[i].split(':')[0].indexOf('hover-') == 0) {
1140               els[j].onmouseover = function(rule, content, func) {
1141                  return function() {
1142                     func()
1143                     this.style[rule] = content
1144                     if (rule == 'background' || rule == 'background-color') {
1145                        var el = getElementsByClass('nowPlaying', this, 'div')[0]
1146                        el.style.borderTop = '3px solid ' + content
1147                        el.style.borderBottom = '3px solid ' + content
1148                     }
1149                  }
1150               } (rules[i].split(':')[0].slice(6), rules[i].split(':')[1], f)
1151               f = els[j].onmouseover
1152               
1153               var old_val = ''
1154               if (els[j].style[rules[i].split(':')[0].slice(6)] != '') {
1155                  old_val = els[j].style[rules[i].split(':')[0].slice(6)]
1156               }
1157               els[j].onmouseout = function(rule, content, func) {
1158                  return function() {
1159                     func()
1160                     this.style[rule] = content
1161                     if (rule == 'background' || rule == 'background-color') {
1162                        var el = getElementsByClass('nowPlaying', this, 'div')[0]
1163                        var bg = getBackgroundColor(el.parentNode)
1164                        el.style.borderTop = '3px solid ' + bg
1165                        el.style.borderBottom = '3px solid ' + bg
1166                     }
1167                  }
1168               } (rules[i].split(':')[0].slice(6), old_val, g)
1169               g = els[j].onmouseout
1170            } else {
1171               els[j].style[rules[i].split(':')[0]] = rules[i].split(':')[1]
1172            }
1173         }
1174      }
1175   }
1176   if (obj.getAttribute('pointercolor')) {
1177      this.setPointerColor(obj.getAttribute('pointercolor'), obj)
1178   }
1179   if (obj.getAttribute('scrollbarcolor')) {
1180      this.setScrollbarColor(obj.getAttribute('scrollbarcolor'), obj)
1181   }
1182
1183   if (document.all && !window.opera && document.compatMode != 'CSS1Compat') {
1184      var el = getElementsByClass('progressScale', obj, 'div')[0]
1185      el.style.width = parseInt(el.parentNode.clientWidth) - parseInt(el.currentStyle.right) - parseInt(el.currentStyle.left) + 'px'
1186   }
1187   
1188   if (obj.titleId && document.getElementById(obj.titleId)) {
1189      if (obj.playlist && obj.playlist.length > 0) {
1190         document.getElementById(obj.titleId).innerHTML = obj.playlist[obj.plPos].title
1191      } else if (obj.getAttribute('songtitle')) {
1192         document.getElementById(obj.titleId).innerHTML = obj.getAttribute('songtitle')
1193      }
1194   }
1195   
1196
1197   var bgcol = getBackgroundColor(obj)
1198
1199   _play.style.borderBottom = '7px solid ' + bgcol
1200   _play.style.borderTop = '7px solid ' + bgcol
1201
1202   var h1 = 7, h2 = 2
1203   if (obj.getAttribute('zoomfactor') != null || obj.getAttribute('buttonsheight') || obj.getAttribute('scalesheight')) {
1204      if (obj.getAttribute('zoomfactor') != null) {
1205         var z = parseFloat(obj.getAttribute('zoomfactor'))
1206         var z2 = z
1207         h1 *= z
1208         h2 *= z
1209         var bh = 13 * z
1210         var sh = 4 * z
1211      } else {
1212         var bh = parseInt(obj.getAttribute('buttonsheight')) || 13
1213         var sh = parseInt(obj.getAttribute('scalesheight')) ||  4
1214         var z = bh / 13
1215         var z2 = sh / 4
1216         var bh2 = Math.round(bh / 2)
1217         var sh2 = Math.round(sh / 2)
1218      }
1219      var s1 = bh
1220      var s2 = Math.round(bh / 2)
1221      var s3 = Math.round((4 / 13) * bh)
1222      var s4 = Math.round((5 / 13) * bh)
1223      var s5 = bh
1224      var s6 = sh
1225      var x1 = 4 + Math.round(z * 12)
1226      var x2 = x1 + bh + Math.round(z*11) + 3
1227      var x3 = x2 + bh + Math.round(z*13) + 4
1228
1229      var top = Math.round((height - bh) / 2)
1230
1231      var c = 8 * ((bh - 13) / 13)
1232      if (bh == 13) s1 = 14
1233      var volWidth = Math.round(z2 * 28)
1234      if (volWidth < 52) volWidth = 52
1235      if (obj.getAttribute('volwidth')) volWidth = obj.getAttribute('volwidth')
1236
1237      var height = bh > sh ? bh + 20 : sh + 20
1238      if (!obj.getAttribute('height')) obj.style.height = height + 'px'
1239      var st = _stop.currentStyle || getComputedStyle(_stop, '')
1240      var col = st.backgroundColor
1241      _play.style.borderLeft = s1 + 'px solid ' + col
1242      _play.style.borderBottom = s2 + 'px solid ' + bgcol
1243      _play.style.borderTop = s2 + 'px solid ' + bgcol
1244
1245      _play.style.top = (bh % 2 == 0 ? top : top-1) + 'px'
1246      _pause.style.top = top + 'px'
1247      _stop.style.top = top + 'px'
1248      _pause.style.borderLeft = s3 + 'px solid ' + col
1249      _pause.style.borderRight = s3 + 'px solid ' + col
1250      _pause.style.width = s4 + 'px'
1251      _pause.style.height = s5 + 'px'
1252      _stop.style.width = s5 + 'px'
1253      _stop.style.height = s5 + 'px'
1254      _play.style.left = x1 + 'px'
1255      _pause.style.left = x1 + 'px'
1256      _stop.style.left = x2 + 'px'
1257      ps.style.height = s6 + 'px'
1258      vs.style.height = s6 + 'px'
1259      ps.style.left = x3 + 'px'
1260      ps.style.right = Math.round(33 + c + volWidth) + 'px'
1261      ps.style.top = vs.style.top = Math.round((height - sh) / 2) + 'px'
1262      vs.style.width = volWidth + 'px'
1263
1264      var zz = z > z2 ? z : z2
1265      var ht = -12 + (height / 2 - sh2 - 14) - Math.ceil(zz)
1266      var pt = getElementsByClass('progresstip', obj, 'div')[0]
1267      var vt = getElementsByClass('volumetip', obj, 'div')[0]
1268      pt.style.top = vt.style.top = ht + 'px'
1269      pt.style.fontSize = vt.style.fontSize = Math.round(12 + Math.ceil(zz)) + 'px'
1270
1271      var zoom = true
1272
1273      if (document.all && !window.opera && document.compatMode != 'CSS1Compat') {
1274         _play.style.height = s5 + 'px'
1275         _play.style.height = s5 + 'px'
1276         _pause.style.width = s5 + 'px'
1277         ps.style.height = (s6 + 1) + 'px'
1278         vs.style.height = (s6 + 1) + 'px'
1279         ps.firstChild.style.height = s6 + 'px'
1280         vs.firstChild.style.height = s6 + 'px'
1281      }
1282      if (detectIE() != -1 && detectIE() < 9) {
1283         _play.style.top = _pause.style.top = _stop.style.top = Math.round((60 - bh) / 2) + 'px'
1284         var gap = Math.round(z * 10)
1285      }
1286   }
1287
1288   if (obj.getAttribute('height')) {
1289      var h = parseInt(obj.getAttribute('height'))
1290      obj.style.height = h + 'px'
1291      var bh = 13
1292      var sh = 4
1293      var bh2 = Math.round(bh/2)
1294      var sh2 = Math.round(sh/2)
1295      var top = Math.round(h/2) - bh2
1296      var top2 = Math.round(h/2) - sh2
1297      _play.style.top = (bh % 2 == 0 ? top : top-1) + 'px'
1298      _pause.style.top = top + 'px'
1299      _stop.style.top = top + 'px'
1300      ps.style.top = top2 + 'px'
1301      vs.style.top = top2 + 'px'
1302      var ht = top2 - 25
1303      getElementsByClass('progresstip', obj, 'div')[0].style.top = ht + 'px'
1304      getElementsByClass('volumetip', obj, 'div')[0].style.top = ht + 'px'
1305   }
1306
1307   if (obj.getAttribute('volwidth')) {
1308      var vw = obj.getAttribute('volwidth')
1309      ps.style.right = Math.round(33 + vw) + 'px'
1310      vs.style.width = vw + 'px'
1311   }
1312
1313   if ((detectIE() == -1 || detectIE() > 8) && obj.hasAttribute('noroundtips')) {
1314      getElementsByClass('progresstip', obj, 'div')[0].style.borderRadius = '0px'
1315      getElementsByClass('volumetip', obj, 'div')[0].style.borderRadius = '0px'
1316   }
1317
1318   _pause.style.display = 'none'
1319   
1320   this.setVolume(0.5, obj)
1321   
1322   _play.onclick = function (event) {
1323      var e = event || window.event
1324      var t = e.target || e.srcElement
1325      xPlayer.play(t.parentNode)
1326   }
1327   
1328   _pause.onclick = function (event) {
1329      var e = event || window.event
1330      var t = e.target || e.srcElement
1331      xPlayer.pause(t.parentNode)
1332   }
1333   
1334   _stop.onclick = function (event) {
1335      var e = event || window.event
1336      var t = e.target || e.srcElement
1337      xPlayer.stop(t.parentNode)
1338   }
1339   
1340   ps.onmousedown = function (event) {
1341      var e = event || window.event
1342      var t = e.target || e.srcElement
1343      if (t.className.indexOf('Scale') == -1) t = t.parentNode
1344      clearInterval(t.timer)
1345      var x = e.clientX + getBodyScrollLeft() - getOffsetRect(t).left
1346      var w = Number(x / t.clientWidth * 100).toPrecision(4)
1347      t.firstChild.style.width = w + '%'
1348      xPlayer.storage.drag = true
1349      if (e.preventDefault) e.preventDefault()
1350   }
1351   ps.onmousemove = function (event) {
1352      var e = event || window.event
1353      var t = e.target || e.srcElement
1354      if (t.className.indexOf('Scale') == -1) t = t.parentNode
1355      var x = e.clientX + getBodyScrollLeft() - getOffsetRect(t).left
1356      if (xPlayer.storage.drag) {
1357         var w = Number(x / t.clientWidth * 100).toPrecision(4)
1358         t.firstChild.style.width = w + '%'
1359      }
1360
1361      var tooltip = getElementsByClass('progresstip', t.parentNode, 'div')[0]
1362      var duration = t.parentNode.flash ? uppodGet('audio_' + t.parentNode.id, 'getimed') : t.parentNode.getElementsByTagName('audio')[0].duration
1363      var time = Math.round(x / t.clientWidth * duration)
1364      var secs = (time % 60 < 10) ? ('0' + time % 60) : (time % 60)
1365      tooltip.innerHTML = Math.floor(time / 60) + ':' + secs
1366      if (xPlayer.storage.drag) {
1367         tooltip.style.left = (t.offsetLeft + t.firstChild.clientWidth - tooltip.clientWidth / 2) + 'px'
1368      } else {
1369         tooltip.style.left = (e.clientX - getOffsetRect(t.parentNode).left - tooltip.clientWidth / 2) + 'px'
1370      }
1371      xPlayer.storage.follow = false
1372      clearTimeout(xPlayer.storage.timer)
1373      if (!xPlayer.storage.drag) xPlayer.storage.timer = setTimeout(function() { xPlayer.storage.follow = true }, 1500)
1374   }
1375   ps.onmouseup = function (event) {
1376      var e = event || window.event
1377      var t = e.target || e.srcElement
1378      if (t.className.indexOf('Scale') == -1) t = t.parentNode
1379      var x = e.clientX + getBodyScrollLeft() - getOffsetRect(t).left
1380      xPlayer.setPosition(x / t.clientWidth, t.parentNode)
1381      xPlayer.storage.drag = false
1382
1383      var p = t
1384      while (p.className != 'pause') p = p.previousSibling
1385      if (p.style.display != 'none') {
1386         t.timer = setInterval(function(obj) {
1387            return function() {
1388               xPlayer.updatePosition(obj)
1389            }
1390         } (t.firstChild), t.parentNode.delay)
1391      }
1392   }
1393   ps.onmouseover = function(event) {
1394      var e = event || window.event
1395      var t = e.target || e.srcElement
1396      if (t.className.indexOf('Scale') == -1) t = t.parentNode
1397
1398      var x = e.clientX + getBodyScrollLeft() - getOffsetRect(t).left
1399      var tooltip = getElementsByClass('progresstip', t.parentNode, 'div')[0]
1400      var duration = t.parentNode.flash ? uppodGet('audio_' + t.parentNode.id, 'getimed') : t.parentNode.getElementsByTagName('audio')[0].duration
1401      var time = Math.round(x / t.clientWidth * duration)
1402      var secs = (time % 60 < 10) ? ('0' + time % 60) : (time % 60)
1403      tooltip.innerHTML = Math.floor(time / 60) + ':' + secs
1404      tooltip.style.display = 'block'
1405   }
1406   ps.onmouseout = function(event) {
1407      var e = event || window.event
1408      var t = e.target || e.srcElement
1409      if (t.className.indexOf('Scale') == -1) t = t.parentNode
1410
1411      var tooltip = getElementsByClass('progresstip', t.parentNode, 'div')[0]
1412      tooltip.style.display = 'none'
1413      clearTimeout(xPlayer.storage.timer)
1414      xPlayer.storage.follow = false
1415   }
1416
1417      
1418   vs.onmousedown = function (event) {
1419      var e = event || window.event
1420      var t = e.target || e.srcElement
1421      if (t.className.indexOf('Scale') == -1) t = t.parentNode
1422      var x = e.clientX + getBodyScrollLeft() - getOffsetRect(t).left
1423      if (x > t.clientWidth) x = t.clientWidth
1424      var n = 2
1425      if (x == t.clientWidth) n = 3
1426      var w = Number(x / t.clientWidth * 100).toPrecision(4)
1427      t.firstChild.style.width = w + '%'
1428
1429      var tooltip = getElementsByClass('volumetip', t.parentNode, 'div')[0]
1430      tooltip.innerHTML = Number(x / t.clientWidth * 100).toPrecision(n) + '%'
1431
1432      xPlayer.setVolume(x / t.clientWidth, t.parentNode)
1433      xPlayer.storage.drag = true
1434      if (e.preventDefault) e.preventDefault()
1435   }
1436   vs.onmousemove = function (event) {
1437      var e = event || window.event
1438      var t = e.target || e.srcElement
1439      if (t.className.indexOf('Scale') == -1) t = t.parentNode
1440      var x = e.clientX + getBodyScrollLeft() - getOffsetRect(t).left
1441      if (x > t.clientWidth) x = t.clientWidth
1442      if (xPlayer.storage.drag) {
1443         var w = Number(x / t.clientWidth * 100).toPrecision(4)
1444         t.firstChild.style.width = w + '%'
1445         xPlayer.setVolume(x / t.clientWidth, t.parentNode)
1446      }
1447
1448      var tooltip = getElementsByClass('volumetip', t.parentNode, 'div')[0]
1449      var n = 2
1450      if (x == t.clientWidth) {
1451         n = 3
1452         if (parseInt(t.firstChild.style.width) == 100) t.firstChild.style.borderRadius = '3px'
1453      } else {
1454         t.firstChild.style.borderRadius = '3px 0px 0px 3px'
1455      }
1456      tooltip.innerHTML = Number(x / t.clientWidth * 100).toPrecision(n) + '%'
1457      if (xPlayer.storage.drag) {
1458         tooltip.style.left = (t.offsetLeft + t.firstChild.clientWidth - tooltip.clientWidth / 2) + 'px'
1459      } else {
1460         tooltip.style.left = (e.clientX + getBodyScrollLeft() - getOffsetRect(t.parentNode).left - tooltip.clientWidth / 2) + 'px'
1461      }
1462   }
1463   vs.onmouseup = function (event) {
1464      xPlayer.storage.drag = false
1465   }
1466   vs.onmouseover = function(event) {
1467      var e = event || window.event
1468      var t = e.target || e.srcElement
1469      if (t.className.indexOf('Scale') == -1) t = t.parentNode
1470
1471      var tooltip = getElementsByClass('volumetip', t.parentNode, 'div')[0]
1472      tooltip.style.display = 'block'
1473   }
1474   vs.onmouseout = function(event) {
1475      var e = event || window.event
1476      var t = e.target || e.srcElement
1477      if (t.className.indexOf('Scale') == -1) t = t.parentNode
1478
1479      var tooltip = getElementsByClass('volumetip', t.parentNode, 'div')[0]
1480      tooltip.style.display = 'none'
1481   }
1482},
1483
1484writeCSS : function() {
1485   var gap = 10
1486   if (!window.opera) gap = 9
1487   var st = document.createElement('style')
1488   var str =  '.play {\r\n\
1489     position: absolute;\r\n\
1490     width: 0px;\r\n\
1491     height: 0px;\r\n\
1492     border-left: 14px solid #5873A3;\r\n\
1493     border-right: 0;\r\n\
1494     border-bottom: 7px solid white;\r\n\
1495     border-top: 7px solid white;\r\n\
1496     top: 8px;\r\n\
1497     left: 16px;\r\n\
1498     cursor: pointer;\r\n\
1499}\r\n\
1500.stop {\r\n\
1501     position: absolute;\r\n\
1502     width: 13px;\r\n\
1503     height: 13px;\r\n\
1504     background: #5873A3;\r\n\
1505     top: 9px;\r\n\
1506     left: 43px;\r\n\
1507     cursor: pointer;\r\n\
1508}\r\n\
1509.pause {\r\n\
1510     position: absolute;\r\n\
1511     width: 5px;\r\n\
1512     height: 13px;\r\n\
1513     top: 9px;\r\n\
1514     left: 16px;\r\n\
1515     cursor: pointer;\r\n\
1516     border-left: 4px solid #5873A3;\r\n\
1517     border-right: 4px solid #5873A3;\r\n\
1518}\r\n\
1519.progressScale {\r\n\
1520     background: #ccc;\r\n\
1521     width: auto;\r\n\
1522     height: 4px;\r\n\
1523     border: 1px solid transparent;\r\n\
1524     border-radius: 3px;\r\n\
1525     cursor: pointer;\r\n\
1526     position: absolute;\r\n\
1527     left: 73px;\r\n\
1528     right: 81px;\r\n\
1529     top: 13px;\r\n\
1530}\r\n\
1531.volumeScale {\r\n\
1532     background: #ccc;\r\n\
1533     width: 48px;\r\n\
1534     height: 4px;\r\n\
1535     border: 1px solid transparent;\r\n\
1536     border-radius: 3px;\r\n\
1537     cursor: pointer;\r\n\
1538     position: absolute;\r\n\
1539     right: ' + (gap + 3) + 'px;\r\n\
1540     top: 13px;\r\n\
1541}\r\n\
1542.progress {\r\n\
1543     position: absolute;\r\n\
1544     left: 0px;\r\n\
1545     top: 0px;\r\n\
1546     height: 100%;\r\n\
1547     background: #5873A3;\r\n\
1548     border-radius: 3px 0px 0px 3px;\r\n\
1549     cursor: pointer;\r\n\
1550}\r\n\
1551.volume {\r\n\
1552     position: absolute;\r\n\
1553     left: 0px;\r\n\
1554     top: 0px;\r\n\
1555     height: 100%;\r\n\
1556     width: 50%;\r\n\
1557     background: #5873A3;\r\n\
1558     border-radius: 3px 0px 0px 3px;\r\n\
1559     cursor: pointer;\r\n\
1560}\r\n\
1561.progresstip, .volumetip {\r\n\
1562     display: none;\r\n\
1563     border: 1px solid #5873A3;\r\n\
1564     border-radius: 2px;\r\n\
1565     padding: 1px 2px 1px 2px;\r\n\
1566     color: #5873A3;\r\n\
1567     font-family: Arial, Sans-Serif;\r\n\
1568     font-size: 12px;\r\n\
1569     position: absolute;\r\n\
1570     top: -10px;\r\n\
1571}\r\n\
1572.playlistView {\r\n\
1573     display: block;\r\n\
1574     border: 1px solid #5873A3;\r\n\
1575     border-radius: 3px;\r\n\
1576     padding: 2px 0px;\r\n\
1577     color: #5873A3;\r\n\
1578     font-family: Arial, Sans-Serif;\r\n\
1579     font-size: 12px;\r\n\
1580     position: absolute;\r\n\
1581     top: 36px;\r\n\
1582     bottom: 10px;\r\n\
1583     left : 10px;\r\n\
1584     right: 10px;\r\n\
1585     overflow: hidden;\r\n\
1586}\r\n\
1587.playlistContents {\r\n\
1588     position: absolute;\r\n\
1589     left:0px;\r\n\
1590     right:3px;\r\n\
1591}\r\n\
1592.scrollBar {\r\n\
1593     position: absolute;\r\n\
1594     right: 2px;\r\n\
1595     width: 4px;\r\n\
1596     background: #5873A3;\r\n\
1597     border-radius: 2px;\r\n\
1598}\r\n\
1599.trackItem {\r\n\
1600     padding: 2px 18px 2px 3px;\r\n\
1601     cursor: default;\r\n\
1602}\r\n\
1603.nowPlaying {\r\n\
1604     display: inline-block;\r\n\
1605     width: 0px;\r\n\
1606     height: 0px;\r\n\
1607     border-left: 6px solid #5873A3;\r\n\
1608     border-right: 0;\r\n\
1609     border-bottom: 3px solid white;\r\n\
1610     border-top: 3px solid white;\r\n\
1611     margin: 1px 4px;\r\n\
1612     visibility: hidden;\r\n\
1613}\r\n'
1614if (document.all && !window.opera && document.compatMode !
1614= 'CSS1Compat') str += '.play {\r\n\
1615     width: 14px;\r\n\
1616     height: 14px;\r\n\
1617     overflow: hidden;\r\n\
1618}\r\n\
1619.stop {\r\n\
1620     overflow: hidden;\r\n\
1621}\r\n\
1622.pause {\r\n\
1623     width: 13px;\r\n\
1624     height: 13px;\r\n\
1625     overflow: hidden;\r\n\
1626}\r\n\
1627.progressScale {\r\n\
1628     height: 6px;\r\n\
1629}\r\n\
1630.volumeScale {\r\n\
1631     height: 6px;\r\n\
1632}\r\n\
1633.progress {\r\n\
1634     height: 4px;\r\n\
1635     overflow: hidden;\r\n\
1636}\r\n\
1637.volume {\r\n\
1638     height: 4px;\r\n\
1639     overflow: hidden;\r\n\
1640}\r\n'
1641if (detectIE() > 0 && detectIE() < 8 && document.compatMode == 'CSS1Compat') str += '.play {\r\n\
1642     width: 1px;\r\n\
1643     height: 1px;\r\n\
1644}\r\n'
1645if (!document.all || window.opera) {
1646   st.innerHTML = str
1647   document.head.appendChild(st)
1648} else {
1649   document.styleSheets[0].cssText += str
1650}
1651},
1652
1653storage : {drag: false, follow: false, timer: null, ticker: 0, ticker2: 0, listeners: {}},
1654
1655init : function(id, cl) {
1656   this.writeCSS()
1657   if (id.length) {
1658      var players = document.getElementsByTagName('div')
1659      for (var i = 0; i < players.length; i++) {
1660         if (players[i].id.indexOf(id) == 0) {
1661            this.createPlayer(players[i])
1662         }
1663      }
1664   }
1665   if (cl.length) {
1666      var players = getElementsByClass(cl, null, 'div')
1667      for (var i = 0; i < players.length; i++) {
1668         this.createPlayer(players[i])
1669      }
1670   }
1671   document.onmouseup = function(event) {
1672      xPlayer.storage.drag = false;
1673      var e = event || window.event
1674      var t = e.target || e.srcElement
1675      var current = null
1676      if (t.className == ('progress')) {
1677         current = getElementsByClass('progresstip', t.parentNode.parentNode, 'div')[0]
1678      }
1679      if (t.className == ('volume')) {
1680         current = getElementsByClass('volumetip', t.parentNode.parentNode, 'div')[0]
1681      }
1682
1683      var els = getElementsByClass('volumetip', null, 'div')
1684
1685      for (var i = 0; i < els.length; i++) {
1686         if (current && current == els[i]) continue
1687         els[i].style.display = 'none'
1688      }
1689
1690      var els = getElementsByClass('progresstip', null, 'div')
1691
1692      for (var i = 0; i < els.length; i++) {
1693         if (current && current == els[i]) continue
1694         els[i].style.display = 'none'
1695      }
1696   }
1697}
1698
1699}
1700
1701function detectIE() {
1702   var agent = navigator.userAgent.toLowerCase()
1703   var i = agent.indexOf('msie')
1704   if (i != -1) return parseFloat(agent.slice(i+5))
1705   return -1
1706}
1707
1708// Commands
1709
1710function uppodSend(playerID, com, callback) {
1711   if (!document.getElementById(playerID) || !document.getElementById(playerID).sendToUppod) {
1712      setTimeout(function() { uppodSend(playerID, com, callback) }, 10)
1713      return
1714   }
1715   document.getElementById(playerID).sendToUppod(com);
1716}
1717
1718// Requests
1719
1720function uppodGet(playerID, com, callback) {
1721   if (!document.getElementById(playerID) || !document.getElementById(playerID).getUppod) {
1722      return null
1723   }
1724   return document.getElementById(playerID).getUppod(com);
1725}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.