PageSourceSearch

https://www.impenimerosi.gr/wp-content/plugins/mp3-jplayer/js/mp3-jplayer-2.7.js?ver=2.7

js impenimerosi.gr collected 2026-10-02 14:01:46 UTC 36,277 bytes, 1,145 lines download raw bytes

1/* 
2	MP3-jPlayer
3	Version 2.7.2
4   	http://mp3-jplayer.com
5*/
6var MP3_JPLAYER = {
7	
8	tID:			'',
9	state:			'',	
10	pl_info:		[],	
11	load_pc:		0,	
12	played_t:		0,
13	total_t:		0,
14	pp_abs:			0,
15	dl_dialogs:		[],
16	timeoutIDs:		[],
17	intervalIDs:	[],
18	jperrorIDs:		[],
19	dl_domain:		'',
20	jp_audio: 		{},
21	jp_seekable:	0,
22	sliding:		false,
23	jpID:			'#mp3_jplayer_1_8',
24	plugin_path:	'',
25	lastformats:	'mp3',
26	popoutformats:	'mp3',
27	allowRanges:	true,
28	extCalls:		{ 
29		init:[],
30		change_pre:			[],
31		change_begin:		[],
32		change_end:			[],
33		change_post:		[],
34		button_playpause:	[],
35		button_popout:		[],
36		update_time:		[],
37		write_titles:		[],
38		write_download:		[],
39		download:			[],
40		download_dialog:	[],
41		error:				[]
42	},
43	extStyles:		[],
44	extJS:			[],
45	skinJS:			'',
46	mutes:			[],
47	preSlideVol:	false,
48	exData:			false,
49	exThresh:		2,
50	showErrors:		false,
51	factors:		{ vol: 1 },
52	hasListMeta:	true,
53	pickup:			true,
54	pRefs:			{ id: false, tr: false, pt: 0, vol: 100 },
55	
56	vars: {
57		play_f:				true,
58		stylesheet_url:		'',
59		dload_text:			'',
60		force_dload:		true,
61		message_interval:	'<h2>Download Audio</h2><p style="margin-top:34px !important;">Your download should start in a second!</p>',
62		message_ok:			'',
63		message_indark:		'<h2>Download Audio</h2><p>Your download should start in a second!</p>',
64		message_promtlink:	'<h2>Download Audio</h2><p>Link to the file:</p><h3><a target="_blank" href="#1">#2</a></h3><p>Depending on your browser settings, you may need to right click the link to save it.</p>',
65		message_fail:		'<h2>Download Failed</h2><p>Sorry, something went wrong!</p>',
66		message_timeout:	'<h2>Download<br />Unavailable</h2><p>please try again later!</p>',
67		message_nosolution:		 'Unable to play this item, please update your browser or try another.',
68		message_nosolution_mpeg: 'To play this item please update your browser or get the <a href="http://get.adobe.com/flashplayer/" target="_blank">Flash plugin</a>.',
69		message_bad_url:	'Can\'t locate audio.',
70		dl_remote_path:		''
71	},
72
73	eID: {
74		play:		'#playpause_mp3j_',
75		playW:		'#playpause_wrap_mp3j_',
76		stp: 		'#stop_mp3j_',
77		prev: 		'#Prev_mp3j_',
78		next: 		'#Next_mp3j_',
79		vol: 		'#vol_mp3j_',
80		loader:		'#load_mp3j_',
81		pos: 		'#posbar_mp3j_',
82		poscol: 	'#poscol_mp3j_',
83		title: 		'#T_mp3j_',
84		caption:	'#C_mp3j_',
85		pT: 		'#P-Time-MI_',
86		tT: 		'#T-Time-MI_',
87		dload: 		'#download_mp3j_',
88		plwrap: 	'#L_mp3j_',
89		ul:			'#UL_mp3j_',
90		li:			'li_mp3j_', //No hash!
91		a:			'mp3j_A_', //No hash!
92		indiM:		'#statusMI_',
93		toglist:	'#playlist-toggle_',
94		lPP:		'#lpp_mp3j_',
95		pplink:		'#mp3j_popout_',
96		img:		'#MI_image_'
97	},
98	
99	runExternals: function ( hookname, data ) {
100		var l = this.extCalls[ hookname ].length;
101		for ( var x = 0; x < l; x += 1 ) {
102			( this.extCalls[ hookname ][ x ] )( data );
103		}
104	},
105	
106	findFile: function ( file ) {
107		var i,
108			p, 
109			list,
110			l,			
111			j,
112			id = false,
113			tr = false;
114			
115		//if ( typeof MP3jPLAYERS  !== "undefined" ) {
116			//for ( i in MP3jPLAYERS ) {
117				//p = MP3jPLAYERS[ i ];
118		if ( typeof this.pl_info  !== "undefined" ) {
119			for ( i in this.pl_info ) {
120				p = this.pl_info[ i ];
121				list = p.list;
122				if ( p.type === 'MI' ) {
123					l = list.length;
124					for ( j = 0; j < l; j += 1 ) { 
125						if ( file === list[ j ].mp3 ) {
126							id = i;
127							tr = j;
128							break;
129						}						
130					}
131				} else if ( p.type === 'single' ) {
132					if ( file === list[ p.tr ].mp3 ) {
133						id = i;
134						tr = p.tr;
135						break;
136					}
137				}
138				if ( id !== false ) {
139					break;
140				}
141			}
142		}
143		return { id: id, tr: tr };
144	},
145	
146	getFormats: function ( player ) {
147		return player.list[ player.tr ].formats[0] + ( ( typeof player.list[ player.tr ].formats[1] !== 'undefined' ) ? ',' + player.list[ player.tr ].formats[1] : '' );
148	},
149	
150	initialise_jp: function ( supplied, track, vol ) { 
151		var that = this;
152		jQuery(this.jpID).jPlayer({
153			ready: function () {
154				if ( track === true ) { 
155					var dinfo = that.deviceInfo();
156					if ( dinfo.device === 'Desk/Laptop' ) {
157						if ( that.pickup ) {
158							if ( that.pRefs.id === false ) {
159								that.startup();
160							} else {
161								var puVol = parseFloat( that.pRefs.vol );
162								that.pl_info[ that.pRefs.id ].vol = puVol;
163								jQuery( that.eID.vol + that.pRefs.id ).slider({ value: puVol });  
164								
165								that.E_change_track( that.pRefs.id, that.pRefs.tr, parseFloat( that.pRefs.pt ) );
166								that.write_cookie( 'mjp_pickup', '', -1 );
167							}
168						} else {
169							that.startup();
170						}
171					} else { //just remove first autolay if there's any
172						var j;
173						for ( j in that.pl_info ) {
174							if ( that.pl_info[j].autoplay ) {
175								that.pl_info[j].autoplay = false;
176								break;
177							}
178						}
179					}
180				} else {
181					that.setAudio( track );
182					that.playit();
183					jQuery(that.jpID).jPlayer("volume", that.factors.vol * vol/100 ); //Set to player vol
184					if ( track === false ) { //silence
185						that.clearit();
186					}
187				}
188			},
189			swfPath: that.plugin_path + '/js/Jplayer271.swf',
190			volume: 1,
191			supplied: supplied,
192			wmode: "window",
193			solution:"html, flash",
194			error: function( event ) {
195				that.check_show_jperrors( event );
196			},
197			preload: "none"
198		});
199		jQuery(this.jpID).bind(jQuery.jPlayer.event.ended, function(event) {
200			that.E_complete(that.tID);
201		});	
202		jQuery(this.jpID).bind(jQuery.jPlayer.event.timeupdate, function(event) {
203			var lp = that.get_loaded(event);
204			var ppA = event.jPlayer.status.currentPercentAbsolute;
205			var pt = event.jPlayer.status.currentTime;
206			var tt = event.jPlayer.status.duration;
207			that.E_update(that.tID, lp, ppA, pt, tt);
208		});
209		jQuery(this.jpID).bind(jQuery.jPlayer.event.ready, function(event) {
210			if(event.jPlayer.html.used && event.jPlayer.html.audio.available) {
211				that.jp_audio = jQuery(that.jpID).data("jPlayer").htmlElement.audio;
212			} else {
213				that.jp_audio = 'flash';
214			}
215		});
216		jQuery(this.jpID).bind(jQuery.jPlayer.event.progress, function(event) {
217			var lp = that.get_loaded(event);
218			var pt = event.jPlayer.status.currentTime;
219			var tt = event.jPlayer.status.duration;
220			that.E_loading( that.tID, lp, tt, pt );
221		});
222		
223		that.lastformats = supplied;
224	},	
225	
226	writePickupData: function () {
227		if ( 'playing' === this.state ) {
228			var p = this.pl_info[ this.tID ];
229			var preppedurl = p.list[ p.tr ].mp3.replace( /;/, ':::' );
230			var valuestring = this.played_t + '?' + p.vol + '?' + preppedurl;
231			this.write_cookie( 'mjp_pickup', valuestring, 0.0001 );
232		} else {
233			this.write_cookie( 'mjp_pickup', '', -1 );
234		}
235	},
236	
237	getPlayerRefs: function () {
238		var playerRefs = { id: false, tr: false, pt: false, vol:false };
239		var cvals = this.read_cookie( 'mjp_pickup' );
240		if ( cvals !== false ) {
241			var cparts = cvals.split('?');
242			var depreppedurl = cparts[2].replace( /:::/, ';' );
243			playerRefs = ( typeof cparts[2] !== 'undefined' ) ? this.findFile( depreppedurl ) : playerRefs;
244			playerRefs.pt = ( typeof cparts[0] !== 'undefined' ) ? cparts[0] : 0;
245			playerRefs.vol = ( typeof cparts[1] !== 'undefined' ) ? cparts[1] : 100;
246		}
247		return playerRefs;					
248	},
249	
250	init: function () {
251		var plpath;
252		plpath = this.plugin_path.split('/');
253		this.dl_domain = plpath[2].replace(/^www./i, "");
254		this.unwrap();
255		if ( this.pickup ) {
256			jQuery('a').on( 'click', function ( e ) {
257				MP3_JPLAYER.writePickupData();
258			});
259			var prefs = this.getPlayerRefs();
260			if ( prefs.id !== false ) {
261				var p = this.pl_info[ prefs.id ];
262				this.lastformats = this.getFormats( p );
263				this.pRefs.id = prefs.id;
264				this.pRefs.tr = prefs.tr;
265				this.pRefs.pt = prefs.pt;
266				this.pRefs.vol = prefs.vol;
267			}
268		}
269		
270		this.write_controls();
271		this.add_jpconstruct_div();
272		this.runExternals( 'init', {} );
273		this.addExtStyles();
274		this.initialise_jp( this.lastformats, true, 1 );		
275	},
276	
277	addExtStyles: function () {
278		var j;
279		var l = this.extStyles.length;
280		for ( j = 0; j < l; j += 1 ) {
281			jQuery( '<style type="text/css">' + this.extStyles[ j ] + '</style>' ).appendTo( 'head' );
282		}
283	},
284		
285	destroy_jp: function () {
286		jQuery(this.jpID).unbind();
287		jQuery(this.jpID).jPlayer("destroy");
288		jQuery(this.jpID).empty();
289	},
290	
291	check_show_jperrors: function ( event ) {
292		if ( this.tID !== '' && ! this.jperrorIDs[ this.tID ] ) {
293			if ( this.showErrors === true ) {
294				this.show_nosolution( this.tID, event.jPlayer.error.type );
295			}
296			this.jperrorIDs[ this.tID ] = event.jPlayer.error.type;
297		}
298	},
299	
300	show_nosolution: function ( j, errortype ) {
301		var p = this.pl_info[j];
302		var track = p.tr;
303		var formats = p.list[track].formats;
304		var message = '';
305		
306		if ( errortype === 'e_no_solution' || errortype === 'e_no_support' ) {
307			message = this.vars.message_nosolution;
308			if ( formats === 'mp3' || formats === 'm4a' ) {
309				message = this.vars.message_nosolution_mpeg;
310			}
311		} else if ( errortype === 'e_url' ) {
312			message = this.vars.message_bad_url;
313		}
314		jQuery('#mp3j_nosolution_' + j).empty().append(message).fadeIn(200);
315		
316		if ( this.exData !== false ) {
317			this.exData.jperror = errortype;
318			this.runExternals( 'change_post', this.exData );
319			this.exData = false;
320		}
321	},
322	
323	add_jpconstruct_div: function () {
324		var html = '<div id="mp3_jplayer_items" style="position:relative; overflow:hidden; margin:0; padding:0; border:0; width:0px; height:0px;"><div id="mp3_jplayer_1_8" style="left:-999em;"></div></div>';
325		jQuery('body').prepend( html );
326	},
327		
328	get_loaded: function (event) {
329		var lp;
330		if ( typeof this.jp_audio.buffered === "object" ) {
331			if( this.jp_audio.buffered.length > 0 && this.jp_audio.duration > 0 ) {
332					lp = 100 * this.jp_audio.buffered.end(this.jp_audio.buffered.length-1) / this.jp_audio.duration;
333			} else {
334				lp = 0; 
335			}
336		} else {
337			lp = event.jPlayer.status.seekPercent;
338		}
339		this.jp_seekable = event.jPlayer.status.seekPercent; //use this for slider calcs for both html/flash solution 
340		this.load_pc = lp;
341		return lp;
342	},
343	
344	Tformat: function ( sec ) { 
345		var t = sec,
346			s = Math.floor((t)%60),
347			m = Math.floor((t/60)%60),
348			h = Math.floor(t/3600);
349		return ((h > 0) ? h+':' : '') + ((m > 9) ? m : '0'+m) + ':' + ((s > 9) ? s : '0'+s);
350	},
351
352	E_loading: function ( j, lp, tt, pt ) {
353		if (j !== '') {		
354			jQuery(this.eID.loader + j).css( "width", lp + '%' );
355			if (this.pl_info[j].type === 'MI') {
356				if (tt > 0 && this.played_t > 0) { 
357					jQuery(this.eID.tT + j).text(this.Tformat(tt)); 
358				}
359			}
360			if ( this.jp_audio !== 'flash' && lp < 100 ) {
361				if ( pt === this.played_t && this.state === 'playing' && pt > 0 && !this.sliding ) {
362					if (this.pl_info[j].type === 'MI') {
363						jQuery(this.eID.indiM + j).empty().append('<span class="mp3-finding"></span><span class="mp3-tint"></span><span class="mjp-buffering">Buffering</span>');
364					}
365					if (this.pl_info[j].type === 'single' ) {
366						jQuery(this.eID.indiM + j).empty().append('<span class="Smp3-finding"></span><span class="mp3-gtint"></span> ' + this.Tformat(pt));
367					}
368				}
369				this.played_t = pt;
370				this.total_t = tt;
371			}
372		}
373	},
374	
375	E_update: function (j, lp, ppA, pt, tt) {
376		if (j !== '') {		
377			jQuery(this.eID.loader + j).css( "width", lp + '%' );
378			jQuery(this.eID.poscol + j).css( "width", ppA + '%' );
379			if ( jQuery(this.eID.pos + j + ' div.ui-widget-header').length > 0 ) {
380				jQuery(this.eID.pos + j).slider('option', 'value', 10*ppA);
381			}
382			if (pt > 0) { 
383				jQuery(this.eID.pos + j).css( 'visibility', 'visible' ); 
384			}
385			if (this.pl_info[j].type === 'MI') {
386				jQuery(this.eID.pT + j).text(this.Tformat(pt));
387			}
388			if ('playing' === this.state) {
389				if ('MI' === this.pl_info[j].type) {
390					if (tt > 0 && this.played_t === pt && lp < 99 && !this.sliding ) {
391						jQuery(this.eID.indiM + j).empty().append('<span class="mp3-finding"></span><span class="mp3-tint"></span><span class="mjp-buffering">Buffering</span>');
392						jQuery(this.eID.tT + j).text(this.Tformat(tt));
393					} else if (pt > 0) {
394						jQuery(this.eID.indiM + j).empty().append('<span class="mjp-playing">Playing</span>');
395						jQuery(this.eID.tT + j).text(this.Tformat(tt));
396					}
397				}
398				if ('single' === this.pl_info[j].type){
399					if (pt > 0 ) {
400						if (this.played_t === pt && lp < 99 && !this.sliding ) {
401							jQuery(this.eID.indiM + j).empty().append('<span class="Smp3-finding"></span><span class="mp3-gtint"></span> ' + this.Tformat(pt));
402						} else {
403							jQuery(this.eID.indiM + j).empty().append('<span class="Smp3-tint tintmarg"></span> ' + this.Tformat(pt));
404						}
405					}
406				}
407			}
408			this.runExternals( 'update_time', { pt: pt, id: j } );
409			if ( pt >= this.exThresh && this.exData !== false ) { 
410				this.runExternals( 'change_post', this.exData );
411				this.exData = false;
412			}	
413			this.played_t = pt;
414			this.total_t = tt;
415			this.pp_abs = ppA;
416		}
417	},
418	
419	E_complete: function (j) {
420		var p = this.pl_info[j];
421		if ('MI' === p.type) {
422			if (p.loop || p.tr+1 < p.list.length) {
423				this.E_change_track(j, 'next');
424			} else {
425				this.E_dblstop(j);
426				this.startup();
427			}
428		}
429		if ('single' === p.type) {
430			if (p.loop) {
431				this.E_change_track(j, 'next');
432			} else {
433				this.E_stop(j);
434				this.startup();
435			}
436		}
437	},
438	
439	write_controls: function () {
440		var j;
441		for ( j in this.pl_info ) {
442			this.setup_a_player(j);
443			this.mutes[j] = false;
444		}
445	},
446	
447	startup: function () {
448		var j;
449		for ( j in this.pl_info ) {
450			if ( this.pl_info[j].autoplay && (this.pl_info[j].type === 'single' || this.pl_info[j].type === 'MI') ) {
451				this.pl_info[j].autoplay = false;
452				this.E_change_track(j, this.pl_info[j].tr);
453				return;
454			}
455		}
456	},
457	
458	setup_a_player: function (j) {
459		var i, li, sel, that = this, p = this.pl_info[j];
460		
461		//PLAYLISTERS and SINGLES
462		if ('MI' === p.type || 'single' === p.type) { 
463			jQuery(this.eID.vol + j).slider({ 
464				value : p.vol,
465				max: 100,
466				range: 'min',
467				start: function ( event, ui ) {
468					that.preSlideVol = p.vol;
469				},
470				stop: function ( event, ui ) {
471					that.preSlideVol = false;
472				},
473				slide: function (event, ui) {
474					if (j === that.tID) {
475						jQuery(that.jpID).jPlayer("volume", that.factors.vol * ui.value/100);
476					}
477					if ( ui.value === 0 ) {
478						jQuery('#innerExt1_' + j).addClass('vol-muted');
479						that.mutes[ j ] = that.preSlideVol;
480					} else {
481						jQuery('#innerExt1_' + j).removeClass('vol-muted');
482						that.mutes[ j ] = false;
483					}
484					p.vol = ui.value;
485				}
486			});
487			
488			jQuery(this.eID.vol + j).click( function ( e ) {
489				e.stopPropagation();
490			});
491			
492			sel = ('MI' === p.type) ? this.eID.play : this.eID.playW;
493			jQuery(sel + j).click(function () { //play-pause click
494				that.E_change_track(j, p.tr);
495				jQuery(this).blur();
496			});
497			jQuery(sel + j).dblclick(function () { //play-pause dbl click
498				if (that.state !== "playing") {
499					that.E_change_track(j, p.tr);
500				}
501				jQuery(this).blur();
502			});
503				
504			this.titles(j, p.tr);
505		}
506		
507		//PLAYLISTERS
508		if ('MI' === p.type) {
509			jQuery(this.eID.pT + j).text('00:00');
510			jQuery(this.eID.indiM + j).empty().append('<span class="mjp-ready">Ready</span>');
511			jQuery(this.eID.stp + j).click(function () {
512				that.E_stop(j);
513			});
514			jQuery(this.eID.stp + j).dblclick(function () {
515				that.E_dblstop(j);
516			});
517			
518			jQuery(this.eID.plwrap + j).hide();
519			if (p.list.length > 1) {
520				jQuery(this.eID.next + j).click(function () {
521					that.E_change_track(j, 'next');
522				});
523				jQuery(this.eID.prev + j).click(function () {
524					that.E_change_track(j, 'prev');
525				});
526				
527				var liClass = '';
528				var l = p.list.length;
529				jQuery(this.eID.ul + j).empty(); 
530				for (i = 0; i < l; i += 1) {
531					liClass = ( i === l-1 ) ? ' mjp-li-last' : '';
532					li = '<li class="li-mjp' + liClass + '" id="' + this.eID.li + j + '_' + i + '"><a class="a-mjp" href="#" id="' + this.eID.a + j + '_' + i + '">';
533					li += p.list[i].name;
534					if ( this.hasListMeta && p.list[i].artist !== '' ) {
535						li += '<br><span>' + p.list[i].artist + '</span>';
536					}
537					li += '</a>';
538					li += '<div class="mjp_ext_li" id="mjp_ext_li_' + j + '_' + i + '"></div><div class="emjp_clear"></div>';
539					li += '</li>';
540					
541					
542					jQuery(this.eID.ul + j).append(li);
543					this.add_ul_click(j, i);
544				}
545				jQuery('#' + this.eID.a + j + '_' + p.tr).addClass('mp3j_A_current');
546				jQuery('#' + this.eID.li + j + '_' + p.tr).addClass('mp3j_LI_current');
547				jQuery(this.eID.toglist + j).click(function () {
548					that.togglelist(j);
549				});
550				if (p.lstate === true) {
551					jQuery(this.eID.plwrap + j).show();
552				}	
553			}
554			
555			this.writedownload(j, p.tr);	
556			if ( this.vars.force_dload === true ) {
557				this.dl_closeinfo_click(j);
558			}
559			
560			jQuery(this.eID.lPP + j).click(function () {
561				return that.E_launchPP(j);
562			});
563			
564			jQuery( '#innerExt1_' + j ).click( function ( e ) {
565				if ( that.mutes[j] === false ) {	
566					if ( j === that.tID ) {
567						jQuery( that.jpID ).jPlayer( 'volume', 0 ); 
568					} 
569					jQuery( '#innerExt1_' + j ).addClass( 'vol-muted' );
570					jQuery( that.eID.vol + j ).slider( 'value', 0 ); 
571					that.mutes[j] = p.vol;
572					p.vol = 0;
573				} else {
574					if ( j === that.tID ) {
575						jQuery( that.jpID ).jPlayer( 'volume', that.factors.vol * that.mutes[j]/100 ); 
576					} 
577					jQuery( '#innerExt1_' + j ).removeClass( 'vol-muted' );
578					jQuery( that.eID.vol + j ).slider( 'value', that.mutes[j] ); 
579					p.vol = that.mutes[j];
580					that.mutes[j] = false;
581				}
582			});
583		}
584		
585		//POPOUT LINKS
586		if ('popout' === p.type) {
587			jQuery(this.eID.pplink + j).click(function () {
588				return that.E_launchPP(j);
589			});
590		}
591	},
592	
593	add_ul_click: function (j, i) { //playlist item click
594		var that = this;
595		jQuery('#' + this.eID.a + j + "_" + i).click(function (e) {
596			that.E_change_track(j, i);
597			e.preventDefault();
598		});
599	},
600		
601	unwrap: function () {
602		var i, j, arr;
603		if ( this.vars.play_f === true && typeof MP3jPLAYLISTS  !== "undefined" ) {
604			for ( var key in MP3jPLAYLISTS ) {
605				if ( MP3jPLAYLISTS.hasOwnProperty( key ) ) {
606					arr = MP3jPLAYLISTS[key];
607					for ( j = 0; j < arr.length; j += 1 ) { 
608						arr[j].mp3 = this.f_undo.f_con( arr[j].mp3 );
609						if ( arr[j].counterpart !== '' ) {
610							arr[j].counterpart = this.f_undo.f_con( arr[j].counterpart );
611						}
612					}
613				}
614			}
615		}
616	},
617	
618	f_undo: {
619		keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
619+/=",
620		f_con : function (input) {
621			var output = "", i = 0, chr1, chr2, chr3, enc1, enc2, enc3, enc4;
622			input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
623			while (i < input.length) {
624				enc1 = this.keyStr.indexOf(input.charAt(i++)); enc2 = this.keyStr.indexOf(input.charAt(i++));
625				enc3 = this.keyStr.indexOf(input.charAt(i++)); enc4 = this.keyStr.indexOf(input.charAt(i++));
626				chr1 = (enc1 << 2) | (enc2 >> 4); chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); chr3 = ((enc3 & 3) << 6) | enc4;
627				output = output + String.fromCharCode(chr1);
628				if (enc3 !== 64) { output = output + String.fromCharCode(chr2); }
629				if (enc4 !== 64) { output = output + String.fromCharCode(chr3); }
630			}
631			output = this.utf8_f_con(output);
632			return output;
633		},
634		utf8_f_con : function (utftext) {
635			var string = "", i = 0, c, c1, c2, c3;
636			while (i < utftext.length) {
637				c = utftext.charCodeAt(i);
638				if (c < 128) {
639					string += String.fromCharCode(c); i++;
640				} else if ((c > 191) && (c < 224)) {
641					c2 = utftext.charCodeAt(i + 1); string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); i += 2;
642				} else {
643					c2 = utftext.charCodeAt(i + 1); c3 = utftext.charCodeAt(i + 2); string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); i += 3;
644				}
645			}
646			return string;
647		}
648	},
649	
650	E_stop: function ( j, caller ) {
651		var exData = { pT:'', tT:'', pState: '', pU: '', lp:'', ppA:'', jperror:'' };
652		if (j === this.tID && j !== '') {
653			var preL = (this.tID !== '' ) ? this.pl_info[this.tID].list : false;
654			var pU = ( preL !== false ) ? preL[ this.pl_info[this.tID].tr ].mp3 : '';
655
656			if ( this.exData === false ) {
657				exData.pT = this.played_t;
658				exData.tT = this.total_t;
659				exData.pState = this.state;
660				exData.pU = pU;
661				exData.lp = this.load_pc;
662				exData.ppA = this.pp_abs;
663			} else {
664				exData = this.exData;
665			}
666			
667			if ( caller !== 'Echange' && this.jperrorIDs[j] === false ) {
668				this.runExternals( 'change_pre', exData );
669			}
670			
671			this.clearit();
672			if ( jQuery(this.eID.pos + j + ' div.ui-widget-header').length > 0 ) {
673				jQuery(this.eID.pos + j).off( 'click', MP3_JPLAYER.stopProp );
674				jQuery(this.eID.pos + j).slider('destroy');
675			}
676			jQuery(this.eID.loader + j).css( "width", '0%' );
677			this.button(j, 'play');
678			if (this.pl_info[j].type === 'MI') {
679				jQuery(this.eID.poscol + j).css( "width", '0%' );
680				jQuery(this.eID.tT + j).empty();
681				jQuery(this.eID.indiM + j).empty().append('<span class="mjp-stopped">Stopped</span>');
682				jQuery(this.eID.pT + j).text(this.Tformat(0));
683			} else {
684				jQuery(this.eID.indiM + j).empty();
685			}
686			this.load_pc = 0;
687			this.played_t = 0;
688			jQuery('#mp3j_nosolution_' + j).empty().hide();
689		}
690		return exData;
691	},
692	
693	E_dblstop: function (j) { //playlisters only
694		this.listclass(j, this.pl_info[j].tr, 0);
695		if ( this.pl_info[j].tr !== 0 ) {
696			this.titles(j, 0);
697		}
698		this.writedownload(j, 0);
699		this.E_stop(j);
700		jQuery(this.eID.indiM + j).empty().append('<span class="mjp-ready">Ready</span>');
701		this.pl_info[j].tr = 0;
702	},
703	
704	E_change_track: function ( j, change, secsIn ) {
705		var track;
706		var txt;
707		var p = this.pl_info[j];
708		
709		this.runExternals( 'change_begin', { id: j, change: change } );		
710		
711		if (j === this.tID && change === p.tr) {
712			if ('playing' === this.state) {
713				if (this.load_pc === 0) {
714					this.E_stop( j, 'Echange');
715				} else {
716					this.pauseit();
717					this.button(j, 'play');
718					if ('MI' === p.type) {
719						jQuery(this.eID.indiM + j).empty().append('<span class="mjp-paused">Paused</span>');
720					}
721				}
722				return;
723			} else if ('paused' === this.state || 'set' === this.state) {
724				this.playit();
725				this.button(j, 'pause');
726				return;
727			}
728		}
729		
730		var exData = this.E_stop( this.tID, 'Echange' );
731		
732		if ('prev' === change) {
733			track = (p.tr-1 < 0) ? p.list.length-1 : p.tr-1;
734		} else if ('next' === change) {
735			track = (p.tr+1 < p.list.length) ? p.tr+1 : 0;
736		} else {
737			track = change;
738		}
739		
740		jQuery(this.jpID).jPlayer("volume", 1 ); //Vol scaling fix
741		jQuery('#mp3j_nosolution_' + j).hide();
742		txt = ('MI' === p.type) ? '<span class="mp3-finding"></span><span class="mp3-tint"></span><span class="mjp-connecting">Connecting</span>' : '<span class="Smp3-finding"></span><span class="mp3-gtint"></span>';
743		jQuery(this.eID.indiM + j).empty().append(txt);
744		this.button(j, 'pause');
745		this.makeslider(j);
746		if ('MI' === p.type) {
747			this.listclass(j, p.tr, track);
748			if ( p.tr !== track ) {
749				this.titles(j, track);
750			}
751			if (p.download) {
752				this.writedownload(j, track);
753				jQuery(this.eID.dload + j).hide().addClass('whilelinks').fadeIn(400);
754			}
755		}
756		p.tr = track;
757		this.tID = j;
758		
759		var formatString = this.getFormats( p );
760		if ( formatString !== this.lastformats || this.jperrorIDs[ j ] ) {
761			this.jperrorIDs[ j ] = false;
762			this.destroy_jp();
763			this.initialise_jp( formatString, p.list[track], p.vol );
764		} else {
765			this.jperrorIDs[ j ] = false;
766			this.setAudio( p.list[track] );
767			this.playit( secsIn );
768			jQuery(this.jpID).jPlayer("volume", this.factors.vol * p.vol/100 ); //Reset to correct vol
769		}
770		exData.mp3 = p.list[track].mp3;
771		exData.name = p.list[track].name;
772		exData.artist = p.list[track].artist;
773		this.exData = exData;
774		this.runExternals( 'change_end', exData );
775	},
776	
777	E_launchPP: function (j) {
778		this.writePickupData();
779		this.popoutformats = this.lastformats;
780		this.launched_ID = j;
781		this.was_playing = ( this.state === "playing" ) ? true : false;
782		var data = { id: this.launched_ID, playing: this.was_playing };
783		this.runExternals( 'button_popout', data );
784		
785		if ( this.tID !== '' ) {
786			this.E_stop(this.tID);
787			if ( 'mp3,oga' !== this.lastformats ) {
788				this.destroy_jp();
789				this.initialise_jp( 'mp3,oga', false, 100 );
790			} else {
791				this.setAudio( false );
792				this.playit(); //make chrome let go of last track (incase it didn't finish loading)
793				this.clearit();
794			}			
795		}
796		
797		var newwindow = window.open( this.plugin_path + '/popout.php', 'mp3jpopout', 'height=' +this.pl_info[j].popout_css.colours[13]+ ', width=' +this.pl_info[j].popout_css.colours[12]+ ', location=1, status=1, scrollbars=1, resizable=1, left=25, top=25' );
798		if ( window.focus ) { 
799			newwindow.focus(); 
800		}
801		return false;
802	},	
803	
804	setAudio: function ( track ) {		
805		var media = {};
806		this.state = 'set';
807		if ( false === track ) {
808			media['mp3'] = this.plugin_path + '/mp3/silence.mp3';
809			media['ogg'] = this.plugin_path + '/mp3/silence.ogg';
810		} else {
811			media[ track.formats[0] ] = track.mp3;
812			if ( typeof track.formats[1] !== 'undefined' ) {
813				media[ track.formats[1] ] = track.counterpart;
814			}
815		}
816		jQuery(this.jpID).jPlayer( "setMedia", media );
817	},
818	
819	playit: function ( secs ) {
820		this.state = 'playing';
821		if ( typeof secs === 'undefined' ) {
822			jQuery( this.jpID ).jPlayer("play");
823		} else {
824			jQuery( this.jpID ).jPlayer( "play",  secs );
825		}
826	},
827	pauseit: function () {
828		this.state = 'paused';
829		jQuery(this.jpID).jPlayer("pause");
830	},
831	clearit: function () {
832		this.state = '';
833		jQuery(this.jpID).jPlayer("clearMedia");
834	},
835			
836	button: function (j, type) {
837		if (j !== '') { 
838			if ('pause' === type) {
839				jQuery( this.eID.play + j ).removeClass( 'play-mjp' ).addClass( 'pause-mjp' ).empty().append( this.pl_info[j].pause_txt );
840			}
841			if ('play' === type) {
842				jQuery( this.eID.play + j ).removeClass( 'pause-mjp' ).addClass( 'play-mjp' ).empty().append( this.pl_info[j].play_txt );
843			}
844		}
845		this.runExternals( 'button_playpause', { type: type } );
846	},
847	
848	listclass: function ( j, rem, add ) {
849		jQuery('#'+ this.eID.a + j +'_'+ rem).removeClass('mp3j_A_current');
850		jQuery('#'+ this.eID.li + j +'_'+ rem).removeClass('mp3j_LI_current');
851		jQuery('#'+ this.eID.a + j +'_'+ add).addClass('mp3j_A_current');
852		jQuery('#'+ this.eID.li + j +'_'+ add).addClass('mp3j_LI_current');
853	},
854	
855	titles: function ( j, track ) {
856		var data;
857		var p = this.pl_info[j], Olink = '', Clink = '';	
858		var img = p.list[track].image;
859		if (p.type === "MI") {
860			jQuery(this.eID.title + j).empty().append(p.list[track].name).append('<br /><div>' + p.list[track].artist + '</div>');
861			var lastImg = jQuery(this.eID.img + j + ' img').attr('src');			
862			if ( img === 'false' || img === 'true' || img === '' ) {
863				jQuery(this.eID.img + j).empty();
864			} else if ( img !== lastImg ) {
865				if (p.list[track].imgurl !== '') {
866					Olink = '<a href="' + p.list[track].imgurl + '">';
867					Clink = '</a>';
868				}
869				jQuery(this.eID.img + j).empty().hide().append(Olink + '<img src="' + p.list[track].image + '" />' + Clink).fadeIn(300);
870			}
871		}
872		data = { title: p.list[track].name, caption: p.list[track].artist, id: j, track: track };
873		this.runExternals( 'write_titles', data );
874	},
875	
876	writedownload: function ( j, track, text ) {
877		var data;
878		var p = this.pl_info[j];
879		text = ( typeof text === 'undefined' ) ? this.vars.dload_text : text;
880		if ( p.download ) {
881			jQuery(this.eID.dload + j).empty().removeClass('whilelinks').append('<a id="mp3j_dlanchor_' + j + '" href="' + p.list[track].mp3 + '" target="_blank">' + text + '</a>');
882			if ( this.vars.force_dload === true ) {
883				this.dl_button_click( j );
884			}
885		}
886		data = { is_download: p.download , url: p.list[track].mp3 };
887		this.runExternals( 'write_download', data );
888	},
889	
890	togglelist: function ( j ) {
891		if (this.pl_info[j].lstate === true) {
892			jQuery(this.eID.plwrap + j).fadeOut(300);
893			jQuery(this.eID.toglist + j).text('SHOW');
894			this.pl_info[j].lstate = false;
895		} else if (this.pl_info[j].lstate === false) {
896			jQuery(this.eID.plwrap + j).fadeIn("slow");
897			jQuery(this.eID.toglist + j).text('HIDE');
898			this.pl_info[j].lstate = true;
899		}
900	},
901		
902	makeslider: function ( j ) {
903		var phmove, cssmove, that = this;
904		jQuery(this.eID.pos + j).css( 'visibility', 'hidden' );
905		
906		jQuery(this.eID.pos + j).slider({
907			max: 1000,
908			range: 'min',
909			slide: function (event, ui) { 
910				if ( that.allowRanges || (ui.value/10) < that.load_pc ) {
911					cssmove = ui.value/10;
912					phmove = ui.value*(10.0/that.jp_seekable);
913				} else {
914					cssmove = 0.99*that.load_pc;
915					phmove = (9.9*that.load_pc)*(10.0/that.jp_seekable);
916				}
917				jQuery(that.eID.poscol + j).css('width', cssmove + '%');
918				jQuery(that.jpID).jPlayer("playHead", phmove );
919				if (that.state === 'paused') { 
920					that.button(j, 'pause');
921					that.playit();
922				}
923				that.state = 'playing';
924			},
925			start: function ( event, ui ) {
926				that.sliding = true;
927			},
928			stop: function ( event, ui ) {
929				that.sliding = false;
930			}
931		});
932		
933		jQuery(this.eID.pos + j).on( 'click', MP3_JPLAYER.stopProp );
934	},
935	
936	stopProp: function ( e ) {
937		e.stopPropagation();
938	},
939	
940	deviceInfo: function () {
941		var isMobile = false;
942		var os = '';
943		var device = '';
944		var ua = navigator.userAgent;
945		var p = navigator.platform;
946		var matched;
947		
948		if ( /bot|spider/i.test( ua ) ) {
949			os = 'spider';
950		} else {
951			if ( /iPhone|iPod|iPad/.test( p ) ) { 
952				os = 'iOS';
953				device = p;
954				isMobile = true; 
955			} else {
956				var matched = /Android|BlackBerry|IEMobile|Opera Mini|Mobi|Tablet/.exec( ua );
957				if ( matched ) {
958					device = ( matched[0] === 'Mobi' ) ? 'Mobile' : matched[0];
959					isMobile = true;
960				}
961			}
962			if ( ! isMobile ) {
963				if ( /Mac/.test( p ) ) {
964					os = 'Mac';
965					device = 'Desk/Laptop';
966				} else if ( /Linux/.test( p ) ) {
967					os = 'Linux';
968					device = 'Desk/Laptop';
969				} else if ( /Win|Pocket PC/.test( p ) ) {
970					os = 'Windows';
971					device = 'Desk/Laptop';
972				}
973			}
974		}
975		return { os:os, device:device, isMobile:isMobile }; 
976	}
977};
978
979MP3_JPLAYER.dl_button_click = function ( j ) {
980	var that = this, p = this.pl_info[j];
981	jQuery('#mp3j_dlanchor_' + j).click(function (e) {
982		that.dl_runinfo( p.list[p.tr].mp3, j, e );
983		that.runExternals( 'download', p.list[p.tr] );
984		e.preventDefault();
985	});
986};
987
988MP3_JPLAYER.dl_closeinfo_click = function ( j ) {
989	var that = this;
990	jQuery('#mp3j_finfo_close_' + j).click(function () {
991		that.dl_dialogue( j, '', 'close');
992		that.clear_timers( j );
993	});
994};	
995
996MP3_JPLAYER.dl_runinfo = function ( get, j, e ) {
997	var can_write,  
998		dlpath,
999		message,
1000		that = this,
1001		dlframe = false,
1002		p = this.pl_info[j],
1003		is_local = this.is_local_dload( get );
1004	
1005	var enc_get;
1006	if ( !this.intervalIDs[ j ] && !this.timeoutIDs[ j ] ) { //if timers not already running for this player
1007		can_write = this.write_cookie('mp3Download' + j, 'waiting', '');
1008		if ( is_local ) {
1009			if ( can_write !== false ) {
1010				this.dl_dialogue( j, this.vars.message_interval, 'check');
1011			} else {
1012				this.dl_dialogue( j, this.vars.message_indark, 'indark');
1013			}
1014			this.intervalIDs[ j ] = setInterval( function(){ that.dl_interval_check( j, can_write ); }, 500);
1015			this.timeoutIDs[ j ] = setTimeout( function(){ that.dl_timeout( j, can_write ); }, 7000);
1016			dlframe = true;
1017		} else {
1018			if ( this.vars.dl_remote_path === '' ) {
1019				message = this.vars.message_promtlink.replace('#1', get);
1020				message = message.replace('#2', p.list[p.tr].name);
1021				this.dl_dialogue( j, message, 'indark');
1022			} else {
1023				message = this.vars.message_indark.replace('#1', get);
1024				message = message.replace('#2', p.list[p.tr].name);
1025				this.dl_dialogue( j, message, 'indark');
1026				dlframe = true;
1027			}
1028		}
1029		this.dl_dialogs[ j ] = 'false';
1030		if ( dlframe ) {
1031			dlpath = this.get_dloader_path( get );
1032			enc_get = encodeURIComponent( get );
1033			jQuery('#mp3j_dlf_' + j).empty().append('<iframe id="mp3j_dlframe_' + j + '" name="mp3j_dlframe_' + j + '" class="mp3j-dlframe" src="' + dlpath + '?mp3=loc' + enc_get + '&pID=' + j + '" style="display:none;"></iframe>');
1034		}	
1035	}
1036};
1037
1038MP3_JPLAYER.dl_interval_check = function  ( j, can_write ) {
1039	if ( can_write !== false && this.read_cookie('mp3Download' + j) === 'true' ) {	//got cookie back, all should be good	
1040		this.dl_dialogue( j, this.vars.message_ok, 'hide');
1041		this.clear_timers( j );
1042	} else if ( this.dl_dialogs[ j ] !== 'false' ) { //got a message back
1043		this.dl_dialogue( j, this.dl_dialogs[ j ], 'add');		
1044		this.clear_timers( j );	
1045	}																		
1046};
1047
1048MP3_JPLAYER.dl_timeout = function ( j, can_write  ) {
1049	this.clear_timers( j );
1050	if ( can_write !== false ) {
1051		this.dl_dialogue( j, this.vars.message_timeout, 'add');
1052	}
1053};
1054
1055MP3_JPLAYER.clear_timers = function ( j ) {
1056	if ( this.intervalIDs[ j ] !== null && this.timeoutIDs[ j ] !== null ) {
1057		clearInterval( this.intervalIDs[j] );
1058		clearTimeout( this.timeoutIDs[j] );
1059		this.intervalIDs[ j ] = null;
1060		this.timeoutIDs[j] = null;
1061	}
1062	jQuery('#mp3j_dlf_' + j).empty(); //ditch iframe
1063	this.write_cookie('mp3Download' + j, '', -1); //clear any cookie
1064};
1065
1066MP3_JPLAYER.dl_dialogue = function ( j, text, state ) {
1067	if ( 'check' === state ) {
1068		jQuery('#mp3j_finfo_gif_' + j).show();
1069		jQuery('#mp3j_finfo_txt_' + j).empty().append(text).show();
1070		jQuery('#mp3j_finfo_' + j).show();
1071	} else if ( 'add' === state ) {
1072		jQuery('#mp3j_finfo_gif_' + j).hide();
1073		jQuery('#mp3j_finfo_txt_' + j).empty().append(text).show();
1074	} else if ( 'indark' === state ) {
1075		jQuery('#mp3j_finfo_gif_' + j).hide();
1076		jQuery('#mp3j_finfo_txt_' + j).empty().append(text).show();
1077		jQuery('#mp3j_finfo_' + j).fadeIn(100);
1078	} else if ( 'close' === state ) {
1079		jQuery('#mp3j_finfo_gif_' + j).hide();
1080		jQuery('#mp3j_finfo_' + j).hide();
1081	} else {
1082		jQuery('#mp3j_finfo_gif_' + j).hide();
1083		if ( text !== '' ) {
1084			jQuery('#mp3j_finfo_txt_' + j).empty().append(text).show();
1085		}
1086		jQuery('#mp3j_finfo_' + j).fadeOut(1000);
1087	}
1088	this.runExternals( 'download_dialog', { id: j, text: text, state: state } );
1089};
1090
1091MP3_JPLAYER.read_cookie = function ( name ) {
1092	var i, cookie, allCookies = document.cookie.split('; ');
1093	if ( allCookies.length > 0 ) {
1094		for ( i = 0; i < allCookies.length; i += 1 ) {
1095			cookie = allCookies[i].split( '=' );
1096			if ( cookie[0] === name ) {
1097				return cookie[1];
1098			}
1099		}
1100	}
1101	return false;
1102};
1103
1104MP3_JPLAYER.write_cookie = function ( name, value, days ) {
1105	var date, expires = "";
1106	if ( days ) {
1107		date = new Date();
1108		date.setTime( date.getTime() + (days*24*60*60*1000) );
1109		expires = "; expires=" + date.toUTCString();
1110	}
1111	document.cookie = name + "=" + value + expires + "; path=/";
1112	return this.read_cookie( name );
1113};
1114
1115MP3_JPLAYER.get_dloader_path = function ( loc ) {
1116	var k, path = "", file = "", chunks; 
1117	chunks = loc.split('/');
1118	file = chunks[chunks.length-1];
1119	if ( loc.charAt(0) === '/' ) {
1120		path = this.plugin_path + '/download.php';
1121	} else {
1122		path = chunks[2].replace(/^www./i, "");
1123		if ( path === this.dl_domain ) {
1124			path = this.plugin_path + '/download.php';
1125		} else {
1126			path = chunks[0] + '//' + chunks[2] + this.vars.dl_remote_path;
1127		}
1128	}
1129	return path;
1130};
1131
1132MP3_JPLAYER.is_local_dload = function ( loc ) {
1133	var domain = "", file = "", chunks, is_local = false; 
1134	chunks = loc.split('/');
1135	file = chunks[chunks.length-1];
1136	if ( loc.charAt(0) === '/' ) {
1137		is_local = true;
1138	} else {
1139		domain = chunks[2].replace(/^www./i, "");
1140		if ( domain === this.dl_domain ) {
1141			is_local = true;
1142		}
1143	}
1144	return is_local;
1145};

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.