PageSourceSearch

https://jakash.kz/plugins/content/jw_allvideos/jw_allvideos/includes/js/wmvplayer/wmvplayer.js?v=4.8.0

js jakash.kz collected 2026-10-06 23:57:06 UTC 23,928 bytes, 749 lines download raw bytes

1/****************************************************************************
2* JW WMV Player version 1.1, created with M$ Silverlight 1.0
3*
4* This file contains all logic for the JW WMV Player. For a functional setup,
5* the following two files are also needed:
6* - silverlight.js (for instantiating the silverlight plugin)
7* - wmvplayer.xaml (or another XAML skin describing the player graphics)
8*
9* More info: http://www.jeroenwijering.com/?item=JW_WMV_Player
10****************************************************************************/
11if(typeof jeroenwijering == "undefined") {
12	var jeroenwijering = new Object();
13	jeroenwijering.utils = new Object();
14}
15
16/****************************************************************************
17* The player wrapper; loads config variables and starts MVC cycle.
18****************************************************************************/
19jeroenwijering.Player = function(cnt,src,cfg) {
20	this.controller;
21	this.model;
22	this.view;
23	this.configuration = {
24		backgroundcolor:'FFFFFF',
25		windowless:'false',
26		file:'',
27		height:'260',
28		image:'',
29		backcolor:'FFFFFF',
30		frontcolor:'000000',
31		lightcolor:'000000',
32		screencolor:'000000',
33		width:'320',
34		logo:'',
35		overstretch:'false',
36		shownavigation:'true',
37		showstop:'false',
38		showdigits:'true',
39		usefullscreen:'true',
40		usemute:'false',
41		autostart:'false',
42		bufferlength:'3',
43		duration:'0',
44		repeat:'false',
45		sender:'',
46		start:'0',
47		volume:'90',
48		link:'',
49		linkfromdisplay:'false',
50		linktarget:'_self'
51	};
52	for(itm in this.configuration) {
53		if(cfg[itm] != undefined) {
54			if (itm.indexOf('color') > 0) {
55				this.configuration[itm] = cfg[itm].substr(cfg[itm].length-6);
56			} else {
57				this.configuration[itm] = cfg[itm];
58			}
59		}
60	}
61	Silverlight.createObjectEx({
62		source:src,
63		parentElement:cnt,
64		properties:{
65			width:this.configuration['width'],
66			height:this.configuration['height'],
67			version:'1.0',
68			inplaceInstallPrompt:true,
69			isWindowless:this.configuration['windowless'],
70			background:'#'+this.configuration['backgroundcolor']
71		},
72		events:{
73			onLoad:this.onLoadHandler,
74			onError:null
75		},
76		context:this
77	});
78}
79
80jeroenwijering.Player.prototype = {
81	addListener: function(typ,fcn) {
82		this.view.listeners.push({type:typ,func:fcn});
83	},
84
85	getConfig: function() {
86		return this.configuration;
87	},
88
89	onLoadHandler: function(pid,tgt,sdr) {
90		tgt.configuration['sender'] = sdr;
91		tgt.controller = new jeroenwijering.Controller(tgt.configuration);
92		tgt.view = new jeroenwijering.View(tgt.configuration,tgt.controller);
93		tgt.model = new jeroenwijering.Model(tgt.configuration,tgt.controller,tgt.view);
94		tgt.controller.startMVC(tgt.view,tgt.model);
95	},
96
97	sendEvent: function(typ,prm) {
98		switch(typ.toUpperCase()) {
99			case 'LINK':
100				this.controller.setLink();
101				break;
102			case 'LOAD':
103				this.controller.setLoad(prm);
104				break;
105			case 'MUTE':
106				this.controller.setMute();
107				break;
108			case 'PLAY':
109				this.controller.setPlay();
110				break;
111			case 'SCRUB':
112				this.controller.setScrub(prm);
113				break;
114			case 'STOP':
115				this.controller.setStop();
116				break;
117			case 'VOLUME':
118				this.controller.setVolume(prm);
119				break;
120		}
121	}
122}
123
124/****************************************************************************
125* The controller of the player MVC triad, which processes all user input.
126****************************************************************************/
127jeroenwijering.Controller = function(cfg) {
128	this.configuration = cfg;
129}
130
131jeroenwijering.Controller.prototype = {
132	startMVC: function(vie,mdl) {
133		this.view = vie;
134		this.model = mdl;
135		if(this.configuration['usemute'] == 'true') {
136			this.view.onVolume(0);
137			this.view.onMute(true);
138			this.model.goVolume(0);
139		} else {
140			this.view.onVolume(this.configuration['volume']);
141			this.model.goVolume(this.configuration['volume']);
142		}
143		if(this.configuration['autostart'] == 'true') {
144			this.model.goStart();
145		} else {
146			this.model.goPause();
147		}
148	},
149
150	setState: function(old,stt) {
151		this.state = stt;
152		var pos = this.configuration['start'];
153		if(old == 'Closed' && pos > 0) {
154			setTimeout(jeroenwijering.utils.delegate(this,this.setScrub),200,pos);
155		}
156	},
157
158	setLink: function() {
159		if (this.configuration['linktarget'].indexOf('javascript:') == 0) {
160			return Function(this.configuration['linktarget']).apply();
161		} else if (this.configuration['linktarget'] == '_blank') {
162			window.open(this.configuration['link']);
163		} else if (this.configuration['linktarget'] != '') {
164			window.location = this.configuration['link'];
165		}
166	},
167
168	setLoad: function(fil) {
169		if(this.model.state != "Closed") {
170			this.model.goStop();
171		}
172		this.configuration['file'] = fil;
173		if(this.configuration['autostart'] == 'true') {
174			setTimeout(jeroenwijering.utils.delegate(this.model,this.model.goStart),100);
175		}
176	},
177
178	setMute: function() {
179		if(this.configuration['usemute'] == 'true') {
180			this.configuration['usemute'] = 'false';
181			this.model.goVolume(this.configuration['volume']);
182			this.view.onMute(false);
183		} else {
184			this.configuration['usemute'] = 'true';
185			this.model.goVolume(0);
186			this.view.onMute(true);
187		}
188	},
189
190	setPlay: function() {
191		if(this.state == 'Buffering' || this.state == 'Playing') {
192			if(this.configuration['duration'] == 0) {
193				this.model.goStop();
194			} else {
195				this.model.goPause();
196			}
197		} else {
198			this.model.goStart();
199		}
200	},
201
202	setScrub: function(sec) {
203		if(sec < 2) {
204			sec = 0;
205		} else if (sec > this.configuration['duration']-4) {
206			sec = this.configuration['duration']-4;
207		}
208		if(this.state == 'Buffering' || this.state == 'Playing') {
209			this.model.goStart(sec);
210		} else {
211			this.model.goPause(sec);
212		}
213	},
214
215	setStop: function() {
216		this.model.goStop();
217	},
218
219	setVolume: function(pct) {
220		if(pct < 0) { pct = 0; } else if(pct > 100) { pct = 100; }
221		this.configuration['volume'] = Math.round(pct);
222		this.model.goVolume(pct);
223		this.view.onVolume(pct);
224		if(this.configuration['usemute'] == 'true') {
225			this.configuration['usemute'] = 'false';
226			this.view.onMute(false);
227		}
228	},
229
230	setFullscreen: function() {
231		var fss = !this.configuration['sender'].getHost().content.FullScreen;
232		this.configuration['sender'].getHost().content.FullScreen = fss;
233		jeroenwijering.utils.delegate(this.view,this.view.onFullscreen);
234	}
235}
236
237/****************************************************************************
238* The view of the player MVC triad, which manages the graphics.
239****************************************************************************/
240jeroenwijering.View = function(cfg,ctr) {
241	this.configuration = cfg;
242	this.listeners = Array();
243	this.controller = ctr;
244	this.fstimeout;
245	this.fslistener;
246	this.display = this.configuration['sender'].findName("PlayerDisplay");
247	this.controlbar = this.configuration['sender'].findName("PlayerControls");
248	this.configuration['sender'].getHost().content.onResize =
249		jeroenwijering.utils.delegate(this,this.resizePlayer);
250	this.configuration['sender'].getHost().content.onFullScreenChange =
251		jeroenwijering.utils.delegate(this,this.onFullscreen);
252	this.assignColorsClicks();
253	this.resizePlayer();
254}
255
256jeroenwijering.View.prototype = {
257	onBuffer: function(pct) {
258		var snd = this.configuration['sender'];
259		if(pct == 0) {
260			snd.findName("BufferText").Text = null;
261		} else {
262			pct < 10 ? pct = "0"+pct: pct = ""+pct;
263			snd.findName("BufferText").Text = pct;
264		}
265		this.delegate('BUFFER',[pct]);
266	},
267
268	onFullscreen: function(fss) {
269		var snd = this.configuration['sender'];
270		var fst = snd.getHost().content.FullScreen;
271		if(fst) {
272			this.fstimeout = setTimeout(jeroenwijering.utils.delegate(this,
273				this.hideFSControls),2000);
274			this.fslistener = this.display.addEventListener('MouseMove',
275				jeroenwijering.utils.delegate(this,this.showFSControls));
276			snd.findName("FullscreenSymbol").Visibility = "Collapsed";
277			snd.findName("FullscreenOffSymbol").Visibility = "Visible";
278		} else {
279			clearTimeout(this.fstimeout);
280			this.display.removeEventListener("MouseMove",this.fslistener);
281			this.controlbar.Visibility = "Visible";
282			this.display.Cursor = "Hand";
283			snd.findName("FullscreenSymbol").Visibility = "Visible";
284			snd.findName("FullscreenOffSymbol").Visibility = "Collapsed";
285		}
286		this.resizePlayer();
287		this.delegate('FULLSCREEN');
288	},
289
290	showFSControls: function(sdr,arg) {
291		var vbt = sdr.findName('PlayerControls');
292		var yps = arg.GetPosition(vbt).Y;
293		clearTimeout(this.fstimeout);
294		this.controlbar.Visibility = "Visible";
295		this.display.Cursor = "Hand";
296		if(yps < 0) {
297			this.fstimeout = setTimeout(jeroenwijering.utils.delegate(this,
298				this.hideFSControls),2000);
299		}
300	},
301
302	hideFSControls: function() {
303		this.controlbar.Visibility = "Collapsed";
304		this.display.Cursor = "None";
305	},
306
307	onLoad: function(pct) {
308		var snd = this.configuration['sender'];
309		var max = snd.findName("TimeSlider").Width;
310		snd.findName("DownloadProgress").Width = Math.round(max*pct/100);
311		this.delegate('LOAD',[pct]);
312	},
313
314	onMute: function(mut) {
315		var snd = this.configuration['sender'];
316		this.configuration['usemute'] = ''+mut;
317		if(mut) {
318			snd.findName("VolumeHighlight").Visibility = "Collapsed";
319			snd.findName("MuteSymbol").Visibility = "Visible";
320			snd.findName("MuteOffSymbol").Visibility = "Collapsed";
321			if(this.state == 'Playing') {
322				snd.findName("MuteIcon").Visibility = "Visible";
323			}
324		} else {
325			snd.findName("VolumeHighlight").Visibility = "Visible";
326			snd.findName("MuteSymbol").Visibility = "Collapsed";
327			snd.findName("MuteOffSymbol").Visibility = "Visible";
328			snd.findName("MuteIcon").Visibility = "Collapsed";
329		}
330		this.delegate('MUTE');
331	},
332
333	onState: function(old,stt) {
334		var snd = this.configuration['sender'];
335		this.state = stt;
336		if(stt == 'Buffering' || stt == 'Playing' || stt == 'Opening') {
337			snd.findName("PlayIcon").Visibility = "Collapsed";
338			snd.findName("PlaySymbol").Visibility = "Collapsed";
339			snd.findName("PlayOffSymbol").Visibility = "Visible";
340			if (stt=='Playing') {
341				snd.findName("BufferIcon").Visibility = "Collapsed";
342				snd.findName("BufferText").Visibility = "Collapsed";
343				if(this.configuration['usemute'] == 'true') {
344					snd.findName("MuteIcon").Visibility = "Visible";
345				}
346			} else{
347				snd.findName("BufferIcon").Visibility = "Visible";
348				snd.findName("BufferText").Visibility = "Visible";
349			}
350		} else {
351			snd.findName("MuteIcon").Visibility = "Collapsed";
352			snd.findName("BufferIcon").Visibility = "Collapsed";
353			snd.findName("BufferText").Visibility = "Collapsed";
354			snd.findName("PlayOffSymbol").Visibility = "Collapsed";
355			snd.findName("PlaySymbol").Visibility = "Visible";
356			if(this.configuration['linkfromdisplay'] == 'true') {
357				snd.findName("PlayIcon").Visibility = "Collapsed";
358			} else {
359				snd.findName("PlayIcon").Visibility = "Visible";
360			}
361		}
362		try {
363			if(!(old == 'Completed' && stt == 'Buffering') &&
364				!(old == 'Buffering' && stt == 'Paused')) {
365				playerStatusChange(old.toUpperCase(),stt.toUpperCase());
366			}
367		} catch (err) {}
368		this.delegate('STATE',[old,stt]);
369	},
370
371	onTime: function(elp,dur) {
372		var snd = this.configuration['sender'];
373		var snd = this.configuration['sender'];
374		var max = snd.findName("TimeSlider").Width;
375		if(dur > 0) {
376			var pos = Math.round(max*elp/dur);
377			this.configuration['duration'] = dur;
378			snd.findName("ElapsedText").Text = jeroenwijering.utils.timestring(elp);
379			snd.findName("RemainingText").Text = jeroenwijering.utils.timestring(dur-elp);
380			snd.findName("TimeSymbol").Visibility = "Visible";
381			snd.findName("TimeSymbol")['Canvas.Left'] = pos+4;
382			snd.findName("TimeHighlight").Width = pos-2;
383		} else  {
384			snd.findName("TimeSymbol").Visibility = "Collapsed";
385		}
386		this.delegate('TIME',[elp,dur]);
387	},
388
389	onVolume: function(pct) {
390		var snd = this.configuration['sender'];
391		snd.findName("VolumeHighlight").Width = Math.round(pct/5);
392		this.delegate('VOLUME',[pct]);
393	},
394
395	assignColorsClicks: function() {
396		this.display.Cursor = "Hand";
397		this.display.Background = "#FF"+this.configuration['screencolor'];
398		if(this.configuration['linkfromdisplay'] == 'false') {
399			this.display.addEventListener('MouseLeftButtonUp',
400				jeroenwijering.utils.delegate(this.controller,
401				this.controller.setPlay));
402		} else {
403			this.display.addEventListener('MouseLeftButtonUp',
404				jeroenwijering.utils.delegate(this.controller,
405				this.controller.setLink));
406			this.display.findName("PlayIcon").Visibility = "Collapsed";
407		}
408		if(this.configuration['logo'] != '') {
409			this.display.findName('OverlayCanvas').Visibility = "Visible";
410			this.display.findName('OverlayLogo').ImageSource =
411				this.configuration['logo'];
412		}
413		this.controlbar.findName("ControlbarBack").Fill =
414			"#FF"+this.configuration['backcolor'];
415		this.assignButton('Play',this.controller.setPlay);
416		this.assignButton('Stop',this.controller.setStop);
417		this.configuration['sender'].findName('ElapsedText').Foreground =
418			"#FF"+this.configuration['frontcolor'];
419		this.assignSlider('Time',this.changeTime);
420		this.configuration['sender'].findName('DownloadProgress').Fill =
421			"#FF"+this.configuration['frontcolor'];
422		this.configuration['sender'].findName('RemainingText').Foreground =
423			"#FF"+this.configuration['frontcolor'];
424		this.assignButton('Link',this.controller.setLink);
425		this.assignButton('Fullscreen',this.controller.setFullscreen);
426		this.assignButton('Mute',this.controller.setMute);
427		this.assignSlider('Volume',this.changeVolume);
428	},
429
430	assignButton: function(btn,act) {
431		var el1 = this.configuration['sender'].findName(btn+'Button');
432		el1.Cursor = "Hand";
433		el1.addEventListener('MouseLeftButtonUp',
434			jeroenwijering.utils.delegate(this.controller,act));
435		el1.addEventListener('MouseEnter',
436			jeroenwijering.utils.delegate(this,this.rollOver));
437		el1.addEventListener('MouseLeave',
438			jeroenwijering.utils.delegate(this,this.rollOut));
439		this.configuration['sender'].findName(btn+'Symbol').Fill =
440			"#FF"+this.configuration['frontcolor'];
441		try {
442			this.configuration['sender'].findName(btn+'OffSymbol').Fill =
443				"#FF"+this.configuration['frontcolor'];
444		} catch(e) {}
445	},
446
447	assignSlider: function(sld,act) {
448		var el1 = this.configuration['sender'].findName(sld+'Button');
449		el1.Cursor = "Hand";
450		el1.addEventListener('MouseLeftButtonUp',
451			jeroenwijering.utils.delegate(this,act));
452		el1.addEventListener('MouseEnter',
453			jeroenwijering.utils.delegate(this,this.rollOver));
454		el1.addEventListener('MouseLeave',
455			jeroenwijering.utils.delegate(this,this.rollOut));
456		this.configuration['sender'].findName(sld+'Slider').Fill =
457			"#FF"+this.configuration['frontcolor'];
458		this.configuration['sender'].findName(sld+'Highlight').Fill =
459			"#FF"+this.configuration['frontcolor'];
460		this.configuration['sender'].findName(sld+'Symbol').Fill =
461			"#FF"+this.configuration['frontcolor'];
462	},
463
464	delegate: function(typ,arg) {
465		for(var i=0; i<this.listeners.length; i++) {
466			if(this.listeners[i]['type'].toUpperCase() == typ) {
467				this.listeners[i]['func'].apply(null,arg);
468			}
469		}
470	},
471
472	rollOver: function(sdr) {
473		var str = sdr.Name.substr(0,sdr.Name.length-6);
474		this.configuration['sender'].findName(str+'Symbol').Fill =
475			"#FF"+this.configuration['lightcolor'];
476		try {
477			this.configuration['sender'].findName(str+'OffSymbol').Fill =
478				"#FF"+this.configuration['lightcolor'];
479		} catch(e) {}
480	},
481
482	rollOut: function(sdr) {
483		var str = sdr.Name.substr(0,sdr.Name.length-6);
484		this.configuration['sender'].findName(str+'Symbol').Fill =
485			"#FF"+this.configuration['frontcolor'];
486		try {
487			this.configuration['sender'].findName(str+'OffSymbol').Fill =
488				"#FF"+this.configuration['frontcolor'];
489		} catch(e) {}
490	},
491
492	changeTime: function(sdr,arg) {
493		var tbt = sdr.findName('TimeSlider');
494		var xps = arg.GetPosition(tbt).X;
495		var sec = Math.floor(xps/tbt.Width*this.configuration['duration']);
496		this.controller.setScrub(sec);
497	},
498
499	changeVolume: function(sdr,arg) {
500		var vbt = sdr.findName('VolumeButton');
501		var xps = arg.GetPosition(vbt).X;
502		this.controller.setVolume(xps*5);
503	},
504
505	resizePlayer: function() {
506		var wid = this.configuration['sender'].getHost().content.actualWidth;
507		var hei = this.configuration['sender'].getHost().content.actualHeight;
508		var fss = this.configuration['sender'].getHost().content.FullScreen;
509		if(this.configuration['shownavigation'] == 'true') {
510			if(fss == true) {
511				this.resizeDisplay(wid,hei);
512				this.controlbar['Canvas.Left'] = Math.round(wid/2-250);
513				this.resizeControlbar(500,hei-this.controlbar.Height-16);
514				this.controlbar.findName('ControlbarBack')['Opacity'] = 0.5;
515			} else {
516				this.resizeDisplay(wid,hei-20);
517				this.controlbar['Canvas.Left'] = 0;
518				this.resizeControlbar(wid,hei-this.controlbar.Height);
519				this.controlbar.findName('ControlbarBack')['Opacity'] = 1;
520			}
521		} else {
522			this.resizeDisplay(wid,hei);
523		}
524	},
525
526	resizeDisplay: function(wid,hei) {
527		this.stretchElement('PlayerDisplay',wid,hei);
528		this.stretchElement('VideoWindow',wid,hei);
529		this.stretchElement('PlaceholderImage',wid,hei);
530		this.centerElement('PlayIcon',wid,hei);
531		this.centerElement('MuteIcon',wid,hei);
532		this.centerElement('BufferIcon',wid,hei);
533		this.centerElement('BufferText',wid,hei);
534		this.display.findName('OverlayCanvas')['Canvas.Left'] = wid -
535			this.display.findName('OverlayCanvas').Width - 10;
536		this.display.Visibility = "Visible";
537	},
538
539	resizeControlbar: function(wid,yps,alp) {
540		this.controlbar['Canvas.Top'] = yps;
541		this.stretchElement('PlayerControls',wid);
542		this.stretchElement('ControlbarBack',wid);
543		this.placeElement('PlayButton',0);
544		var lft = 17;
545		this.placeElement('VolumeButton',wid-24);
546		this.placeElement('MuteButton',wid-37);
547		var rgt = 37;
548		if(this.configuration['showstop'] == 'true') {
549			this.placeElement('StopButton',lft);
550			lft += 17;
551		} else {
552			this.controlbar.findName('StopButton').Visibility="Collapsed";
553		}
554		if(this.configuration['usefullscreen'] == 'true') {
555			rgt += 18;
556			this.placeElement('FullscreenButton',wid-rgt);
557		} else {
558			this.controlbar.findName('FullscreenButton').Visibility =
559				"Collapsed";
560		}
561		if(this.configuration['link'] != '') {
562			rgt += 18;
563			this.placeElement('LinkButton',wid-rgt);
564		} else {
565			this.controlbar.findName('LinkButton').Visibility="Collapsed";
566		}
567		if(this.configuration['showdigits'] == 'true' && wid-rgt-lft> 160) {
568			rgt += 35;
569			this.controlbar.findName('RemainingButton').Visibility="Visible";
570			this.controlbar.findName('ElapsedButton').Visibility="Visible";
571			this.placeElement('RemainingButton',wid-rgt);
572			this.placeElement('ElapsedButton',lft);
573			lft +=35;
574		} else {
575			this.controlbar.findName('RemainingButton').Visibility =
576				"Collapsed";
577			this.controlbar.findName('ElapsedButton').Visibility="Collapsed";
578		}
579		this.placeElement('TimeButton',lft);
580		this.stretchElement('TimeButton',wid-lft-rgt);
581		this.stretchElement('TimeShadow',wid-lft-rgt);
582		this.stretchElement('TimeStroke',wid-lft-rgt);
583		this.stretchElement('TimeFill',wid-lft-rgt);
584		this.stretchElement('TimeSlider',wid-lft-rgt-10);
585		this.stretchElement('DownloadProgress',wid-lft-rgt-10);
586		var tsb = this.configuration['sender'].findName('TimeSymbol');
587		this.stretchElement('TimeHighlight',tsb['Canvas.Left']-5);
588		this.controlbar.Visibility = "Visible";
589	},
590
591	centerElement: function(nam,wid,hei) {
592		var elm = this.configuration['sender'].findName(nam);
593		elm['Canvas.Left'] = Math.round(wid/2 - elm.Width/2);
594		elm['Canvas.Top'] = Math.round(hei/2 - elm.Height/2);
595	},
596
597	stretchElement: function(nam,wid,hei) {
598		var elm = this.configuration['sender'].findName(nam);
599		elm.Width = wid;
600		if (hei != undefined) { elm.Height = hei; }
601	},
602
603	placeElement: function(nam,xps,yps) {
604		var elm = this.configuration['sender'].findName(nam);
605		elm['Canvas.Left'] = xps;
606		if(yps) { elm['Canvas.Top'] = yps; }
607	}
608}
609
610/****************************************************************************
611* The model of the player MVC triad, which stores all playback logic.
612****************************************************************************/
613jeroenwijering.Model = function(cfg,ctr,vie) {
614	this.configuration = cfg;
615	this.controller = ctr;
616	this.view = vie;
617	this.video = this.configuration['sender'].findName("VideoWindow");
618	this.preview = this.configuration['sender'].findName("PlaceholderImage");
619	var str = {
620		'true':'UniformToFill',
621		'false':'Uniform',
622		'fit':'Fill',
623		'none':'None'
624	}
625	this.state = this.video.CurrentState;
626	this.timeint;
627	this.video.Stretch = str[this.configuration['overstretch']];
628	this.preview.Stretch = str[this.configuration['overstretch']];
629	this.video.BufferingTime =
630		jeroenwijering.utils.spanstring(this.configuration['bufferlength']);
631	this.video.AutoPlay = true;
632	this.video.AddEventListener("CurrentStateChanged",
633		jeroenwijering.utils.delegate(this,this.stateChanged));
634	this.video.AddEventListener("MediaEnded",
635		jeroenwijering.utils.delegate(this,this.mediaEnded));
636	this.video.AddEventListener("BufferingProgressChanged",
637		jeroenwijering.utils.delegate(this,this.bufferChanged));
638	this.video.AddEventListener("DownloadProgressChanged",
639		jeroenwijering.utils.delegate(this,this.downloadChanged));
640	if(this.configuration['image'] != '') {
641		this.preview.Source = this.configuration['image'];
642	}
643}
644
645jeroenwijering.Model.prototype = {
646	goPause: function(sec) {
647		this.video.pause();
648		if(!isNaN(sec)) {
649			this.video.Position = jeroenwijering.utils.spanstring(sec);
650		}
651		this.timeChanged();
652	},
653
654	goStart: function(sec) {
655		this.video.Visibility = 'Visible';
656		this.preview.Visibility = 'Collapsed';
657		if(this.state == "Closed") {
658			this.video.Source = this.configuration['file'];
659		} else {
660			this.video.play();
661		}
662		if(!isNaN(sec)) {
663			this.video.Position = jeroenwijering.utils.spanstring(sec);
664		}
665	},
666
667	goStop: function() {
668		this.video.Visibility = 'Collapsed';
669		this.preview.Visibility = 'Visible';
670		this.goPause(0);
671		this.video.Source = 'null';
672		this.view.onBuffer(0);
673		clearInterval(this.timeint);
674	},
675
676	goVolume: function(pct) {
677		this.video.Volume = pct/100;
678	},
679
680	stateChanged: function() {
681		var stt = this.video.CurrentState;
682		if(stt != this.state) {
683			this.controller.setState(this.state,stt);
684			this.view.onState(this.state,stt);
685			this.state = stt;
686			this.configuration['duration'] =
687				Math.round(this.video.NaturalDuration.Seconds*10)/10;
688			if(stt != "Playing" && stt != "Buffering" && stt != "Opening") {
689				clearInterval(this.timeint);
690			} else {
691				this.timeint = setInterval(jeroenwijering.utils.delegate(
692					this,this.timeChanged),100);
693			}
694		}
695	},
696
697	mediaEnded: function() {
698		if(this.configuration['repeat'] == 'true') {
699			this.goStart(0);
700		} else {
701			this.state = 'Completed';
702			this.view.onState(this.state,'Completed');
703			this.video.Visibility = 'Collapsed';
704			this.preview.Visibility = 'Visible';
705			this.goPause(0);
706		}
707	},
708
709	bufferChanged: function() {
710		var bfr = Math.round(this.video.BufferingProgress*100);
711		this.view.onBuffer(bfr);
712	},
713
714	downloadChanged: function() {
715		var dld = Math.round(this.video.DownloadProgress*100);
716		this.view.onLoad(dld);
717	},
718
719	timeChanged: function() {
720		var pos = Math.round(this.video.Position.Seconds*10)/10;
721		this.view.onTime(pos,this.configuration['duration']);
722	}
723}
724
725/****************************************************************************
726* Some utility functions.
727****************************************************************************/
728jeroenwijering.utils.delegate = function(obj,fcn) {
729	return function() {
730		return fcn.apply(obj,arguments);
731	}
732}
733jeroenwijering.utils.timestring = function(stp) {
734	var hrs = Math.floor(stp/3600);
735	var min = Math.floor(stp%3600/60);
736	var sec = Math.round(stp%60);
737	var str = "";
738	sec > 9 ? str += sec: str +='0'+sec;
739	min > 9 ? str = min+":"+str: str='0'+min+":"+str;
740	hrs > 0 ? str = hrs+":"+str: null;
741	return str;
742}
743jeroenwijering.utils.spanstring = function(stp) {
744	var hrs = Math.floor(stp/3600);
745	var min = Math.floor(stp%3600/60);
746	var sec = Math.round(stp%60*10)/10;
747	var str = hrs+':'+min+':'+sec;
748	return str;
749}

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.