|
0
|
1 |
/*
|
|
|
2 |
*
|
|
|
3 |
* Copyright 2010 Institut de recherche et d'innovation
|
|
|
4 |
* contributor(s) : Samuel Huron
|
|
|
5 |
*
|
|
|
6 |
* contact@iri.centrepompidou.fr
|
|
|
7 |
* http://www.iri.centrepompidou.fr
|
|
|
8 |
*
|
|
|
9 |
* This software is a computer program whose purpose is to show and add annotations on a video .
|
|
|
10 |
* This software is governed by the CeCILL-C license under French law and
|
|
|
11 |
* abiding by the rules of distribution of free software. You can use,
|
|
|
12 |
* modify and/ or redistribute the software under the terms of the CeCILL-C
|
|
|
13 |
* license as circulated by CEA, CNRS and INRIA at the following URL
|
|
|
14 |
* "http://www.cecill.info".
|
|
|
15 |
*
|
|
|
16 |
* The fact that you are presently reading this means that you have had
|
|
|
17 |
* knowledge of the CeCILL-C license and that you accept its terms.
|
|
|
18 |
*/
|
|
|
19 |
(function(global, document) {
|
|
|
20 |
|
|
|
21 |
// Popcorn.js does not support archaic browsers
|
|
|
22 |
if ( !document.addEventListener ) {
|
|
|
23 |
global.Popcorn = {
|
|
|
24 |
isSupported: false
|
|
|
25 |
};
|
|
|
26 |
|
|
|
27 |
var methods = ( "forEach extend effects error guid sizeOf isArray nop position disable enable destroy " +
|
|
|
28 |
"addTrackEvent removeTrackEvent getTrackEvents getTrackEvent getLastTrackEventId " +
|
|
|
29 |
"timeUpdate plugin removePlugin compose effect parser xhr getJSONP getScript" ).split(/\s+/);
|
|
|
30 |
|
|
|
31 |
while ( methods.length ) {
|
|
|
32 |
global.Popcorn[ methods.shift() ] = function() {};
|
|
|
33 |
}
|
|
|
34 |
return;
|
|
|
35 |
}
|
|
|
36 |
|
|
|
37 |
var
|
|
|
38 |
|
|
|
39 |
AP = Array.prototype,
|
|
|
40 |
OP = Object.prototype,
|
|
|
41 |
|
|
|
42 |
forEach = AP.forEach,
|
|
|
43 |
slice = AP.slice,
|
|
|
44 |
hasOwn = OP.hasOwnProperty,
|
|
|
45 |
toString = OP.toString,
|
|
|
46 |
|
|
|
47 |
// Copy global Popcorn (may not exist)
|
|
|
48 |
_Popcorn = global.Popcorn,
|
|
|
49 |
|
|
|
50 |
// ID string matching
|
|
|
51 |
rIdExp = /^(#([\w\-\_\.]+))$/,
|
|
|
52 |
|
|
|
53 |
// Ready fn cache
|
|
|
54 |
readyStack = [],
|
|
|
55 |
readyBound = false,
|
|
|
56 |
readyFired = false,
|
|
|
57 |
|
|
|
58 |
// Non-public internal data object
|
|
|
59 |
internal = {
|
|
|
60 |
events: {
|
|
|
61 |
hash: {},
|
|
|
62 |
apis: {}
|
|
|
63 |
}
|
|
|
64 |
},
|
|
|
65 |
|
|
|
66 |
// Non-public `requestAnimFrame`
|
|
|
67 |
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
|
|
|
68 |
requestAnimFrame = (function(){
|
|
|
69 |
return global.requestAnimationFrame ||
|
|
|
70 |
global.webkitRequestAnimationFrame ||
|
|
|
71 |
global.mozRequestAnimationFrame ||
|
|
|
72 |
global.oRequestAnimationFrame ||
|
|
|
73 |
global.msRequestAnimationFrame ||
|
|
|
74 |
function( callback, element ) {
|
|
|
75 |
global.setTimeout( callback, 16 );
|
|
|
76 |
};
|
|
|
77 |
}()),
|
|
|
78 |
|
|
|
79 |
refresh = function( obj ) {
|
|
|
80 |
var currentTime = obj.media.currentTime,
|
|
|
81 |
animation = obj.options.frameAnimation,
|
|
|
82 |
disabled = obj.data.disabled,
|
|
|
83 |
tracks = obj.data.trackEvents,
|
|
|
84 |
animating = tracks.animating,
|
|
|
85 |
start = tracks.startIndex,
|
|
|
86 |
registryByName = Popcorn.registryByName,
|
|
|
87 |
animIndex = 0,
|
|
|
88 |
byStart, natives, type;
|
|
|
89 |
|
|
|
90 |
start = Math.min( start + 1, tracks.byStart.length - 2 );
|
|
|
91 |
|
|
|
92 |
while ( start > 0 && tracks.byStart[ start ] ) {
|
|
|
93 |
|
|
|
94 |
byStart = tracks.byStart[ start ];
|
|
|
95 |
natives = byStart._natives;
|
|
|
96 |
type = natives && natives.type;
|
|
|
97 |
|
|
|
98 |
if ( !natives ||
|
|
|
99 |
( !!registryByName[ type ] || !!obj[ type ] ) ) {
|
|
|
100 |
|
|
|
101 |
if ( ( byStart.start <= currentTime && byStart.end > currentTime ) &&
|
|
|
102 |
disabled.indexOf( type ) === -1 ) {
|
|
|
103 |
|
|
|
104 |
if ( !byStart._running ) {
|
|
|
105 |
byStart._running = true;
|
|
|
106 |
natives.start.call( obj, null, byStart );
|
|
|
107 |
|
|
|
108 |
// if the 'frameAnimation' option is used,
|
|
|
109 |
// push the current byStart object into the `animating` cue
|
|
|
110 |
if ( animation &&
|
|
|
111 |
( byStart && byStart._running && byStart.natives.frame ) ) {
|
|
|
112 |
|
|
|
113 |
natives.frame.call( obj, null, byStart, currentTime );
|
|
|
114 |
}
|
|
|
115 |
}
|
|
|
116 |
} else if ( byStart._running === true ) {
|
|
|
117 |
|
|
|
118 |
byStart._running = false;
|
|
|
119 |
natives.end.call( obj, null, byStart );
|
|
|
120 |
|
|
|
121 |
if ( animation && byStart._natives.frame ) {
|
|
|
122 |
animIndex = animating.indexOf( byStart );
|
|
|
123 |
if ( animIndex >= 0 ) {
|
|
|
124 |
animating.splice( animIndex, 1 );
|
|
|
125 |
}
|
|
|
126 |
}
|
|
|
127 |
}
|
|
|
128 |
}
|
|
|
129 |
|
|
|
130 |
start--;
|
|
|
131 |
}
|
|
|
132 |
},
|
|
|
133 |
|
|
|
134 |
// Declare constructor
|
|
|
135 |
// Returns an instance object.
|
|
|
136 |
Popcorn = function( entity, options ) {
|
|
|
137 |
// Return new Popcorn object
|
|
|
138 |
return new Popcorn.p.init( entity, options || null );
|
|
|
139 |
};
|
|
|
140 |
|
|
|
141 |
// Popcorn API version, automatically inserted via build system.
|
|
|
142 |
Popcorn.version = "@VERSION";
|
|
|
143 |
|
|
|
144 |
// Boolean flag allowing a client to determine if Popcorn can be supported
|
|
|
145 |
Popcorn.isSupported = true;
|
|
|
146 |
|
|
|
147 |
// Instance caching
|
|
|
148 |
Popcorn.instances = [];
|
|
|
149 |
|
|
|
150 |
// Declare a shortcut (Popcorn.p) to and a definition of
|
|
|
151 |
// the new prototype for our Popcorn constructor
|
|
|
152 |
Popcorn.p = Popcorn.prototype = {
|
|
|
153 |
|
|
|
154 |
init: function( entity, options ) {
|
|
|
155 |
|
|
|
156 |
var matches;
|
|
|
157 |
|
|
|
158 |
// Supports Popcorn(function () { /../ })
|
|
|
159 |
// Originally proposed by Daniel Brooks
|
|
|
160 |
|
|
|
161 |
if ( typeof entity === "function" ) {
|
|
|
162 |
|
|
|
163 |
// If document ready has already fired
|
|
|
164 |
if ( document.readyState === "interactive" || document.readyState === "complete" ) {
|
|
|
165 |
|
|
|
166 |
entity( document, Popcorn );
|
|
|
167 |
|
|
|
168 |
return;
|
|
|
169 |
}
|
|
|
170 |
// Add `entity` fn to ready stack
|
|
|
171 |
readyStack.push( entity );
|
|
|
172 |
|
|
|
173 |
// This process should happen once per page load
|
|
|
174 |
if ( !readyBound ) {
|
|
|
175 |
|
|
|
176 |
// set readyBound flag
|
|
|
177 |
readyBound = true;
|
|
|
178 |
|
|
|
179 |
var DOMContentLoaded = function() {
|
|
|
180 |
|
|
|
181 |
readyFired = true;
|
|
|
182 |
|
|
|
183 |
// Remove global DOM ready listener
|
|
|
184 |
document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
|
|
|
185 |
|
|
|
186 |
// Execute all ready function in the stack
|
|
|
187 |
for ( var i = 0, readyStackLength = readyStack.length; i < readyStackLength; i++ ) {
|
|
|
188 |
|
|
|
189 |
readyStack[ i ].call( document, Popcorn );
|
|
|
190 |
|
|
|
191 |
}
|
|
|
192 |
// GC readyStack
|
|
|
193 |
readyStack = null;
|
|
|
194 |
};
|
|
|
195 |
|
|
|
196 |
// Register global DOM ready listener
|
|
|
197 |
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
|
|
|
198 |
}
|
|
|
199 |
|
|
|
200 |
return;
|
|
|
201 |
}
|
|
|
202 |
|
|
|
203 |
// Check if entity is a valid string id
|
|
|
204 |
matches = rIdExp.exec( entity );
|
|
|
205 |
|
|
|
206 |
// Get media element by id or object reference
|
|
|
207 |
this.media = matches && matches.length && matches[ 2 ] ?
|
|
|
208 |
document.getElementById( matches[ 2 ] ) :
|
|
|
209 |
entity;
|
|
|
210 |
|
|
|
211 |
// Create an audio or video element property reference
|
|
|
212 |
this[ ( this.media.nodeName && this.media.nodeName.toLowerCase() ) || "video" ] = this.media;
|
|
|
213 |
|
|
|
214 |
// Register new instance
|
|
|
215 |
Popcorn.instances.push( this );
|
|
|
216 |
|
|
|
217 |
this.options = options || {};
|
|
|
218 |
|
|
|
219 |
this.isDestroyed = false;
|
|
|
220 |
|
|
|
221 |
this.data = {
|
|
|
222 |
|
|
|
223 |
// Executed by either timeupdate event or in rAF loop
|
|
|
224 |
timeUpdate: Popcorn.nop,
|
|
|
225 |
|
|
|
226 |
// Allows disabling a plugin per instance
|
|
|
227 |
disabled: [],
|
|
|
228 |
|
|
|
229 |
// Stores DOM event queues by type
|
|
|
230 |
events: {},
|
|
|
231 |
|
|
|
232 |
// Stores Special event hooks data
|
|
|
233 |
hooks: {},
|
|
|
234 |
|
|
|
235 |
// Store track event history data
|
|
|
236 |
history: [],
|
|
|
237 |
|
|
|
238 |
// Stores ad-hoc state related data]
|
|
|
239 |
state: {
|
|
|
240 |
volume: this.media.volume
|
|
|
241 |
},
|
|
|
242 |
|
|
|
243 |
// Store track event object references by trackId
|
|
|
244 |
trackRefs: {},
|
|
|
245 |
|
|
|
246 |
// Playback track event queues
|
|
|
247 |
trackEvents: {
|
|
|
248 |
byStart: [{
|
|
|
249 |
|
|
|
250 |
start: -1,
|
|
|
251 |
end: -1
|
|
|
252 |
}],
|
|
|
253 |
byEnd: [{
|
|
|
254 |
start: -1,
|
|
|
255 |
end: -1
|
|
|
256 |
}],
|
|
|
257 |
animating: [],
|
|
|
258 |
startIndex: 0,
|
|
|
259 |
endIndex: 0,
|
|
|
260 |
previousUpdateTime: -1
|
|
|
261 |
}
|
|
|
262 |
};
|
|
|
263 |
|
|
|
264 |
// Wrap true ready check
|
|
|
265 |
var isReady = function( that ) {
|
|
|
266 |
|
|
|
267 |
var duration, videoDurationPlus;
|
|
|
268 |
|
|
|
269 |
if ( that.media.readyState >= 2 ) {
|
|
|
270 |
// Adding padding to the front and end of the arrays
|
|
|
271 |
// this is so we do not fall off either end
|
|
|
272 |
|
|
|
273 |
duration = that.media.duration;
|
|
|
274 |
// Check for no duration info (NaN)
|
|
|
275 |
videoDurationPlus = duration != duration ? Number.MAX_VALUE : duration + 1;
|
|
|
276 |
|
|
|
277 |
Popcorn.addTrackEvent( that, {
|
|
|
278 |
start: videoDurationPlus,
|
|
|
279 |
end: videoDurationPlus
|
|
|
280 |
});
|
|
|
281 |
|
|
|
282 |
if ( that.options.frameAnimation ) {
|
|
|
283 |
// if Popcorn is created with frameAnimation option set to true,
|
|
|
284 |
// requestAnimFrame is used instead of "timeupdate" media event.
|
|
|
285 |
// This is for greater frame time accuracy, theoretically up to
|
|
|
286 |
// 60 frames per second as opposed to ~4 ( ~every 15-250ms)
|
|
|
287 |
that.data.timeUpdate = function () {
|
|
|
288 |
|
|
|
289 |
Popcorn.timeUpdate( that, {} );
|
|
|
290 |
|
|
|
291 |
that.trigger( "timeupdate" );
|
|
|
292 |
|
|
|
293 |
!that.isDestroyed && requestAnimFrame( that.data.timeUpdate );
|
|
|
294 |
};
|
|
|
295 |
|
|
|
296 |
!that.isDestroyed && requestAnimFrame( that.data.timeUpdate );
|
|
|
297 |
|
|
|
298 |
} else {
|
|
|
299 |
|
|
|
300 |
that.data.timeUpdate = function( event ) {
|
|
|
301 |
Popcorn.timeUpdate( that, event );
|
|
|
302 |
};
|
|
|
303 |
|
|
|
304 |
if ( !that.isDestroyed ) {
|
|
|
305 |
that.media.addEventListener( "timeupdate", that.data.timeUpdate, false );
|
|
|
306 |
}
|
|
|
307 |
}
|
|
|
308 |
} else {
|
|
|
309 |
global.setTimeout(function() {
|
|
|
310 |
isReady( that );
|
|
|
311 |
}, 1 );
|
|
|
312 |
}
|
|
|
313 |
};
|
|
|
314 |
|
|
|
315 |
isReady( this );
|
|
|
316 |
|
|
|
317 |
return this;
|
|
|
318 |
}
|
|
|
319 |
};
|
|
|
320 |
|
|
|
321 |
// Extend constructor prototype to instance prototype
|
|
|
322 |
// Allows chaining methods to instances
|
|
|
323 |
Popcorn.p.init.prototype = Popcorn.p;
|
|
|
324 |
|
|
|
325 |
Popcorn.forEach = function( obj, fn, context ) {
|
|
|
326 |
|
|
|
327 |
if ( !obj || !fn ) {
|
|
|
328 |
return {};
|
|
|
329 |
}
|
|
|
330 |
|
|
|
331 |
context = context || this;
|
|
|
332 |
|
|
|
333 |
var key, len;
|
|
|
334 |
|
|
|
335 |
// Use native whenever possible
|
|
|
336 |
if ( forEach && obj.forEach === forEach ) {
|
|
|
337 |
return obj.forEach( fn, context );
|
|
|
338 |
}
|
|
|
339 |
|
|
|
340 |
if ( toString.call( obj ) === "[object NodeList]" ) {
|
|
|
341 |
for ( key = 0, len = obj.length; key < len; key++ ) {
|
|
|
342 |
fn.call( context, obj[ key ], key, obj );
|
|
|
343 |
}
|
|
|
344 |
return obj;
|
|
|
345 |
}
|
|
|
346 |
|
|
|
347 |
for ( key in obj ) {
|
|
|
348 |
if ( hasOwn.call( obj, key ) ) {
|
|
|
349 |
fn.call( context, obj[ key ], key, obj );
|
|
|
350 |
}
|
|
|
351 |
}
|
|
|
352 |
return obj;
|
|
|
353 |
};
|
|
|
354 |
|
|
|
355 |
Popcorn.extend = function( obj ) {
|
|
|
356 |
var dest = obj, src = slice.call( arguments, 1 );
|
|
|
357 |
|
|
|
358 |
Popcorn.forEach( src, function( copy ) {
|
|
|
359 |
for ( var prop in copy ) {
|
|
|
360 |
dest[ prop ] = copy[ prop ];
|
|
|
361 |
}
|
|
|
362 |
});
|
|
|
363 |
|
|
|
364 |
return dest;
|
|
|
365 |
};
|
|
|
366 |
|
|
|
367 |
|
|
|
368 |
// A Few reusable utils, memoized onto Popcorn
|
|
|
369 |
Popcorn.extend( Popcorn, {
|
|
|
370 |
noConflict: function( deep ) {
|
|
|
371 |
|
|
|
372 |
if ( deep ) {
|
|
|
373 |
global.Popcorn = _Popcorn;
|
|
|
374 |
}
|
|
|
375 |
|
|
|
376 |
return Popcorn;
|
|
|
377 |
},
|
|
|
378 |
error: function( msg ) {
|
|
|
379 |
throw new Error( msg );
|
|
|
380 |
},
|
|
|
381 |
guid: function( prefix ) {
|
|
|
382 |
Popcorn.guid.counter++;
|
|
|
383 |
return ( prefix ? prefix : "" ) + ( +new Date() + Popcorn.guid.counter );
|
|
|
384 |
},
|
|
|
385 |
sizeOf: function( obj ) {
|
|
|
386 |
var size = 0;
|
|
|
387 |
|
|
|
388 |
for ( var prop in obj ) {
|
|
|
389 |
size++;
|
|
|
390 |
}
|
|
|
391 |
|
|
|
392 |
return size;
|
|
|
393 |
},
|
|
|
394 |
isArray: Array.isArray || function( array ) {
|
|
|
395 |
return toString.call( array ) === "[object Array]";
|
|
|
396 |
},
|
|
|
397 |
|
|
|
398 |
nop: function() {},
|
|
|
399 |
|
|
|
400 |
position: function( elem ) {
|
|
|
401 |
|
|
|
402 |
var clientRect = elem.getBoundingClientRect(),
|
|
|
403 |
bounds = {},
|
|
|
404 |
doc = elem.ownerDocument,
|
|
|
405 |
docElem = document.documentElement,
|
|
|
406 |
body = document.body,
|
|
|
407 |
clientTop, clientLeft, scrollTop, scrollLeft, top, left;
|
|
|
408 |
|
|
|
409 |
// Determine correct clientTop/Left
|
|
|
410 |
clientTop = docElem.clientTop || body.clientTop || 0;
|
|
|
411 |
clientLeft = docElem.clientLeft || body.clientLeft || 0;
|
|
|
412 |
|
|
|
413 |
// Determine correct scrollTop/Left
|
|
|
414 |
scrollTop = ( global.pageYOffset && docElem.scrollTop || body.scrollTop );
|
|
|
415 |
scrollLeft = ( global.pageXOffset && docElem.scrollLeft || body.scrollLeft );
|
|
|
416 |
|
|
|
417 |
// Temp top/left
|
|
|
418 |
top = Math.ceil( clientRect.top + scrollTop - clientTop );
|
|
|
419 |
left = Math.ceil( clientRect.left + scrollLeft - clientLeft );
|
|
|
420 |
|
|
|
421 |
for ( var p in clientRect ) {
|
|
|
422 |
bounds[ p ] = Math.round( clientRect[ p ] );
|
|
|
423 |
}
|
|
|
424 |
|
|
|
425 |
return Popcorn.extend({}, bounds, { top: top, left: left });
|
|
|
426 |
},
|
|
|
427 |
|
|
|
428 |
disable: function( instance, plugin ) {
|
|
|
429 |
|
|
|
430 |
var disabled = instance.data.disabled;
|
|
|
431 |
|
|
|
432 |
if ( disabled.indexOf( plugin ) === -1 ) {
|
|
|
433 |
disabled.push( plugin );
|
|
|
434 |
}
|
|
|
435 |
|
|
|
436 |
refresh( instance );
|
|
|
437 |
|
|
|
438 |
return instance;
|
|
|
439 |
},
|
|
|
440 |
enable: function( instance, plugin ) {
|
|
|
441 |
|
|
|
442 |
var disabled = instance.data.disabled,
|
|
|
443 |
index = disabled.indexOf( plugin );
|
|
|
444 |
|
|
|
445 |
if ( index > -1 ) {
|
|
|
446 |
disabled.splice( index, 1 );
|
|
|
447 |
}
|
|
|
448 |
|
|
|
449 |
refresh( instance );
|
|
|
450 |
|
|
|
451 |
return instance;
|
|
|
452 |
},
|
|
|
453 |
destroy: function( instance ) {
|
|
|
454 |
var events = instance.data.events,
|
|
|
455 |
singleEvent, item, fn;
|
|
|
456 |
|
|
|
457 |
// Iterate through all events and remove them
|
|
|
458 |
for ( item in events ) {
|
|
|
459 |
singleEvent = events[ item ];
|
|
|
460 |
for ( fn in singleEvent ) {
|
|
|
461 |
delete singleEvent[ fn ];
|
|
|
462 |
}
|
|
|
463 |
events[ item ] = null;
|
|
|
464 |
}
|
|
|
465 |
|
|
|
466 |
if ( !instance.isDestroyed ) {
|
|
|
467 |
instance.data.timeUpdate && instance.media.removeEventListener( "timeupdate", instance.data.timeUpdate, false );
|
|
|
468 |
instance.isDestroyed = true;
|
|
|
469 |
}
|
|
|
470 |
}
|
|
|
471 |
});
|
|
|
472 |
|
|
|
473 |
// Memoized GUID Counter
|
|
|
474 |
Popcorn.guid.counter = 1;
|
|
|
475 |
|
|
|
476 |
// Factory to implement getters, setters and controllers
|
|
|
477 |
// as Popcorn instance methods. The IIFE will create and return
|
|
|
478 |
// an object with defined methods
|
|
|
479 |
Popcorn.extend(Popcorn.p, (function() {
|
|
|
480 |
|
|
|
481 |
var methods = "load play pause currentTime playbackRate volume duration preload playbackRate " +
|
|
|
482 |
"autoplay loop controls muted buffered readyState seeking paused played seekable ended",
|
|
|
483 |
ret = {};
|
|
|
484 |
|
|
|
485 |
|
|
|
486 |
// Build methods, store in object that is returned and passed to extend
|
|
|
487 |
Popcorn.forEach( methods.split( /\s+/g ), function( name ) {
|
|
|
488 |
|
|
|
489 |
ret[ name ] = function( arg ) {
|
|
|
490 |
|
|
|
491 |
if ( typeof this.media[ name ] === "function" ) {
|
|
|
492 |
|
|
|
493 |
// Support for shorthanded play(n)/pause(n) jump to currentTime
|
|
|
494 |
// If arg is not null or undefined and called by one of the
|
|
|
495 |
// allowed shorthandable methods, then set the currentTime
|
|
|
496 |
// Supports time as seconds or SMPTE
|
|
|
497 |
if ( arg != null && /play|pause/.test( name ) ) {
|
|
|
498 |
this.media.currentTime = Popcorn.util.toSeconds( arg );
|
|
|
499 |
}
|
|
|
500 |
|
|
|
501 |
this.media[ name ]();
|
|
|
502 |
|
|
|
503 |
return this;
|
|
|
504 |
}
|
|
|
505 |
|
|
|
506 |
|
|
|
507 |
if ( arg != null ) {
|
|
|
508 |
|
|
|
509 |
this.media[ name ] = arg;
|
|
|
510 |
|
|
|
511 |
return this;
|
|
|
512 |
}
|
|
|
513 |
|
|
|
514 |
return this.media[ name ];
|
|
|
515 |
};
|
|
|
516 |
});
|
|
|
517 |
|
|
|
518 |
return ret;
|
|
|
519 |
|
|
|
520 |
})()
|
|
|
521 |
);
|
|
|
522 |
|
|
|
523 |
Popcorn.forEach( "enable disable".split(" "), function( method ) {
|
|
|
524 |
Popcorn.p[ method ] = function( plugin ) {
|
|
|
525 |
return Popcorn[ method ]( this, plugin );
|
|
|
526 |
};
|
|
|
527 |
});
|
|
|
528 |
|
|
|
529 |
Popcorn.extend(Popcorn.p, {
|
|
|
530 |
|
|
|
531 |
// Rounded currentTime
|
|
|
532 |
roundTime: function() {
|
|
|
533 |
return -~this.media.currentTime;
|
|
|
534 |
},
|
|
|
535 |
|
|
|
536 |
// Attach an event to a single point in time
|
|
|
537 |
exec: function( time, fn ) {
|
|
|
538 |
|
|
|
539 |
// Creating a one second track event with an empty end
|
|
|
540 |
Popcorn.addTrackEvent( this, {
|
|
|
541 |
start: time,
|
|
|
542 |
end: time + 1,
|
|
|
543 |
_running: false,
|
|
|
544 |
_natives: {
|
|
|
545 |
start: fn || Popcorn.nop,
|
|
|
546 |
end: Popcorn.nop,
|
|
|
547 |
type: "exec"
|
|
|
548 |
}
|
|
|
549 |
});
|
|
|
550 |
|
|
|
551 |
return this;
|
|
|
552 |
},
|
|
|
553 |
|
|
|
554 |
// Mute the calling media, optionally toggle
|
|
|
555 |
mute: function( toggle ) {
|
|
|
556 |
|
|
|
557 |
var event = toggle == null || toggle === true ? "muted" : "unmuted";
|
|
|
558 |
|
|
|
559 |
// If `toggle` is explicitly `false`,
|
|
|
560 |
// unmute the media and restore the volume level
|
|
|
561 |
if ( event === "unmuted" ) {
|
|
|
562 |
this.media.muted = false;
|
|
|
563 |
this.media.volume = this.data.state.volume;
|
|
|
564 |
}
|
|
|
565 |
|
|
|
566 |
// If `toggle` is either null or undefined,
|
|
|
567 |
// save the current volume and mute the media element
|
|
|
568 |
if ( event === "muted" ) {
|
|
|
569 |
this.data.state.volume = this.media.volume;
|
|
|
570 |
this.media.muted = true;
|
|
|
571 |
}
|
|
|
572 |
|
|
|
573 |
// Trigger either muted|unmuted event
|
|
|
574 |
this.trigger( event );
|
|
|
575 |
|
|
|
576 |
return this;
|
|
|
577 |
},
|
|
|
578 |
|
|
|
579 |
// Convenience method, unmute the calling media
|
|
|
580 |
unmute: function( toggle ) {
|
|
|
581 |
|
|
|
582 |
return this.mute( toggle == null ? false : !toggle );
|
|
|
583 |
},
|
|
|
584 |
|
|
|
585 |
// Get the client bounding box of an instance element
|
|
|
586 |
position: function() {
|
|
|
587 |
return Popcorn.position( this.media );
|
|
|
588 |
},
|
|
|
589 |
|
|
|
590 |
// Toggle a plugin's playback behaviour (on or off) per instance
|
|
|
591 |
toggle: function( plugin ) {
|
|
|
592 |
return Popcorn[ this.data.disabled.indexOf( plugin ) > -1 ? "enable" : "disable" ]( this, plugin );
|
|
|
593 |
},
|
|
|
594 |
|
|
|
595 |
// Set default values for plugin options objects per instance
|
|
|
596 |
defaults: function( plugin, defaults ) {
|
|
|
597 |
|
|
|
598 |
// If an array of default configurations is provided,
|
|
|
599 |
// iterate and apply each to this instance
|
|
|
600 |
if ( Popcorn.isArray( plugin ) ) {
|
|
|
601 |
|
|
|
602 |
Popcorn.forEach( plugin, function( obj ) {
|
|
|
603 |
for ( var name in obj ) {
|
|
|
604 |
this.defaults( name, obj[ name ] );
|
|
|
605 |
}
|
|
|
606 |
}, this );
|
|
|
607 |
|
|
|
608 |
return this;
|
|
|
609 |
}
|
|
|
610 |
|
|
|
611 |
if ( !this.options.defaults ) {
|
|
|
612 |
this.options.defaults = {};
|
|
|
613 |
}
|
|
|
614 |
|
|
|
615 |
if ( !this.options.defaults[ plugin ] ) {
|
|
|
616 |
this.options.defaults[ plugin ] = {};
|
|
|
617 |
}
|
|
|
618 |
|
|
|
619 |
Popcorn.extend( this.options.defaults[ plugin ], defaults );
|
|
|
620 |
|
|
|
621 |
return this;
|
|
|
622 |
}
|
|
|
623 |
});
|
|
|
624 |
|
|
|
625 |
Popcorn.Events = {
|
|
|
626 |
UIEvents: "blur focus focusin focusout load resize scroll unload",
|
|
|
627 |
MouseEvents: "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave click dblclick",
|
|
|
628 |
Events: "loadstart progress suspend emptied stalled play pause " +
|
|
|
629 |
"loadedmetadata loadeddata waiting playing canplay canplaythrough " +
|
|
|
630 |
"seeking seeked timeupdate ended ratechange durationchange volumechange"
|
|
|
631 |
};
|
|
|
632 |
|
|
|
633 |
Popcorn.Events.Natives = Popcorn.Events.UIEvents + " " +
|
|
|
634 |
Popcorn.Events.MouseEvents + " " +
|
|
|
635 |
Popcorn.Events.Events;
|
|
|
636 |
|
|
|
637 |
internal.events.apiTypes = [ "UIEvents", "MouseEvents", "Events" ];
|
|
|
638 |
|
|
|
639 |
// Privately compile events table at load time
|
|
|
640 |
(function( events, data ) {
|
|
|
641 |
|
|
|
642 |
var apis = internal.events.apiTypes,
|
|
|
643 |
eventsList = events.Natives.split( /\s+/g ),
|
|
|
644 |
idx = 0, len = eventsList.length, prop;
|
|
|
645 |
|
|
|
646 |
for( ; idx < len; idx++ ) {
|
|
|
647 |
data.hash[ eventsList[idx] ] = true;
|
|
|
648 |
}
|
|
|
649 |
|
|
|
650 |
apis.forEach(function( val, idx ) {
|
|
|
651 |
|
|
|
652 |
data.apis[ val ] = {};
|
|
|
653 |
|
|
|
654 |
var apiEvents = events[ val ].split( /\s+/g ),
|
|
|
655 |
len = apiEvents.length,
|
|
|
656 |
k = 0;
|
|
|
657 |
|
|
|
658 |
for ( ; k < len; k++ ) {
|
|
|
659 |
data.apis[ val ][ apiEvents[ k ] ] = true;
|
|
|
660 |
}
|
|
|
661 |
});
|
|
|
662 |
})( Popcorn.Events, internal.events );
|
|
|
663 |
|
|
|
664 |
Popcorn.events = {
|
|
|
665 |
|
|
|
666 |
isNative: function( type ) {
|
|
|
667 |
return !!internal.events.hash[ type ];
|
|
|
668 |
},
|
|
|
669 |
getInterface: function( type ) {
|
|
|
670 |
|
|
|
671 |
if ( !Popcorn.events.isNative( type ) ) {
|
|
|
672 |
return false;
|
|
|
673 |
}
|
|
|
674 |
|
|
|
675 |
var eventApi = internal.events,
|
|
|
676 |
apis = eventApi.apiTypes,
|
|
|
677 |
apihash = eventApi.apis,
|
|
|
678 |
idx = 0, len = apis.length, api, tmp;
|
|
|
679 |
|
|
|
680 |
for ( ; idx < len; idx++ ) {
|
|
|
681 |
tmp = apis[ idx ];
|
|
|
682 |
|
|
|
683 |
if ( apihash[ tmp ][ type ] ) {
|
|
|
684 |
api = tmp;
|
|
|
685 |
break;
|
|
|
686 |
}
|
|
|
687 |
}
|
|
|
688 |
return api;
|
|
|
689 |
},
|
|
|
690 |
// Compile all native events to single array
|
|
|
691 |
all: Popcorn.Events.Natives.split( /\s+/g ),
|
|
|
692 |
// Defines all Event handling static functions
|
|
|
693 |
fn: {
|
|
|
694 |
trigger: function( type, data ) {
|
|
|
695 |
|
|
|
696 |
var eventInterface, evt;
|
|
|
697 |
// setup checks for custom event system
|
|
|
698 |
if ( this.data.events[ type ] && Popcorn.sizeOf( this.data.events[ type ] ) ) {
|
|
|
699 |
|
|
|
700 |
eventInterface = Popcorn.events.getInterface( type );
|
|
|
701 |
|
|
|
702 |
if ( eventInterface ) {
|
|
|
703 |
|
|
|
704 |
evt = document.createEvent( eventInterface );
|
|
|
705 |
evt.initEvent( type, true, true, global, 1 );
|
|
|
706 |
|
|
|
707 |
this.media.dispatchEvent( evt );
|
|
|
708 |
|
|
|
709 |
return this;
|
|
|
710 |
}
|
|
|
711 |
|
|
|
712 |
// Custom events
|
|
|
713 |
Popcorn.forEach( this.data.events[ type ], function( obj, key ) {
|
|
|
714 |
|
|
|
715 |
obj.call( this, data );
|
|
|
716 |
|
|
|
717 |
}, this );
|
|
|
718 |
|
|
|
719 |
}
|
|
|
720 |
|
|
|
721 |
return this;
|
|
|
722 |
},
|
|
|
723 |
listen: function( type, fn ) {
|
|
|
724 |
|
|
|
725 |
var self = this,
|
|
|
726 |
hasEvents = true,
|
|
|
727 |
eventHook = Popcorn.events.hooks[ type ],
|
|
|
728 |
origType = type,
|
|
|
729 |
tmp;
|
|
|
730 |
|
|
|
731 |
if ( !this.data.events[ type ] ) {
|
|
|
732 |
this.data.events[ type ] = {};
|
|
|
733 |
hasEvents = false;
|
|
|
734 |
}
|
|
|
735 |
|
|
|
736 |
// Check and setup event hooks
|
|
|
737 |
if ( eventHook ) {
|
|
|
738 |
|
|
|
739 |
// Execute hook add method if defined
|
|
|
740 |
if ( eventHook.add ) {
|
|
|
741 |
eventHook.add.call( this, {}, fn );
|
|
|
742 |
}
|
|
|
743 |
|
|
|
744 |
// Reassign event type to our piggyback event type if defined
|
|
|
745 |
if ( eventHook.bind ) {
|
|
|
746 |
type = eventHook.bind;
|
|
|
747 |
}
|
|
|
748 |
|
|
|
749 |
// Reassign handler if defined
|
|
|
750 |
if ( eventHook.handler ) {
|
|
|
751 |
tmp = fn;
|
|
|
752 |
|
|
|
753 |
fn = function wrapper( event ) {
|
|
|
754 |
eventHook.handler.call( self, event, tmp );
|
|
|
755 |
};
|
|
|
756 |
}
|
|
|
757 |
|
|
|
758 |
// assume the piggy back event is registered
|
|
|
759 |
hasEvents = true;
|
|
|
760 |
|
|
|
761 |
// Setup event registry entry
|
|
|
762 |
if ( !this.data.events[ type ] ) {
|
|
|
763 |
this.data.events[ type ] = {};
|
|
|
764 |
// Toggle if the previous assumption was untrue
|
|
|
765 |
hasEvents = false;
|
|
|
766 |
}
|
|
|
767 |
}
|
|
|
768 |
|
|
|
769 |
// Register event and handler
|
|
|
770 |
this.data.events[ type ][ fn.name || ( fn.toString() + Popcorn.guid() ) ] = fn;
|
|
|
771 |
|
|
|
772 |
// only attach one event of any type
|
|
|
773 |
if ( !hasEvents && Popcorn.events.all.indexOf( type ) > -1 ) {
|
|
|
774 |
|
|
|
775 |
this.media.addEventListener( type, function( event ) {
|
|
|
776 |
|
|
|
777 |
Popcorn.forEach( self.data.events[ type ], function( obj, key ) {
|
|
|
778 |
if ( typeof obj === "function" ) {
|
|
|
779 |
obj.call( self, event );
|
|
|
780 |
}
|
|
|
781 |
});
|
|
|
782 |
|
|
|
783 |
}, false);
|
|
|
784 |
}
|
|
|
785 |
return this;
|
|
|
786 |
},
|
|
|
787 |
unlisten: function( type, fn ) {
|
|
|
788 |
|
|
|
789 |
if ( this.data.events[ type ] && this.data.events[ type ][ fn ] ) {
|
|
|
790 |
|
|
|
791 |
delete this.data.events[ type ][ fn ];
|
|
|
792 |
|
|
|
793 |
return this;
|
|
|
794 |
}
|
|
|
795 |
|
|
|
796 |
this.data.events[ type ] = null;
|
|
|
797 |
|
|
|
798 |
return this;
|
|
|
799 |
}
|
|
|
800 |
},
|
|
|
801 |
hooks: {
|
|
|
802 |
canplayall: {
|
|
|
803 |
bind: "canplaythrough",
|
|
|
804 |
add: function( event, callback ) {
|
|
|
805 |
|
|
|
806 |
var state = false;
|
|
|
807 |
|
|
|
808 |
if ( this.media.readyState ) {
|
|
|
809 |
|
|
|
810 |
callback.call( this, event );
|
|
|
811 |
|
|
|
812 |
state = true;
|
|
|
813 |
}
|
|
|
814 |
|
|
|
815 |
this.data.hooks.canplayall = {
|
|
|
816 |
fired: state
|
|
|
817 |
};
|
|
|
818 |
},
|
|
|
819 |
// declare special handling instructions
|
|
|
820 |
handler: function canplayall( event, callback ) {
|
|
|
821 |
|
|
|
822 |
if ( !this.data.hooks.canplayall.fired ) {
|
|
|
823 |
// trigger original user callback once
|
|
|
824 |
callback.call( this, event );
|
|
|
825 |
|
|
|
826 |
this.data.hooks.canplayall.fired = true;
|
|
|
827 |
}
|
|
|
828 |
}
|
|
|
829 |
}
|
|
|
830 |
}
|
|
|
831 |
};
|
|
|
832 |
|
|
|
833 |
// Extend Popcorn.events.fns (listen, unlisten, trigger) to all Popcorn instances
|
|
|
834 |
Popcorn.forEach( [ "trigger", "listen", "unlisten" ], function( key ) {
|
|
|
835 |
Popcorn.p[ key ] = Popcorn.events.fn[ key ];
|
|
|
836 |
});
|
|
|
837 |
|
|
|
838 |
// Internal Only - Adds track events to the instance object
|
|
|
839 |
Popcorn.addTrackEvent = function( obj, track ) {
|
|
|
840 |
|
|
|
841 |
// Determine if this track has default options set for it
|
|
|
842 |
// If so, apply them to the track object
|
|
|
843 |
if ( track && track._natives && track._natives.type &&
|
|
|
844 |
( obj.options.defaults && obj.options.defaults[ track._natives.type ] ) ) {
|
|
|
845 |
|
|
|
846 |
track = Popcorn.extend( {}, obj.options.defaults[ track._natives.type ], track );
|
|
|
847 |
}
|
|
|
848 |
|
|
|
849 |
if ( track._natives ) {
|
|
|
850 |
// Supports user defined track event id
|
|
|
851 |
track._id = !track.id ? Popcorn.guid( track._natives.type ) : track.id;
|
|
|
852 |
|
|
|
853 |
// Push track event ids into the history
|
|
|
854 |
obj.data.history.push( track._id );
|
|
|
855 |
}
|
|
|
856 |
|
|
|
857 |
track.start = Popcorn.util.toSeconds( track.start, obj.options.framerate );
|
|
|
858 |
track.end = Popcorn.util.toSeconds( track.end, obj.options.framerate );
|
|
|
859 |
|
|
|
860 |
// Store this definition in an array sorted by times
|
|
|
861 |
var byStart = obj.data.trackEvents.byStart,
|
|
|
862 |
byEnd = obj.data.trackEvents.byEnd,
|
|
|
863 |
startIndex, endIndex,
|
|
|
864 |
currentTime;
|
|
|
865 |
|
|
|
866 |
for ( startIndex = byStart.length - 1; startIndex >= 0; startIndex-- ) {
|
|
|
867 |
|
|
|
868 |
if ( track.start >= byStart[ startIndex ].start ) {
|
|
|
869 |
byStart.splice( startIndex + 1, 0, track );
|
|
|
870 |
break;
|
|
|
871 |
}
|
|
|
872 |
}
|
|
|
873 |
|
|
|
874 |
for ( endIndex = byEnd.length - 1; endIndex >= 0; endIndex-- ) {
|
|
|
875 |
|
|
|
876 |
if ( track.end > byEnd[ endIndex ].end ) {
|
|
|
877 |
byEnd.splice( endIndex + 1, 0, track );
|
|
|
878 |
break;
|
|
|
879 |
}
|
|
|
880 |
}
|
|
|
881 |
|
|
|
882 |
// Display track event immediately if it's enabled and current
|
|
|
883 |
if ( track._natives &&
|
|
|
884 |
( !!Popcorn.registryByName[ track._natives.type ] || !!obj[ track._natives.type ] ) ) {
|
|
|
885 |
|
|
|
886 |
currentTime = obj.media.currentTime;
|
|
|
887 |
if ( track.end > currentTime &&
|
|
|
888 |
track.start <= currentTime &&
|
|
|
889 |
obj.data.disabled.indexOf( track._natives.type ) === -1 ) {
|
|
|
890 |
|
|
|
891 |
track._running = true;
|
|
|
892 |
track._natives.start.call( obj, null, track );
|
|
|
893 |
|
|
|
894 |
if ( obj.options.frameAnimation &&
|
|
|
895 |
track._natives.frame ) {
|
|
|
896 |
|
|
|
897 |
obj.data.trackEvents.animating.push( track );
|
|
|
898 |
track._natives.frame.call( obj, null, track, currentTime );
|
|
|
899 |
}
|
|
|
900 |
}
|
|
|
901 |
}
|
|
|
902 |
|
|
|
903 |
// update startIndex and endIndex
|
|
|
904 |
if ( startIndex <= obj.data.trackEvents.startIndex &&
|
|
|
905 |
track.start <= obj.data.trackEvents.previousUpdateTime ) {
|
|
|
906 |
|
|
|
907 |
obj.data.trackEvents.startIndex++;
|
|
|
908 |
}
|
|
|
909 |
|
|
|
910 |
if ( endIndex <= obj.data.trackEvents.endIndex &&
|
|
|
911 |
track.end < obj.data.trackEvents.previousUpdateTime ) {
|
|
|
912 |
|
|
|
913 |
obj.data.trackEvents.endIndex++;
|
|
|
914 |
}
|
|
|
915 |
|
|
|
916 |
this.timeUpdate( obj, null, true );
|
|
|
917 |
|
|
|
918 |
// Store references to user added trackevents in ref table
|
|
|
919 |
if ( track._id ) {
|
|
|
920 |
Popcorn.addTrackEvent.ref( obj, track );
|
|
|
921 |
}
|
|
|
922 |
};
|
|
|
923 |
|
|
|
924 |
// Internal Only - Adds track event references to the instance object's trackRefs hash table
|
|
|
925 |
Popcorn.addTrackEvent.ref = function( obj, track ) {
|
|
|
926 |
obj.data.trackRefs[ track._id ] = track;
|
|
|
927 |
|
|
|
928 |
return obj;
|
|
|
929 |
};
|
|
|
930 |
|
|
|
931 |
Popcorn.removeTrackEvent = function( obj, trackId ) {
|
|
|
932 |
|
|
|
933 |
var historyLen = obj.data.history.length,
|
|
|
934 |
indexWasAt = 0,
|
|
|
935 |
byStart = [],
|
|
|
936 |
byEnd = [],
|
|
|
937 |
animating = [],
|
|
|
938 |
history = [];
|
|
|
939 |
|
|
|
940 |
Popcorn.forEach( obj.data.trackEvents.byStart, function( o, i, context ) {
|
|
|
941 |
// Preserve the original start/end trackEvents
|
|
|
942 |
if ( !o._id ) {
|
|
|
943 |
byStart.push( obj.data.trackEvents.byStart[i] );
|
|
|
944 |
byEnd.push( obj.data.trackEvents.byEnd[i] );
|
|
|
945 |
}
|
|
|
946 |
|
|
|
947 |
// Filter for user track events (vs system track events)
|
|
|
948 |
if ( o._id ) {
|
|
|
949 |
|
|
|
950 |
// Filter for the trackevent to remove
|
|
|
951 |
if ( o._id !== trackId ) {
|
|
|
952 |
byStart.push( obj.data.trackEvents.byStart[i] );
|
|
|
953 |
byEnd.push( obj.data.trackEvents.byEnd[i] );
|
|
|
954 |
}
|
|
|
955 |
|
|
|
956 |
// Capture the position of the track being removed.
|
|
|
957 |
if ( o._id === trackId ) {
|
|
|
958 |
indexWasAt = i;
|
|
|
959 |
o._natives._teardown && o._natives._teardown.call( obj, o );
|
|
|
960 |
}
|
|
|
961 |
}
|
|
|
962 |
|
|
|
963 |
});
|
|
|
964 |
|
|
|
965 |
if ( obj.data.trackEvents.animating.length ) {
|
|
|
966 |
Popcorn.forEach( obj.data.trackEvents.animating, function( o, i, context ) {
|
|
|
967 |
// Preserve the original start/end trackEvents
|
|
|
968 |
if ( !o._id ) {
|
|
|
969 |
animating.push( obj.data.trackEvents.animating[i] );
|
|
|
970 |
}
|
|
|
971 |
|
|
|
972 |
// Filter for user track events (vs system track events)
|
|
|
973 |
if ( o._id ) {
|
|
|
974 |
// Filter for the trackevent to remove
|
|
|
975 |
if ( o._id !== trackId ) {
|
|
|
976 |
animating.push( obj.data.trackEvents.animating[i] );
|
|
|
977 |
}
|
|
|
978 |
}
|
|
|
979 |
});
|
|
|
980 |
}
|
|
|
981 |
|
|
|
982 |
// Update
|
|
|
983 |
if ( indexWasAt <= obj.data.trackEvents.startIndex ) {
|
|
|
984 |
obj.data.trackEvents.startIndex--;
|
|
|
985 |
}
|
|
|
986 |
|
|
|
987 |
if ( indexWasAt <= obj.data.trackEvents.endIndex ) {
|
|
|
988 |
obj.data.trackEvents.endIndex--;
|
|
|
989 |
}
|
|
|
990 |
|
|
|
991 |
obj.data.trackEvents.byStart = byStart;
|
|
|
992 |
obj.data.trackEvents.byEnd = byEnd;
|
|
|
993 |
obj.data.trackEvents.animating = animating;
|
|
|
994 |
|
|
|
995 |
for ( var i = 0; i < historyLen; i++ ) {
|
|
|
996 |
if ( obj.data.history[ i ] !== trackId ) {
|
|
|
997 |
history.push( obj.data.history[ i ] );
|
|
|
998 |
}
|
|
|
999 |
}
|
|
|
1000 |
|
|
|
1001 |
// Update ordered history array
|
|
|
1002 |
obj.data.history = history;
|
|
|
1003 |
|
|
|
1004 |
// Update track event references
|
|
|
1005 |
Popcorn.removeTrackEvent.ref( obj, trackId );
|
|
|
1006 |
};
|
|
|
1007 |
|
|
|
1008 |
// Internal Only - Removes track event references from instance object's trackRefs hash table
|
|
|
1009 |
Popcorn.removeTrackEvent.ref = function( obj, trackId ) {
|
|
|
1010 |
delete obj.data.trackRefs[ trackId ];
|
|
|
1011 |
|
|
|
1012 |
return obj;
|
|
|
1013 |
};
|
|
|
1014 |
|
|
|
1015 |
// Return an array of track events bound to this instance object
|
|
|
1016 |
Popcorn.getTrackEvents = function( obj ) {
|
|
|
1017 |
|
|
|
1018 |
var trackevents = [],
|
|
|
1019 |
refs = obj.data.trackEvents.byStart,
|
|
|
1020 |
length = refs.length,
|
|
|
1021 |
idx = 0,
|
|
|
1022 |
ref;
|
|
|
1023 |
|
|
|
1024 |
for ( ; idx < length; idx++ ) {
|
|
|
1025 |
ref = refs[ idx ];
|
|
|
1026 |
// Return only user attributed track event references
|
|
|
1027 |
if ( ref._id ) {
|
|
|
1028 |
trackevents.push( ref );
|
|
|
1029 |
}
|
|
|
1030 |
}
|
|
|
1031 |
|
|
|
1032 |
return trackevents;
|
|
|
1033 |
};
|
|
|
1034 |
|
|
|
1035 |
// Internal Only - Returns an instance object's trackRefs hash table
|
|
|
1036 |
Popcorn.getTrackEvents.ref = function( obj ) {
|
|
|
1037 |
return obj.data.trackRefs;
|
|
|
1038 |
};
|
|
|
1039 |
|
|
|
1040 |
// Return a single track event bound to this instance object
|
|
|
1041 |
Popcorn.getTrackEvent = function( obj, trackId ) {
|
|
|
1042 |
return obj.data.trackRefs[ trackId ];
|
|
|
1043 |
};
|
|
|
1044 |
|
|
|
1045 |
// Internal Only - Returns an instance object's track reference by track id
|
|
|
1046 |
Popcorn.getTrackEvent.ref = function( obj, trackId ) {
|
|
|
1047 |
return obj.data.trackRefs[ trackId ];
|
|
|
1048 |
};
|
|
|
1049 |
|
|
|
1050 |
Popcorn.getLastTrackEventId = function( obj ) {
|
|
|
1051 |
return obj.data.history[ obj.data.history.length - 1 ];
|
|
|
1052 |
};
|
|
|
1053 |
|
|
|
1054 |
Popcorn.timeUpdate = function( obj, event ) {
|
|
|
1055 |
|
|
|
1056 |
var currentTime = obj.media.currentTime,
|
|
|
1057 |
previousTime = obj.data.trackEvents.previousUpdateTime,
|
|
|
1058 |
tracks = obj.data.trackEvents,
|
|
|
1059 |
animating = tracks.animating,
|
|
|
1060 |
end = tracks.endIndex,
|
|
|
1061 |
start = tracks.startIndex,
|
|
|
1062 |
animIndex = 0,
|
|
|
1063 |
|
|
|
1064 |
registryByName = Popcorn.registryByName,
|
|
|
1065 |
|
|
|
1066 |
byEnd, byStart, byAnimate, natives, type;
|
|
|
1067 |
|
|
|
1068 |
// Playbar advancing
|
|
|
1069 |
if ( previousTime <= currentTime ) {
|
|
|
1070 |
|
|
|
1071 |
while ( tracks.byEnd[ end ] && tracks.byEnd[ end ].end <= currentTime ) {
|
|
|
1072 |
|
|
|
1073 |
byEnd = tracks.byEnd[ end ];
|
|
|
1074 |
natives = byEnd._natives;
|
|
|
1075 |
type = natives && natives.type;
|
|
|
1076 |
|
|
|
1077 |
// If plugin does not exist on this instance, remove it
|
|
|
1078 |
if ( !natives ||
|
|
|
1079 |
( !!registryByName[ type ] ||
|
|
|
1080 |
!!obj[ type ] ) ) {
|
|
|
1081 |
|
|
|
1082 |
if ( byEnd._running === true ) {
|
|
|
1083 |
byEnd._running = false;
|
|
|
1084 |
natives.end.call( obj, event, byEnd );
|
|
|
1085 |
}
|
|
|
1086 |
|
|
|
1087 |
end++;
|
|
|
1088 |
} else {
|
|
|
1089 |
// remove track event
|
|
|
1090 |
Popcorn.removeTrackEvent( obj, byEnd._id );
|
|
|
1091 |
return;
|
|
|
1092 |
}
|
|
|
1093 |
}
|
|
|
1094 |
|
|
|
1095 |
while ( tracks.byStart[ start ] && tracks.byStart[ start ].start <= currentTime ) {
|
|
|
1096 |
|
|
|
1097 |
byStart = tracks.byStart[ start ];
|
|
|
1098 |
natives = byStart._natives;
|
|
|
1099 |
type = natives && natives.type;
|
|
|
1100 |
|
|
|
1101 |
// If plugin does not exist on this instance, remove it
|
|
|
1102 |
if ( !natives ||
|
|
|
1103 |
( !!registryByName[ type ] ||
|
|
|
1104 |
!!obj[ type ] ) ) {
|
|
|
1105 |
|
|
|
1106 |
if ( byStart.end > currentTime &&
|
|
|
1107 |
byStart._running === false &&
|
|
|
1108 |
obj.data.disabled.indexOf( type ) === -1 ) {
|
|
|
1109 |
|
|
|
1110 |
byStart._running = true;
|
|
|
1111 |
natives.start.call( obj, event, byStart );
|
|
|
1112 |
|
|
|
1113 |
// If the `frameAnimation` option is used,
|
|
|
1114 |
// push the current byStart object into the `animating` cue
|
|
|
1115 |
if ( obj.options.frameAnimation &&
|
|
|
1116 |
( byStart && byStart._running && byStart._natives.frame ) ) {
|
|
|
1117 |
|
|
|
1118 |
animating.push( byStart );
|
|
|
1119 |
}
|
|
|
1120 |
}
|
|
|
1121 |
start++;
|
|
|
1122 |
} else {
|
|
|
1123 |
// remove track event
|
|
|
1124 |
Popcorn.removeTrackEvent( obj, byStart._id );
|
|
|
1125 |
return;
|
|
|
1126 |
}
|
|
|
1127 |
}
|
|
|
1128 |
|
|
|
1129 |
// If the `frameAnimation` option is used, iterate the animating track
|
|
|
1130 |
// and execute the `frame` callback
|
|
|
1131 |
if ( obj.options.frameAnimation ) {
|
|
|
1132 |
while ( animIndex < animating.length ) {
|
|
|
1133 |
|
|
|
1134 |
byAnimate = animating[ animIndex ];
|
|
|
1135 |
|
|
|
1136 |
if ( !byAnimate._running ) {
|
|
|
1137 |
animating.splice( animIndex, 1 );
|
|
|
1138 |
} else {
|
|
|
1139 |
byAnimate._natives.frame.call( obj, event, byAnimate, currentTime );
|
|
|
1140 |
animIndex++;
|
|
|
1141 |
}
|
|
|
1142 |
}
|
|
|
1143 |
}
|
|
|
1144 |
|
|
|
1145 |
// Playbar receding
|
|
|
1146 |
} else if ( previousTime > currentTime ) {
|
|
|
1147 |
|
|
|
1148 |
while ( tracks.byStart[ start ] && tracks.byStart[ start ].start > currentTime ) {
|
|
|
1149 |
|
|
|
1150 |
byStart = tracks.byStart[ start ];
|
|
|
1151 |
natives = byStart._natives;
|
|
|
1152 |
type = natives && natives.type;
|
|
|
1153 |
|
|
|
1154 |
// if plugin does not exist on this instance, remove it
|
|
|
1155 |
if ( !natives ||
|
|
|
1156 |
( !!registryByName[ type ] ||
|
|
|
1157 |
!!obj[ type ] ) ) {
|
|
|
1158 |
|
|
|
1159 |
if ( byStart._running === true ) {
|
|
|
1160 |
byStart._running = false;
|
|
|
1161 |
natives.end.call( obj, event, byStart );
|
|
|
1162 |
}
|
|
|
1163 |
start--;
|
|
|
1164 |
} else {
|
|
|
1165 |
// remove track event
|
|
|
1166 |
Popcorn.removeTrackEvent( obj, byStart._id );
|
|
|
1167 |
return;
|
|
|
1168 |
}
|
|
|
1169 |
}
|
|
|
1170 |
|
|
|
1171 |
while ( tracks.byEnd[ end ] && tracks.byEnd[ end ].end > currentTime ) {
|
|
|
1172 |
|
|
|
1173 |
byEnd = tracks.byEnd[ end ];
|
|
|
1174 |
natives = byEnd._natives;
|
|
|
1175 |
type = natives && natives.type;
|
|
|
1176 |
|
|
|
1177 |
// if plugin does not exist on this instance, remove it
|
|
|
1178 |
if ( !natives ||
|
|
|
1179 |
( !!registryByName[ type ] ||
|
|
|
1180 |
!!obj[ type ] ) ) {
|
|
|
1181 |
|
|
|
1182 |
if ( byEnd.start <= currentTime &&
|
|
|
1183 |
byEnd._running === false &&
|
|
|
1184 |
obj.data.disabled.indexOf( type ) === -1 ) {
|
|
|
1185 |
|
|
|
1186 |
byEnd._running = true;
|
|
|
1187 |
natives.start.call( obj, event, byEnd );
|
|
|
1188 |
|
|
|
1189 |
// If the `frameAnimation` option is used,
|
|
|
1190 |
// push the current byEnd object into the `animating` cue
|
|
|
1191 |
if ( obj.options.frameAnimation &&
|
|
|
1192 |
( byEnd && byEnd._running && byEnd._natives.frame ) ) {
|
|
|
1193 |
|
|
|
1194 |
animating.push( byEnd );
|
|
|
1195 |
}
|
|
|
1196 |
}
|
|
|
1197 |
end--;
|
|
|
1198 |
} else {
|
|
|
1199 |
// remove track event
|
|
|
1200 |
Popcorn.removeTrackEvent( obj, byEnd._id );
|
|
|
1201 |
return;
|
|
|
1202 |
}
|
|
|
1203 |
}
|
|
|
1204 |
|
|
|
1205 |
// If the `frameAnimation` option is used, iterate the animating track
|
|
|
1206 |
// and execute the `frame` callback
|
|
|
1207 |
if ( obj.options.frameAnimation ) {
|
|
|
1208 |
while ( animIndex < animating.length ) {
|
|
|
1209 |
|
|
|
1210 |
byAnimate = animating[ animIndex ];
|
|
|
1211 |
|
|
|
1212 |
if ( !byAnimate._running ) {
|
|
|
1213 |
animating.splice( animIndex, 1 );
|
|
|
1214 |
} else {
|
|
|
1215 |
byAnimate._natives.frame.call( obj, event, byAnimate, currentTime );
|
|
|
1216 |
animIndex++;
|
|
|
1217 |
}
|
|
|
1218 |
}
|
|
|
1219 |
}
|
|
|
1220 |
// time bar is not moving ( video is paused )
|
|
|
1221 |
}
|
|
|
1222 |
|
|
|
1223 |
tracks.endIndex = end;
|
|
|
1224 |
tracks.startIndex = start;
|
|
|
1225 |
tracks.previousUpdateTime = currentTime;
|
|
|
1226 |
};
|
|
|
1227 |
|
|
|
1228 |
// Map and Extend TrackEvent functions to all Popcorn instances
|
|
|
1229 |
Popcorn.extend( Popcorn.p, {
|
|
|
1230 |
|
|
|
1231 |
getTrackEvents: function() {
|
|
|
1232 |
return Popcorn.getTrackEvents.call( null, this );
|
|
|
1233 |
},
|
|
|
1234 |
|
|
|
1235 |
getTrackEvent: function( id ) {
|
|
|
1236 |
return Popcorn.getTrackEvent.call( null, this, id );
|
|
|
1237 |
},
|
|
|
1238 |
|
|
|
1239 |
getLastTrackEventId: function() {
|
|
|
1240 |
return Popcorn.getLastTrackEventId.call( null, this );
|
|
|
1241 |
},
|
|
|
1242 |
|
|
|
1243 |
removeTrackEvent: function( id ) {
|
|
|
1244 |
|
|
|
1245 |
Popcorn.removeTrackEvent.call( null, this, id );
|
|
|
1246 |
return this;
|
|
|
1247 |
},
|
|
|
1248 |
|
|
|
1249 |
removePlugin: function( name ) {
|
|
|
1250 |
Popcorn.removePlugin.call( null, this, name );
|
|
|
1251 |
return this;
|
|
|
1252 |
},
|
|
|
1253 |
|
|
|
1254 |
timeUpdate: function( event ) {
|
|
|
1255 |
Popcorn.timeUpdate.call( null, this, event );
|
|
|
1256 |
return this;
|
|
|
1257 |
},
|
|
|
1258 |
|
|
|
1259 |
destroy: function() {
|
|
|
1260 |
Popcorn.destroy.call( null, this );
|
|
|
1261 |
return this;
|
|
|
1262 |
}
|
|
|
1263 |
});
|
|
|
1264 |
|
|
|
1265 |
// Plugin manifests
|
|
|
1266 |
Popcorn.manifest = {};
|
|
|
1267 |
// Plugins are registered
|
|
|
1268 |
Popcorn.registry = [];
|
|
|
1269 |
Popcorn.registryByName = {};
|
|
|
1270 |
// An interface for extending Popcorn
|
|
|
1271 |
// with plugin functionality
|
|
|
1272 |
Popcorn.plugin = function( name, definition, manifest ) {
|
|
|
1273 |
|
|
|
1274 |
if ( Popcorn.protect.natives.indexOf( name.toLowerCase() ) >= 0 ) {
|
|
|
1275 |
Popcorn.error( "'" + name + "' is a protected function name" );
|
|
|
1276 |
return;
|
|
|
1277 |
}
|
|
|
1278 |
|
|
|
1279 |
// Provides some sugar, but ultimately extends
|
|
|
1280 |
// the definition into Popcorn.p
|
|
|
1281 |
var reserved = [ "start", "end" ],
|
|
|
1282 |
plugin = {},
|
|
|
1283 |
setup,
|
|
|
1284 |
isfn = typeof definition === "function",
|
|
|
1285 |
methods = [ "_setup", "_teardown", "start", "end", "frame" ];
|
|
|
1286 |
|
|
|
1287 |
// combines calls of two function calls into one
|
|
|
1288 |
var combineFn = function( first, second ) {
|
|
|
1289 |
|
|
|
1290 |
first = first || Popcorn.nop;
|
|
|
1291 |
second = second || Popcorn.nop;
|
|
|
1292 |
|
|
|
1293 |
return function() {
|
|
|
1294 |
first.apply( this, arguments );
|
|
|
1295 |
second.apply( this, arguments );
|
|
|
1296 |
};
|
|
|
1297 |
};
|
|
|
1298 |
|
|
|
1299 |
// If `manifest` arg is undefined, check for manifest within the `definition` object
|
|
|
1300 |
// If no `definition.manifest`, an empty object is a sufficient fallback
|
|
|
1301 |
Popcorn.manifest[ name ] = manifest = manifest || definition.manifest || {};
|
|
|
1302 |
|
|
|
1303 |
// apply safe, and empty default functions
|
|
|
1304 |
methods.forEach(function( method ) {
|
|
|
1305 |
definition[ method ] = safeTry( definition[ method ] || Popcorn.nop, name );
|
|
|
1306 |
});
|
|
|
1307 |
|
|
|
1308 |
var pluginFn = function( setup, options ) {
|
|
|
1309 |
|
|
|
1310 |
if ( !options ) {
|
|
|
1311 |
return this;
|
|
|
1312 |
}
|
|
|
1313 |
|
|
|
1314 |
// Storing the plugin natives
|
|
|
1315 |
var natives = options._natives = {},
|
|
|
1316 |
compose = "",
|
|
|
1317 |
defaults, originalOpts, manifestOpts, mergedSetupOpts;
|
|
|
1318 |
|
|
|
1319 |
Popcorn.extend( natives, setup );
|
|
|
1320 |
|
|
|
1321 |
options._natives.type = name;
|
|
|
1322 |
options._running = false;
|
|
|
1323 |
|
|
|
1324 |
natives.start = natives.start || natives[ "in" ];
|
|
|
1325 |
natives.end = natives.end || natives[ "out" ];
|
|
|
1326 |
|
|
|
1327 |
// extend teardown to always call end if running
|
|
|
1328 |
natives._teardown = combineFn(function() {
|
|
|
1329 |
|
|
|
1330 |
var args = slice.call( arguments );
|
|
|
1331 |
|
|
|
1332 |
// end function signature is not the same as teardown,
|
|
|
1333 |
// put null on the front of arguments for the event parameter
|
|
|
1334 |
args.unshift( null );
|
|
|
1335 |
|
|
|
1336 |
// only call end if event is running
|
|
|
1337 |
args[ 1 ]._running && natives.end.apply( this, args );
|
|
|
1338 |
}, natives._teardown );
|
|
|
1339 |
|
|
|
1340 |
// Check for previously set default options
|
|
|
1341 |
defaults = this.options.defaults && this.options.defaults[ options._natives && options._natives.type ];
|
|
|
1342 |
|
|
|
1343 |
// default to an empty string if no effect exists
|
|
|
1344 |
// split string into an array of effects
|
|
|
1345 |
options.compose = options.compose && options.compose.split( " " ) || [];
|
|
|
1346 |
options.effect = options.effect && options.effect.split( " " ) || [];
|
|
|
1347 |
|
|
|
1348 |
// join the two arrays together
|
|
|
1349 |
options.compose = options.compose.concat( options.effect );
|
|
|
1350 |
|
|
|
1351 |
options.compose.forEach(function( composeOption ) {
|
|
|
1352 |
|
|
|
1353 |
// if the requested compose is garbage, throw it away
|
|
|
1354 |
compose = Popcorn.compositions[ composeOption ] || {};
|
|
|
1355 |
|
|
|
1356 |
// extends previous functions with compose function
|
|
|
1357 |
methods.forEach(function( method ) {
|
|
|
1358 |
natives[ method ] = combineFn( natives[ method ], compose[ method ] );
|
|
|
1359 |
});
|
|
|
1360 |
});
|
|
|
1361 |
|
|
|
1362 |
// Ensure a manifest object, an empty object is a sufficient fallback
|
|
|
1363 |
options._natives.manifest = manifest;
|
|
|
1364 |
|
|
|
1365 |
// Checks for expected properties
|
|
|
1366 |
if ( !( "start" in options ) ) {
|
|
|
1367 |
options.start = options[ "in" ] || 0;
|
|
|
1368 |
}
|
|
|
1369 |
|
|
|
1370 |
if ( !( "end" in options ) ) {
|
|
|
1371 |
options.end = options[ "out" ] || this.duration() || Number.MAX_VALUE;
|
|
|
1372 |
}
|
|
|
1373 |
|
|
|
1374 |
// Merge with defaults if they exist, make sure per call is prioritized
|
|
|
1375 |
mergedSetupOpts = defaults ? Popcorn.extend( {}, defaults, options ) :
|
|
|
1376 |
options;
|
|
|
1377 |
|
|
|
1378 |
// Resolves 239, 241, 242
|
|
|
1379 |
if ( !mergedSetupOpts.target ) {
|
|
|
1380 |
|
|
|
1381 |
// Sometimes the manifest may be missing entirely
|
|
|
1382 |
// or it has an options object that doesn't have a `target` property
|
|
|
1383 |
manifestOpts = "options" in manifest && manifest.options;
|
|
|
1384 |
|
|
|
1385 |
mergedSetupOpts.target = manifestOpts && "target" in manifestOpts && manifestOpts.target;
|
|
|
1386 |
}
|
|
|
1387 |
|
|
|
1388 |
// Trigger _setup method if exists
|
|
|
1389 |
options._natives._setup && options._natives._setup.call( this, mergedSetupOpts );
|
|
|
1390 |
|
|
|
1391 |
// Create new track event for this instance
|
|
|
1392 |
Popcorn.addTrackEvent( this, Popcorn.extend( mergedSetupOpts, options ) );
|
|
|
1393 |
|
|
|
1394 |
// Future support for plugin event definitions
|
|
|
1395 |
// for all of the native events
|
|
|
1396 |
Popcorn.forEach( setup, function( callback, type ) {
|
|
|
1397 |
|
|
|
1398 |
if ( type !== "type" ) {
|
|
|
1399 |
|
|
|
1400 |
if ( reserved.indexOf( type ) === -1 ) {
|
|
|
1401 |
|
|
|
1402 |
this.listen( type, callback );
|
|
|
1403 |
}
|
|
|
1404 |
}
|
|
|
1405 |
|
|
|
1406 |
}, this );
|
|
|
1407 |
|
|
|
1408 |
return this;
|
|
|
1409 |
};
|
|
|
1410 |
|
|
|
1411 |
// Assign new named definition
|
|
|
1412 |
plugin[ name ] = function( options ) {
|
|
|
1413 |
return pluginFn.call( this, isfn ? definition.call( this, options ) : definition,
|
|
|
1414 |
options );
|
|
|
1415 |
};
|
|
|
1416 |
|
|
|
1417 |
// Extend Popcorn.p with new named definition
|
|
|
1418 |
Popcorn.extend( Popcorn.p, plugin );
|
|
|
1419 |
|
|
|
1420 |
// Push into the registry
|
|
|
1421 |
var entry = {
|
|
|
1422 |
fn: plugin[ name ],
|
|
|
1423 |
definition: definition,
|
|
|
1424 |
base: definition,
|
|
|
1425 |
parents: [],
|
|
|
1426 |
name: name
|
|
|
1427 |
};
|
|
|
1428 |
Popcorn.registry.push(
|
|
|
1429 |
Popcorn.extend( plugin, entry, {
|
|
|
1430 |
type: name
|
|
|
1431 |
})
|
|
|
1432 |
);
|
|
|
1433 |
Popcorn.registryByName[ name ] = entry;
|
|
|
1434 |
|
|
|
1435 |
return plugin;
|
|
|
1436 |
};
|
|
|
1437 |
|
|
|
1438 |
// Storage for plugin function errors
|
|
|
1439 |
Popcorn.plugin.errors = [];
|
|
|
1440 |
|
|
|
1441 |
// Returns wrapped plugin function
|
|
|
1442 |
function safeTry( fn, pluginName ) {
|
|
|
1443 |
return function() {
|
|
|
1444 |
|
|
|
1445 |
// When Popcorn.plugin.debug is true, do not suppress errors
|
|
|
1446 |
if ( Popcorn.plugin.debug ) {
|
|
|
1447 |
return fn.apply( this, arguments );
|
|
|
1448 |
}
|
|
|
1449 |
|
|
|
1450 |
try {
|
|
|
1451 |
return fn.apply( this, arguments );
|
|
|
1452 |
} catch ( ex ) {
|
|
|
1453 |
|
|
|
1454 |
// Push plugin function errors into logging queue
|
|
|
1455 |
Popcorn.plugin.errors.push({
|
|
|
1456 |
plugin: pluginName,
|
|
|
1457 |
thrown: ex,
|
|
|
1458 |
source: fn.toString()
|
|
|
1459 |
});
|
|
|
1460 |
|
|
|
1461 |
// Trigger an error that the instance can listen for
|
|
|
1462 |
// and react to
|
|
|
1463 |
this.trigger( "error", Popcorn.plugin.errors );
|
|
|
1464 |
}
|
|
|
1465 |
};
|
|
|
1466 |
}
|
|
|
1467 |
|
|
|
1468 |
// Debug-mode flag for plugin development
|
|
|
1469 |
Popcorn.plugin.debug = false;
|
|
|
1470 |
|
|
|
1471 |
// removePlugin( type ) removes all tracks of that from all instances of popcorn
|
|
|
1472 |
// removePlugin( obj, type ) removes all tracks of type from obj, where obj is a single instance of popcorn
|
|
|
1473 |
Popcorn.removePlugin = function( obj, name ) {
|
|
|
1474 |
|
|
|
1475 |
// Check if we are removing plugin from an instance or from all of Popcorn
|
|
|
1476 |
if ( !name ) {
|
|
|
1477 |
|
|
|
1478 |
// Fix the order
|
|
|
1479 |
name = obj;
|
|
|
1480 |
obj = Popcorn.p;
|
|
|
1481 |
|
|
|
1482 |
if ( Popcorn.protect.natives.indexOf( name.toLowerCase() ) >= 0 ) {
|
|
|
1483 |
Popcorn.error( "'" + name + "' is a protected function name" );
|
|
|
1484 |
return;
|
|
|
1485 |
}
|
|
|
1486 |
|
|
|
1487 |
var registryLen = Popcorn.registry.length,
|
|
|
1488 |
registryIdx;
|
|
|
1489 |
|
|
|
1490 |
// remove plugin reference from registry
|
|
|
1491 |
for ( registryIdx = 0; registryIdx < registryLen; registryIdx++ ) {
|
|
|
1492 |
if ( Popcorn.registry[ registryIdx ].name === name ) {
|
|
|
1493 |
Popcorn.registry.splice( registryIdx, 1 );
|
|
|
1494 |
delete Popcorn.registryByName[ name ];
|
|
|
1495 |
delete Popcorn.manifest[ name ];
|
|
|
1496 |
|
|
|
1497 |
// delete the plugin
|
|
|
1498 |
delete obj[ name ];
|
|
|
1499 |
|
|
|
1500 |
// plugin found and removed, stop checking, we are done
|
|
|
1501 |
return;
|
|
|
1502 |
}
|
|
|
1503 |
}
|
|
|
1504 |
|
|
|
1505 |
}
|
|
|
1506 |
|
|
|
1507 |
var byStart = obj.data.trackEvents.byStart,
|
|
|
1508 |
byEnd = obj.data.trackEvents.byEnd,
|
|
|
1509 |
animating = obj.data.trackEvents.animating,
|
|
|
1510 |
idx, sl;
|
|
|
1511 |
|
|
|
1512 |
// remove all trackEvents
|
|
|
1513 |
for ( idx = 0, sl = byStart.length; idx < sl; idx++ ) {
|
|
|
1514 |
|
|
|
1515 |
if ( ( byStart[ idx ] && byStart[ idx ]._natives && byStart[ idx ]._natives.type === name ) &&
|
|
|
1516 |
( byEnd[ idx ] && byEnd[ idx ]._natives && byEnd[ idx ]._natives.type === name ) ) {
|
|
|
1517 |
|
|
|
1518 |
byStart[ idx ]._natives._teardown && byStart[ idx ]._natives._teardown.call( obj, byStart[ idx ] );
|
|
|
1519 |
|
|
|
1520 |
byStart.splice( idx, 1 );
|
|
|
1521 |
byEnd.splice( idx, 1 );
|
|
|
1522 |
|
|
|
1523 |
// update for loop if something removed, but keep checking
|
|
|
1524 |
idx--; sl--;
|
|
|
1525 |
if ( obj.data.trackEvents.startIndex <= idx ) {
|
|
|
1526 |
obj.data.trackEvents.startIndex--;
|
|
|
1527 |
obj.data.trackEvents.endIndex--;
|
|
|
1528 |
}
|
|
|
1529 |
}
|
|
|
1530 |
}
|
|
|
1531 |
|
|
|
1532 |
//remove all animating events
|
|
|
1533 |
for ( idx = 0, sl = animating.length; idx < sl; idx++ ) {
|
|
|
1534 |
|
|
|
1535 |
if ( animating[ idx ] && animating[ idx ]._natives && animating[ idx ]._natives.type === name ) {
|
|
|
1536 |
|
|
|
1537 |
animating.splice( idx, 1 );
|
|
|
1538 |
|
|
|
1539 |
// update for loop if something removed, but keep checking
|
|
|
1540 |
idx--; sl--;
|
|
|
1541 |
}
|
|
|
1542 |
}
|
|
|
1543 |
|
|
|
1544 |
};
|
|
|
1545 |
|
|
|
1546 |
Popcorn.compositions = {};
|
|
|
1547 |
|
|
|
1548 |
// Plugin inheritance
|
|
|
1549 |
Popcorn.compose = function( name, definition, manifest ) {
|
|
|
1550 |
|
|
|
1551 |
// If `manifest` arg is undefined, check for manifest within the `definition` object
|
|
|
1552 |
// If no `definition.manifest`, an empty object is a sufficient fallback
|
|
|
1553 |
Popcorn.manifest[ name ] = manifest = manifest || definition.manifest || {};
|
|
|
1554 |
|
|
|
1555 |
// register the effect by name
|
|
|
1556 |
Popcorn.compositions[ name ] = definition;
|
|
|
1557 |
};
|
|
|
1558 |
|
|
|
1559 |
Popcorn.plugin.effect = Popcorn.effect = Popcorn.compose;
|
|
|
1560 |
|
|
|
1561 |
// stores parsers keyed on filetype
|
|
|
1562 |
Popcorn.parsers = {};
|
|
|
1563 |
|
|
|
1564 |
// An interface for extending Popcorn
|
|
|
1565 |
// with parser functionality
|
|
|
1566 |
Popcorn.parser = function( name, type, definition ) {
|
|
|
1567 |
|
|
|
1568 |
if ( Popcorn.protect.natives.indexOf( name.toLowerCase() ) >= 0 ) {
|
|
|
1569 |
Popcorn.error( "'" + name + "' is a protected function name" );
|
|
|
1570 |
return;
|
|
|
1571 |
}
|
|
|
1572 |
|
|
|
1573 |
// fixes parameters for overloaded function call
|
|
|
1574 |
if ( typeof type === "function" && !definition ) {
|
|
|
1575 |
definition = type;
|
|
|
1576 |
type = "";
|
|
|
1577 |
}
|
|
|
1578 |
|
|
|
1579 |
if ( typeof definition !== "function" || typeof type !== "string" ) {
|
|
|
1580 |
return;
|
|
|
1581 |
}
|
|
|
1582 |
|
|
|
1583 |
// Provides some sugar, but ultimately extends
|
|
|
1584 |
// the definition into Popcorn.p
|
|
|
1585 |
|
|
|
1586 |
var natives = Popcorn.events.all,
|
|
|
1587 |
parseFn,
|
|
|
1588 |
parser = {};
|
|
|
1589 |
|
|
|
1590 |
parseFn = function( filename, callback ) {
|
|
|
1591 |
|
|
|
1592 |
if ( !filename ) {
|
|
|
1593 |
return this;
|
|
|
1594 |
}
|
|
|
1595 |
|
|
|
1596 |
var that = this;
|
|
|
1597 |
|
|
|
1598 |
Popcorn.xhr({
|
|
|
1599 |
url: filename,
|
|
|
1600 |
dataType: type,
|
|
|
1601 |
success: function( data ) {
|
|
|
1602 |
|
|
|
1603 |
var tracksObject = definition( data ),
|
|
|
1604 |
tracksData,
|
|
|
1605 |
tracksDataLen,
|
|
|
1606 |
tracksDef,
|
|
|
1607 |
idx = 0;
|
|
|
1608 |
|
|
|
1609 |
tracksData = tracksObject.data || [];
|
|
|
1610 |
tracksDataLen = tracksData.length;
|
|
|
1611 |
tracksDef = null;
|
|
|
1612 |
|
|
|
1613 |
// If no tracks to process, return immediately
|
|
|
1614 |
if ( !tracksDataLen ) {
|
|
|
1615 |
return;
|
|
|
1616 |
}
|
|
|
1617 |
|
|
|
1618 |
// Create tracks out of parsed object
|
|
|
1619 |
for ( ; idx < tracksDataLen; idx++ ) {
|
|
|
1620 |
|
|
|
1621 |
tracksDef = tracksData[ idx ];
|
|
|
1622 |
|
|
|
1623 |
for ( var key in tracksDef ) {
|
|
|
1624 |
|
|
|
1625 |
if ( hasOwn.call( tracksDef, key ) && !!that[ key ] ) {
|
|
|
1626 |
|
|
|
1627 |
that[ key ]( tracksDef[ key ] );
|
|
|
1628 |
}
|
|
|
1629 |
}
|
|
|
1630 |
}
|
|
|
1631 |
if ( callback ) {
|
|
|
1632 |
callback();
|
|
|
1633 |
}
|
|
|
1634 |
}
|
|
|
1635 |
});
|
|
|
1636 |
|
|
|
1637 |
return this;
|
|
|
1638 |
};
|
|
|
1639 |
|
|
|
1640 |
// Assign new named definition
|
|
|
1641 |
parser[ name ] = parseFn;
|
|
|
1642 |
|
|
|
1643 |
// Extend Popcorn.p with new named definition
|
|
|
1644 |
Popcorn.extend( Popcorn.p, parser );
|
|
|
1645 |
|
|
|
1646 |
// keys the function name by filetype extension
|
|
|
1647 |
//Popcorn.parsers[ name ] = true;
|
|
|
1648 |
|
|
|
1649 |
return parser;
|
|
|
1650 |
};
|
|
|
1651 |
|
|
|
1652 |
Popcorn.player = function( name, player ) {
|
|
|
1653 |
|
|
|
1654 |
player = player || {};
|
|
|
1655 |
|
|
|
1656 |
var playerFn = function( target, src, options ) {
|
|
|
1657 |
|
|
|
1658 |
options = options || {};
|
|
|
1659 |
|
|
|
1660 |
// List of events
|
|
|
1661 |
var date = new Date() / 1000,
|
|
|
1662 |
baselineTime = date,
|
|
|
1663 |
currentTime = 0,
|
|
|
1664 |
volume = 1,
|
|
|
1665 |
muted = false,
|
|
|
1666 |
events = {},
|
|
|
1667 |
|
|
|
1668 |
// The container div of the resource
|
|
|
1669 |
container = document.getElementById( rIdExp.exec( target ) && rIdExp.exec( target )[ 2 ] ) ||
|
|
|
1670 |
document.getElementById( target ) ||
|
|
|
1671 |
target,
|
|
|
1672 |
basePlayer = {},
|
|
|
1673 |
timeout,
|
|
|
1674 |
popcorn;
|
|
|
1675 |
|
|
|
1676 |
// copies a div into the media object
|
|
|
1677 |
for( var val in container ) {
|
|
|
1678 |
|
|
|
1679 |
if ( typeof container[ val ] === "object" ) {
|
|
|
1680 |
|
|
|
1681 |
basePlayer[ val ] = container[ val ];
|
|
|
1682 |
} else if ( typeof container[ val ] === "function" ) {
|
|
|
1683 |
|
|
|
1684 |
basePlayer[ val ] = (function( value ) {
|
|
|
1685 |
|
|
|
1686 |
// this is a stupid ugly kludgy hack in honour of Safari
|
|
|
1687 |
// in Safari a NodeList is a function, not an object
|
|
|
1688 |
if ( "length" in container[ value ] && !container[ value ].call ) {
|
|
|
1689 |
|
|
|
1690 |
return container[ value ];
|
|
|
1691 |
} else {
|
|
|
1692 |
|
|
|
1693 |
return function() {
|
|
|
1694 |
|
|
|
1695 |
return container[ value ].apply( container, arguments );
|
|
|
1696 |
};
|
|
|
1697 |
}
|
|
|
1698 |
}( val ));
|
|
|
1699 |
} else {
|
|
|
1700 |
|
|
|
1701 |
Popcorn.player.defineProperty( basePlayer, val, {
|
|
|
1702 |
get: (function( value ) {
|
|
|
1703 |
|
|
|
1704 |
return function() {
|
|
|
1705 |
|
|
|
1706 |
return container[ value ];
|
|
|
1707 |
};
|
|
|
1708 |
}( val )),
|
|
|
1709 |
set: Popcorn.nop,
|
|
|
1710 |
configurable: true
|
|
|
1711 |
});
|
|
|
1712 |
}
|
|
|
1713 |
}
|
|
|
1714 |
|
|
|
1715 |
var timeupdate = function() {
|
|
|
1716 |
|
|
|
1717 |
date = new Date() / 1000;
|
|
|
1718 |
|
|
|
1719 |
if ( !basePlayer.paused ) {
|
|
|
1720 |
|
|
|
1721 |
basePlayer.currentTime = basePlayer.currentTime + ( date - baselineTime );
|
|
|
1722 |
basePlayer.dispatchEvent( "timeupdate" );
|
|
|
1723 |
timeout = setTimeout( timeupdate, 10 );
|
|
|
1724 |
}
|
|
|
1725 |
|
|
|
1726 |
baselineTime = date;
|
|
|
1727 |
};
|
|
|
1728 |
|
|
|
1729 |
basePlayer.play = function() {
|
|
|
1730 |
|
|
|
1731 |
this.paused = false;
|
|
|
1732 |
|
|
|
1733 |
if ( basePlayer.readyState >= 4 ) {
|
|
|
1734 |
|
|
|
1735 |
baselineTime = new Date() / 1000;
|
|
|
1736 |
basePlayer.dispatchEvent( "play" );
|
|
|
1737 |
timeupdate();
|
|
|
1738 |
}
|
|
|
1739 |
};
|
|
|
1740 |
|
|
|
1741 |
basePlayer.pause = function() {
|
|
|
1742 |
|
|
|
1743 |
this.paused = true;
|
|
|
1744 |
basePlayer.dispatchEvent( "pause" );
|
|
|
1745 |
};
|
|
|
1746 |
|
|
|
1747 |
Popcorn.player.defineProperty( basePlayer, "currentTime", {
|
|
|
1748 |
get: function() {
|
|
|
1749 |
|
|
|
1750 |
return currentTime;
|
|
|
1751 |
},
|
|
|
1752 |
set: function( val ) {
|
|
|
1753 |
|
|
|
1754 |
// make sure val is a number
|
|
|
1755 |
currentTime = +val;
|
|
|
1756 |
basePlayer.dispatchEvent( "timeupdate" );
|
|
|
1757 |
return currentTime;
|
|
|
1758 |
},
|
|
|
1759 |
configurable: true
|
|
|
1760 |
});
|
|
|
1761 |
|
|
|
1762 |
Popcorn.player.defineProperty( basePlayer, "volume", {
|
|
|
1763 |
get: function() {
|
|
|
1764 |
|
|
|
1765 |
return volume;
|
|
|
1766 |
},
|
|
|
1767 |
set: function( val ) {
|
|
|
1768 |
|
|
|
1769 |
// make sure val is a number
|
|
|
1770 |
volume = +val;
|
|
|
1771 |
basePlayer.dispatchEvent( "volumechange" );
|
|
|
1772 |
return volume;
|
|
|
1773 |
},
|
|
|
1774 |
configurable: true
|
|
|
1775 |
});
|
|
|
1776 |
|
|
|
1777 |
Popcorn.player.defineProperty( basePlayer, "muted", {
|
|
|
1778 |
get: function() {
|
|
|
1779 |
|
|
|
1780 |
return muted;
|
|
|
1781 |
},
|
|
|
1782 |
set: function( val ) {
|
|
|
1783 |
|
|
|
1784 |
// make sure val is a number
|
|
|
1785 |
muted = +val;
|
|
|
1786 |
basePlayer.dispatchEvent( "volumechange" );
|
|
|
1787 |
return muted;
|
|
|
1788 |
},
|
|
|
1789 |
configurable: true
|
|
|
1790 |
});
|
|
|
1791 |
|
|
|
1792 |
// Adds an event listener to the object
|
|
|
1793 |
basePlayer.addEventListener = function( evtName, fn ) {
|
|
|
1794 |
|
|
|
1795 |
if ( !events[ evtName ] ) {
|
|
|
1796 |
|
|
|
1797 |
events[ evtName ] = [];
|
|
|
1798 |
}
|
|
|
1799 |
|
|
|
1800 |
events[ evtName ].push( fn );
|
|
|
1801 |
return fn;
|
|
|
1802 |
};
|
|
|
1803 |
|
|
|
1804 |
// Can take event object or simple string
|
|
|
1805 |
basePlayer.dispatchEvent = function( oEvent ) {
|
|
|
1806 |
|
|
|
1807 |
var evt,
|
|
|
1808 |
self = this,
|
|
|
1809 |
eventInterface,
|
|
|
1810 |
eventName = oEvent.type;
|
|
|
1811 |
|
|
|
1812 |
// A string was passed, create event object
|
|
|
1813 |
if ( !eventName ) {
|
|
|
1814 |
|
|
|
1815 |
eventName = oEvent;
|
|
|
1816 |
eventInterface = Popcorn.events.getInterface( eventName );
|
|
|
1817 |
|
|
|
1818 |
if ( eventInterface ) {
|
|
|
1819 |
|
|
|
1820 |
evt = document.createEvent( eventInterface );
|
|
|
1821 |
evt.initEvent( eventName, true, true, window, 1 );
|
|
|
1822 |
}
|
|
|
1823 |
}
|
|
|
1824 |
|
|
|
1825 |
Popcorn.forEach( events[ eventName ], function( val ) {
|
|
|
1826 |
|
|
|
1827 |
val.call( self, evt, self );
|
|
|
1828 |
});
|
|
|
1829 |
};
|
|
|
1830 |
|
|
|
1831 |
// Attempt to get src from playerFn parameter
|
|
|
1832 |
basePlayer.src = src || "";
|
|
|
1833 |
basePlayer.readyState = 0;
|
|
|
1834 |
basePlayer.duration = 0;
|
|
|
1835 |
basePlayer.paused = true;
|
|
|
1836 |
basePlayer.ended = 0;
|
|
|
1837 |
|
|
|
1838 |
if ( player._setup ) {
|
|
|
1839 |
|
|
|
1840 |
player._setup.call( basePlayer, options );
|
|
|
1841 |
} else {
|
|
|
1842 |
|
|
|
1843 |
// there is no setup, which means there is nothing to load
|
|
|
1844 |
basePlayer.readyState = 4;
|
|
|
1845 |
basePlayer.dispatchEvent( "load" );
|
|
|
1846 |
basePlayer.dispatchEvent( "loadeddata" );
|
|
|
1847 |
}
|
|
|
1848 |
|
|
|
1849 |
// when a custom player is loaded, load basePlayer state into custom player
|
|
|
1850 |
basePlayer.addEventListener( "load", function() {
|
|
|
1851 |
|
|
|
1852 |
// if a player is not ready before currentTime is called, this will set it after it is ready
|
|
|
1853 |
basePlayer.currentTime = currentTime;
|
|
|
1854 |
|
|
|
1855 |
// same as above with volume and muted
|
|
|
1856 |
basePlayer.volume = volume;
|
|
|
1857 |
basePlayer.muted = muted;
|
|
|
1858 |
});
|
|
|
1859 |
|
|
|
1860 |
basePlayer.addEventListener( "loadeddata", function() {
|
|
|
1861 |
|
|
|
1862 |
// if play was called before player ready, start playing video
|
|
|
1863 |
!basePlayer.paused && basePlayer.play();
|
|
|
1864 |
});
|
|
|
1865 |
|
|
|
1866 |
popcorn = new Popcorn.p.init( basePlayer, options );
|
|
|
1867 |
|
|
|
1868 |
return popcorn;
|
|
|
1869 |
};
|
|
|
1870 |
|
|
|
1871 |
Popcorn[ name ] = Popcorn[ name ] || playerFn;
|
|
|
1872 |
};
|
|
|
1873 |
|
|
|
1874 |
Popcorn.player.defineProperty = Object.defineProperty || function( object, description, options ) {
|
|
|
1875 |
|
|
|
1876 |
object.__defineGetter__( description, options.get || Popcorn.nop );
|
|
|
1877 |
object.__defineSetter__( description, options.set || Popcorn.nop );
|
|
|
1878 |
};
|
|
|
1879 |
|
|
|
1880 |
// Cache references to reused RegExps
|
|
|
1881 |
var rparams = /\?/,
|
|
|
1882 |
// XHR Setup object
|
|
|
1883 |
setup = {
|
|
|
1884 |
url: "",
|
|
|
1885 |
data: "",
|
|
|
1886 |
dataType: "",
|
|
|
1887 |
success: Popcorn.nop,
|
|
|
1888 |
type: "GET",
|
|
|
1889 |
async: true,
|
|
|
1890 |
xhr: function() {
|
|
|
1891 |
return new global.XMLHttpRequest();
|
|
|
1892 |
}
|
|
|
1893 |
};
|
|
|
1894 |
|
|
|
1895 |
Popcorn.xhr = function( options ) {
|
|
|
1896 |
|
|
|
1897 |
options.dataType = options.dataType && options.dataType.toLowerCase() || null;
|
|
|
1898 |
|
|
|
1899 |
if ( options.dataType &&
|
|
|
1900 |
( options.dataType === "jsonp" || options.dataType === "script" ) ) {
|
|
|
1901 |
|
|
|
1902 |
Popcorn.xhr.getJSONP(
|
|
|
1903 |
options.url,
|
|
|
1904 |
options.success,
|
|
|
1905 |
options.dataType === "script"
|
|
|
1906 |
);
|
|
|
1907 |
return;
|
|
|
1908 |
}
|
|
|
1909 |
|
|
|
1910 |
var settings = Popcorn.extend( {}, setup, options );
|
|
|
1911 |
|
|
|
1912 |
// Create new XMLHttpRequest object
|
|
|
1913 |
settings.ajax = settings.xhr();
|
|
|
1914 |
|
|
|
1915 |
if ( settings.ajax ) {
|
|
|
1916 |
|
|
|
1917 |
if ( settings.type === "GET" && settings.data ) {
|
|
|
1918 |
|
|
|
1919 |
// append query string
|
|
|
1920 |
settings.url += ( rparams.test( settings.url ) ? "&" : "?" ) + settings.data;
|
|
|
1921 |
|
|
|
1922 |
// Garbage collect and reset settings.data
|
|
|
1923 |
settings.data = null;
|
|
|
1924 |
}
|
|
|
1925 |
|
|
|
1926 |
|
|
|
1927 |
settings.ajax.open( settings.type, settings.url, settings.async );
|
|
|
1928 |
settings.ajax.send( settings.data || null );
|
|
|
1929 |
|
|
|
1930 |
return Popcorn.xhr.httpData( settings );
|
|
|
1931 |
}
|
|
|
1932 |
};
|
|
|
1933 |
|
|
|
1934 |
|
|
|
1935 |
Popcorn.xhr.httpData = function( settings ) {
|
|
|
1936 |
|
|
|
1937 |
var data, json = null,
|
|
|
1938 |
parser, xml = null;
|
|
|
1939 |
|
|
|
1940 |
settings.ajax.onreadystatechange = function() {
|
|
|
1941 |
|
|
|
1942 |
if ( settings.ajax.readyState === 4 ) {
|
|
|
1943 |
|
|
|
1944 |
try {
|
|
|
1945 |
json = JSON.parse( settings.ajax.responseText );
|
|
|
1946 |
} catch( e ) {
|
|
|
1947 |
//suppress
|
|
|
1948 |
}
|
|
|
1949 |
|
|
|
1950 |
data = {
|
|
|
1951 |
xml: settings.ajax.responseXML,
|
|
|
1952 |
text: settings.ajax.responseText,
|
|
|
1953 |
json: json
|
|
|
1954 |
};
|
|
|
1955 |
|
|
|
1956 |
// Normalize: data.xml is non-null in IE9 regardless of if response is valid xml
|
|
|
1957 |
if ( !data.xml || !data.xml.documentElement ) {
|
|
|
1958 |
data.xml = null;
|
|
|
1959 |
|
|
|
1960 |
try {
|
|
|
1961 |
parser = new DOMParser();
|
|
|
1962 |
xml = parser.parseFromString( settings.ajax.responseText, "text/xml" );
|
|
|
1963 |
|
|
|
1964 |
if ( !xml.getElementsByTagName( "parsererror" ).length ) {
|
|
|
1965 |
data.xml = xml;
|
|
|
1966 |
}
|
|
|
1967 |
} catch ( e ) {
|
|
|
1968 |
// data.xml remains null
|
|
|
1969 |
}
|
|
|
1970 |
}
|
|
|
1971 |
|
|
|
1972 |
// If a dataType was specified, return that type of data
|
|
|
1973 |
if ( settings.dataType ) {
|
|
|
1974 |
data = data[ settings.dataType ];
|
|
|
1975 |
}
|
|
|
1976 |
|
|
|
1977 |
|
|
|
1978 |
settings.success.call( settings.ajax, data );
|
|
|
1979 |
|
|
|
1980 |
}
|
|
|
1981 |
};
|
|
|
1982 |
return data;
|
|
|
1983 |
};
|
|
|
1984 |
|
|
|
1985 |
Popcorn.xhr.getJSONP = function( url, success, isScript ) {
|
|
|
1986 |
|
|
|
1987 |
var head = document.head || document.getElementsByTagName( "head" )[ 0 ] || document.documentElement,
|
|
|
1988 |
script = document.createElement( "script" ),
|
|
|
1989 |
paramStr = url.split( "?" )[ 1 ],
|
|
|
1990 |
isFired = false,
|
|
|
1991 |
params = [],
|
|
|
1992 |
callback, parts, callparam;
|
|
|
1993 |
|
|
|
1994 |
if ( paramStr && !isScript ) {
|
|
|
1995 |
params = paramStr.split( "&" );
|
|
|
1996 |
}
|
|
|
1997 |
|
|
|
1998 |
if ( params.length ) {
|
|
|
1999 |
parts = params[ params.length - 1 ].split( "=" );
|
|
|
2000 |
}
|
|
|
2001 |
|
|
|
2002 |
callback = params.length ? ( parts[ 1 ] ? parts[ 1 ] : parts[ 0 ] ) : "jsonp";
|
|
|
2003 |
|
|
|
2004 |
if ( !paramStr && !isScript ) {
|
|
|
2005 |
url += "?callback=" + callback;
|
|
|
2006 |
}
|
|
|
2007 |
|
|
|
2008 |
if ( callback && !isScript ) {
|
|
|
2009 |
|
|
|
2010 |
// If a callback name already exists
|
|
|
2011 |
if ( !!window[ callback ] ) {
|
|
|
2012 |
// Create a new unique callback name
|
|
|
2013 |
callback = Popcorn.guid( callback );
|
|
|
2014 |
}
|
|
|
2015 |
|
|
|
2016 |
// Define the JSONP success callback globally
|
|
|
2017 |
window[ callback ] = function( data ) {
|
|
|
2018 |
// Fire success callbacks
|
|
|
2019 |
success && success( data );
|
|
|
2020 |
isFired = true;
|
|
|
2021 |
};
|
|
|
2022 |
|
|
|
2023 |
// Replace callback param and callback name
|
|
|
2024 |
url = url.replace( parts.join( "=" ), parts[ 0 ] + "=" + callback );
|
|
|
2025 |
}
|
|
|
2026 |
|
|
|
2027 |
script.onload = function() {
|
|
|
2028 |
|
|
|
2029 |
// Handling remote script loading callbacks
|
|
|
2030 |
if ( isScript ) {
|
|
|
2031 |
// getScript
|
|
|
2032 |
success && success();
|
|
|
2033 |
}
|
|
|
2034 |
|
|
|
2035 |
// Executing for JSONP requests
|
|
|
2036 |
if ( isFired ) {
|
|
|
2037 |
// Garbage collect the callback
|
|
|
2038 |
delete window[ callback ];
|
|
|
2039 |
}
|
|
|
2040 |
// Garbage collect the script resource
|
|
|
2041 |
head.removeChild( script );
|
|
|
2042 |
};
|
|
|
2043 |
|
|
|
2044 |
script.src = url;
|
|
|
2045 |
|
|
|
2046 |
head.insertBefore( script, head.firstChild );
|
|
|
2047 |
|
|
|
2048 |
return;
|
|
|
2049 |
};
|
|
|
2050 |
|
|
|
2051 |
Popcorn.getJSONP = Popcorn.xhr.getJSONP;
|
|
|
2052 |
|
|
|
2053 |
Popcorn.getScript = Popcorn.xhr.getScript = function( url, success ) {
|
|
|
2054 |
|
|
|
2055 |
return Popcorn.xhr.getJSONP( url, success, true );
|
|
|
2056 |
};
|
|
|
2057 |
|
|
|
2058 |
Popcorn.util = {
|
|
|
2059 |
// Simple function to parse a timestamp into seconds
|
|
|
2060 |
// Acceptable formats are:
|
|
|
2061 |
// HH:MM:SS.MMM
|
|
|
2062 |
// HH:MM:SS;FF
|
|
|
2063 |
// Hours and minutes are optional. They default to 0
|
|
|
2064 |
toSeconds: function( timeStr, framerate ) {
|
|
|
2065 |
// Hours and minutes are optional
|
|
|
2066 |
// Seconds must be specified
|
|
|
2067 |
// Seconds can be followed by milliseconds OR by the frame information
|
|
|
2068 |
var validTimeFormat = /^([0-9]+:){0,2}[0-9]+([.;][0-9]+)?$/,
|
|
|
2069 |
errorMessage = "Invalid time format",
|
|
|
2070 |
digitPairs, lastIndex, lastPair, firstPair,
|
|
|
2071 |
frameInfo, frameTime;
|
|
|
2072 |
|
|
|
2073 |
if ( typeof timeStr === "number" ) {
|
|
|
2074 |
return timeStr;
|
|
|
2075 |
}
|
|
|
2076 |
|
|
|
2077 |
if ( typeof timeStr === "string" &&
|
|
|
2078 |
!validTimeFormat.test( timeStr ) ) {
|
|
|
2079 |
Popcorn.error( errorMessage );
|
|
|
2080 |
}
|
|
|
2081 |
|
|
|
2082 |
digitPairs = timeStr.split( ":" );
|
|
|
2083 |
lastIndex = digitPairs.length - 1;
|
|
|
2084 |
lastPair = digitPairs[ lastIndex ];
|
|
|
2085 |
|
|
|
2086 |
// Fix last element:
|
|
|
2087 |
if ( lastPair.indexOf( ";" ) > -1 ) {
|
|
|
2088 |
|
|
|
2089 |
frameInfo = lastPair.split( ";" );
|
|
|
2090 |
frameTime = 0;
|
|
|
2091 |
|
|
|
2092 |
if ( framerate && ( typeof framerate === "number" ) ) {
|
|
|
2093 |
frameTime = parseFloat( frameInfo[ 1 ], 10 ) / framerate;
|
|
|
2094 |
}
|
|
|
2095 |
|
|
|
2096 |
digitPairs[ lastIndex ] = parseInt( frameInfo[ 0 ], 10 ) + frameTime;
|
|
|
2097 |
}
|
|
|
2098 |
|
|
|
2099 |
firstPair = digitPairs[ 0 ];
|
|
|
2100 |
|
|
|
2101 |
return {
|
|
|
2102 |
|
|
|
2103 |
1: parseFloat( firstPair, 10 ),
|
|
|
2104 |
|
|
|
2105 |
2: ( parseInt( firstPair, 10 ) * 60 ) +
|
|
|
2106 |
parseFloat( digitPairs[ 1 ], 10 ),
|
|
|
2107 |
|
|
|
2108 |
3: ( parseInt( firstPair, 10 ) * 3600 ) +
|
|
|
2109 |
( parseInt( digitPairs[ 1 ], 10 ) * 60 ) +
|
|
|
2110 |
parseFloat( digitPairs[ 2 ], 10 )
|
|
|
2111 |
|
|
|
2112 |
}[ digitPairs.length || 1 ];
|
|
|
2113 |
}
|
|
|
2114 |
};
|
|
|
2115 |
|
|
|
2116 |
|
|
|
2117 |
// Initialize locale data
|
|
|
2118 |
// Based on http://en.wikipedia.org/wiki/Language_localisation#Language_tags_and_codes
|
|
|
2119 |
function initLocale( arg ) {
|
|
|
2120 |
|
|
|
2121 |
var locale = typeof arg === "string" ? arg : [ arg.language, arg.region ].join( "-" ),
|
|
|
2122 |
parts = locale.split( "-" );
|
|
|
2123 |
|
|
|
2124 |
// Setup locale data table
|
|
|
2125 |
return {
|
|
|
2126 |
iso6391: locale,
|
|
|
2127 |
language: parts[ 0 ] || "",
|
|
|
2128 |
region: parts[ 1 ] || ""
|
|
|
2129 |
};
|
|
|
2130 |
}
|
|
|
2131 |
|
|
|
2132 |
// Declare locale data table
|
|
|
2133 |
var localeData = initLocale( global.navigator.userLanguage || global.navigator.language );
|
|
|
2134 |
|
|
|
2135 |
Popcorn.locale = {
|
|
|
2136 |
|
|
|
2137 |
// Popcorn.locale.get()
|
|
|
2138 |
// returns reference to privately
|
|
|
2139 |
// defined localeData
|
|
|
2140 |
get: function() {
|
|
|
2141 |
return localeData;
|
|
|
2142 |
},
|
|
|
2143 |
|
|
|
2144 |
// Popcorn.locale.set( string|object );
|
|
|
2145 |
set: function( arg ) {
|
|
|
2146 |
|
|
|
2147 |
localeData = initLocale( arg );
|
|
|
2148 |
|
|
|
2149 |
Popcorn.locale.broadcast();
|
|
|
2150 |
|
|
|
2151 |
return localeData;
|
|
|
2152 |
},
|
|
|
2153 |
|
|
|
2154 |
// Popcorn.locale.broadcast( type )
|
|
|
2155 |
// Sends events to all popcorn media instances that are
|
|
|
2156 |
// listening for locale events
|
|
|
2157 |
broadcast: function( type ) {
|
|
|
2158 |
|
|
|
2159 |
var instances = Popcorn.instances,
|
|
|
2160 |
length = instances.length,
|
|
|
2161 |
idx = 0,
|
|
|
2162 |
instance;
|
|
|
2163 |
|
|
|
2164 |
type = type || "locale:changed";
|
|
|
2165 |
|
|
|
2166 |
// Iterate all current instances
|
|
|
2167 |
for ( ; idx < length; idx++ ) {
|
|
|
2168 |
instance = instances[ idx ];
|
|
|
2169 |
|
|
|
2170 |
// For those instances with locale event listeners,
|
|
|
2171 |
// trigger a locale change event
|
|
|
2172 |
if ( type in instance.data.events ) {
|
|
|
2173 |
instance.trigger( type );
|
|
|
2174 |
}
|
|
|
2175 |
}
|
|
|
2176 |
}
|
|
|
2177 |
};
|
|
|
2178 |
|
|
|
2179 |
// alias for exec function
|
|
|
2180 |
Popcorn.p.cue = Popcorn.p.exec;
|
|
|
2181 |
|
|
|
2182 |
function getItems() {
|
|
|
2183 |
|
|
|
2184 |
var item,
|
|
|
2185 |
list = [];
|
|
|
2186 |
|
|
|
2187 |
if ( Object.keys ) {
|
|
|
2188 |
list = Object.keys( Popcorn.p );
|
|
|
2189 |
} else {
|
|
|
2190 |
|
|
|
2191 |
for ( item in Popcorn.p ) {
|
|
|
2192 |
if ( hasOwn.call( Popcorn.p, item ) ) {
|
|
|
2193 |
list.push( item );
|
|
|
2194 |
}
|
|
|
2195 |
}
|
|
|
2196 |
}
|
|
|
2197 |
|
|
|
2198 |
return list.join( "," ).toLowerCase().split( ",");
|
|
|
2199 |
}
|
|
|
2200 |
|
|
|
2201 |
// Protected API methods
|
|
|
2202 |
Popcorn.protect = {
|
|
|
2203 |
natives: getItems()
|
|
|
2204 |
};
|
|
|
2205 |
|
|
|
2206 |
// Exposes Popcorn to global context
|
|
|
2207 |
global.Popcorn = Popcorn;
|
|
|
2208 |
|
|
|
2209 |
})(window, window.document);
|
|
|
2210 |
// A global callback for youtube... that makes me angry
|
|
|
2211 |
var onYouTubePlayerReady = function( containerId ) {
|
|
|
2212 |
|
|
|
2213 |
onYouTubePlayerReady[ containerId ] && onYouTubePlayerReady[ containerId ]();
|
|
|
2214 |
};
|
|
|
2215 |
onYouTubePlayerReady.stateChangeEventHandler = {};
|
|
|
2216 |
|
|
|
2217 |
Popcorn.player( "youtube", {
|
|
|
2218 |
_setup: function( options ) {
|
|
|
2219 |
|
|
|
2220 |
var media = this,
|
|
|
2221 |
youtubeObject,
|
|
|
2222 |
container = document.createElement( "div" ),
|
|
|
2223 |
currentTime = 0,
|
|
|
2224 |
seekTime = 0,
|
|
|
2225 |
seeking = false,
|
|
|
2226 |
|
|
|
2227 |
// state code for volume changed polling
|
|
|
2228 |
volumeChanged = false,
|
|
|
2229 |
lastMuted = false,
|
|
|
2230 |
lastVolume = 0;
|
|
|
2231 |
|
|
|
2232 |
container.id = media.id + Popcorn.guid();
|
|
|
2233 |
|
|
|
2234 |
media.appendChild( container );
|
|
|
2235 |
|
|
|
2236 |
var youtubeInit = function() {
|
|
|
2237 |
|
|
|
2238 |
var flashvars,
|
|
|
2239 |
params,
|
|
|
2240 |
attributes,
|
|
|
2241 |
src;
|
|
|
2242 |
|
|
|
2243 |
// expose a callback to this scope, that is called from the global callback youtube calls
|
|
|
2244 |
onYouTubePlayerReady[ container.id ] = function() {
|
|
|
2245 |
|
|
|
2246 |
youtubeObject = document.getElementById( container.id );
|
|
|
2247 |
|
|
|
2248 |
// more youtube callback nonsense
|
|
|
2249 |
onYouTubePlayerReady.stateChangeEventHandler[ container.id ] = function( state ) {
|
|
|
2250 |
|
|
|
2251 |
// playing is state 1
|
|
|
2252 |
// paused is state 2
|
|
|
2253 |
if ( state === 1 ) {
|
|
|
2254 |
|
|
|
2255 |
media.paused && media.play();
|
|
|
2256 |
// youtube fires paused events while seeking
|
|
|
2257 |
// this is the only way to get seeking events
|
|
|
2258 |
} else if ( state === 2 ) {
|
|
|
2259 |
|
|
|
2260 |
// silly logic forced on me by the youtube API
|
|
|
2261 |
// calling youtube.seekTo triggers multiple events
|
|
|
2262 |
// with the second events getCurrentTime being the old time
|
|
|
2263 |
if ( seeking && seekTime === currentTime && seekTime !== youtubeObject.getCurrentTime() ) {
|
|
|
2264 |
|
|
|
2265 |
seeking = false;
|
|
|
2266 |
youtubeObject.seekTo( currentTime );
|
|
|
2267 |
return;
|
|
|
2268 |
}
|
|
|
2269 |
|
|
|
2270 |
currentTime = youtubeObject.getCurrentTime();
|
|
|
2271 |
media.dispatchEvent( "timeupdate" );
|
|
|
2272 |
!media.paused && media.pause();
|
|
|
2273 |
}
|
|
|
2274 |
};
|
|
|
2275 |
|
|
|
2276 |
// youtube requires callbacks to be a string to a function path from the global scope
|
|
|
2277 |
youtubeObject.addEventListener( "onStateChange", "onYouTubePlayerReady.stateChangeEventHandler." + container.id );
|
|
|
2278 |
|
|
|
2279 |
var timeupdate = function() {
|
|
|
2280 |
|
|
|
2281 |
if ( !media.paused ) {
|
|
|
2282 |
|
|
|
2283 |
currentTime = youtubeObject.getCurrentTime();
|
|
|
2284 |
media.dispatchEvent( "timeupdate" );
|
|
|
2285 |
setTimeout( timeupdate, 10 );
|
|
|
2286 |
}
|
|
|
2287 |
};
|
|
|
2288 |
|
|
|
2289 |
var volumeupdate = function() {
|
|
|
2290 |
|
|
|
2291 |
if ( lastMuted !== youtubeObject.isMuted() ) {
|
|
|
2292 |
|
|
|
2293 |
lastMuted = youtubeObject.isMuted();
|
|
|
2294 |
media.dispatchEvent( "volumechange" );
|
|
|
2295 |
}
|
|
|
2296 |
|
|
|
2297 |
if ( lastVolume !== youtubeObject.getVolume() ) {
|
|
|
2298 |
|
|
|
2299 |
lastVolume = youtubeObject.getVolume();
|
|
|
2300 |
media.dispatchEvent( "volumechange" );
|
|
|
2301 |
}
|
|
|
2302 |
|
|
|
2303 |
setTimeout( volumeupdate, 250 );
|
|
|
2304 |
};
|
|
|
2305 |
|
|
|
2306 |
media.play = function() {
|
|
|
2307 |
|
|
|
2308 |
media.paused = false;
|
|
|
2309 |
media.dispatchEvent( "play" );
|
|
|
2310 |
|
|
|
2311 |
media.dispatchEvent( "playing" );
|
|
|
2312 |
timeupdate();
|
|
|
2313 |
youtubeObject.playVideo();
|
|
|
2314 |
};
|
|
|
2315 |
|
|
|
2316 |
media.pause = function() {
|
|
|
2317 |
|
|
|
2318 |
if ( !media.paused ) {
|
|
|
2319 |
|
|
|
2320 |
media.paused = true;
|
|
|
2321 |
media.dispatchEvent( "pause" );
|
|
|
2322 |
youtubeObject.pauseVideo();
|
|
|
2323 |
}
|
|
|
2324 |
};
|
|
|
2325 |
|
|
|
2326 |
Popcorn.player.defineProperty( media, "currentTime", {
|
|
|
2327 |
set: function( val ) {
|
|
|
2328 |
|
|
|
2329 |
// make sure val is a number
|
|
|
2330 |
currentTime = seekTime = +val;
|
|
|
2331 |
seeking = true;
|
|
|
2332 |
media.dispatchEvent( "seeked" );
|
|
|
2333 |
media.dispatchEvent( "timeupdate" );
|
|
|
2334 |
youtubeObject.seekTo( currentTime );
|
|
|
2335 |
return currentTime;
|
|
|
2336 |
},
|
|
|
2337 |
get: function() {
|
|
|
2338 |
|
|
|
2339 |
return currentTime;
|
|
|
2340 |
}
|
|
|
2341 |
});
|
|
|
2342 |
|
|
|
2343 |
Popcorn.player.defineProperty( media, "muted", {
|
|
|
2344 |
set: function( val ) {
|
|
|
2345 |
|
|
|
2346 |
if ( youtubeObject.isMuted() !== val ) {
|
|
|
2347 |
|
|
|
2348 |
if ( val ) {
|
|
|
2349 |
|
|
|
2350 |
youtubeObject.mute();
|
|
|
2351 |
} else {
|
|
|
2352 |
|
|
|
2353 |
youtubeObject.unMute();
|
|
|
2354 |
}
|
|
|
2355 |
|
|
|
2356 |
lastMuted = youtubeObject.isMuted();
|
|
|
2357 |
media.dispatchEvent( "volumechange" );
|
|
|
2358 |
}
|
|
|
2359 |
|
|
|
2360 |
return youtubeObject.isMuted();
|
|
|
2361 |
},
|
|
|
2362 |
get: function() {
|
|
|
2363 |
|
|
|
2364 |
return youtubeObject.isMuted();
|
|
|
2365 |
}
|
|
|
2366 |
});
|
|
|
2367 |
|
|
|
2368 |
Popcorn.player.defineProperty( media, "volume", {
|
|
|
2369 |
set: function( val ) {
|
|
|
2370 |
|
|
|
2371 |
if ( youtubeObject.getVolume() !== val ) {
|
|
|
2372 |
|
|
|
2373 |
youtubeObject.setVolume( val );
|
|
|
2374 |
lastVolume = youtubeObject.getVolume();
|
|
|
2375 |
media.dispatchEvent( "volumechange" );
|
|
|
2376 |
}
|
|
|
2377 |
|
|
|
2378 |
return youtubeObject.getVolume();
|
|
|
2379 |
},
|
|
|
2380 |
get: function() {
|
|
|
2381 |
|
|
|
2382 |
return youtubeObject.getVolume();
|
|
|
2383 |
}
|
|
|
2384 |
});
|
|
|
2385 |
|
|
|
2386 |
media.readyState = 4;
|
|
|
2387 |
media.dispatchEvent( "load" );
|
|
|
2388 |
media.duration = youtubeObject.getDuration();
|
|
|
2389 |
media.dispatchEvent( "durationchange" );
|
|
|
2390 |
volumeupdate();
|
|
|
2391 |
|
|
|
2392 |
media.dispatchEvent( "loadeddata" );
|
|
|
2393 |
};
|
|
|
2394 |
|
|
|
2395 |
options.controls = +options.controls === 0 || +options.controls === 1 ? options.controls : 1;
|
|
|
2396 |
options.annotations = +options.annotations === 1 || +options.annotations === 3 ? options.annotations : 1;
|
|
|
2397 |
|
|
|
2398 |
flashvars = {
|
|
|
2399 |
playerapiid: container.id,
|
|
|
2400 |
controls: options.controls,
|
|
|
2401 |
iv_load_policy: options.annotations
|
|
|
2402 |
};
|
|
|
2403 |
|
|
|
2404 |
params = {
|
|
|
2405 |
wmode: "transparent",
|
|
|
2406 |
allowScriptAccess: "always"
|
|
|
2407 |
};
|
|
|
2408 |
|
|
|
2409 |
attributes = {
|
|
|
2410 |
id: container.id
|
|
|
2411 |
};
|
|
|
2412 |
|
|
|
2413 |
src = /^.*[\/=](.{11})/.exec( media.src )[ 1 ];
|
|
|
2414 |
|
|
|
2415 |
swfobject.embedSWF( "http://www.youtube.com/e/" + src + "?enablejsapi=1&playerapiid=" + container.id + "&version=3",
|
|
|
2416 |
container.id, media.offsetWidth, media.offsetHeight, "8", null,
|
|
|
2417 |
flashvars, params, attributes );
|
|
|
2418 |
};
|
|
|
2419 |
|
|
|
2420 |
if ( !window.swfobject ) {
|
|
|
2421 |
|
|
|
2422 |
Popcorn.getScript( "http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js", youtubeInit );
|
|
|
2423 |
} else {
|
|
|
2424 |
|
|
|
2425 |
youtubeInit();
|
|
|
2426 |
}
|
|
|
2427 |
}
|
|
|
2428 |
});
|
|
|
2429 |
|
|
|
2430 |
// PLUGIN: Code
|
|
|
2431 |
|
|
|
2432 |
(function ( Popcorn ) {
|
|
|
2433 |
|
|
|
2434 |
/**
|
|
|
2435 |
* Code Popcorn Plug-in
|
|
|
2436 |
*
|
|
|
2437 |
* Adds the ability to run arbitrary code (JavaScript functions) according to video timing.
|
|
|
2438 |
*
|
|
|
2439 |
* @param {Object} options
|
|
|
2440 |
*
|
|
|
2441 |
* Required parameters: start, end, template, data, and target.
|
|
|
2442 |
* Optional parameter: static.
|
|
|
2443 |
*
|
|
|
2444 |
* start: the time in seconds when the mustache template should be rendered
|
|
|
2445 |
* in the target div.
|
|
|
2446 |
*
|
|
|
2447 |
* end: the time in seconds when the rendered mustache template should be
|
|
|
2448 |
* removed from the target div.
|
|
|
2449 |
*
|
|
|
2450 |
* onStart: the function to be run when the start time is reached.
|
|
|
2451 |
*
|
|
|
2452 |
* onFrame: [optional] a function to be run on each paint call
|
|
|
2453 |
* (e.g., called ~60 times per second) between the start and end times.
|
|
|
2454 |
*
|
|
|
2455 |
* onEnd: [optional] a function to be run when the end time is reached.
|
|
|
2456 |
*
|
|
|
2457 |
* Example:
|
|
|
2458 |
var p = Popcorn('#video')
|
|
|
2459 |
|
|
|
2460 |
// onStart function only
|
|
|
2461 |
.code({
|
|
|
2462 |
start: 1,
|
|
|
2463 |
end: 4,
|
|
|
2464 |
onStart: function( options ) {
|
|
|
2465 |
// called on start
|
|
|
2466 |
}
|
|
|
2467 |
})
|
|
|
2468 |
|
|
|
2469 |
// onStart + onEnd only
|
|
|
2470 |
.code({
|
|
|
2471 |
start: 6,
|
|
|
2472 |
end: 8,
|
|
|
2473 |
onStart: function( options ) {
|
|
|
2474 |
// called on start
|
|
|
2475 |
},
|
|
|
2476 |
onEnd: function ( options ) {
|
|
|
2477 |
// called on end
|
|
|
2478 |
}
|
|
|
2479 |
})
|
|
|
2480 |
|
|
|
2481 |
// onStart, onEnd, onFrame
|
|
|
2482 |
.code({
|
|
|
2483 |
start: 10,
|
|
|
2484 |
end: 14,
|
|
|
2485 |
onStart: function( options ) {
|
|
|
2486 |
// called on start
|
|
|
2487 |
},
|
|
|
2488 |
onFrame: function ( options ) {
|
|
|
2489 |
// called on every paint frame between start and end.
|
|
|
2490 |
// uses mozRequestAnimationFrame, webkitRequestAnimationFrame,
|
|
|
2491 |
// or setTimeout with 16ms window.
|
|
|
2492 |
},
|
|
|
2493 |
onEnd: function ( options ) {
|
|
|
2494 |
// called on end
|
|
|
2495 |
}
|
|
|
2496 |
});
|
|
|
2497 |
*
|
|
|
2498 |
*/
|
|
|
2499 |
|
|
|
2500 |
Popcorn.plugin( "code" , function( options ) {
|
|
|
2501 |
var running = false;
|
|
|
2502 |
|
|
|
2503 |
// Setup a proper frame interval function (60fps), favouring paint events.
|
|
|
2504 |
var step = (function() {
|
|
|
2505 |
|
|
|
2506 |
var buildFrameRunner = function( runner ) {
|
|
|
2507 |
return function( f, options ) {
|
|
|
2508 |
|
|
|
2509 |
var _f = function() {
|
|
|
2510 |
running && f();
|
|
|
2511 |
running && runner( _f );
|
|
|
2512 |
};
|
|
|
2513 |
|
|
|
2514 |
_f();
|
|
|
2515 |
};
|
|
|
2516 |
};
|
|
|
2517 |
|
|
|
2518 |
// Figure out which level of browser support we have for this
|
|
|
2519 |
if ( window.webkitRequestAnimationFrame ) {
|
|
|
2520 |
return buildFrameRunner( window.webkitRequestAnimationFrame );
|
|
|
2521 |
} else if ( window.mozRequestAnimationFrame ) {
|
|
|
2522 |
return buildFrameRunner( window.mozRequestAnimationFrame );
|
|
|
2523 |
} else {
|
|
|
2524 |
return buildFrameRunner( function( f ) {
|
|
|
2525 |
window.setTimeout( f, 16 );
|
|
|
2526 |
});
|
|
|
2527 |
}
|
|
|
2528 |
|
|
|
2529 |
})();
|
|
|
2530 |
|
|
|
2531 |
if ( !options.onStart || typeof options.onStart !== "function" ) {
|
|
|
2532 |
|
|
|
2533 |
if ( Popcorn.plugin.debug ) {
|
|
|
2534 |
throw new Error( "Popcorn Code Plugin Error: onStart must be a function." );
|
|
|
2535 |
}
|
|
|
2536 |
options.onStart = Popcorn.nop;
|
|
|
2537 |
}
|
|
|
2538 |
|
|
|
2539 |
if ( options.onEnd && typeof options.onEnd !== "function" ) {
|
|
|
2540 |
|
|
|
2541 |
if ( Popcorn.plugin.debug ) {
|
|
|
2542 |
throw new Error( "Popcorn Code Plugin Error: onEnd must be a function." );
|
|
|
2543 |
}
|
|
|
2544 |
options.onEnd = undefined;
|
|
|
2545 |
}
|
|
|
2546 |
|
|
|
2547 |
if ( options.onFrame && typeof options.onFrame !== "function" ) {
|
|
|
2548 |
|
|
|
2549 |
if ( Popcorn.plugin.debug ) {
|
|
|
2550 |
throw new Error( "Popcorn Code Plugin Error: onFrame must be a function." );
|
|
|
2551 |
}
|
|
|
2552 |
options.onFrame = undefined;
|
|
|
2553 |
}
|
|
|
2554 |
|
|
|
2555 |
return {
|
|
|
2556 |
start: function( event, options ) {
|
|
|
2557 |
options.onStart( options );
|
|
|
2558 |
|
|
|
2559 |
if ( options.onFrame ) {
|
|
|
2560 |
running = true;
|
|
|
2561 |
step( options.onFrame, options );
|
|
|
2562 |
}
|
|
|
2563 |
},
|
|
|
2564 |
|
|
|
2565 |
end: function( event, options ) {
|
|
|
2566 |
if ( options.onFrame ) {
|
|
|
2567 |
running = false;
|
|
|
2568 |
}
|
|
|
2569 |
|
|
|
2570 |
if ( options.onEnd ) {
|
|
|
2571 |
options.onEnd( options );
|
|
|
2572 |
}
|
|
|
2573 |
}
|
|
|
2574 |
};
|
|
|
2575 |
},
|
|
|
2576 |
{
|
|
|
2577 |
about: {
|
|
|
2578 |
name: "Popcorn Code Plugin",
|
|
|
2579 |
version: "0.1",
|
|
|
2580 |
author: "David Humphrey (@humphd)",
|
|
|
2581 |
website: "http://vocamus.net/dave"
|
|
|
2582 |
},
|
|
|
2583 |
options: {
|
|
|
2584 |
start: {
|
|
|
2585 |
elem: "input",
|
|
|
2586 |
type: "text",
|
|
|
2587 |
label: "In"
|
|
|
2588 |
},
|
|
|
2589 |
end: {
|
|
|
2590 |
elem: "input",
|
|
|
2591 |
type: "text",
|
|
|
2592 |
label: "Out"
|
|
|
2593 |
},
|
|
|
2594 |
onStart: {
|
|
|
2595 |
elem: "input",
|
|
|
2596 |
type: "function",
|
|
|
2597 |
label: "onStart"
|
|
|
2598 |
},
|
|
|
2599 |
onFrame: {
|
|
|
2600 |
elem: "input",
|
|
|
2601 |
type: "function",
|
|
|
2602 |
label: "onFrame"
|
|
|
2603 |
},
|
|
|
2604 |
onEnd: {
|
|
|
2605 |
elem: "input",
|
|
|
2606 |
type: "function",
|
|
|
2607 |
label: "onEnd"
|
|
|
2608 |
}
|
|
|
2609 |
}
|
|
|
2610 |
});
|
|
|
2611 |
})( Popcorn );
|
|
|
2612 |
var jwplayerObjects = {};
|
|
|
2613 |
|
|
|
2614 |
Popcorn.player( "jwplayer", {
|
|
|
2615 |
_setup: function( options ) {
|
|
|
2616 |
|
|
|
2617 |
var media = this,
|
|
|
2618 |
player = {},
|
|
|
2619 |
container = document.createElement( "div" ),
|
|
|
2620 |
currentTime = 0,
|
|
|
2621 |
seekTime = 0,
|
|
|
2622 |
seeking = false,
|
|
|
2623 |
dataLoaded = false;
|
|
|
2624 |
container.id = media.id + Popcorn.guid();
|
|
|
2625 |
|
|
|
2626 |
media.appendChild( container );
|
|
|
2627 |
|
|
|
2628 |
var initApi = function () {
|
|
|
2629 |
jwplayer( container.id ).onTime(function() {
|
|
|
2630 |
currentTime = jwplayer(container.id).getPosition();
|
|
|
2631 |
media.dispatchEvent( "timeupdate" );
|
|
|
2632 |
// timeout = setTimeout( timeupdate, 10 );
|
|
|
2633 |
});
|
|
|
2634 |
|
|
|
2635 |
media.play = function() {
|
|
|
2636 |
media.paused = false;
|
|
|
2637 |
media.dispatchEvent( "play" );
|
|
|
2638 |
|
|
|
2639 |
media.dispatchEvent( "playing" );
|
|
|
2640 |
jwplayer( container.id ).play();
|
|
|
2641 |
};
|
|
|
2642 |
|
|
|
2643 |
media.pause = function() {
|
|
|
2644 |
|
|
|
2645 |
if ( !media.paused ) {
|
|
|
2646 |
media.paused = true;
|
|
|
2647 |
media.dispatchEvent( "pause" );
|
|
|
2648 |
jwplayer( container.id ).pause();
|
|
|
2649 |
}
|
|
|
2650 |
};
|
|
|
2651 |
|
|
|
2652 |
Popcorn.player.defineProperty( media, "currentTime", {
|
|
|
2653 |
set: function( val ) {
|
|
|
2654 |
// make sure val is a number
|
|
|
2655 |
currentTime = seekTime = +val;
|
|
|
2656 |
seeking = true;
|
|
|
2657 |
media.dispatchEvent( "seeked" );
|
|
|
2658 |
media.dispatchEvent( "timeupdate" );
|
|
|
2659 |
jwplayer( container.id ).seek( currentTime );
|
|
|
2660 |
return currentTime;
|
|
|
2661 |
},
|
|
|
2662 |
get: function() {
|
|
|
2663 |
return jwplayer( container.id ).getPosition();
|
|
|
2664 |
}
|
|
|
2665 |
});
|
|
|
2666 |
|
|
|
2667 |
Popcorn.player.defineProperty( media, "muted", {
|
|
|
2668 |
set: function( val ) {
|
|
|
2669 |
if ( jwplayer( container.id ).getMute() !== val ) {
|
|
|
2670 |
if ( val ) {
|
|
|
2671 |
jwplayer( container.id ).setMute(true);
|
|
|
2672 |
} else {
|
|
|
2673 |
jwplayer( container.id ).setMute(false);
|
|
|
2674 |
}
|
|
|
2675 |
|
|
|
2676 |
media.dispatchEvent( "volumechange" );
|
|
|
2677 |
}
|
|
|
2678 |
|
|
|
2679 |
return jwplayer( container.id ).getMute();
|
|
|
2680 |
},
|
|
|
2681 |
get: function() {
|
|
|
2682 |
return jwplayer( container.id ).getMute();
|
|
|
2683 |
}
|
|
|
2684 |
});
|
|
|
2685 |
|
|
|
2686 |
Popcorn.player.defineProperty( media, "volume", {
|
|
|
2687 |
|
|
|
2688 |
set: function( val ) {
|
|
|
2689 |
|
|
|
2690 |
if ( jwplayer( container.id ).getVolume() !== val *100 ) {
|
|
|
2691 |
jwplayer( container.id ).setVolume( val * 100);
|
|
|
2692 |
media.dispatchEvent( "volumechange" );
|
|
|
2693 |
}
|
|
|
2694 |
|
|
|
2695 |
return (jwplayer( container.id ).getVolume()) / 100;
|
|
|
2696 |
},
|
|
|
2697 |
|
|
|
2698 |
get: function() {
|
|
|
2699 |
return jwplayer( container.id ).getVolume() / 100;
|
|
|
2700 |
}
|
|
|
2701 |
});
|
|
|
2702 |
|
|
|
2703 |
media.readyState = 4;
|
|
|
2704 |
media.dispatchEvent( 'load' );
|
|
|
2705 |
dataLoaded = true;
|
|
|
2706 |
|
|
|
2707 |
media.duration = options.duration;
|
|
|
2708 |
media.dispatchEvent( 'durationchange' );
|
|
|
2709 |
|
|
|
2710 |
media.paused && media.dispatchEvent( 'loadeddata' );
|
|
|
2711 |
|
|
|
2712 |
};
|
|
|
2713 |
|
|
|
2714 |
options.events = {
|
|
|
2715 |
onReady: initApi
|
|
|
2716 |
};
|
|
|
2717 |
|
|
|
2718 |
jwplayer( container.id ).setup(options);
|
|
|
2719 |
|
|
|
2720 |
}
|
|
|
2721 |
});
|
|
|
2722 |
|
|
|
2723 |
// PLUGIN: Mediafragment
|
|
|
2724 |
|
|
|
2725 |
(function ( Popcorn ) {
|
|
|
2726 |
|
|
|
2727 |
/**
|
|
|
2728 |
* Mediafragment popcorn plug-in
|
|
|
2729 |
* Adds (limited) support for mediafragment requests
|
|
|
2730 |
* to a popcorn video.
|
|
|
2731 |
* @param {Object} options
|
|
|
2732 |
*
|
|
|
2733 |
**/
|
|
|
2734 |
Popcorn.plugin( "mediafragment" , {
|
|
|
2735 |
|
|
|
2736 |
manifest: {
|
|
|
2737 |
about: {
|
|
|
2738 |
name: "Popcorn mediafragment plugin",
|
|
|
2739 |
version: "0.1",
|
|
|
2740 |
author: "Karim Hamidou",
|
|
|
2741 |
website: "http://neyret.fr/~karim"
|
|
|
2742 |
},
|
|
|
2743 |
options: {
|
|
|
2744 |
}
|
|
|
2745 |
},
|
|
|
2746 |
|
|
|
2747 |
_setup: function( options ) {
|
|
|
2748 |
var advanceTime = function() {
|
|
|
2749 |
var url = window.location.href;
|
|
|
2750 |
|
|
|
2751 |
if ( url.split( "#" )[ 1 ] != null ) {
|
|
|
2752 |
pageoffset = url.split( "#" )[1];
|
|
|
2753 |
|
|
|
2754 |
if ( pageoffset.substring( 2 ) != null ) {
|
|
|
2755 |
var offsettime = pageoffset.substring( 2 );
|
|
|
2756 |
this.currentTime( parseFloat( offsettime ) );
|
|
|
2757 |
}
|
|
|
2758 |
}
|
|
|
2759 |
}
|
|
|
2760 |
|
|
|
2761 |
var updateTime = function() {
|
|
|
2762 |
var history = window.history;
|
|
|
2763 |
if ( !history.pushState ) {
|
|
|
2764 |
return false;
|
|
|
2765 |
}
|
|
|
2766 |
|
|
|
2767 |
splitArr = window.location.href.split( "#" )
|
|
|
2768 |
history.replaceState( {}, "", splitArr[0] + "#t=" + this.currentTime().toFixed( 2 ) );
|
|
|
2769 |
};
|
|
|
2770 |
|
|
|
2771 |
this.listen( "loadedmetadata", advanceTime );
|
|
|
2772 |
this.listen( "pause", updateTime );
|
|
|
2773 |
this.listen( "seeked", updateTime );
|
|
|
2774 |
},
|
|
|
2775 |
|
|
|
2776 |
_teardown: function( options ) {
|
|
|
2777 |
// FIXME: anything to implement here ?
|
|
|
2778 |
}
|
|
|
2779 |
});
|
|
|
2780 |
})( Popcorn );
|
|
|
2781 |
if(typeof jwplayer=="undefined"){var jwplayer=function(a){if(jwplayer.api){return jwplayer.api.selectPlayer(a)}};var $jw=jwplayer;jwplayer.version="5.7.1896";jwplayer.vid=document.createElement("video");jwplayer.audio=document.createElement("audio");jwplayer.source=document.createElement("source");(function(b){b.utils=function(){};b.utils.typeOf=function(d){var c=typeof d;if(c==="object"){if(d){if(d instanceof Array){c="array"}}else{c="null"}}return c};b.utils.extend=function(){var c=b.utils.extend["arguments"];if(c.length>1){for(var e=1;e<c.length;e++){for(var d in c[e]){c[0][d]=c[e][d]}}return c[0]}return null};b.utils.clone=function(f){var c;var d=b.utils.clone["arguments"];if(d.length==1){switch(b.utils.typeOf(d[0])){case"object":c={};for(var e in d[0]){c[e]=b.utils.clone(d[0][e])}break;case"array":c=[];for(var e in d[0]){c[e]=b.utils.clone(d[0][e])}break;default:return d[0];break}}return c};b.utils.extension=function(c){if(!c){return""}c=c.substring(c.lastIndexOf("/")+1,c.length);c=c.split("?")[0];if(c.lastIndexOf(".")>-1){return c.substr(c.lastIndexOf(".")+1,c.length).toLowerCase()}return};b.utils.html=function(c,d){c.innerHTML=d};b.utils.wrap=function(c,d){if(c.parentNode){c.parentNode.replaceChild(d,c)}d.appendChild(c)};b.utils.ajax=function(g,f,c){var e;if(window.XMLHttpRequest){e=new XMLHttpRequest()}else{e=new ActiveXObject("Microsoft.XMLHTTP")}e.onreadystatechange=function(){if(e.readyState===4){if(e.status===200){if(f){f(e)}}else{if(c){c(g)}}}};try{e.open("GET",g,true);e.send(null)}catch(d){if(c){c(g)}}return e};b.utils.load=function(d,e,c){d.onreadystatechange=function(){if(d.readyState===4){if(d.status===200){if(e){e()}}else{if(c){c()}}}}};b.utils.find=function(d,c){return d.getElementsByTagName(c)};b.utils.append=function(c,d){c.appendChild(d)};b.utils.isIE=function(){return((!+"\v1")||(typeof window.ActiveXObject!="undefined"))};b.utils.isLegacyAndroid=function(){var c=navigator.userAgent.toLowerCase();return(c.match(/android 2.[012]/i)!==null)};b.utils.isIOS=function(d){if(typeof d=="undefined"){d=/iP(hone|ad|od)/i}var c=navigator.userAgent.toLowerCase();return(c.match(d)!==null)};b.utils.isIPad=function(){return b.utils.isIOS(/iPad/i)};b.utils.isIPod=function(){return b.utils.isIOS(/iP(hone|od)/i)};b.utils.getFirstPlaylistItemFromConfig=function(c){var d={};var e;if(c.playlist&&c.playlist.length){e=c.playlist[0]}else{e=c}d.file=e.file;d.levels=e.levels;d.streamer=e.streamer;d.playlistfile=e.playlistfile;d.provider=e.provider;if(!d.provider){if(d.file&&(d.file.toLowerCase().indexOf("youtube.com")>-1||d.file.toLowerCase().indexOf("youtu.be")>-1)){d.provider="youtube"}if(d.streamer&&d.streamer.toLowerCase().indexOf("rtmp://")==0){d.provider="rtmp"}if(e.type){d.provider=e.type.toLowerCase()}}if(d.provider=="audio"){d.provider="sound"}return d};b.utils.getOuterHTML=function(c){if(c.outerHTML){return c.outerHTML}else{try{return new XMLSerializer().serializeToString(c)}catch(d){return""}}};b.utils.setOuterHTML=function(f,e){if(f.outerHTML){f.outerHTML=e}else{var g=document.createElement("div");g.innerHTML=e;var c=document.createRange();c.selectNodeContents(g);var d=c.extractContents();f.parentNode.insertBefore(d,f);f.parentNode.removeChild(f)}};b.utils.hasFlash=function(){if(typeof navigator.plugins!="undefined"&&typeof navigator.plugins["Shockwave Flash"]!="undefined"){return true}if(typeof window.ActiveXObject!="undefined"){try{new ActiveXObject("ShockwaveFlash.ShockwaveFlash");return true}catch(c){}}return false};b.utils.getPluginName=function(c){if(c.lastIndexOf("/")>=0){c=c.substring(c.lastIndexOf("/")+1,c.length)}if(c.lastIndexOf("-")>=0){c=c.substring(0,c.lastIndexOf("-"))}if(c.lastIndexOf(".swf")>=0){c=c.substring(0,c.lastIndexOf(".swf"))}if(c.lastIndexOf(".js")>=0){c=c.substring(0,c.lastIndexOf(".js"))}return c};b.utils.getPluginVersion=function(c){if(c.lastIndexOf("-")>=0){if(c.lastIndexOf(".js")>=0){return c.substring(c.lastIndexOf("-")+1,c.lastIndexOf(".js"))}else{if(c.lastIndexOf(".swf")>=0){return c.substring(c.lastIndexOf("-")+1,c.lastIndexOf(".swf"))}else{return c.substring(c.lastIndexOf("-")+1)}}}return""};b.utils.getAbsolutePath=function(j,h){if(!b.utils.exists(h)){h=document.location.href}if(!b.utils.exists(j)){return undefined}if(a(j)){return j}var k=h.substring(0,h.indexOf("://")+3);var g=h.substring(k.length,h.indexOf("/",k.length+1));var d;if(j.indexOf("/")===0){d=j.split("/")}else{var e=h.split("?")[0];e=e.substring(k.length+g.length+1,e.lastIndexOf("/"));d=e.split("/").concat(j.split("/"))}var c=[];for(var f=0;f<d.length;f++){if(!d[f]||!b.utils.exists(d[f])||d[f]=="."){continue}else{if(d[f]==".."){c.pop()}else{c.push(d[f])}}}return k+g+"/"+c.join("/")};function a(d){if(!b.utils.exists(d)){return}var e=d.indexOf("://");var c=d.indexOf("?");return(e>0&&(c<0||(c>e)))}b.utils.pluginPathType={ABSOLUTE:"ABSOLUTE",RELATIVE:"RELATIVE",CDN:"CDN"};b.utils.getPluginPathType=function(d){if(typeof d!="string"){return}d=d.split("?")[0];var e=d.indexOf("://");if(e>0){return b.utils.pluginPathType.ABSOLUTE}var c=d.indexOf("/");var f=b.utils.extension(d);if(e<0&&c<0&&(!f||!isNaN(f))){return b.utils.pluginPathType.CDN}return b.utils.pluginPathType.RELATIVE};b.utils.mapEmpty=function(c){for(var d in c){return false}return true};b.utils.mapLength=function(d){var c=0;for(var e in d){c++}return c};b.utils.log=function(d,c){if(typeof console!="undefined"&&typeof console.log!="undefined"){if(c){console.log(d,c)}else{console.log(d)}}};b.utils.css=function(d,g,c){if(b.utils.exists(d)){for(var e in g){try{if(typeof g[e]==="undefined"){continue}else{if(typeof g[e]=="number"&&!(e=="zIndex"||e=="opacity")){if(isNaN(g[e])){continue}if(e.match(/color/i)){g[e]="#"+b.utils.strings.pad(g[e].toString(16),6)}else{g[e]=Math.ceil(g[e])+"px"}}}d.style[e]=g[e]}catch(f){}}}};b.utils.isYouTube=function(c){return(c.indexOf("youtube.com")>-1||c.indexOf("youtu.be")>-1)};b.utils.transform=function(c,d){c.style.webkitTransform=d;c.style.MozTransform=d;c.style.OTransform=d};b.utils.stretch=function(h,n,m,f,l,g){if(typeof m=="undefined"||typeof f=="undefined"||typeof l=="undefined"||typeof g=="undefined"){return}var d=m/l;var e=f/g;var k=0;var j=0;n.style.overflow="hidden";b.utils.transform(n,"");var c={};switch(h.toUpperCase()){case b.utils.stretching.NONE:c.width=l;c.height=g;break;case b.utils.stretching.UNIFORM:if(d>e){c.width=l*e;c.height=g*e}else{c.width=l*d;c.height=g*d}break;case b.utils.stretching.FILL:if(d>e){c.width=l*d;c.height=g*d}else{c.width=l*e;c.height=g*e}break;case b.utils.stretching.EXACTFIT:b.utils.transform(n,["scale(",d,",",e,")"," translate(0px,0px)"].join(""));c.width=l;c.height=g;break;default:break}c.top=(f-c.height)/2;c.left=(m-c.width)/2;b.utils.css(n,c)};b.utils.stretching={NONE:"NONE",FILL:"FILL",UNIFORM:"UNIFORM",EXACTFIT:"EXACTFIT"};b.utils.deepReplaceKeyName=function(h,e,c){switch(b.utils.typeOf(h)){case"array":for(var g=0;g<h.length;g++){h[g]=b.utils.deepReplaceKeyName(h[g],e,c)}break;case"object":for(var f in h){var d=f.replace(new RegExp(e,"g"),c);h[d]=b.utils.deepReplaceKeyName(h[f],e,c);if(f!=d){delete h[f]}}break}return h};b.utils.isInArray=function(e,d){if(!(e)||!(e instanceof Array)){return false}for(var c=0;c<e.length;c++){if(d===e[c]){return true}}return false};b.utils.exists=function(c){switch(typeof(c)){case"string":return(c.length>0);break;case"object":return(c!==null);case"undefined":return false}return true};b.utils.empty=function(c){if(typeof c.hasChildNodes=="function"){while(c.hasChildNodes()){c.removeChild(c.firstChild)}}};b.utils.parseDimension=function(c){if(typeof c=="string"){if(c===""){return 0}else{if(c.lastIndexOf("%")>-1){return c}else{return parseInt(c.replace("px",""),10)}}}return c};b.utils.getDimensions=function(c){if(c&&c.style){return{x:b.utils.parseDimension(c.style.left),y:b.utils.parseDimension(c.style.top),width:b.utils.parseDimension(c.style.width),height:b.utils.parseDimension(c.style.height)}}else{return{}}};b.utils.timeFormat=function(c){str="00:00";if(c>0){str=Math.floor(c/60)<10?"0"+Math.floor(c/60)+":":Math.floor(c/60)+":";str+=Math.floor(c%60)<10?"0"+Math.floor(c%60):Math.floor(c%60)}return str}})(jwplayer);(function(a){a.events=function(){};a.events.COMPLETE="COMPLETE";a.events.ERROR="ERROR"})(jwplayer);(function(jwplayer){jwplayer.events.eventdispatcher=function(debug){var _debug=debug;var _listeners;var _globallisteners;this.resetEventListeners=function(){_listeners={};_globallisteners=[]};this.resetEventListeners();this.addEventListener=function(type,listener,count){try{if(!jwplayer.utils.exists(_listeners[type])){_listeners[type]=[]}if(typeof(listener)=="string"){eval("listener = "+listener)}_listeners[type].push({listener:listener,count:count})}catch(err){jwplayer.utils.log("error",err)}return false};this.removeEventListener=function(type,listener){if(!_listeners[type]){return}try{for(var listenerIndex=0;listenerIndex<_listeners[type].length;listenerIndex++){if(_listeners[type][listenerIndex].listener.toString()==listener.toString()){_listeners[type].splice(listenerIndex,1);break}}}catch(err){jwplayer.utils.log("error",err)}return false};this.addGlobalListener=function(listener,count){try{if(typeof(listener)=="string"){eval("listener = "+listener)}_globallisteners.push({listener:listener,count:count})}catch(err){jwplayer.utils.log("error",err)}return false};this.removeGlobalListener=function(listener){if(!_globallisteners[type]){return}try{for(var globalListenerIndex=0;globalListenerIndex<_globallisteners.length;globalListenerIndex++){if(_globallisteners[globalListenerIndex].listener.toString()==listener.toString()){_globallisteners.splice(globalListenerIndex,1);break}}}catch(err){jwplayer.utils.log("error",err)}return false};this.sendEvent=function(type,data){if(!jwplayer.utils.exists(data)){data={}}if(_debug){jwplayer.utils.log(type,data)}if(typeof _listeners[type]!="undefined"){for(var listenerIndex=0;listenerIndex<_listeners[type].length;listenerIndex++){try{_listeners[type][listenerIndex].listener(data)}catch(err){jwplayer.utils.log("There was an error while handling a listener: "+err.toString(),_listeners[type][listenerIndex].listener)}if(_listeners[type][listenerIndex]){if(_listeners[type][listenerIndex].count===1){delete _listeners[type][listenerIndex]}else{if(_listeners[type][listenerIndex].count>0){_listeners[type][listenerIndex].count=_listeners[type][listenerIndex].count-1}}}}}for(var globalListenerIndex=0;globalListenerIndex<_globallisteners.length;globalListenerIndex++){try{_globallisteners[globalListenerIndex].listener(data)}catch(err){jwplayer.utils.log("There was an error while handling a listener: "+err.toString(),_globallisteners[globalListenerIndex].listener)}if(_globallisteners[globalListenerIndex]){if(_globallisteners[globalListenerIndex].count===1){delete _globallisteners[globalListenerIndex]}else{if(_globallisteners[globalListenerIndex].count>0){_globallisteners[globalListenerIndex].count=_globallisteners[globalListenerIndex].count-1}}}}}}})(jwplayer);(function(a){var b={};a.utils.animations=function(){};a.utils.animations.transform=function(c,d){c.style.webkitTransform=d;c.style.MozTransform=d;c.style.OTransform=d;c.style.msTransform=d};a.utils.animations.transformOrigin=function(c,d){c.style.webkitTransformOrigin=d;c.style.MozTransformOrigin=d;c.style.OTransformOrigin=d;c.style.msTransformOrigin=d};a.utils.animations.rotate=function(c,d){a.utils.animations.transform(c,["rotate(",d,"deg)"].join(""))};a.utils.cancelAnimation=function(c){delete b[c.id]};a.utils.fadeTo=function(m,f,e,j,h,d){if(b[m.id]!=d&&a.utils.exists(d)){return}if(m.style.opacity==f){return}var c=new Date().getTime();if(d>c){setTimeout(function(){a.utils.fadeTo(m,f,e,j,0,d)},d-c)}if(m.style.display=="none"){m.style.display="block"}if(!a.utils.exists(j)){j=m.style.opacity===""?1:m.style.opacity}if(m.style.opacity==f&&m.style.opacity!==""&&a.utils.exists(d)){if(f===0){m.style.display="none"}return}if(!a.utils.exists(d)){d=c;b[m.id]=d}if(!a.utils.exists(h)){h=0}var k=(e>0)?((c-d)/(e*1000)):0;k=k>1?1:k;var l=f-j;var g=j+(k*l);if(g>1){g=1}else{if(g<0){g=0}}m.style.opacity=g;if(h>0){b[m.id]=d+h*1000;a.utils.fadeTo(m,f,e,j,0,b[m.id]);return}setTimeout(function(){a.utils.fadeTo(m,f,e,j,0,d)},10)}})(jwplayer);(function(a){a.utils.arrays=function(){};a.utils.arrays.indexOf=function(c,d){for(var b=0;b<c.length;b++){if(c[b]==d){return b}}return -1};a.utils.arrays.remove=function(c,d){var b=a.utils.arrays.indexOf(c,d);if(b>-1){c.splice(b,1)}}})(jwplayer);(function(a){a.utils.extensionmap={"3gp":{html5:"video/3gpp",flash:"video"},"3gpp":{html5:"video/3gpp"},"3g2":{html5:"video/3gpp2",flash:"video"},"3gpp2":{html5:"video/3gpp2"},flv:{flash:"video"},f4a:{html5:"audio/mp4"},f4b:{html5:"audio/mp4",flash:"video"},f4v:{html5:"video/mp4",flash:"video"},mov:{html5:"video/quicktime",flash:"video"},m4a:{html5:"audio/mp4",flash:"video"},m4b:{html5:"audio/mp4"},m4p:{html5:"audio/mp4"},m4v:{html5:"video/mp4",flash:"video"},mp4:{html5:"video/mp4",flash:"video"},rbs:{flash:"sound"},aac:{html5:"audio/aac",flash:"video"},mp3:{html5:"audio/mp3",flash:"sound"},ogg:{html5:"audio/ogg"},oga:{html5:"audio/ogg"},ogv:{html5:"video/ogg"},webm:{html5:"video/webm"},m3u8:{html5:"audio/x-mpegurl"},gif:{flash:"image"},jpeg:{flash:"image"},jpg:{flash:"image"},swf:{flash:"image"},png:{flash:"image"},wav:{html5:"audio/x-wav"}}})(jwplayer);(function(e){e.utils.mediaparser=function(){};var g={element:{width:"width",height:"height",id:"id","class":"className",name:"name"},media:{src:"file",preload:"preload",autoplay:"autostart",loop:"repeat",controls:"controls"},source:{src:"file",type:"type",media:"media","data-jw-width":"width","data-jw-bitrate":"bitrate"},video:{poster:"image"}};var f={};e.utils.mediaparser.parseMedia=function(j){return d(j)};function c(k,j){if(!e.utils.exists(j)){j=g[k]}else{e.utils.extend(j,g[k])}return j}function d(n,j){if(f[n.tagName.toLowerCase()]&&!e.utils.exists(j)){return f[n.tagName.toLowerCase()](n)}else{j=c("element",j);var o={};for(var k in j){if(k!="length"){var m=n.getAttribute(k);if(e.utils.exists(m)){o[j[k]]=m}}}var l=n.style["#background-color"];if(l&&!(l=="transparent"||l=="rgba(0, 0, 0, 0)")){o.screencolor=l}return o}}function h(n,k){k=c("media",k);var l=[];var j=e.utils.selectors("source",n);for(var m in j){if(!isNaN(m)){l.push(a(j[m]))}}var o=d(n,k);if(e.utils.exists(o.file)){l[0]={file:o.file}}o.levels=l;return o}function a(l,k){k=c("source",k);var j=d(l,k);j.width=j.width?j.width:0;j.bitrate=j.bitrate?j.bitrate:0;return j}function b(l,k){k=c("video",k);var j=h(l,k);return j}f.media=h;f.audio=h;f.source=a;f.video=b})(jwplayer);(function(a){a.utils.loaderstatus={NEW:"NEW",LOADING:"LOADING",ERROR:"ERROR",COMPLETE:"COMPLETE"};a.utils.scriptloader=function(c){var d=a.utils.loaderstatus.NEW;var b=new a.events.eventdispatcher();a.utils.extend(this,b);this.load=function(){if(d==a.utils.loaderstatus.NEW){d=a.utils.loaderstatus.LOADING;var e=document.createElement("script");e.onload=function(f){d=a.utils.loaderstatus.COMPLETE;b.sendEvent(a.events.COMPLETE)};e.onerror=function(f){d=a.utils.loaderstatus.ERROR;b.sendEvent(a.events.ERROR)};e.onreadystatechange=function(){if(e.readyState=="loaded"||e.readyState=="complete"){d=a.utils.loaderstatus.COMPLETE;b.sendEvent(a.events.COMPLETE)}};document.getElementsByTagName("head")[0].appendChild(e);e.src=c}};this.getStatus=function(){return d}}})(jwplayer);(function(a){a.utils.selectors=function(b,e){if(!a.utils.exists(e)){e=document}b=a.utils.strings.trim(b);var c=b.charAt(0);if(c=="#"){return e.getElementById(b.substr(1))}else{if(c=="."){if(e.getElementsByClassName){return e.getElementsByClassName(b.substr(1))}else{return a.utils.selectors.getElementsByTagAndClass("*",b.substr(1))}}else{if(b.indexOf(".")>0){var d=b.split(".");return a.utils.selectors.getElementsByTagAndClass(d[0],d[1])}else{return e.getElementsByTagName(b)}}}return null};a.utils.selectors.getElementsByTagAndClass=function(e,h,g){var j=[];if(!a.utils.exists(g)){g=document}var f=g.getElementsByTagName(e);for(var d=0;d<f.length;d++){if(a.utils.exists(f[d].className)){var c=f[d].className.split(" ");for(var b=0;b<c.length;b++){if(c[b]==h){j.push(f[d])}}}}return j}})(jwplayer);(function(a){a.utils.strings=function(){};a.utils.strings.trim=function(b){return b.replace(/^\s*/,"").replace(/\s*$/,"")};a.utils.strings.pad=function(c,d,b){if(!b){b="0"}while(c.length<d){c=b+c}return c};a.utils.strings.serialize=function(b){if(b==null){return null}else{if(b=="true"){return true}else{if(b=="false"){return false}else{if(isNaN(Number(b))||b.length>5||b.length==0){return b}else{return Number(b)}}}}};a.utils.strings.seconds=function(d){d=d.replace(",",".");var b=d.split(":");var c=0;if(d.substr(-1)=="s"){c=Number(d.substr(0,d.length-1))}else{if(d.substr(-1)=="m"){c=Number(d.substr(0,d.length-1))*60}else{if(d.substr(-1)=="h"){c=Number(d.substr(0,d.length-1))*3600}else{if(b.length>1){c=Number(b[b.length-1]);c+=Number(b[b.length-2])*60;if(b.length==3){c+=Number(b[b.length-3])*3600}}else{c=Number(d)}}}}return c};a.utils.strings.xmlAttribute=function(b,c){for(var d=0;d<b.attributes.length;d++){if(b.attributes[d].name&&b.attributes[d].name.toLowerCase()==c.toLowerCase()){return b.attributes[d].value.toString()}}return""};a.utils.strings.jsonToString=function(f){var h=h||{};if(h&&h.stringify){return h.stringify(f)}var c=typeof(f);if(c!="object"||f===null){if(c=="string"){f='"'+f+'"'}else{return String(f)}}else{var g=[],b=(f&&f.constructor==Array);for(var d in f){var e=f[d];switch(typeof(e)){case"string":e='"'+e+'"';break;case"object":if(a.utils.exists(e)){e=a.utils.strings.jsonToString(e)}break}if(b){if(typeof(e)!="function"){g.push(String(e))}}else{if(typeof(e)!="function"){g.push('"'+d+'":'+String(e))}}}if(b){return"["+String(g)+"]"}else{return"{"+String(g)+"}"}}}})(jwplayer);(function(c){var d=new RegExp(/^(#|0x)[0-9a-fA-F]{3,6}/);c.utils.typechecker=function(g,f){f=!c.utils.exists(f)?b(g):f;return e(g,f)};function b(f){var g=["true","false","t","f"];if(g.toString().indexOf(f.toLowerCase().replace(" ",""))>=0){return"boolean"}else{if(d.test(f)){return"color"}else{if(!isNaN(parseInt(f,10))&&parseInt(f,10).toString().length==f.length){return"integer"}else{if(!isNaN(parseFloat(f))&&parseFloat(f).toString().length==f.length){return"float"}}}}return"string"}function e(g,f){if(!c.utils.exists(f)){return g}switch(f){case"color":if(g.length>0){return a(g)}return null;case"integer":return parseInt(g,10);case"float":return parseFloat(g);case"boolean":if(g.toLowerCase()=="true"){return true}else{if(g=="1"){return true}}return false}return g}function a(f){switch(f.toLowerCase()){case"blue":return parseInt("0000FF",16);case"green":return parseInt("00FF00",16);case"red":return parseInt("FF0000",16);case"cyan":return parseInt("00FFFF",16);case"magenta":return parseInt("FF00FF",16);case"yellow":return parseInt("FFFF00",16);case"black":return parseInt("000000",16);case"white":return parseInt("FFFFFF",16);default:f=f.replace(/(#|0x)?([0-9A-F]{3,6})$/gi,"$2");if(f.length==3){f=f.charAt(0)+f.charAt(0)+f.charAt(1)+f.charAt(1)+f.charAt(2)+f.charAt(2)}return parseInt(f,16)}return parseInt("000000",16)}})(jwplayer);(function(a){a.utils.parsers=function(){};a.utils.parsers.localName=function(b){if(!b){return""}else{if(b.localName){return b.localName}else{if(b.baseName){return b.baseName}else{return""}}}};a.utils.parsers.textContent=function(b){if(!b){return""}else{if(b.textContent){return b.textContent}else{if(b.text){return b.text}else{return""}}}}})(jwplayer);(function(a){a.utils.parsers.jwparser=function(){};a.utils.parsers.jwparser.PREFIX="jwplayer";a.utils.parsers.jwparser.parseEntry=function(c,d){for(var b=0;b<c.childNodes.length;b++){if(c.childNodes[b].prefix==a.utils.parsers.jwparser.PREFIX){d[a.utils.parsers.localName(c.childNodes[b])]=a.utils.strings.serialize(a.utils.parsers.textContent(c.childNodes[b]))}if(!d.file&&String(d.link).toLowerCase().indexOf("youtube")>-1){d.file=d.link}}return d};a.utils.parsers.jwparser.getProvider=function(c){if(c.type){return c.type}else{if(c.file.indexOf("youtube.com/w")>-1||c.file.indexOf("youtube.com/v")>-1||c.file.indexOf("youtu.be/")>-1){return"youtube"}else{if(c.streamer&&c.streamer.indexOf("rtmp")==0){return"rtmp"}else{if(c.streamer&&c.streamer.indexOf("http")==0){return"http"}else{var b=a.utils.strings.extension(c.file);if(extensions.hasOwnProperty(b)){return extensions[b]}}}}}return""}})(jwplayer);(function(a){a.utils.parsers.mediaparser=function(){};a.utils.parsers.mediaparser.PREFIX="media";a.utils.parsers.mediaparser.parseGroup=function(d,f){var e=false;for(var c=0;c<d.childNodes.length;c++){if(d.childNodes[c].prefix==a.utils.parsers.mediaparser.PREFIX){if(!a.utils.parsers.localName(d.childNodes[c])){continue}switch(a.utils.parsers.localName(d.childNodes[c]).toLowerCase()){case"content":if(!e){f.file=a.utils.strings.xmlAttribute(d.childNodes[c],"url")}if(a.utils.strings.xmlAttribute(d.childNodes[c],"duration")){f.duration=a.utils.strings.seconds(a.utils.strings.xmlAttribute(d.childNodes[c],"duration"))}if(a.utils.strings.xmlAttribute(d.childNodes[c],"start")){f.start=a.utils.strings.seconds(a.utils.strings.xmlAttribute(d.childNodes[c],"start"))}if(d.childNodes[c].childNodes&&d.childNodes[c].childNodes.length>0){f=a.utils.parsers.mediaparser.parseGroup(d.childNodes[c],f)}if(a.utils.strings.xmlAttribute(d.childNodes[c],"width")||a.utils.strings.xmlAttribute(d.childNodes[c],"bitrate")||a.utils.strings.xmlAttribute(d.childNodes[c],"url")){if(!f.levels){f.levels=[]}f.levels.push({width:a.utils.strings.xmlAttribute(d.childNodes[c],"width"),bitrate:a.utils.strings.xmlAttribute(d.childNodes[c],"bitrate"),file:a.utils.strings.xmlAttribute(d.childNodes[c],"url")})}break;case"title":f.title=a.utils.parsers.textContent(d.childNodes[c]);break;case"description":f.description=a.utils.parsers.textContent(d.childNodes[c]);break;case"keywords":f.tags=a.utils.parsers.textContent(d.childNodes[c]);break;case"thumbnail":f.image=a.utils.strings.xmlAttribute(d.childNodes[c],"url");break;case"credit":f.author=a.utils.parsers.textContent(d.childNodes[c]);break;case"player":var b=d.childNodes[c].url;if(b.indexOf("youtube.com")>=0||b.indexOf("youtu.be")>=0){e=true;f.file=a.utils.strings.xmlAttribute(d.childNodes[c],"url")}break;case"group":a.utils.parsers.mediaparser.parseGroup(d.childNodes[c],f);break}}}return f}})(jwplayer);(function(b){b.utils.parsers.rssparser=function(){};b.utils.parsers.rssparser.parse=function(f){var c=[];for(var e=0;e<f.childNodes.length;e++){if(b.utils.parsers.localName(f.childNodes[e]).toLowerCase()=="channel"){for(var d=0;d<f.childNodes[e].childNodes.length;d++){if(b.utils.parsers.localName(f.childNodes[e].childNodes[d]).toLowerCase()=="item"){c.push(a(f.childNodes[e].childNodes[d]))}}}}return c};function a(d){var e={};for(var c=0;c<d.childNodes.length;c++){if(!b.utils.parsers.localName(d.childNodes[c])){continue}switch(b.utils.parsers.localName(d.childNodes[c]).toLowerCase()){case"enclosure":e.file=b.utils.strings.xmlAttribute(d.childNodes[c],"url");break;case"title":e.title=b.utils.parsers.textContent(d.childNodes[c]);break;case"pubdate":e.date=b.utils.parsers.textContent(d.childNodes[c]);break;case"description":e.description=b.utils.parsers.textContent(d.childNodes[c]);break;case"link":e.link=b.utils.parsers.textContent(d.childNodes[c]);break;case"category":if(e.tags){e.tags+=b.utils.parsers.textContent(d.childNodes[c])}else{e.tags=b.utils.parsers.textContent(d.childNodes[c])}break}}e=b.utils.parsers.mediaparser.parseGroup(d,e);e=b.utils.parsers.jwparser.parseEntry(d,e);return new b.html5.playlistitem(e)}})(jwplayer);(function(a){var c={};var b={};a.plugins=function(){};a.plugins.loadPlugins=function(e,d){b[e]=new a.plugins.pluginloader(new a.plugins.model(c),d);return b[e]};a.plugins.registerPlugin=function(h,f,e){var d=a.utils.getPluginName(h);if(c[d]){c[d].registerPlugin(h,f,e)}else{a.utils.log("A plugin ("+h+") was registered with the player that was not loaded. Please check your configuration.");for(var g in b){b[g].pluginFailed()}}}})(jwplayer);(function(a){a.plugins.model=function(b){this.addPlugin=function(c){var d=a.utils.getPluginName(c);if(!b[d]){b[d]=new a.plugins.plugin(c)}return b[d]}}})(jwplayer);(function(a){a.plugins.pluginmodes={FLASH:"FLASH",JAVASCRIPT:"JAVASCRIPT",HYBRID:"HYBRID"};a.plugins.plugin=function(b){var d="http://plugins.longtailvideo.com";var j=a.utils.loaderstatus.NEW;var k;var h;var l;var c=new a.events.eventdispatcher();a.utils.extend(this,c);function e(){switch(a.utils.getPluginPathType(b)){case a.utils.pluginPathType.ABSOLUTE:return b;case a.utils.pluginPathType.RELATIVE:return a.utils.getAbsolutePath(b,window.location.href);case a.utils.pluginPathType.CDN:var n=a.utils.getPluginName(b);var m=a.utils.getPluginVersion(b);return d+"/"+a.version.split(".")[0]+"/"+n+"/"+n+(m!==""?("-"+m):"")+".js"}}function g(m){l=setTimeout(function(){j=a.utils.loaderstatus.COMPLETE;c.sendEvent(a.events.COMPLETE)},1000)}function f(m){j=a.utils.loaderstatus.ERROR;c.sendEvent(a.events.ERROR)}this.load=function(){if(j==a.utils.loaderstatus.NEW){if(b.lastIndexOf(".swf")>0){k=b;j=a.utils.loaderstatus.COMPLETE;c.sendEvent(a.events.COMPLETE);return}j=a.utils.loaderstatus.LOADING;var m=new a.utils.scriptloader(e());m.addEventListener(a.events.COMPLETE,g);m.addEventListener(a.events.ERROR,f);m.load()}};this.registerPlugin=function(o,n,m){if(l){clearTimeout(l);l=undefined}if(n&&m){k=m;h=n}else{if(typeof n=="string"){k=n}else{if(typeof n=="function"){h=n}else{if(!n&&!m){k=o}}}}j=a.utils.loaderstatus.COMPLETE;c.sendEvent(a.events.COMPLETE)};this.getStatus=function(){return j};this.getPluginName=function(){return a.utils.getPluginName(b)};this.getFlashPath=function(){if(k){switch(a.utils.getPluginPathType(k)){case a.utils.pluginPathType.ABSOLUTE:return k;case a.utils.pluginPathType.RELATIVE:if(b.lastIndexOf(".swf")>0){return a.utils.getAbsolutePath(k,window.location.href)}return a.utils.getAbsolutePath(k,e());case a.utils.pluginPathType.CDN:if(k.indexOf("-")>-1){return k+"h"}return k+"-h"}}return null};this.getJS=function(){return h};this.getPluginmode=function(){if(typeof k!="undefined"&&typeof h!="undefined"){return a.plugins.pluginmodes.HYBRID}else{if(typeof k!="undefined"){return a.plugins.pluginmodes.FLASH}else{if(typeof h!="undefined"){return a.plugins.pluginmodes.JAVASCRIPT}}}};this.getNewInstance=function(n,m,o){return new h(n,m,o)};this.getURL=function(){return b}}})(jwplayer);(function(a){a.plugins.pluginloader=function(h,e){var g={};var k=a.utils.loaderstatus.NEW;var d=false;var b=false;var c=new a.events.eventdispatcher();a.utils.extend(this,c);function f(){if(!b){b=true;k=a.utils.loaderstatus.COMPLETE;c.sendEvent(a.events.COMPLETE)}}function j(){if(!b){var m=0;for(plugin in g){var l=g[plugin].getStatus();if(l==a.utils.loaderstatus.LOADING||l==a.utils.loaderstatus.NEW){m++}}if(m==0){f()}}}this.setupPlugins=function(n,l,s){var m={length:0,plugins:{}};var p={length:0,plugins:{}};for(var o in g){var q=g[o].getPluginName();if(g[o].getFlashPath()){m.plugins[g[o].getFlashPath()]=l.plugins[o];m.plugins[g[o].getFlashPath()].pluginmode=g[o].getPluginmode();m.length++}if(g[o].getJS()){var r=document.createElement("div");r.id=n.id+"_"+q;r.style.position="absolute";r.style.zIndex=p.length+10;p.plugins[q]=g[o].getNewInstance(n,l.plugins[o],r);p.length++;if(typeof p.plugins[q].resize!="undefined"){n.onReady(s(p.plugins[q],r,true));n.onResize(s(p.plugins[q],r))}}}n.plugins=p.plugins;return m};this.load=function(){k=a.utils.loaderstatus.LOADING;d=true;for(var l in e){if(a.utils.exists(l)){g[l]=h.addPlugin(l);g[l].addEventListener(a.events.COMPLETE,j);g[l].addEventListener(a.events.ERROR,j)}}for(l in g){g[l].load()}d=false;j()};this.pluginFailed=function(){f()};this.getStatus=function(){return k}}})(jwplayer);(function(b){var a=[];b.api=function(d){this.container=d;this.id=d.id;var n={};var s={};var q={};var c=[];var h=undefined;var l=false;var j=[];var p=b.utils.getOuterHTML(d);var r={};var k={};this.getBuffer=function(){return this.callInternal("jwGetBuffer")};this.getContainer=function(){return this.container};function e(u,t){return function(z,v,w,x){if(u.renderingMode=="flash"||u.renderingMode=="html5"){var y;if(v){k[z]=v;y="jwplayer('"+u.id+"').callback('"+z+"')"}else{if(!v&&k[z]){delete k[z]}}h.jwDockSetButton(z,y,w,x)}return t}}this.getPlugin=function(t){var v=this;var u={};if(t=="dock"){return b.utils.extend(u,{setButton:e(v,u),show:function(){v.callInternal("jwDockShow");return u},hide:function(){v.callInternal("jwDockHide");return u},onShow:function(w){v.componentListener("dock",b.api.events.JWPLAYER_COMPONENT_SHOW,w);return u},onHide:function(w){v.componentListener("dock",b.api.events.JWPLAYER_COMPONENT_HIDE,w);return u}})}else{if(t=="controlbar"){return b.utils.extend(u,{show:function(){v.callInternal("jwControlbarShow");return u},hide:function(){v.callInternal("jwControlbarHide");return u},onShow:function(w){v.componentListener("controlbar",b.api.events.JWPLAYER_COMPONENT_SHOW,w);return u},onHide:function(w){v.componentListener("controlbar",b.api.events.JWPLAYER_COMPONENT_HIDE,w);return u}})}else{if(t=="display"){return b.utils.extend(u,{show:function(){v.callInternal("jwDisplayShow");return u},hide:function(){v.callInternal("jwDisplayHide");return u},onShow:function(w){v.componentListener("display",b.api.events.JWPLAYER_COMPONENT_SHOW,w);return u},onHide:function(w){v.componentListener("display",b.api.events.JWPLAYER_COMPONENT_HIDE,w);return u}})}else{return this.plugins[t]}}}};this.callback=function(t){if(k[t]){return k[t]()}};this.getDuration=function(){return this.callInternal("jwGetDuration")};this.getFullscreen=function(){return this.callInternal("jwGetFullscreen")};this.getHeight=function(){return this.callInternal("jwGetHeight")};this.getLockState=function(){return this.callInternal("jwGetLockState")};this.getMeta=function(){return this.getItemMeta()};this.getMute=function(){return this.callInternal("jwGetMute")};this.getPlaylist=function(){var u=this.callInternal("jwGetPlaylist");if(this.renderingMode=="flash"){b.utils.deepReplaceKeyName(u,"__dot__",".")}for(var t=0;t<u.length;t++){if(!b.utils.exists(u[t].index)){u[t].index=t}}return u};this.getPlaylistItem=function(t){if(!b.utils.exists(t)){t=this.getCurrentItem()}return this.getPlaylist()[t]};this.getPosition=function(){return this.callInternal("jwGetPosition")};this.getRenderingMode=function(){return this.renderingMode};this.getState=function(){return this.callInternal("jwGetState")};this.getVolume=function(){return this.callInternal("jwGetVolume")};this.getWidth=function(){return this.callInternal("jwGetWidth")};this.setFullscreen=function(t){if(!b.utils.exists(t)){this.callInternal("jwSetFullscreen",!this.callInternal("jwGetFullscreen"))}else{this.callInternal("jwSetFullscreen",t)}return this};this.setMute=function(t){if(!b.utils.exists(t)){this.callInternal("jwSetMute",!this.callInternal("jwGetMute"))}else{this.callInternal("jwSetMute",t)}return this};this.lock=function(){return this};this.unlock=function(){return this};this.load=function(t){this.callInternal("jwLoad",t);return this};this.playlistItem=function(t){this.callInternal("jwPlaylistItem",t);return this};this.playlistPrev=function(){this.callInternal("jwPlaylistPrev");return this};this.playlistNext=function(){this.callInternal("jwPlaylistNext");return this};this.resize=function(u,t){if(this.renderingMode=="html5"){h.jwResize(u,t)}else{this.container.width=u;this.container.height=t}return this};this.play=function(t){if(typeof t=="undefined"){t=this.getState();if(t==b.api.events.state.PLAYING||t==b.api.events.state.BUFFERING){this.callInternal("jwPause")}else{this.callInternal("jwPlay")}}else{this.callInternal("jwPlay",t)}return this};this.pause=function(t){if(typeof t=="undefined"){t=this.getState();if(t==b.api.events.state.PLAYING||t==b.api.events.state.BUFFERING){this.callInternal("jwPause")}else{this.callInternal("jwPlay")}}else{this.callInternal("jwPause",t)}return this};this.stop=function(){this.callInternal("jwStop");return this};this.seek=function(t){this.callInternal("jwSeek",t);return this};this.setVolume=function(t){this.callInternal("jwSetVolume",t);return this};this.onBufferChange=function(t){return this.eventListener(b.api.events.JWPLAYER_MEDIA_BUFFER,t)};this.onBufferFull=function(t){return this.eventListener(b.api.events.JWPLAYER_MEDIA_BUFFER_FULL,t)};this.onError=function(t){return this.eventListener(b.api.events.JWPLAYER_ERROR,t)};this.onFullscreen=function(t){return this.eventListener(b.api.events.JWPLAYER_FULLSCREEN,t)};this.onMeta=function(t){return this.eventListener(b.api.events.JWPLAYER_MEDIA_META,t)};this.onMute=function(t){return this.eventListener(b.api.events.JWPLAYER_MEDIA_MUTE,t)};this.onPlaylist=function(t){return this.eventListener(b.api.events.JWPLAYER_PLAYLIST_LOADED,t)};this.onPlaylistItem=function(t){return this.eventListener(b.api.events.JWPLAYER_PLAYLIST_ITEM,t)};this.onReady=function(t){return this.eventListener(b.api.events.API_READY,t)};this.onResize=function(t){return this.eventListener(b.api.events.JWPLAYER_RESIZE,t)};this.onComplete=function(t){return this.eventListener(b.api.events.JWPLAYER_MEDIA_COMPLETE,t)};this.onSeek=function(t){return this.eventListener(b.api.events.JWPLAYER_MEDIA_SEEK,t)};this.onTime=function(t){return this.eventListener(b.api.events.JWPLAYER_MEDIA_TIME,t)};this.onVolume=function(t){return this.eventListener(b.api.events.JWPLAYER_MEDIA_VOLUME,t)};this.onBuffer=function(t){return this.stateListener(b.api.events.state.BUFFERING,t)};this.onPause=function(t){return this.stateListener(b.api.events.state.PAUSED,t)};this.onPlay=function(t){return this.stateListener(b.api.events.state.PLAYING,t)};this.onIdle=function(t){return this.stateListener(b.api.events.state.IDLE,t)};this.remove=function(){n={};j=[];if(b.utils.getOuterHTML(this.container)!=p){b.api.destroyPlayer(this.id,p)}};this.setup=function(u){if(b.embed){var t=this.id;this.remove();var v=b(t);v.config=u;return new b.embed(v)}return this};this.registerPlugin=function(v,u,t){b.plugins.registerPlugin(v,u,t)};this.setPlayer=function(t,u){h=t;this.renderingMode=u};this.stateListener=function(t,u){if(!s[t]){s[t]=[];this.eventListener(b.api.events.JWPLAYER_PLAYER_STATE,g(t))}s[t].push(u);return this};function g(t){return function(v){var u=v.newstate,x=v.oldstate;if(u==t){var w=s[u];if(w){for(var y=0;y<w.length;y++){if(typeof w[y]=="function"){w[y].call(this,{oldstate:x,newstate:u})}}}}}}this.componentListener=function(t,u,v){if(!q[t]){q[t]={}}if(!q[t][u]){q[t][u]=[];this.eventListener(u,m(t,u))}q[t][u].push(v);return this};function m(t,u){return function(w){if(t==w.component){var v=q[t][u];if(v){for(var x=0;x<v.length;x++){if(typeof v[x]=="function"){v[x].call(this,w)}}}}}}this.addInternalListener=function(t,u){t.jwAddEventListener(u,'function(dat) { jwplayer("'+this.id+'").dispatchEvent("'+u+'", dat); }')};this.eventListener=function(t,u){if(!n[t]){n[t]=[];if(h&&l){this.addInternalListener(h,t)}}n[t].push(u);return this};this.dispatchEvent=function(v){if(n[v]){var u=f(v,arguments[1]);for(var t=0;t<n[v].length;t++){if(typeof n[v][t]=="function"){n[v][t].call(this,u)}}}};function f(v,t){var x=b.utils.extend({},t);if(v==b.api.events.JWPLAYER_FULLSCREEN&&!x.fullscreen){x.fullscreen=x.message=="true"?true:false;delete x.message}else{if(typeof x.data=="object"){x=b.utils.extend(x,x.data);delete x.data}}var u=["position","duration","offset"];for(var w in u){if(x[u[w]]){x[u[w]]=Math.round(x[u[w]]*1000)/1000}}return x}this.callInternal=function(u,t){if(l){if(typeof h!="undefined"&&typeof h[u]=="function"){if(b.utils.exists(t)){return(h[u])(t)}else{return(h[u])()}}return null}else{j.push({method:u,parameters:t})}};this.playerReady=function(v){l=true;if(!h){this.setPlayer(document.getElementById(v.id))}this.container=document.getElementById(this.id);for(var t in n){this.addInternalListener(h,t)}this.eventListener(b.api.events.JWPLAYER_PLAYLIST_ITEM,function(w){r={}});this.eventListener(b.api.events.JWPLAYER_MEDIA_META,function(w){b.utils.extend(r,w.metadata)});this.dispatchEvent(b.api.events.API_READY);while(j.length>0){var u=j.shift();this.callInternal(u.method,u.parameters)}};this.getItemMeta=function(){return r};this.getCurrentItem=function(){return this.callInternal("jwGetPlaylistIndex")};function o(v,x,w){var t=[];if(!x){x=0}if(!w){w=v.length-1}for(var u=x;u<=w;u++){t.push(v[u])}return t}return this};b.api.selectPlayer=function(d){var c;if(!b.utils.exists(d)){d=0}if(d.nodeType){c=d}else{if(typeof d=="string"){c=document.getElementById(d)}}if(c){var e=b.api.playerById(c.id);if(e){return e}else{return b.api.addPlayer(new b.api(c))}}else{if(typeof d=="number"){return b.getPlayers()[d]}}return null};b.api.events={API_READY:"jwplayerAPIReady",JWPLAYER_READY:"jwplayerReady",JWPLAYER_FULLSCREEN:"jwplayerFullscreen",JWPLAYER_RESIZE:"jwplayerResize",JWPLAYER_ERROR:"jwplayerError",JWPLAYER_COMPONENT_SHOW:"jwplayerComponentShow",JWPLAYER_COMPONENT_HIDE:"jwplayerComponentHide",JWPLAYER_MEDIA_BUFFER:"jwplayerMediaBuffer",JWPLAYER_MEDIA_BUFFER_FULL:"jwplayerMediaBufferFull",JWPLAYER_MEDIA_ERROR:"jwplayerMediaError",JWPLAYER_MEDIA_LOADED:"jwplayerMediaLoaded",JWPLAYER_MEDIA_COMPLETE:"jwplayerMediaComplete",JWPLAYER_MEDIA_SEEK:"jwplayerMediaSeek",JWPLAYER_MEDIA_TIME:"jwplayerMediaTime",JWPLAYER_MEDIA_VOLUME:"jwplayerMediaVolume",JWPLAYER_MEDIA_META:"jwplayerMediaMeta",JWPLAYER_MEDIA_MUTE:"jwplayerMediaMute",JWPLAYER_PLAYER_STATE:"jwplayerPlayerState",JWPLAYER_PLAYLIST_LOADED:"jwplayerPlaylistLoaded",JWPLAYER_PLAYLIST_ITEM:"jwplayerPlaylistItem"};b.api.events.state={BUFFERING:"BUFFERING",IDLE:"IDLE",PAUSED:"PAUSED",PLAYING:"PLAYING"};b.api.playerById=function(d){for(var c=0;c<a.length;c++){if(a[c].id==d){return a[c]}}return null};b.api.addPlayer=function(c){for(var d=0;d<a.length;d++){if(a[d]==c){return c}}a.push(c);return c};b.api.destroyPlayer=function(g,d){var f=-1;for(var j=0;j<a.length;j++){if(a[j].id==g){f=j;continue}}if(f>=0){var c=document.getElementById(a[f].id);if(document.getElementById(a[f].id+"_wrapper")){c=document.getElementById(a[f].id+"_wrapper")}if(c){if(d){b.utils.setOuterHTML(c,d)}else{var h=document.createElement("div");var e=c.id;if(c.id.indexOf("_wrapper")==c.id.length-8){newID=c.id.substring(0,c.id.length-8)}h.setAttribute("id",e);c.parentNode.replaceChild(h,c)}}a.splice(f,1)}return null};b.getPlayers=function(){return a.slice(0)}})(jwplayer);var _userPlayerReady=(typeof playerReady=="function")?playerReady:undefined;playerReady=function(b){var a=jwplayer.api.playerById(b.id);if(a){a.playerReady(b)}else{jwplayer.api.selectPlayer(b.id).playerReady(b)}if(_userPlayerReady){_userPlayerReady.call(this,b)}};(function(a){a.embed=function(g){var j={width:400,height:300,components:{controlbar:{position:"over"}}};var f=a.utils.mediaparser.parseMedia(g.container);var e=new a.embed.config(a.utils.extend(j,f,g.config),this);var h=a.plugins.loadPlugins(g.id,e.plugins);function c(m,l){for(var k in l){if(typeof m[k]=="function"){(m[k]).call(m,l[k])}}}function d(){if(h.getStatus()==a.utils.loaderstatus.COMPLETE){for(var m=0;m<e.modes.length;m++){if(e.modes[m].type&&a.embed[e.modes[m].type]){var k=e;if(e.modes[m].config){k=a.utils.extend(a.utils.clone(e),e.modes[m].config)}var l=new a.embed[e.modes[m].type](document.getElementById(g.id),e.modes[m],k,h,g);if(l.supportsConfig()){l.embed();c(g,e.events);return g}}}a.utils.log("No suitable players found");new a.embed.logo(a.utils.extend({hide:true},e.components.logo),"none",g.id)}}h.addEventListener(a.events.COMPLETE,d);h.addEventListener(a.events.ERROR,d);h.load();return g};function b(){if(!document.body){return setTimeout(b,15)}var c=a.utils.selectors.getElementsByTagAndClass("video","jwplayer");for(var d=0;d<c.length;d++){var e=c[d];a(e.id).setup({})}}b()})(jwplayer);(function(e){function h(){return[{type:"flash",src:"/jwplayer/player.swf"},{type:"html5"},{type:"download"}]}var a={players:"modes",autoplay:"autostart"};function b(n){var m=n.toLowerCase();var l=["left","right","top","bottom"];for(var k=0;k<l.length;k++){if(m==l[k]){return true}}return false}function c(l){var k=false;k=(l instanceof Array)||(typeof l=="object"&&!l.position&&!l.size);return k}function j(k){if(typeof k=="string"){if(parseInt(k).toString()==k||k.toLowerCase().indexOf("px")>-1){return parseInt(k)}}return k}var g=["playlist","dock","controlbar","logo","display"];function f(k){var n={};switch(e.utils.typeOf(k.plugins)){case"object":for(var m in k.plugins){n[e.utils.getPluginName(m)]=m}break;case"string":var o=k.plugins.split(",");for(var l=0;l<o.length;l++){n[e.utils.getPluginName(o[l])]=o[l]}break}return n}function d(o,n,m,k){if(e.utils.typeOf(o[n])!="object"){o[n]={}}var l=o[n][m];if(e.utils.typeOf(l)!="object"){o[n][m]=l={}}if(k){if(n=="plugins"){var p=e.utils.getPluginName(m);l[k]=o[p+"."+k];delete o[p+"."+k]}else{l[k]=o[m+"."+k];delete o[m+"."+k]}}}e.embed.deserialize=function(l){var m=f(l);for(var k in m){d(l,"plugins",m[k])}for(var p in l){if(p.indexOf(".")>-1){var o=p.split(".");var n=o[0];var p=o[1];if(e.utils.isInArray(g,n)){d(l,"components",n,p)}else{if(m[n]){d(l,"plugins",m[n],p)}}}}return l};e.embed.config=function(k,u){var t=e.utils.extend({},k);var r;if(c(t.playlist)){r=t.playlist;delete t.playlist}t=e.embed.deserialize(t);t.height=j(t.height);t.width=j(t.width);if(typeof t.plugins=="string"){var l=t.plugins.split(",");if(typeof t.plugins!="object"){t.plugins={}}for(var p=0;p<l.length;p++){var q=e.utils.getPluginName(l[p]);if(typeof t[q]=="object"){t.plugins[l[p]]=t[q];delete t[q]}else{t.plugins[l[p]]={}}}}for(var s=0;s<g.length;s++){var o=g[s];if(e.utils.exists(t[o])){if(typeof t[o]!="object"){if(!t.components[o]){t.components[o]={}}if(o=="logo"){t.components[o].file=t[o]}else{t.components[o].position=t[o]}delete t[o]}else{if(!t.components[o]){t.components[o]={}}e.utils.extend(t.components[o],t[o]);delete t[o]}}if(typeof t[o+"size"]!="undefined"){if(!t.components[o]){t.components[o]={}}t.components[o].size=t[o+"size"];delete t[o+"size"]}}if(typeof t.icons!="undefined"){if(!t.components.display){t.components.display={}}t.components.display.icons=t.icons;delete t.icons}for(var n in a){if(t[n]){if(!t[a[n]]){t[a[n]]=t[n]}delete t[n]}}var m;if(t.flashplayer&&!t.modes){m=h();m[0].src=t.flashplayer;delete t.flashplayer}else{if(t.modes){if(typeof t.modes=="string"){m=h();m[0].src=t.modes}else{if(t.modes instanceof Array){m=t.modes}else{if(typeof t.modes=="object"&&t.modes.type){m=[t.modes]}}}delete t.modes}else{m=h()}}t.modes=m;if(r){t.playlist=r}return t}})(jwplayer);(function(a){a.embed.download=function(c,g,b,d,f){this.embed=function(){var k=a.utils.extend({},b);var q={};var j=b.width?b.width:480;if(typeof j!="number"){j=parseInt(j,10)}var m=b.height?b.height:320;if(typeof m!="number"){m=parseInt(m,10)}var u,o,n;var s={};if(b.playlist&&b.playlist.length){s.file=b.playlist[0].file;o=b.playlist[0].image;s.levels=b.playlist[0].levels}else{s.file=b.file;o=b.image;s.levels=b.levels}if(s.file){u=s.file}else{if(s.levels&&s.levels.length){u=s.levels[0].file}}n=u?"pointer":"auto";var l={display:{style:{cursor:n,width:j,height:m,backgroundColor:"#000",position:"relative",textDecoration:"none",border:"none",display:"block"}},display_icon:{style:{cursor:n,position:"absolute",display:u?"block":"none",top:0,left:0,border:0,margin:0,padding:0,zIndex:3,width:50,height:50,backgroundImage:"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAALdJREFUeNrs18ENgjAYhmFouDOCcQJGcARHgE10BDcgTOIosAGwQOuPwaQeuFRi2p/3Sb6EC5L3QCxZBgAAAOCorLW1zMn65TrlkH4NcV7QNcUQt7Gn7KIhxA+qNIR81spOGkL8oFJDyLJRdosqKDDkK+iX5+d7huzwM40xptMQMkjIOeRGo+VkEVvIPfTGIpKASfYIfT9iCHkHrBEzf4gcUQ56aEzuGK/mw0rHpy4AAACAf3kJMACBxjAQNRckhwAAAABJRU5ErkJggg==)"}},display_iconBackground:{style:{cursor:n,position:"absolute",display:u?"block":"none",top:((m-50)/2),left:((j-50)/2),border:0,width:50,height:50,margin:0,padding:0,zIndex:2,backgroundImage:"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAEpJREFUeNrszwENADAIA7DhX8ENoBMZ5KR10EryckCJiIiIiIiIiIiIiIiIiIiIiIh8GmkRERERERERERERERERERERERGRHSPAAPlXH1phYpYaAAAAAElFTkSuQmCC)"}},display_image:{style:{width:j,height:m,display:o?"block":"none",position:"absolute",cursor:n,left:0,top:0,margin:0,padding:0,textDecoration:"none",zIndex:1,border:"none"}}};var h=function(v,x,y){var w=document.createElement(v);if(y){w.id=y}else{w.id=c.id+"_jwplayer_"+x}a.utils.css(w,l[x].style);return w};q.display=h("a","display",c.id);if(u){q.display.setAttribute("href",a.utils.getAbsolutePath(u))}q.display_image=h("img","display_image");q.display_image.setAttribute("alt","Click to download...");if(o){q.display_image.setAttribute("src",a.utils.getAbsolutePath(o))}if(true){q.display_icon=h("div","display_icon");q.display_iconBackground=h("div","display_iconBackground");q.display.appendChild(q.display_image);q.display_iconBackground.appendChild(q.display_icon);q.display.appendChild(q.display_iconBackground)}_css=a.utils.css;_hide=function(v){_css(v,{display:"none"})};function r(v){_imageWidth=q.display_image.naturalWidth;_imageHeight=q.display_image.naturalHeight;t()}function t(){a.utils.stretch(a.utils.stretching.UNIFORM,q.display_image,j,m,_imageWidth,_imageHeight)}q.display_image.onerror=function(v){_hide(q.display_image)};q.display_image.onload=r;c.parentNode.replaceChild(q.display,c);var p=(b.plugins&&b.plugins.logo)?b.plugins.logo:{};q.display.appendChild(new a.embed.logo(b.components.logo,"download",c.id));f.container=document.getElementById(f.id);f.setPlayer(q.display,"download")};this.supportsConfig=function(){if(b){var j=a.utils.getFirstPlaylistItemFromConfig(b);if(typeof j.file=="undefined"&&typeof j.levels=="undefined"){return true}else{if(j.file){return e(j.file,j.provider,j.playlistfile)}else{if(j.levels&&j.levels.length){for(var h=0;h<j.levels.length;h++){if(j.levels[h].file&&e(j.levels[h].file,j.provider,j.playlistfile)){return true}}}}}}else{return true}};function e(j,l,h){if(h){return false}var k=["image","sound","youtube","http"];if(l&&(k.toString().indexOf(l)>-1)){return true}if(!l||(l&&l=="video")){var m=a.utils.extension(j);if(m&&a.utils.extensionmap[m]){return true}}return false}}})(jwplayer);(function(a){a.embed.flash=function(f,g,l,e,j){function m(o,n,p){var q=document.createElement("param");q.setAttribute("name",n);q.setAttribute("value",p);o.appendChild(q)}function k(o,p,n){return function(q){if(n){document.getElementById(j.id+"_wrapper").appendChild(p)}var s=document.getElementById(j.id).getPluginConfig("display");o.resize(s.width,s.height);var r={left:s.x,top:s.y};a.utils.css(p,r)}}function d(p){if(!p){return{}}var r={};for(var o in p){var n=p[o];for(var q in n){r[o+"."+q]=n[q]}}return r}function h(q,p){if(q[p]){var s=q[p];for(var o in s){var n=s[o];if(typeof n=="string"){if(!q[o]){q[o]=n}}else{for(var r in n){if(!q[o+"."+r]){q[o+"."+r]=n[r]}}}}delete q[p]}}function b(q){if(!q){return{}}var t={},s=[];for(var n in q){var p=a.utils.getPluginName(n);var o=q[n];s.push(n);for(var r in o){t[p+"."+r]=o[r]}}t.plugins=s.join(",");return t}function c(p){var n=p.netstreambasepath?"":"netstreambasepath="+encodeURIComponent(window.location.href.split("#")[0])+"&";for(var o in p){if(typeof(p[o])=="object"){n+=o+"="+encodeURIComponent("[[JSON]]"+a.utils.strings.jsonToString(p[o]))+"&"}else{n+=o+"="+encodeURIComponent(p[o])+"&"}}return n.substring(0,n.length-1)}this.embed=function(){l.id=j.id;var y;var q=a.utils.extend({},l);var n=q.width;var w=q.height;if(f.id+"_wrapper"==f.parentNode.id){y=document.getElementById(f.id+"_wrapper")}else{y=document.createElement("div");y.id=f.id+"_wrapper";a.utils.wrap(f,y);a.utils.css(y,{position:"relative",width:n,height:w})}var o=e.setupPlugins(j,q,k);if(o.length>0){a.utils.extend(q,b(o.plugins))}else{delete q.plugins}var r=["height","width","modes","events"];for(var u=0;u<r.length;u++){delete q[r[u]]}var p="opaque";if(q.wmode){p=q.wmode}h(q,"components");h(q,"providers");if(typeof q["dock.position"]!="undefined"){if(q["dock.position"].toString().toLowerCase()=="false"){q.dock=q["dock.position"];delete q["dock.position"]}}var x="#000000";var t;if(a.utils.isIE()){var v='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" bgcolor="'+x+'" width="100%" height="100%" id="'+f.id+'" name="'+f.id+'" tabindex=0"">';v+='<param name="movie" value="'+g.src+'">';v+='<param name="allowfullscreen" value="true">';v+='<param name="allowscriptaccess" value="always">';v+='<param name="seamlesstabbing" value="true">';v+='<param name="wmode" value="'+p+'">';v+='<param name="flashvars" value="'+c(q)+'">';v+="</object>";a.utils.setOuterHTML(f,v);t=document.getElementById(f.id)}else{var s=document.createElement("object");s.setAttribute("type","application/x-shockwave-flash");s.setAttribute("data",g.src);s.setAttribute("width","100%");s.setAttribute("height","100%");s.setAttribute("bgcolor","#000000");s.setAttribute("id",f.id);s.setAttribute("name",f.id);s.setAttribute("tabindex",0);m(s,"allowfullscreen","true");m(s,"allowscriptaccess","always");m(s,"seamlesstabbing","true");m(s,"wmode",p);m(s,"flashvars",c(q));f.parentNode.replaceChild(s,f);t=s}j.container=t;j.setPlayer(t,"flash")};this.supportsConfig=function(){if(a.utils.hasFlash()){if(l){var o=a.utils.getFirstPlaylistItemFromConfig(l);if(typeof o.file=="undefined"&&typeof o.levels=="undefined"){return true}else{if(o.file){return flashCanPlay(o.file,o.provider)}else{if(o.levels&&o.levels.length){for(var n=0;n<o.levels.length;n++){if(o.levels[n].file&&flashCanPlay(o.levels[n].file,o.provider)){return true}}}}}}else{return true}}return false};flashCanPlay=function(n,p){var o=["video","http","sound","image"];if(p&&(o.toString().indexOf(p<0))){return true}var q=a.utils.extension(n);if(!q){return true}if(a.utils.exists(a.utils.extensionmap[q])&&!a.utils.exists(a.utils.extensionmap[q].flash)){return false}return true}}})(jwplayer);(function(a){a.embed.html5=function(c,g,b,d,f){function e(j,k,h){return function(l){var m=document.getElementById(c.id+"_displayarea");if(h){m.appendChild(k)}var n=m.style;j.resize(parseInt(n.width.replace("px","")),parseInt(n.height.replace("px","")));k.left=n.left;k.top=n.top}}this.embed=function(){if(a.html5){d.setupPlugins(f,b,e);c.innerHTML="";var j=a.utils.extend({screencolor:"0x000000"},b);var h=["plugins","modes","events"];for(var k=0;k<h.length;k++){delete j[h[k]]}if(j.levels&&!j.sources){j.sources=b.levels}if(j.skin&&j.skin.toLowerCase().indexOf(".zip")>0){j.skin=j.skin.replace(/\.zip/i,".xml")}var l=new (a.html5(c)).setup(j);f.container=document.getElementById(f.id);f.setPlayer(l,"html5")}else{return null}};this.supportsConfig=function(){if(!!a.vid.canPlayType){if(b){var j=a.utils.getFirstPlaylistItemFromConfig(b);if(typeof j.file=="undefined"&&typeof j.levels=="undefined"){return true}else{if(j.file){return html5CanPlay(a.vid,j.file,j.provider,j.playlistfile)}else{if(j.levels&&j.levels.length){for(var h=0;h<j.levels.length;h++){if(j.levels[h].file&&html5CanPlay(a.vid,j.levels[h].file,j.provider,j.playlistfile)){return true}}}}}}else{return true}}return false};html5CanPlay=function(k,j,l,h){if(h){return false}if(l&&l=="youtube"){return true}if(l&&l!="video"&&l!="http"&&l!="sound"){return false}var m=a.utils.extension(j);if(!a.utils.exists(m)||!a.utils.exists(a.utils.extensionmap[m])){return true}if(!a.utils.exists(a.utils.extensionmap[m].html5)){return false}if(a.utils.isLegacyAndroid()&&m.match(/m4v|mp4/)){return true}return browserCanPlay(k,a.utils.extensionmap[m].html5)};browserCanPlay=function(j,h){if(!h){return true}if(j.canPlayType(h)){return true}else{if(h=="audio/mp3"&&navigator.userAgent.match(/safari/i)){return j.canPlayType("audio/mpeg")}else{return false}}}}})(jwplayer);(function(a){a.embed.logo=function(m,l,d){var j={prefix:"http://l.longtailvideo.com/"+l+"/",file:"logo.png",link:"http://www.longtailvideo.com/players/jw-flv-player/",margin:8,out:0.5,over:1,timeout:5,hide:false,position:"bottom-left"};_css=a.utils.css;var b;var h;k();function k(){o();c();f()}function o(){if(j.prefix){var q=a.version.split(/\W/).splice(0,2).join("/");if(j.prefix.indexOf(q)<0){j.prefix+=q+"/"}}h=a.utils.extend({},j)}function p(){var s={border:"none",textDecoration:"none",position:"absolute",cursor:"pointer",zIndex:10};s.display=h.hide?"none":"block";var r=h.position.toLowerCase().split("-");for(var q in r){s[r[q]]=h.margin}return s}function c(){b=document.createElement("img");b.id=d+"_jwplayer_logo";b.style.display="none";b.onload=function(q){_css(b,p());e()};if(!h.file){return}if(h.file.indexOf("http://")===0){b.src=h.file}else{b.src=h.prefix+h.file}}if(!h.file){return}function f(){if(h.link){b.onmouseover=g;b.onmouseout=e;b.onclick=n}else{this.mouseEnabled=false}}function n(q){if(typeof q!="undefined"){q.preventDefault();q.stopPropagation()}if(h.link){window.open(h.link,"_blank")}return}function e(q){if(h.link){b.style.opacity=h.out}return}function g(q){if(h.hide){b.style.opacity=h.over}return}return b}})(jwplayer);(function(a){a.html5=function(b){var c=b;this.setup=function(d){a.utils.extend(this,new a.html5.api(c,d));return this};return this}})(jwplayer);(function(b){var d=b.utils;var c=d.css;b.html5.view=function(r,q,f){var u=r;var n=q;var x=f;var w;var g;var C;var s;var D;var p;var A;function z(){w=document.createElement("div");w.id=n.id;w.className=n.className;_videowrapper=document.createElement("div");_videowrapper.id=w.id+"_video_wrapper";n.id=w.id+"_video";c(w,{position:"relative",height:x.height,width:x.width,padding:0,backgroundColor:E(),zIndex:0});function E(){if(u.skin.getComponentSettings("display")&&u.skin.getComponentSettings("display").backgroundcolor){return u.skin.getComponentSettings("display").backgroundcolor}return parseInt("000000",16)}c(n,{width:x.width,height:x.height,top:0,left:0,zIndex:1,margin:"auto",display:"block"});c(_videowrapper,{overflow:"hidden",position:"absolute",top:0,left:0,bottom:0,right:0});d.wrap(n,w);d.wrap(n,_videowrapper);s=document.createElement("div");s.id=w.id+"_displayarea";w.appendChild(s)}function k(){for(var E=0;E<x.plugins.order.length;E++){var F=x.plugins.order[E];if(d.exists(x.plugins.object[F].getDisplayElement)){x.plugins.object[F].height=d.parseDimension(x.plugins.object[F].getDisplayElement().style.height);x.plugins.object[F].width=d.parseDimension(x.plugins.object[F].getDisplayElement().style.width);x.plugins.config[F].currentPosition=x.plugins.config[F].position}}v()}function m(E){c(s,{display:x.getMedia().hasChrome()?"none":"block"})}function v(F){var H=x.getMedia()?x.getMedia().getDisplayElement():null;if(d.exists(H)){if(A!=H){if(A&&A.parentNode){A.parentNode.replaceChild(H,A)}A=H}for(var E=0;E<x.plugins.order.length;E++){var G=x.plugins.order[E];if(d.exists(x.plugins.object[G].getDisplayElement)){x.plugins.config[G].currentPosition=x.plugins.config[G].position}}}j(x.width,x.height)}this.setup=function(){if(x&&x.getMedia()){n=x.getMedia().getDisplayElement()}z();k();u.jwAddEventListener(b.api.events.JWPLAYER_PLAYER_STATE,m);u.jwAddEventListener(b.api.events.JWPLAYER_MEDIA_LOADED,v);u.jwAddEventListener(b.api.events.JWPLAYER_MEDIA_META,function(){y()});var E;if(d.exists(window.onresize)){E=window.onresize}window.onresize=function(F){if(d.exists(E)){try{E(F)}catch(H){}}if(u.jwGetFullscreen()){var G=document.body.getBoundingClientRect();x.width=Math.abs(G.left)+Math.abs(G.right);x.height=window.innerHeight}j(x.width,x.height)}};function h(E){switch(E.keyCode){case 27:if(u.jwGetFullscreen()){u.jwSetFullscreen(false)}break;case 32:if(u.jwGetState()!=b.api.events.state.IDLE&&u.jwGetState()!=b.api.events.state.PAUSED){u.jwPause()}else{u.jwPlay()}break}}function j(H,E){if(w.style.display=="none"){return}var G=[].concat(x.plugins.order);G.reverse();D=G.length+2;if(!x.fullscreen){x.width=H;x.height=E;g=H;C=E;c(s,{top:0,bottom:0,left:0,right:0,width:H,height:E,position:"relative"});c(w,{height:C,width:g});var F=o(t,G);if(F.length>0){D+=F.length;var J=F.indexOf("playlist"),I=F.indexOf("controlbar");if(J>=0&&I>=0){F[J]=F.splice(I,1,F[J])[0]}o(l,F,true)}}else{if(!(navigator&&navigator.vendor&&navigator.vendor.indexOf("Apple")==0)){o(B,G,true)}}y()}function o(J,G,H){var F=[];for(var E=0;E<G.length;E++){var K=G[E];if(d.exists(x.plugins.object[K].getDisplayElement)){if(x.plugins.config[K].currentPosition!=b.html5.view.positions.NONE){var I=J(K,D--);if(!I){F.push(K)}else{x.plugins.object[K].resize(I.width,I.height);if(H){delete I.width;delete I.height}c(x.plugins.object[K].getDisplayElement(),I)}}else{c(x.plugins.object[K].getDisplayElement(),{display:"none"})}}}return F}function t(F,G){if(d.exists(x.plugins.object[F].getDisplayElement)){if(x.plugins.config[F].position&&a(x.plugins.config[F].position)){if(!d.exists(x.plugins.object[F].getDisplayElement().parentNode)){w.appendChild(x.plugins.object[F].getDisplayElement())}var E=e(F);E.zIndex=G;return E}}return false}function l(G,H){if(!d.exists(x.plugins.object[G].getDisplayElement().parentNode)){s.appendChild(x.plugins.object[G].getDisplayElement())}var E=x.width,F=x.height;if(typeof x.width=="string"&&x.width.lastIndexOf("%")>-1){percentage=parseFloat(x.width.substring(0,x.width.lastIndexOf("%")))/100;E=Math.round(window.innerWidth*percentage)}if(typeof x.height=="string"&&x.height.lastIndexOf("%")>-1){percentage=parseFloat(x.height.substring(0,x.height.lastIndexOf("%")))/100;F=Math.round(window.innerHeight*percentage)}return{position:"absolute",width:(E-d.parseDimension(s.style.left)-d.parseDimension(s.style.right)),height:(F-d.parseDimension(s.style.top)-d.parseDimension(s.style.bottom)),zIndex:H}}function B(E,F){return{position:"fixed",width:x.width,height:x.height,zIndex:F}}function y(){if(!d.exists(x.getMedia())){return}s.style.position="absolute";var H=x.getMedia().getDisplayElement();if(H&&H.tagName.toLowerCase()=="video"){H.style.position="absolute";var E,I;if(s.style.width.toString().lastIndexOf("%")>-1||s.style.width.toString().lastIndexOf("%")>-1){var F=s.getBoundingClientRect();E=Math.abs(F.left)+Math.abs(F.right);I=Math.abs(F.top)+Math.abs(F.bottom)}else{E=d.parseDimension(s.style.width);I=d.parseDimension(s.style.height)}if(H.parentNode){H.parentNode.style.left=s.style.left;H.parentNode.style.top=s.style.top}d.stretch(u.jwGetStretching(),H,E,I,H.videoWidth?H.videoWidth:400,H.videoHeight?H.videoHeight:300)}else{var G=x.plugins.object.display.getDisplayElement();if(G){x.getMedia().resize(d.parseDimension(G.style.width),d.parseDimension(G.style.height))}else{x.getMedia().resize(d.parseDimension(s.style.width),d.parseDimension(s.style.height))}}}function e(F){var G={position:"absolute",margin:0,padding:0,top:null};var E=x.plugins.config[F].currentPosition.toLowerCase();switch(E.toUpperCase()){case b.html5.view.positions.TOP:G.top=d.parseDimension(s.style.top);G.left=d.parseDimension(s.style.left);G.width=g-d.parseDimension(s.style.left)-d.parseDimension(s.style.right);G.height=x.plugins.object[F].height;s.style[E]=d.parseDimension(s.style[E])+x.plugins.object[F].height+"px";s.style.height=d.parseDimension(s.style.height)-G.height+"px";break;case b.html5.view.positions.RIGHT:G.top=d.parseDimension(s.style.top);G.right=d.parseDimension(s.style.right);G.width=x.plugins.object[F].width;G.height=C-d.parseDimension(s.style.top)-d.parseDimension(s.style.bottom);s.style[E]=d.parseDimension(s.style[E])+x.plugins.object[F].width+"px";s.style.width=d.parseDimension(s.style.width)-G.width+"px";break;case b.html5.view.positions.BOTTOM:G.bottom=d.parseDimension(s.style.bottom);G.left=d.parseDimension(s.style.left);G.width=g-d.parseDimension(s.style.left)-d.parseDimension(s.style.right);G.height=x.plugins.object[F].height;s.style[E]=d.parseDimension(s.style[E])+x.plugins.object[F].height+"px";s.style.height=d.parseDimension(s.style.height)-G.height+"px";break;case b.html5.view.positions.LEFT:G.top=d.parseDimension(s.style.top);G.left=d.parseDimension(s.style.left);G.width=x.plugins.object[F].width;G.height=C-d.parseDimension(s.style.top)-d.parseDimension(s.style.bottom);s.style[E]=d.parseDimension(s.style[E])+x.plugins.object[F].width+"px";s.style.width=d.parseDimension(s.style.width)-G.width+"px";break;default:break}return G}this.resize=j;this.fullscreen=function(H){if(navigator&&navigator.vendor&&navigator.vendor.indexOf("Apple")===0){if(x.getMedia().getDisplayElement().webkitSupportsFullscreen){if(H){try{x.getMedia().getDisplayElement().webkitEnterFullscreen()}catch(G){}}else{try{x.getMedia().getDisplayElement().webkitExitFullscreen()}catch(G){}}}}else{if(H){document.onkeydown=h;clearInterval(p);var F=document.body.getBoundingClientRect();x.width=Math.abs(F.left)+Math.abs(F.right);x.height=window.innerHeight;var E={position:"fixed",width:"100%",height:"100%",top:0,left:0,zIndex:2147483000};c(w,E);E.zIndex=1;if(x.getMedia()&&x.getMedia().getDisplayElement()){c(x.getMedia().getDisplayElement(),E)}E.zIndex=2;c(s,E)}else{document.onkeydown="";x.width=g;x.height=C;c(w,{position:"relative",height:x.height,width:x.width,zIndex:0})}j(x.width,x.height)}}};function a(e){return([b.html5.view.positions.TOP,b.html5.view.positions.RIGHT,b.html5.view.positions.BOTTOM,b.html5.view.positions.LEFT].toString().indexOf(e.toUpperCase())>-1)}b.html5.view.positions={TOP:"TOP",RIGHT:"RIGHT",BOTTOM:"BOTTOM",LEFT:"LEFT",OVER:"OVER",NONE:"NONE"}})(jwplayer);(function(a){var b={backgroundcolor:"",margin:10,font:"Arial,sans-serif",fontsize:10,fontcolor:parseInt("000000",16),fontstyle:"normal",fontweight:"bold",buttoncolor:parseInt("ffffff",16),position:a.html5.view.positions.BOTTOM,idlehide:false,layout:{left:{position:"left",elements:[{name:"play",type:"button"},{name:"divider",type:"divider"},{name:"prev",type:"button"},{name:"divider",type:"divider"},{name:"next",type:"button"},{name:"divider",type:"divider"},{name:"elapsed",type:"text"}]},center:{position:"center",elements:[{name:"time",type:"slider"}]},right:{position:"right",elements:[{name:"duration",type:"text"},{name:"blank",type:"button"},{name:"divider",type:"divider"},{name:"mute",type:"button"},{name:"volume",type:"slider"},{name:"divider",type:"divider"},{name:"fullscreen",type:"button"}]}}};_utils=a.utils;_css=_utils.css;_hide=function(c){_css(c,{display:"none"})};_show=function(c){_css(c,{display:"block"})};a.html5.controlbar=function(l,V){var k=l;var D=_utils.extend({},b,k.skin.getComponentSettings("controlbar"),V);if(D.position==a.html5.view.positions.NONE||typeof a.html5.view.positions[D.position]=="undefined"){return}if(_utils.mapLength(k.skin.getComponentLayout("controlbar"))>0){D.layout=k.skin.getComponentLayout("controlbar")}var ac;var P;var ab;var E;var v="none";var g;var j;var ad;var f;var e;var y;var Q={};var p=false;var c={};var Y;var h=false;var o;var d;var S=false;var G=false;var W=new a.html5.eventdispatcher();_utils.extend(this,W);function J(){if(!Y){Y=k.skin.getSkinElement("controlbar","background");if(!Y){Y={width:0,height:0,src:null}}}return Y}function N(){ab=0;E=0;P=0;if(!p){var ak={height:J().height,backgroundColor:D.backgroundcolor};ac=document.createElement("div");ac.id=k.id+"_jwplayer_controlbar";_css(ac,ak)}var aj=(k.skin.getSkinElement("controlbar","capLeft"));var ai=(k.skin.getSkinElement("controlbar","capRight"));if(aj){x("capLeft","left",false,ac)}var al={position:"absolute",height:J().height,left:(aj?aj.width:0),zIndex:0};Z("background",ac,al,"img");if(J().src){Q.background.src=J().src}al.zIndex=1;Z("elements",ac,al);if(ai){x("capRight","right",false,ac)}}this.getDisplayElement=function(){return ac};this.resize=function(ak,ai){_utils.cancelAnimation(ac);document.getElementById(k.id).onmousemove=A;e=ak;y=ai;if(G!=k.jwGetFullscreen()){G=k.jwGetFullscreen();d=undefined}var aj=w();A();I({id:k.id,duration:ad,position:j});u({id:k.id,bufferPercent:f});return aj};this.show=function(){if(h){h=false;_show(ac);T()}};this.hide=function(){if(!h){h=true;_hide(ac);aa()}};function q(){var aj=["timeSlider","volumeSlider","timeSliderRail","volumeSliderRail"];for(var ak in aj){var ai=aj[ak];if(typeof Q[ai]!="undefined"){c[ai]=Q[ai].getBoundingClientRect()}}}function A(ai){if(h){return}if(D.position==a.html5.view.positions.OVER||k.jwGetFullscreen()){clearTimeout(o);switch(k.jwGetState()){case a.api.events.state.PAUSED:case a.api.events.state.IDLE:if(!D.idlehide||_utils.exists(ai)){U()}if(D.idlehide){o=setTimeout(function(){z()},2000)}break;default:if(ai){U()}o=setTimeout(function(){z()},2000);break}}}function z(ai){aa();_utils.cancelAnimation(ac);_utils.fadeTo(ac,0,0.1,1,0)}function U(){T();_utils.cancelAnimation(ac);_utils.fadeTo(ac,1,0,1,0)}function H(ai){return function(){if(S&&d!=ai){d=ai;W.sendEvent(ai,{component:"controlbar",boundingRect:O()})}}}var T=H(a.api.events.JWPLAYER_COMPONENT_SHOW);var aa=H(a.api.events.JWPLAYER_COMPONENT_HIDE);function O(){if(D.position==a.html5.view.positions.OVER||k.jwGetFullscreen()){return _utils.getDimensions(ac)}else{return{x:0,y:0,width:0,height:0}}}function Z(am,al,ak,ai){var aj;if(!p){if(!ai){ai="div"}aj=document.createElement(ai);Q[am]=aj;aj.id=ac.id+"_"+am;al.appendChild(aj)}else{aj=document.getElementById(ac.id+"_"+am)}if(_utils.exists(ak)){_css(aj,ak)}return aj}function M(){ah(D.layout.left);ah(D.layout.right,-1);ah(D.layout.center)}function ah(al,ai){var am=al.position=="right"?"right":"left";var ak=_utils.extend([],al.elements);if(_utils.exists(ai)){ak.reverse()}for(var aj=0;aj<ak.length;aj++){C(ak[aj],am)}}function K(){return P++}function C(am,ao){var al,aj,ak,ai,aq;if(am.type=="divider"){x("divider"+K(),ao,true,undefined,undefined,am.width,am.element);return}switch(am.name){case"play":x("playButton",ao,false);x("pauseButton",ao,true);R("playButton","jwPlay");R("pauseButton","jwPause");break;case"prev":x("prevButton",ao,true);R("prevButton","jwPlaylistPrev");break;case"stop":x("stopButton",ao,true);R("stopButton","jwStop");break;case"next":x("nextButton",ao,true);R("nextButton","jwPlaylistNext");break;case"elapsed":x("elapsedText",ao,true);break;case"time":aj=!_utils.exists(k.skin.getSkinElement("controlbar","timeSliderCapLeft"))?0:k.skin.getSkinElement("controlbar","timeSliderCapLeft").width;ak=!_utils.exists(k.skin.getSkinElement("controlbar","timeSliderCapRight"))?0:k.skin.getSkinElement("controlbar","timeSliderCapRight").width;al=ao=="left"?aj:ak;ai=k.skin.getSkinElement("controlbar","timeSliderRail").width+aj+ak;aq={height:J().height,position:"absolute",top:0,width:ai};aq[ao]=ao=="left"?ab:E;var an=Z("timeSlider",Q.elements,aq);x("timeSliderCapLeft",ao,true,an,ao=="left"?0:al);x("timeSliderRail",ao,false,an,al);x("timeSliderBuffer",ao,false,an,al);x("timeSliderProgress",ao,false,an,al);x("timeSliderThumb",ao,false,an,al);x("timeSliderCapRight",ao,true,an,ao=="right"?0:al);X("time");break;case"fullscreen":x("fullscreenButton",ao,false);x("normalscreenButton",ao,true);R("fullscreenButton","jwSetFullscreen",true);R("normalscreenButton","jwSetFullscreen",false);break;case"volume":aj=!_utils.exists(k.skin.getSkinElement("controlbar","volumeSliderCapLeft"))?0:k.skin.getSkinElement("controlbar","volumeSliderCapLeft").width;ak=!_utils.exists(k.skin.getSkinElement("controlbar","volumeSliderCapRight"))?0:k.skin.getSkinElement("controlbar","volumeSliderCapRight").width;al=ao=="left"?aj:ak;ai=k.skin.getSkinElement("controlbar","volumeSliderRail").width+aj+ak;aq={height:J().height,position:"absolute",top:0,width:ai};aq[ao]=ao=="left"?ab:E;var ap=Z("volumeSlider",Q.elements,aq);x("volumeSliderCapLeft",ao,true,ap,ao=="left"?0:al);x("volumeSliderRail",ao,true,ap,al);x("volumeSliderProgress",ao,false,ap,al);x("volumeSliderCapRight",ao,true,ap,ao=="right"?0:al);X("volume");break;case"mute":x("muteButton",ao,false);x("unmuteButton",ao,true);R("muteButton","jwSetMute",true);R("unmuteButton","jwSetMute",false);break;case"duration":x("durationText",ao,true);break}}function x(al,ao,aj,ar,am,ai,ak){if(_utils.exists(k.skin.getSkinElement("controlbar",al))||al.indexOf("Text")>0||al.indexOf("divider")===0){var an={height:J().height,position:"absolute",display:"block",top:0};if((al.indexOf("next")===0||al.indexOf("prev")===0)&&k.jwGetPlaylist().length<2){aj=false;an.display="none"}var at;if(al.indexOf("Text")>0){al.innerhtml="00:00";an.font=D.fontsize+"px/"+(J().height+1)+"px "+D.font;an.color=D.fontcolor;an.textAlign="center";an.fontWeight=D.fontweight;an.fontStyle=D.fontstyle;an.cursor="default";at=14+3*D.fontsize}else{if(al.indexOf("divider")===0){if(ai){if(!isNaN(parseInt(ai))){at=parseInt(ai)}}else{if(ak){var ap=k.skin.getSkinElement("controlbar",ak);if(ap){an.background="url("+ap.src+") repeat-x center left";at=ap.width}}else{an.background="url("+k.skin.getSkinElement("controlbar","divider").src+") repeat-x center left";at=k.skin.getSkinElement("controlbar","divider").width}}}else{an.background="url("+k.skin.getSkinElement("controlbar",al).src+") repeat-x center left";at=k.skin.getSkinElement("controlbar",al).width}}if(ao=="left"){an.left=isNaN(am)?ab:am;if(aj){ab+=at}}else{if(ao=="right"){an.right=isNaN(am)?E:am;if(aj){E+=at}}}if(_utils.typeOf(ar)=="undefined"){ar=Q.elements}an.width=at;if(p){_css(Q[al],an)}else{var aq=Z(al,ar,an);if(_utils.exists(k.skin.getSkinElement("controlbar",al+"Over"))){aq.onmouseover=function(au){aq.style.backgroundImage=["url(",k.skin.getSkinElement("controlbar",al+"Over").src,")"].join("")};aq.onmouseout=function(au){aq.style.backgroundImage=["url(",k.skin.getSkinElement("controlbar",al).src,")"].join("")}}}}}function F(){k.jwAddEventListener(a.api.events.JWPLAYER_PLAYLIST_LOADED,B);k.jwAddEventListener(a.api.events.JWPLAYER_PLAYLIST_ITEM,s);k.jwAddEventListener(a.api.events.JWPLAYER_MEDIA_BUFFER,u);k.jwAddEventListener(a.api.events.JWPLAYER_PLAYER_STATE,r);k.jwAddEventListener(a.api.events.JWPLAYER_MEDIA_TIME,I);k.jwAddEventListener(a.api.events.JWPLAYER_MEDIA_MUTE,ag);k.jwAddEventListener(a.api.events.JWPLAYER_MEDIA_VOLUME,m);k.jwAddEventListener(a.api.events.JWPLAYER_MEDIA_COMPLETE,L)}function B(){N();M();w();ae()}function s(ai){ad=k.jwGetPlaylist()[ai.index].duration;I({id:k.id,duration:ad,position:0});u({id:k.id,bufferProgress:0})}function ae(){I({id:k.id,duration:k.jwGetDuration(),position:0});u({id:k.id,bufferProgress:0});ag({id:k.id,mute:k.jwGetMute()});r({id:k.id,newstate:a.api.events.state.IDLE});m({id:k.id,volume:k.jwGetVolume()})}function R(ak,al,aj){if(p){return}if(_utils.exists(k.skin.getSkinElement("controlbar",ak))){var ai=Q[ak];if(_utils.exists(ai)){_css(ai,{cursor:"pointer"});if(al=="fullscreen"){ai.onmouseup=function(am){am.stopPropagation();k.jwSetFullscreen(!k.jwGetFullscreen())}}else{ai.onmouseup=function(am){am.stopPropagation();if(_utils.exists(aj)){k[al](aj)}else{k[al]()}}}}}}function X(ai){if(p){return}var aj=Q[ai+"Slider"];_css(Q.elements,{cursor:"pointer"});_css(aj,{cursor:"pointer"});aj.onmousedown=function(ak){v=ai};aj.onmouseup=function(ak){ak.stopPropagation();af(ak.pageX)};aj.onmousemove=function(ak){if(v=="time"){g=true;var al=ak.pageX-c[ai+"Slider"].left-window.pageXOffset;_css(Q.timeSliderThumb,{left:al})}}}function af(aj){g=false;var ai;if(v=="time"){ai=aj-c.timeSliderRail.left+window.pageXOffset;var al=ai/c.timeSliderRail.width*ad;if(al<0){al=0}else{if(al>ad){al=ad-3}}if(k.jwGetState()==a.api.events.state.PAUSED||k.jwGetState()==a.api.events.state.IDLE){k.jwPlay()}k.jwSeek(al)}else{if(v=="volume"){ai=aj-c.volumeSliderRail.left-window.pageXOffset;var ak=Math.round(ai/c.volumeSliderRail.width*100);if(ak<0){ak=0}else{if(ak>100){ak=100}}if(k.jwGetMute()){k.jwSetMute(false)}k.jwSetVolume(ak)}}v="none"}function u(aj){if(_utils.exists(aj.bufferPercent)){f=aj.bufferPercent}if(c.timeSliderRail){var ak=c.timeSliderRail.width;var ai=isNaN(Math.round(ak*f/100))?0:Math.round(ak*f/100);_css(Q.timeSliderBuffer,{width:ai})}}function ag(ai){if(ai.mute){_hide(Q.muteButton);_show(Q.unmuteButton);_hide(Q.volumeSliderProgress)}else{_show(Q.muteButton);_hide(Q.unmuteButton);_show(Q.volumeSliderProgress)}}function r(ai){if(ai.newstate==a.api.events.state.BUFFERING||ai.newstate==a.api.events.state.PLAYING){_show(Q.pauseButton);_hide(Q.playButton)}else{_hide(Q.pauseButton);_show(Q.playButton)}A();if(ai.newstate==a.api.events.state.IDLE){_hide(Q.timeSliderBuffer);_hide(Q.timeSliderProgress);_hide(Q.timeSliderThumb);I({id:k.id,duration:k.jwGetDuration(),position:0})}else{_show(Q.timeSliderBuffer);if(ai.newstate!=a.api.events.state.BUFFERING){_show(Q.timeSliderProgress);_show(Q.timeSliderThumb)}}}function L(ai){u({bufferPercent:0});I(_utils.extend(ai,{position:0,duration:ad}))}function I(al){if(_utils.exists(al.position)){j=al.position}if(_utils.exists(al.duration)){ad=al.duration}var aj=(j===ad===0)?0:j/ad;var am=c.timeSliderRail;if(am){var ai=isNaN(Math.round(am.width*aj))?0:Math.round(am.width*aj);var ak=ai;if(Q.timeSliderProgress){Q.timeSliderProgress.style.width=ai+"px";if(!g){if(Q.timeSliderThumb){Q.timeSliderThumb.style.left=ak+"px"}}}}if(Q.durationText){Q.durationText.innerHTML=_utils.timeFormat(ad)}if(Q.elapsedText){Q.elapsedText.innerHTML=_utils.timeFormat(j)}}function n(){var am,aj;var ak=document.getElementById(ac.id+"_elements");if(!ak){return}var al=ak.childNodes;for(var ai in ak.childNodes){if(isNaN(parseInt(ai,10))){continue}if(al[ai].id.indexOf(ac.id+"_divider")===0&&aj&&aj.id.indexOf(ac.id+"_divider")===0&&al[ai].style.backgroundImage==aj.style.backgroundImage){al[ai].style.display="none"}else{if(al[ai].id.indexOf(ac.id+"_divider")===0&&am&&am.style.display!="none"){al[ai].style.display="block"}}if(al[ai].style.display!="none"){aj=al[ai]}am=al[ai]}}function w(){n();if(k.jwGetFullscreen()){_show(Q.normalscreenButton);_hide(Q.fullscreenButton)}else{_hide(Q.normalscreenButton);_show(Q.fullscreenButton)}var aj={width:e};var ai={};if(D.position==a.html5.view.positions.OVER||k.jwGetFullscreen()){aj.left=D.margin;aj.width-=2*D.margin;aj.top=y-J().height-D.margin;aj.height=J().height}var al=k.skin.getSkinElement("controlbar","capLeft");var ak=k.skin.getSkinElement("controlbar","capRight");ai.left=al?al.width:0;ai.width=aj.width-ai.left-(ak?ak.width:0);var am=!_utils.exists(k.skin.getSkinElement("controlbar","timeSliderCapLeft"))?0:k.skin.getSkinElement("controlbar","timeSliderCapLeft").width;_css(Q.timeSliderRail,{width:(ai.width-ab-E),left:am});if(_utils.exists(Q.timeSliderCapRight)){_css(Q.timeSliderCapRight,{left:am+(ai.width-ab-E)})}_css(ac,aj);_css(Q.elements,ai);_css(Q.background,ai);q();return aj}function m(am){if(_utils.exists(Q.volumeSliderRail)){var ak=isNaN(am.volume/100)?1:am.volume/100;var al=_utils.parseDimension(Q.volumeSliderRail.style.width);var ai=isNaN(Math.round(al*ak))?0:Math.round(al*ak);var an=_utils.parseDimension(Q.volumeSliderRail.style.right);var aj=(!_utils.exists(k.skin.getSkinElement("controlbar","volumeSliderCapLeft")))?0:k.skin.getSkinElement("controlbar","volumeSliderCapLeft").width;_css(Q.volumeSliderProgress,{width:ai,left:aj});if(_utils.exists(Q.volumeSliderCapLeft)){_css(Q.volumeSliderCapLeft,{left:0})}}}function t(){N();M();q();p=true;F();D.idlehide=(D.idlehide.toString().toLowerCase()=="true");if(D.position==a.html5.view.positions.OVER&&D.idlehide){ac.style.opacity=0;S=true}else{setTimeout((function(){S=true;T()}),1)}ae()}t();return this}})(jwplayer);(function(b){var a=["width","height","state","playlist","item","position","buffer","duration","volume","mute","fullscreen"];var c=b.utils;b.html5.controller=function(z,w,h,v){var C=z;var G=h;var g=v;var o=w;var J=true;var e=-1;var A=c.exists(G.config.debug)&&(G.config.debug.toString().toLowerCase()=="console");var m=new b.html5.eventdispatcher(o.id,A);c.extend(this,m);var E=[];var d=false;function r(M){if(d){m.sendEvent(M.type,M)}else{E.push(M)}}function K(M){if(!d){m.sendEvent(b.api.events.JWPLAYER_READY,M);if(b.utils.exists(window.playerReady)){playerReady(M)}if(b.utils.exists(window[h.config.playerReady])){window[h.config.playerReady](M)}while(E.length>0){var O=E.shift();m.sendEvent(O.type,O)}if(h.config.autostart&&!b.utils.isIOS()){t(G.item)}while(p.length>0){var N=p.shift();x(N.method,N.arguments)}d=true}}G.addGlobalListener(r);G.addEventListener(b.api.events.JWPLAYER_MEDIA_BUFFER_FULL,function(){G.getMedia().play()});G.addEventListener(b.api.events.JWPLAYER_MEDIA_TIME,function(M){if(M.position>=G.playlist[G.item].start&&e>=0){G.playlist[G.item].start=e;e=-1}});G.addEventListener(b.api.events.JWPLAYER_MEDIA_COMPLETE,function(M){setTimeout(s,25)});function u(){try{f(G.item);if(G.playlist[G.item].levels[0].file.length>0){if(J||G.state==b.api.events.state.IDLE){G.getMedia().load(G.playlist[G.item]);J=false}else{if(G.state==b.api.events.state.PAUSED){G.getMedia().play()}}}return true}catch(M){m.sendEvent(b.api.events.JWPLAYER_ERROR,M)}return false}function I(){try{if(G.playlist[G.item].levels[0].file.length>0){switch(G.state){case b.api.events.state.PLAYING:case b.api.events.state.BUFFERING:G.getMedia().pause();break}}return true}catch(M){m.sendEvent(b.api.events.JWPLAYER_ERROR,M)}return false}function D(M){try{if(G.playlist[G.item].levels[0].file.length>0){if(typeof M!="number"){M=parseFloat(M)}switch(G.state){case b.api.events.state.IDLE:if(e<0){e=G.playlist[G.item].start;G.playlist[G.item].start=M}u();break;case b.api.events.state.PLAYING:case b.api.events.state.PAUSED:case b.api.events.state.BUFFERING:G.seek(M);break}}return true}catch(N){m.sendEvent(b.api.events.JWPLAYER_ERROR,N)}return false}function n(M){if(!c.exists(M)){M=true}try{G.getMedia().stop(M);return true}catch(N){m.sendEvent(b.api.events.JWPLAYER_ERROR,N)}return false}function k(){try{if(G.playlist[G.item].levels[0].file.length>0){if(G.config.shuffle){f(y())}else{if(G.item+1==G.playlist.length){f(0)}else{f(G.item+1)}}}if(G.state!=b.api.events.state.IDLE){var N=G.state;G.state=b.api.events.state.IDLE;m.sendEvent(b.api.events.JWPLAYER_PLAYER_STATE,{oldstate:N,newstate:b.api.events.state.IDLE})}u();return true}catch(M){m.sendEvent(b.api.events.JWPLAYER_ERROR,M)}return false}function j(){try{if(G.playlist[G.item].levels[0].file.length>0){if(G.config.shuffle){f(y())}else{if(G.item===0){f(G.playlist.length-1)}else{f(G.item-1)}}}if(G.state!=b.api.events.state.IDLE){var N=G.state;G.state=b.api.events.state.IDLE;m.sendEvent(b.api.events.JWPLAYER_PLAYER_STATE,{oldstate:N,newstate:b.api.events.state.IDLE})}u();return true}catch(M){m.sendEvent(b.api.events.JWPLAYER_ERROR,M)}return false}function y(){var M=null;if(G.playlist.length>1){while(!c.exists(M)){M=Math.floor(Math.random()*G.playlist.length);if(M==G.item){M=null}}}else{M=0}return M}function t(N){if(!G.playlist||!G.playlist[N]){return false}try{if(G.playlist[N].levels[0].file.length>0){var O=G.state;if(O!==b.api.events.state.IDLE){if(G.playlist[G.item].provider==G.playlist[N].provider){n(false)}else{n()}}f(N);u()}return true}catch(M){m.sendEvent(b.api.events.JWPLAYER_ERROR,M)}return false}function f(M){if(!G.playlist[M]){return}G.setActiveMediaProvider(G.playlist[M]);if(G.item!=M){G.item=M;J=true;m.sendEvent(b.api.events.JWPLAYER_PLAYLIST_ITEM,{index:M})}}function H(N){try{f(G.item);var O=G.getMedia();switch(typeof(N)){case"number":O.volume(N);break;case"string":O.volume(parseInt(N,10));break}return true}catch(M){m.sendEvent(b.api.events.JWPLAYER_ERROR,M)}return false}function q(N){try{f(G.item);var O=G.getMedia();if(typeof N=="undefined"){O.mute(!G.mute)}else{if(N.toString().toLowerCase()=="true"){O.mute(true)}else{O.mute(false)}}return true}catch(M){m.sendEvent(b.api.events.JWPLAYER_ERROR,M)}return false}function l(N,M){try{G.width=N;G.height=M;g.resize(N,M);m.sendEvent(b.api.events.JWPLAYER_RESIZE,{width:G.width,height:G.height});return true}catch(O){m.sendEvent(b.api.events.JWPLAYER_ERROR,O)}return false}function B(N){try{if(typeof N=="undefined"){G.fullscreen=!G.fullscreen;g.fullscreen(!G.fullscreen)}else{if(N.toString().toLowerCase()=="true"){G.fullscreen=true;g.fullscreen(true)}else{G.fullscreen=false;g.fullscreen(false)}}m.sendEvent(b.api.events.JWPLAYER_RESIZE,{width:G.width,height:G.height});m.sendEvent(b.api.events.JWPLAYER_FULLSCREEN,{fullscreen:N});return true}catch(M){m.sendEvent(b.api.events.JWPLAYER_ERROR,M)}return false}function L(M){try{n();G.loadPlaylist(M);f(G.item);return true}catch(N){m.sendEvent(b.api.events.JWPLAYER_ERROR,N)}return false}b.html5.controller.repeatoptions={LIST:"LIST",ALWAYS:"ALWAYS",SINGLE:"SINGLE",NONE:"NONE"};function s(){switch(G.config.repeat.toUpperCase()){case b.html5.controller.repeatoptions.SINGLE:u();break;case b.html5.controller.repeatoptions.ALWAYS:if(G.item==G.playlist.length-1&&!G.config.shuffle){t(0)}else{k()}break;case b.html5.controller.repeatoptions.LIST:if(G.item==G.playlist.length-1&&!G.config.shuffle){n();f(0)}else{k()}break;default:n();break}}var p=[];function F(M){return function(){if(d){x(M,arguments)}else{p.push({method:M,arguments:arguments})}}}function x(O,N){var M=[];for(i=0;i<N.length;i++){M.push(N[i])}O.apply(this,M)}this.play=F(u);this.pause=F(I);this.seek=F(D);this.stop=F(n);this.next=F(k);this.prev=F(j);this.item=F(t);this.setVolume=F(H);this.setMute=F(q);this.resize=F(l);this.setFullscreen=F(B);this.load=F(L);this.playerReady=K}})(jwplayer);(function(a){a.html5.defaultSkin=function(){this.text='<?xml version="1.0" ?><skin author="LongTail Video" name="Five" version="1.0"><settings><setting name="backcolor" value="0xFFFFFF"/><setting name="frontcolor" value="0x000000"/><setting name="lightcolor" value="0x000000"/><setting name="screencolor" value="0x000000"/></settings><components><component name="controlbar"><settings><setting name="margin" value="20"/><setting name="fontsize" value="11"/></settings><elements><element name="background" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAIAAABvFaqvAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAFJJREFUeNrslLENwAAIwxLU/09j5AiOgD5hVQzNAVY8JK4qEfHMIKBnd2+BQlBINaiRtL/aV2rdzYBsM6CIONbI1NZENTr3RwdB2PlnJgJ6BRgA4hwu5Qg5iswAAAAASUVORK5CYII="/><element name="capLeft" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAYCAIAAAC0rgCNAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAD5JREFUeNosi8ENACAMAgnuv14H0Z8asI19XEjhOiKCMmibVgJTUt7V6fe9KXOtSQCfctJHu2q3/ot79hNgANc2OTz9uTCCAAAAAElFTkSuQmCC"/><element name="capRight" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAYCAIAAAC0rgCNAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAD5JREFUeNosi8ENACAMAgnuv14H0Z8asI19XEjhOiKCMmibVgJTUt7V6fe9KXOtSQCfctJHu2q3/ot79hNgANc2OTz9uTCCAAAAAElFTkSuQmCC"/><element name="divider" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAYCAIAAAC0rgCNAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAD5JREFUeNosi8ENACAMAgnuv14H0Z8asI19XEjhOiKCMmibVgJTUt7V6fe9KXOtSQCfctJHu2q3/ot79hNgANc2OTz9uTCCAAAAAElFTkSuQmCC"/><element name="playButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAYCAYAAAAVibZIAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAEhJREFUeNpiYqABYBo1dNRQ+hr6H4jvA3E8NS39j4SpZvh/LJig4YxEGEqy3kET+w+AOGFQRhTJhrEQkGcczfujhg4CQwECDADpTRWU/B3wHQAAAABJRU5ErkJggg=="/><element name="pauseButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAYCAYAAAAVibZIAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAChJREFUeNpiYBgFo2DwA0YC8v/R1P4nRu+ooaOGUtnQUTAKhgIACDAAFCwQCfAJ4gwAAAAASUVORK5CYII="/><element name="prevButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAYCAYAAAAVibZIAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAEtJREFUeNpiYBgFo2Dog/9QDAPyQHweTYwiQ/2B+D0Wi8g2tB+JTdBQRiIMJVkvEy0iglhDF9Aq9uOpHVEwoE+NJDUKRsFgAAABBgDe2hqZcNNL0AAAAABJRU5ErkJggg=="/><element name="nextButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAYCAYAAAAVibZIAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAElJREFUeNpiYBgFo2Dog/9AfB6I5dHE/lNqKAi/B2J/ahsKw/3EGMpIhKEk66WJoaR6fz61IyqemhEFSlL61ExSo2AUDAYAEGAAiG4hj+5t7M8AAAAASUVORK5CYII="/><element name="timeSliderRail" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADxJREFUeNpiYBgFo2AU0Bwwzluw+D8tLWARFhKiqQ9YuLg4aWsBGxs7bS1gZ6e5BWyjSX0UjIKhDgACDABlYQOGh5pYywAAAABJRU5ErkJggg=="/><element name="timeSliderBuffer" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAD1JREFUeNpiYBgFo2AU0Bww1jc0/aelBSz8/Pw09QELOzs7bS1gY2OjrQWsrKy09gHraFIfBaNgqAOAAAMAvy0DChXHsZMAAAAASUVORK5CYII="/><element name="timeSliderProgress" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAClJREFUeNpiYBgFo2AU0BwwAvF/WlrARGsfjFow8BaMglEwCugAAAIMAOHfAQunR+XzAAAAAElFTkSuQmCC"/><element name="timeSliderThumb" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAICAYAAAA870V8AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABZJREFUeNpiZICA/yCCiQEJUJcDEGAAY0gBD1/m7Q0AAAAASUVORK5CYII="/><element name="muteButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAYCAYAAADKx8xXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADFJREFUeNpiYBgFIw3MB+L/5Gj8j6yRiRTFyICJXHfTXyMLAXlGati4YDRFDj8AEGAABk8GSqqS4CoAAAAASUVORK5CYII="/><element name="unmuteButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAYCAYAAADKx8xXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAD1JREFUeNpiYBgFgxz8p7bm+cQa+h8LHy7GhEcjIz4bmAjYykiun/8j0fakGPIfTfPgiSr6aB4FVAcAAQYAWdwR1G1Wd2gAAAAASUVORK5CYII="/><element name="volumeSliderRail" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAYCAYAAADkgu3FAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAGpJREFUeNpi/P//PwM9ABMDncCoRYPfIqqDZcuW1UPp/6AUDcNM1DQYKtRAlaAj1mCSLSLXYIIWUctgDItoZfDA5aOoqKhGEANIM9LVR7SymGDQUctikuOIXkFNdhHEOFrDjlpEd4sAAgwAriRMub95fu8AAAAASUVORK5CYII="/><element name="volumeSliderProgress" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAYCAYAAADkgu3FAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAFtJREFUeNpi/P//PwM9ABMDncCoRYPfIlqAeij9H5SiYZiqBqPTlFqE02BKLSLaYFItIttgQhZRzWB8FjENiuRJ7aAbsMQwYMl7wDIsWUUQ42gNO2oR3S0CCDAAKhKq6MLLn8oAAAAASUVORK5CYII="/><element name="fullscreenButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAE5JREFUeNpiYBgFo2DQA0YC8v/xqP1PjDlMRDrEgUgxkgHIlfZoriVGjmzLsLFHAW2D6D8eA/9Tw7L/BAwgJE90PvhPpNgoGAVDEQAEGAAMdhTyXcPKcAAAAABJRU5ErkJggg=="/><element name="normalscreenButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAEZJREFUeNpiYBgFo2DIg/9UUkOUAf8JiFFsyX88fJyAkcQgYMQjNkzBoAgiezyRbE+tFGSPxQJ7auYBmma0UTAKBhgABBgAJAEY6zON61sAAAAASUVORK5CYII="/></elements></component><component name="display"><elements><element name="background" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAEpJREFUeNrszwENADAIA7DhX8ENoBMZ5KR10EryckCJiIiIiIiIiIiIiIiIiIiIiIh8GmkRERERERERERERERERERERERGRHSPAAPlXH1phYpYaAAAAAElFTkSuQmCC"/><element name="playIcon" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAALdJREFUeNrs18ENgjAYhmFouDOCcQJGcARHgE10BDcgTOIosAGwQOuPwaQeuFRi2p/3Sb6EC5L3QCxZBgAAAOCorLW1zMn65TrlkH4NcV7QNcUQt7Gn7KIhxA+qNIR81spOGkL8oFJDyLJRdosqKDDkK+iX5+d7huzwM40xptMQMkjIOeRGo+VkEVvIPfTGIpKASfYIfT9iCHkHrBEzf4gcUQ56aEzuGK/mw0rHpy4AAACAf3kJMACBxjAQNRckhwAAAABJRU5ErkJggg=="/><element name="muteIcon" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAHJJREFUeNrs1jEOgCAMBVAg7t5/8qaoIy4uoobyXsLCxA+0NCUAAADGUWvdQoQ41x4ixNBB2hBvBskdD3w5ZCkl3+33VqI0kjBBlh9rp+uTcyOP33TnolfsU85XX3yIRpQph8ZQY3wTZtU5AACASA4BBgDHoVuY1/fvOQAAAABJRU5ErkJggg=="/><element name="errorIcon" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAWlJREFUeNrsl+1twjAQhsHq/7BBYQLYIBmBDcoGMAIjtBPQTcII2SDtBDBBwrU6pGsUO7YbO470PtKJkz9iH++d4ywWAAAAAABgljRNsyWr2bZzDuJG1rLdZhcMbTjrBCGDyUKsqQLFciJb9bSvuG/WagRVRUVUI6gqy5HVeKWfSgRyJruKIU//TrZTSn2nmlaXThrloi/v9F2STC1W4+Aw5cBzkquRc09bofFNc6YLxEON0VUZS5FPTftO49vMjRsIF3RhOGr7/D/pJw+FKU+q0vDyq8W42jCunDqI3LC5XxNj2wHLU1XjaRnb0Lhykhqhhd8MtSF5J9tbjCv4mXGvKJz/65FF/qJryyaaIvzP2QRxZTX2nTuXjvV/VPFSwyLnW7mpH99yTh1FEVro6JBSd40/pMrRdV8vPtcKl28T2pT8TnFZ4yNosct3Q0io6JfBiz1FlGdqVQH3VHnepAEAAAAAADDzEGAAcTwB10jWgxcAAAAASUVORK5CYII="/><element name="bufferIcon" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAuhJREFUeNrsWr9rU1EUznuNGqvFQh1ULOhiBx0KDtIuioO4pJuik3FxFfUPaAV1FTdx0Q5d2g4FFxehTnEpZHFoBy20tCIWtGq0TZP4HfkeHB5N8m6Sl/sa74XDybvv3vvOd8/Pe4lXrVZT3dD8VJc0B8QBcUAcEAfESktHGeR5XtMfqFQq/f92zPe/NbtGlKTdCY30kuxrpMGO94BlQCXs+rbh3ONgA6BlzP1p20d80gEI5hmA2A92Qua1Q2PtAFISM+bvjMG8U+Q7oA3rQGASwrYCU6WpNdLGYbA+Pq5jjXIiwi8EEa2UDbQSaKOIuV+SlkcCrfjY8XTI9EpKGwP0C2kru2hLtHqa4zoXtZRWyvi4CLwv9Opr6Hkn6A9HKgEANsQ1iqC3Ub/vRUk2JgmRkatK36kVrnt0qObunwUdUUMXMWYpakJsO5Am8tAw2GBIgwWA+G2S2dMpiw0gDioQRQJoKhRb1QiDwlHZUABYbaXWsm5ae6loTE4ZDxN4CZar8foVzOJ2iyZ2kWF3t7YIevffaMT5yJ70kQb2fQ1sE5SHr2wazs2wgMxgbsEKEAgxAvZUJbQLBGTSBMgNrncJbA6AljtS/eKDJ0Ez+DmrQEzXS2h1Ck25kAg0IZcUOaydCy4sYnN2fOA+2AP16gNoHALlQ+fwH7XO4CxLenUpgj4xr6ugY2roPMbMx+Xs18m/E8CVEIhxsNeg83XWOAN6grG3lGbk8uE5fr4B/WH3cJw+co/l9nTYsSGYCJ/lY5/qv0thn6nrIWmjeJcPSnWOeY++AkF8tpJHIMAUs/MaBBpj3znZfQo5psY+ZrG4gv5HickjEOymKjEeRpgyST6IuZcTcWbnjcgdPi5ghxciRKsl1lDSsgwA1i8fssonJgzmTSqfGUkCENndNdAL7PS6QQ7ZYISTo+1qq0LEWjTWcvY4isa4z+yfQB+7ooyHVg5RI7/i1Ijn/vnggDggDogD4oC00P4KMACd/juEHOrS4AAAAABJRU5ErkJggg=="/></elements></component><component name="dock"><elements><element name="button" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAFBJREFUeNrs0cEJACAQA8Eofu0fu/W6EM5ZSAFDRpKTBs00CQQEBAQEBAQEBAQEBAQEBATkK8iqbY+AgICAgICAgICAgICAgICAgIC86QowAG5PAQzEJ0lKAAAAAElFTkSuQmCC"/></elements></component><component name="playlist"><elements><element name="item" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAIAAAC1nk4lAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAHhJREFUeNrs2NEJwCAMBcBYuv/CFuIE9VN47WWCR7iocXR3pdWdGPqqwIoMjYfQeAiNh9B4JHc6MHQVHnjggQceeOCBBx77TifyeOY0iHi8DqIdEY8dD5cL094eePzINB5CO/LwcOTptNB4CP25L4TIbZzpU7UEGAA5wz1uF5rF9AAAAABJRU5ErkJggg=="/><element name="sliderRail" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAA8CAIAAADpFA0BAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADhJREFUeNrsy6ENACAMAMHClp2wYxZLAg5Fcu9e3OjuOKqqfTMzbs14CIZhGIZhGIZhGP4VLwEGAK/BBnVFpB0oAAAAAElFTkSuQmCC"/><element name="sliderThumb" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAA8CAIAAADpFA0BAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNrsy7ENACAMBLE8++8caFFKKiRffU53112SGs3ttOohGIZhGIZhGIZh+Fe8BRgAiaUGde6NOSEAAAAASUVORK5CYII="/></elements></component></components></skin>';this.xml=null;if(window.DOMParser){parser=new DOMParser();this.xml=parser.parseFromString(this.text,"text/xml")}else{this.xml=new ActiveXObject("Microsoft.XMLDOM");this.xml.async="false";this.xml.loadXML(this.text)}return this}})(jwplayer);(function(a){_utils=a.utils;_css=_utils.css;_hide=function(b){_css(b,{display:"none"})};_show=function(b){_css(b,{display:"block"})};a.html5.display=function(k,G){var j={icons:true,showmute:false};var Q=_utils.extend({},j,G);var h=k;var P={};var e;var u;var w;var N;var s;var I;var A;var J=!_utils.exists(h.skin.getComponentSettings("display").bufferrotation)?15:parseInt(h.skin.getComponentSettings("display").bufferrotation,10);var q=!_utils.exists(h.skin.getComponentSettings("display").bufferinterval)?100:parseInt(h.skin.getComponentSettings("display").bufferinterval,10);var z=-1;var t="";var K=true;var d;var g=false;var n=false;var H=new a.html5.eventdispatcher();_utils.extend(this,H);var D={display:{style:{cursor:"pointer",top:0,left:0,overflow:"hidden"},click:m},display_icon:{style:{cursor:"pointer",position:"absolute",top:((h.skin.getSkinElement("display","background").height-h.skin.getSkinElement("display","playIcon").height)/2),left:((h.skin.getSkinElement("display","background").width-h.skin.getSkinElement("display","playIcon").width)/2),border:0,margin:0,padding:0,zIndex:3,display:"none"}},display_iconBackground:{style:{cursor:"pointer",position:"absolute",top:((u-h.skin.getSkinElement("display","background").height)/2),left:((e-h.skin.getSkinElement("display","background").width)/2),border:0,backgroundImage:(["url(",h.skin.getSkinElement("display","background").src,")"]).join(""),width:h.skin.getSkinElement("display","background").width,height:h.skin.getSkinElement("display","background").height,margin:0,padding:0,zIndex:2,display:"none"}},display_image:{style:{display:"none",width:e,height:u,position:"absolute",cursor:"pointer",left:0,top:0,margin:0,padding:0,textDecoration:"none",zIndex:1}},display_text:{style:{zIndex:4,position:"relative",opacity:0.8,backgroundColor:parseInt("000000",16),color:parseInt("ffffff",16),textAlign:"center",fontFamily:"Arial,sans-serif",padding:"0 5px",fontSize:14}}};h.jwAddEventListener(a.api.events.JWPLAYER_PLAYER_STATE,p);h.jwAddEventListener(a.api.events.JWPLAYER_MEDIA_MUTE,p);h.jwAddEventListener(a.api.events.JWPLAYER_PLAYLIST_ITEM,p);h.jwAddEventListener(a.api.events.JWPLAYER_ERROR,o);L();function L(){P.display=C("div","display");P.display_text=C("div","display_text");P.display.appendChild(P.display_text);P.display_image=C("img","display_image");P.display_image.onerror=function(R){_hide(P.display_image)};P.display_image.onload=y;P.display_icon=C("div","display_icon");P.display_iconBackground=C("div","display_iconBackground");P.display.appendChild(P.display_image);P.display_iconBackground.appendChild(P.display_icon);P.display.appendChild(P.display_iconBackground);f();setTimeout((function(){n=true;if(Q.icons.toString()=="true"){F()}}),1)}this.getDisplayElement=function(){return P.display};this.resize=function(S,R){_css(P.display,{width:S,height:R});_css(P.display_text,{width:(S-10),top:((R-P.display_text.getBoundingClientRect().height)/2)});_css(P.display_iconBackground,{top:((R-h.skin.getSkinElement("display","background").height)/2),left:((S-h.skin.getSkinElement("display","background").width)/2)});if(e!=S||u!=R){e=S;u=R;d=undefined;F()}c();p({})};this.show=function(){if(g){g=false;r(h.jwGetState())}};this.hide=function(){if(!g){B();g=true}};function y(R){w=P.display_image.naturalWidth;N=P.display_image.naturalHeight;c()}function c(){_utils.stretch(h.jwGetStretching(),P.display_image,e,u,w,N)}function C(R,T){var S=document.createElement(R);S.id=h.id+"_jwplayer_"+T;_css(S,D[T].style);return S}function f(){for(var R in P){if(_utils.exists(D[R].click)){P[R].onclick=D[R].click}}}function m(R){if(typeof R.preventDefault!="undefined"){R.preventDefault()}else{R.returnValue=false}if(h.jwGetState()!=a.api.events.state.PLAYING){h.jwPlay()}else{h.jwPause()}}function O(R){if(A){B();return}P.display_icon.style.backgroundImage=(["url(",h.skin.getSkinElement("display",R).src,")"]).join("");_css(P.display_icon,{width:h.skin.getSkinElement("display",R).width,height:h.skin.getSkinElement("display",R).height,top:(h.skin.getSkinElement("display","background").height-h.skin.getSkinElement("display",R).height)/2,left:(h.skin.getSkinElement("display","background").width-h.skin.getSkinElement("display",R).width)/2});b();if(_utils.exists(h.skin.getSkinElement("display",R+"Over"))){P.display_icon.onmouseover=function(S){P.display_icon.style.backgroundImage=["url(",h.skin.getSkinElement("display",R+"Over").src,")"].join("")};P.display_icon.onmouseout=function(S){P.display_icon.style.backgroundImage=["url(",h.skin.getSkinElement("display",R).src,")"].join("")}}else{P.display_icon.onmouseover=null;P.display_icon.onmouseout=null}}function B(){if(Q.icons.toString()=="true"){_hide(P.display_icon);_hide(P.display_iconBackground);M()}}function b(){if(!g&&Q.icons.toString()=="true"){_show(P.display_icon);_show(P.display_iconBackground);F()}}function o(R){A=true;B();P.display_text.innerHTML=R.error;_show(P.display_text);P.display_text.style.top=((u-P.display_text.getBoundingClientRect().height)/2)+"px"}function E(){P.display_image.style.display="none"}function p(R){if((R.type==a.api.events.JWPLAYER_PLAYER_STATE||R.type==a.api.events.JWPLAYER_PLAYLIST_ITEM)&&A){A=false;_hide(P.display_text)}var S=h.jwGetState();if(S==t){return}t=S;if(z>=0){clearTimeout(z)}if(K||h.jwGetState()==a.api.events.state.PLAYING||h.jwGetState()==a.api.events.state.PAUSED){r(h.jwGetState())}else{z=setTimeout(l(h.jwGetState()),500)}}function l(R){return(function(){r(R)})}function r(R){if(_utils.exists(I)){clearInterval(I);I=null;_utils.animations.rotate(P.display_icon,0)}switch(R){case a.api.events.state.BUFFERING:if(_utils.isIOS()){E();B()}else{if(h.jwGetPlaylist()[h.jwGetItem()].provider=="sound"){v()}s=0;I=setInterval(function(){s+=J;_utils.animations.rotate(P.display_icon,s%360)},q);O("bufferIcon");K=true}break;case a.api.events.state.PAUSED:if(!_utils.isIOS()){if(h.jwGetPlaylist()[h.jwGetItem()].provider!="sound"){_css(P.display_image,{background:"transparent no-repeat center center"})}O("playIcon");K=true}break;case a.api.events.state.IDLE:if(h.jwGetPlaylist()[h.jwGetItem()]&&h.jwGetPlaylist()[h.jwGetItem()].image){v()}else{E()}O("playIcon");K=true;break;default:if(h.jwGetPlaylist()[h.jwGetItem()]&&h.jwGetPlaylist()[h.jwGetItem()].provider=="sound"){if(_utils.isIOS()){E();K=false}else{v()}}else{E();K=false}if(h.jwGetMute()&&Q.showmute){O("muteIcon")}else{B()}break}z=-1}function v(){if(h.jwGetPlaylist()[h.jwGetItem()]&&h.jwGetPlaylist()[h.jwGetItem()].image){_css(P.display_image,{display:"block"});P.display_image.src=_utils.getAbsolutePath(h.jwGetPlaylist()[h.jwGetItem()].image)}}function x(R){return function(){if(!n){return}if(!g&&d!=R){d=R;H.sendEvent(R,{component:"display",boundingRect:_utils.getDimensions(P.display_iconBackground)})}}}var F=x(a.api.events.JWPLAYER_COMPONENT_SHOW);var M=x(a.api.events.JWPLAYER_COMPONENT_HIDE);return this}})(jwplayer);(function(a){_css=a.utils.css;a.html5.dock=function(p,u){function q(){return{align:a.html5.view.positions.RIGHT}}var k=a.utils.extend({},q(),u);if(k.align=="FALSE"){return}var f={};var s=[];var g;var v;var d=false;var t=false;var e={x:0,y:0,width:0,height:0};var r;var j=new a.html5.eventdispatcher();_utils.extend(this,j);var m=document.createElement("div");m.id=p.id+"_jwplayer_dock";p.jwAddEventListener(a.api.events.JWPLAYER_PLAYER_STATE,l);this.getDisplayElement=function(){return m};this.setButton=function(A,x,y,z){if(!x&&f[A]){a.utils.arrays.remove(s,A);m.removeChild(f[A].div);delete f[A]}else{if(x){if(!f[A]){f[A]={}}f[A].handler=x;f[A].outGraphic=y;f[A].overGraphic=z;if(!f[A].div){s.push(A);f[A].div=document.createElement("div");f[A].div.style.position="relative";m.appendChild(f[A].div);f[A].div.appendChild(document.createElement("img"));f[A].div.childNodes[0].style.position="absolute";f[A].div.childNodes[0].style.left=0;f[A].div.childNodes[0].style.top=0;f[A].div.childNodes[0].style.zIndex=10;f[A].div.childNodes[0].style.cursor="pointer";f[A].div.appendChild(document.createElement("img"));f[A].div.childNodes[1].style.position="absolute";f[A].div.childNodes[1].style.left=0;f[A].div.childNodes[1].style.top=0;if(p.skin.getSkinElement("dock","button")){f[A].div.childNodes[1].src=p.skin.getSkinElement("dock","button").src}f[A].div.childNodes[1].style.zIndex=9;f[A].div.childNodes[1].style.cursor="pointer";f[A].div.onmouseover=function(){if(f[A].overGraphic){f[A].div.childNodes[0].src=f[A].overGraphic}if(p.skin.getSkinElement("dock","buttonOver")){f[A].div.childNodes[1].src=p.skin.getSkinElement("dock","buttonOver").src}};f[A].div.onmouseout=function(){if(f[A].outGraphic){f[A].div.childNodes[0].src=f[A].outGraphic}if(p.skin.getSkinElement("dock","button")){f[A].div.childNodes[1].src=p.skin.getSkinElement("dock","button").src}};if(f[A].overGraphic){f[A].div.childNodes[0].src=f[A].overGraphic}if(f[A].outGraphic){f[A].div.childNodes[0].src=f[A].outGraphic}if(p.skin.getSkinElement("dock","button")){f[A].div.childNodes[1].src=p.skin.getSkinElement("dock","button").src}}if(x){f[A].div.onclick=function(B){B.preventDefault();a(p.id).callback(A);if(f[A].overGraphic){f[A].div.childNodes[0].src=f[A].overGraphic}if(p.skin.getSkinElement("dock","button")){f[A].div.childNodes[1].src=p.skin.getSkinElement("dock","button").src}}}}}h(g,v)};function h(x,J){if(s.length>0){var y=10;var I=y;var F=-1;var G=p.skin.getSkinElement("dock","button").height;var E=p.skin.getSkinElement("dock","button").width;var C=x-E-y;var H,B;if(k.align==a.html5.view.positions.LEFT){F=1;C=y}for(var z=0;z<s.length;z++){var K=Math.floor(I/J);if((I+G+y)>((K+1)*J)){I=((K+1)*J)+y;K=Math.floor(I/J)}var A=f[s[z]].div;A.style.top=(I%J)+"px";A.style.left=(C+(p.skin.getSkinElement("dock","button").width+y)*K*F)+"px";var D={x:a.utils.parseDimension(A.style.left),y:a.utils.parseDimension(A.style.top),width:E,height:G};if(!H||(D.x<=H.x&&D.y<=H.y)){H=D}if(!B||(D.x>=B.x&&D.y>=B.y)){B=D}I+=p.skin.getSkinElement("dock","button").height+y}e={x:H.x,y:H.y,width:B.x-H.x+B.width,height:H.y-B.y+B.height}}if(t!=p.jwGetFullscreen()||g!=x||v!=J){g=x;v=J;t=p.jwGetFullscreen();r=undefined;setTimeout(n,1)}}function b(x){return function(){if(!d&&r!=x&&s.length>0){r=x;j.sendEvent(x,{component:"dock",boundingRect:e})}}}function l(x){if(a.utils.isIOS()){switch(x.newstate){case a.api.events.state.IDLE:o();break;default:c();break}}}var n=b(a.api.events.JWPLAYER_COMPONENT_SHOW);var w=b(a.api.events.JWPLAYER_COMPONENT_HIDE);this.resize=h;var o=function(){_css(m,{display:"block"});if(d){d=false;n()}};var c=function(){_css(m,{display:"none"});if(!d){w();d=true}};this.hide=c;this.show=o;return this}})(jwplayer);(function(a){a.html5.eventdispatcher=function(d,b){var c=new a.events.eventdispatcher(b);a.utils.extend(this,c);this.sendEvent=function(e,f){if(!a.utils.exists(f)){f={}}a.utils.extend(f,{id:d,version:a.version,type:e});c.sendEvent(e,f)}}})(jwplayer);(function(a){var b={prefix:"http://l.longtailvideo.com/html5/",file:"logo.png",link:"http://www.longtailvideo.com/players/jw-flv-player/",margin:8,out:0.5,over:1,timeout:5,hide:true,position:"bottom-left"};_css=a.utils.css;a.html5.logo=function(n,r){var q=n;var u;var d;var t;var h=false;g();function g(){o();c();l()}function o(){if(b.prefix){var v=n.version.split(/\W/).splice(0,2).join("/");if(b.prefix.indexOf(v)<0){b.prefix+=v+"/"}}if(r.position==a.html5.view.positions.OVER){r.position=b.position}d=a.utils.extend({},b)}function c(){t=document.createElement("img");t.id=q.id+"_jwplayer_logo";t.style.display="none";t.onload=function(v){_css(t,k());q.jwAddEventListener(a.api.events.JWPLAYER_PLAYER_STATE,j);p()};if(!d.file){return}if(d.file.indexOf("http://")===0){t.src=d.file}else{t.src=d.prefix+d.file}}if(!d.file){return}this.resize=function(w,v){};this.getDisplayElement=function(){return t};function l(){if(d.link){t.onmouseover=f;t.onmouseout=p;t.onclick=s}else{this.mouseEnabled=false}}function s(v){if(typeof v!="undefined"){v.stopPropagation()}if(!h){return}q.jwPause();q.jwSetFullscreen(false);if(d.link){window.open(d.link,"_top")}return}function p(v){if(d.link&&h){t.style.opacity=d.out}return}function f(v){if(d.hide.toString()=="true"&&h){t.style.opacity=d.over}return}function k(){var x={textDecoration:"none",position:"absolute",cursor:"pointer"};x.display=(d.hide.toString()=="true")?"none":"block";var w=d.position.toLowerCase().split("-");for(var v in w){x[w[v]]=d.margin}return x}function m(){if(d.hide.toString()=="true"){t.style.display="block";t.style.opacity=0;a.utils.fadeTo(t,d.out,0.1,parseFloat(t.style.opacity));u=setTimeout(function(){e()},d.timeout*1000)}h=true}function e(){h=false;if(d.hide.toString()=="true"){a.utils.fadeTo(t,0,0.1,parseFloat(t.style.opacity))}}function j(v){if(v.newstate==a.api.events.state.BUFFERING){clearTimeout(u);m()}}return this}})(jwplayer);(function(a){var c={ended:a.api.events.state.IDLE,playing:a.api.events.state.PLAYING,pause:a.api.events.state.PAUSED,buffering:a.api.events.state.BUFFERING};var e=a.utils;var b=e.css;var d=e.isIOS();a.html5.mediavideo=function(h,s){var r={abort:n,canplay:k,canplaythrough:k,durationchange:G,emptied:n,ended:k,error:u,loadeddata:G,loadedmetadata:G,loadstart:k,pause:k,play:n,playing:k,progress:v,ratechange:n,seeked:k,seeking:k,stalled:k,suspend:k,timeupdate:D,volumechange:n,waiting:k,canshowcurrentframe:n,dataunavailable:n,empty:n,load:z,loadedfirstframe:n};var j=new a.html5.eventdispatcher();e.extend(this,j);var y=h,l=s,m,B,A,x,f,H=false,C,p,q;o();this.load=function(J,K){if(typeof K=="undefined"){K=true}x=J;e.empty(m);q=0;if(J.levels&&J.levels.length>0){if(J.levels.length==1){m.src=J.levels[0].file}else{if(m.src){m.removeAttribute("src")}for(var I=0;I<J.levels.length;I++){var L=m.ownerDocument.createElement("source");L.src=J.levels[I].file;m.appendChild(L);q++}}}else{m.src=J.file}if(d){if(J.image){m.poster=J.image}m.controls="controls";m.style.display="block"}C=p=A=false;y.buffer=0;if(!e.exists(J.start)){J.start=0}y.duration=J.duration;j.sendEvent(a.api.events.JWPLAYER_MEDIA_LOADED);if((!d&&J.levels.length==1)||!H){m.load()}H=false;if(K){E(a.api.events.state.BUFFERING);j.sendEvent(a.api.events.JWPLAYER_MEDIA_BUFFER,{bufferPercent:0});this.play()}};this.play=function(){if(B!=a.api.events.state.PLAYING){t();if(p){E(a.api.events.state.PLAYING)}else{E(a.api.events.state.BUFFERING)}m.play()}};this.pause=function(){m.pause();E(a.api.events.state.PAUSED)};this.seek=function(I){if(!(y.duration<=0||isNaN(y.duration))&&!(y.position<=0||isNaN(y.position))){m.currentTime=I;m.play()}};_stop=this.stop=function(I){if(!e.exists(I)){I=true}g();if(I){m.style.display="none";p=false;var J=navigator.userAgent;if(J.match(/chrome/i)){m.src=undefined}else{if(J.match(/safari/i)){m.removeAttribute("src")}else{m.src=""}}m.removeAttribute("controls");m.removeAttribute("poster");e.empty(m);m.load();H=true;if(m.webkitSupportsFullscreen){try{m.webkitExitFullscreen()}catch(K){}}}E(a.api.events.state.IDLE)};this.fullscreen=function(I){if(I===true){this.resize("100%","100%")}else{this.resize(y.config.width,y.config.height)}};this.resize=function(J,I){if(false){b(l,{width:J,height:I})}j.sendEvent(a.api.events.JWPLAYER_MEDIA_RESIZE,{fullscreen:y.fullscreen,width:J,hieght:I})};this.volume=function(I){if(!d){m.volume=I/100;y.volume=I;j.sendEvent(a.api.events.JWPLAYER_MEDIA_VOLUME,{volume:Math.round(I)})}};this.mute=function(I){if(!d){m.muted=I;y.mute=I;j.sendEvent(a.api.events.JWPLAYER_MEDIA_MUTE,{mute:I})}};this.getDisplayElement=function(){return m};this.hasChrome=function(){return false};function o(){m=document.createElement("video");B=a.api.events.state.IDLE;for(var I in r){m.addEventListener(I,function(J){if(e.exists(J.target.parentNode)){r[J.type](J)}},true)}m.setAttribute("x-webkit-airplay","allow");if(l.parentNode){l.parentNode.replaceChild(m,l)}if(!m.id){m.id=l.id}}function E(I){if(I==a.api.events.state.PAUSED&&B==a.api.events.state.IDLE){return}if(B!=I){var J=B;y.state=B=I;j.sendEvent(a.api.events.JWPLAYER_PLAYER_STATE,{oldstate:J,newstate:I})}}function n(I){}function v(K){var J;if(e.exists(K)&&K.lengthComputable&&K.total){J=K.loaded/K.total*100}else{if(e.exists(m.buffered)&&(m.buffered.length>0)){var I=m.buffered.length-1;if(I>=0){J=m.buffered.end(I)/m.duration*100}}}if(p===false&&B==a.api.events.state.BUFFERING){j.sendEvent(a.api.events.JWPLAYER_MEDIA_BUFFER_FULL);p=true}if(!C){if(J==100){C=true}if(e.exists(J)&&(J>y.buffer)){y.buffer=Math.round(J);j.sendEvent(a.api.events.JWPLAYER_MEDIA_BUFFER,{bufferPercent:Math.round(J)})}}}function D(J){if(e.exists(J)&&e.exists(J.target)){if(!isNaN(J.target.duration)&&(isNaN(y.duration)||y.duration<1)){if(J.target.duration==Infinity){y.duration=0}else{y.duration=Math.round(J.target.duration*10)/10}}if(!A&&m.readyState>0){m.style.display="block";E(a.api.events.state.PLAYING)}if(B==a.api.events.state.PLAYING){if(!A&&m.readyState>0){A=true;try{if(m.currentTime<x.start){m.currentTime=x.start}}catch(I){}m.volume=y.volume/100;m.muted=y.mute}y.position=y.duration>0?(Math.round(J.target.currentTime*10)/10):0;j.sendEvent(a.api.events.JWPLAYER_MEDIA_TIME,{position:y.position,duration:y.duration});if(y.position>=y.duration&&(y.position>0||y.duration>0)){w()}}}v(J)}function z(I){}function k(I){if(c[I.type]){if(I.type=="ended"){w()}else{E(c[I.type])}}}function G(I){var J={height:I.target.videoHeight,width:I.target.videoWidth,duration:Math.round(I.target.duration*10)/10};if((y.duration===0||isNaN(y.duration))&&I.target.duration!=Infinity){y.duration=Math.round(I.target.duration*10)/10}j.sendEvent(a.api.events.JWPLAYER_MEDIA_META,{metadata:J})}function u(K){if(B==a.api.events.state.IDLE){return}var J="There was an error: ";if((K.target.error&&K.target.tagName.toLowerCase()=="video")||K.target.parentNode.error&&K.target.parentNode.tagName.toLowerCase()=="video"){var I=!e.exists(K.target.error)?K.target.parentNode.error:K.target.error;switch(I.code){case I.MEDIA_ERR_ABORTED:J="You aborted the video playback: ";break;case I.MEDIA_ERR_NETWORK:J="A network error caused the video download to fail part-way: ";break;case I.MEDIA_ERR_DECODE:J="The video playback was aborted due to a corruption problem or because the video used features your browser did not support: ";break;case I.MEDIA_ERR_SRC_NOT_SUPPORTED:J="The video could not be loaded, either because the server or network failed or because the format is not supported: ";break;default:J="An unknown error occurred: ";break}}else{if(K.target.tagName.toLowerCase()=="source"){q--;if(q>0){return}J="The video could not be loaded, either because the server or network failed or because the format is not supported: "}else{e.log("An unknown error occurred. Continuing...");return}}_stop(false);J+=F();_error=true;j.sendEvent(a.api.events.JWPLAYER_ERROR,{error:J});return}function F(){var K="";for(var J in x.levels){var I=x.levels[J];var L=l.ownerDocument.createElement("source");K+=a.utils.getAbsolutePath(I.file);if(J<(x.levels.length-1)){K+=", "}}return K}function t(){if(!e.exists(f)){f=setInterval(function(){v()},100)}}function g(){clearInterval(f);f=null}function w(){if(B!=a.api.events.state.IDLE){_stop(false);j.sendEvent(a.api.events.JWPLAYER_MEDIA_COMPLETE)}}}})(jwplayer);(function(a){var c={ended:a.api.events.state.IDLE,playing:a.api.events.state.PLAYING,pause:a.api.events.state.PAUSED,buffering:a.api.events.state.BUFFERING};var b=a.utils.css;a.html5.mediayoutube=function(j,e){var f=new a.html5.eventdispatcher();a.utils.extend(this,f);var l=j;var h=document.getElementById(e.id);var g=a.api.events.state.IDLE;var n,m;function k(p){if(g!=p){var q=g;l.state=p;g=p;f.sendEvent(a.api.events.JWPLAYER_PLAYER_STATE,{oldstate:q,newstate:p})}}this.getDisplayElement=function(){return h};this.play=function(){if(g==a.api.events.state.IDLE){f.sendEvent(a.api.events.JWPLAYER_MEDIA_BUFFER,{bufferPercent:100});f.sendEvent(a.api.events.JWPLAYER_MEDIA_BUFFER_FULL);k(a.api.events.state.PLAYING)}else{if(g==a.api.events.state.PAUSED){k(a.api.events.state.PLAYING)}}};this.pause=function(){k(a.api.events.state.PAUSED)};this.seek=function(p){};this.stop=function(p){if(!_utils.exists(p)){p=true}l.position=0;k(a.api.events.state.IDLE);if(p){b(h,{display:"none"})}};this.volume=function(p){l.volume=p;f.sendEvent(a.api.events.JWPLAYER_MEDIA_VOLUME,{volume:Math.round(p)})};this.mute=function(p){h.muted=p;l.mute=p;f.sendEvent(a.api.events.JWPLAYER_MEDIA_MUTE,{mute:p})};this.resize=function(q,p){if(q*p>0&&n){n.width=m.width=q;n.height=m.height=p}f.sendEvent(a.api.events.JWPLAYER_MEDIA_RESIZE,{fullscreen:l.fullscreen,width:q,height:p})};this.fullscreen=function(p){if(p===true){this.resize("100%","100%")}else{this.resize(l.config.width,l.config.height)}};this.load=function(p){o(p);b(n,{display:"block"});k(a.api.events.state.BUFFERING);f.sendEvent(a.api.events.JWPLAYER_MEDIA_BUFFER,{bufferPercent:0});f.sendEvent(a.api.events.JWPLAYER_MEDIA_LOADED);this.play()};this.hasChrome=function(){return(g!=a.api.events.state.IDLE)};function o(v){var s=v.levels[0].file;s=["http://www.youtube.com/v/",d(s),"&hl=en_US&fs=1&autoplay=1"].join("");n=document.createElement("object");n.id=h.id;n.style.position="absolute";var u={movie:s,allowfullscreen:"true",allowscriptaccess:"always"};for(var p in u){var t=document.createElement("param");t.name=p;t.value=u[p];n.appendChild(t)}m=document.createElement("embed");n.appendChild(m);var q={src:s,type:"application/x-shockwave-flash",allowfullscreen:"true",allowscriptaccess:"always",width:n.width,height:n.height};for(var r in q){m.setAttribute(r,q[r])}n.appendChild(m);n.style.zIndex=2147483000;if(h!=n&&h.parentNode){h.parentNode.replaceChild(n,h)}h=n}function d(q){var p=q.split(/\?|\#\!/);var s="";for(var r=0;r<p.length;r++){if(p[r].substr(0,2)=="v="){s=p[r].substr(2)}}if(s==""){if(q.indexOf("/v/")>=0){s=q.substr(q.indexOf("/v/")+3)}else{if(q.indexOf("youtu.be")>=0){s=q.substr(q.indexOf("youtu.be/")+9)}else{s=q}}}if(s.indexOf("?")>-1){s=s.substr(0,s.indexOf("?"))}if(s.indexOf("&")>-1){s=s.substr(0,s.indexOf("&"))}return s}this.embed=m;return this}})(jwplayer);(function(jwplayer){var _configurableStateVariables=["width","height","start","duration","volume","mute","fullscreen","item","plugins","stretching"];jwplayer.html5.model=function(api,container,options){var _api=api;var _container=container;var _model={id:_container.id,playlist:[],state:jwplayer.api.events.state.IDLE,position:0,buffer:0,config:{width:480,height:320,item:-1,skin:undefined,file:undefined,image:undefined,start:0,duration:0,bufferlength:5,volume:90,mute:false,fullscreen:false,repeat:"",stretching:jwplayer.utils.stretching.UNIFORM,autostart:false,debug:undefined,screencolor:undefined}};var _media;var _eventDispatcher=new jwplayer.html5.eventdispatcher();var _components=["display","logo","controlbar","playlist","dock"];jwplayer.utils.extend(_model,_eventDispatcher);for(var option in options){if(typeof options[option]=="string"){var type=/color$/.test(option)?"color":null;options[option]=jwplayer.utils.typechecker(options[option],type)}var config=_model.config;var path=option.split(".");for(var edge in path){if(edge==path.length-1){config[path[edge]]=options[option]}else{if(!jwplayer.utils.exists(config[path[edge]])){config[path[edge]]={}}config=config[path[edge]]}}}for(var index in _configurableStateVariables){var configurableStateVariable=_configurableStateVariables[index];_model[configurableStateVariable]=_model.config[configurableStateVariable]}var pluginorder=_components.concat([]);if(jwplayer.utils.exists(_model.plugins)){if(typeof _model.plugins=="string"){var userplugins=_model.plugins.split(",");for(var userplugin in userplugins){if(typeof userplugins[userplugin]=="string"){pluginorder.push(userplugins[userplugin].replace(/^\s+|\s+$/g,""))}}}}if(jwplayer.utils.isIOS()){pluginorder=["display","logo","dock","playlist"];if(!jwplayer.utils.exists(_model.config.repeat)){_model.config.repeat="list"}}else{if(_model.config.chromeless){pluginorder=["logo","dock","playlist"];if(!jwplayer.utils.exists(_model.config.repeat)){_model.config.repeat="list"}}}_model.plugins={order:pluginorder,config:{},object:{}};if(typeof _model.config.components!="undefined"){for(var component in _model.config.components){_model.plugins.config[component]=_model.config.components[component]}}for(var pluginIndex in _model.plugins.order){var pluginName=_model.plugins.order[pluginIndex];var pluginConfig=!jwplayer.utils.exists(_model.plugins.config[pluginName])?{}:_model.plugins.config[pluginName];_model.plugins.config[pluginName]=!jwplayer.utils.exists(_model.plugins.config[pluginName])?pluginConfig:jwplayer.utils.extend(_model.plugins.config[pluginName],pluginConfig);if(!jwplayer.utils.exists(_model.plugins.config[pluginName].position)){if(pluginName=="playlist"){_model.plugins.config[pluginName].position=jwplayer.html5.view.positions.NONE}else{_model.plugins.config[pluginName].position=jwplayer.html5.view.positions.OVER}}else{_model.plugins.config[pluginName].position=_model.plugins.config[pluginName].position.toString().toUpperCase()}}if(typeof _model.plugins.config.dock!="undefined"){if(typeof _model.plugins.config.dock!="object"){var position=_model.plugins.config.dock.toString().toUpperCase();_model.plugins.config.dock={position:position}}if(typeof _model.plugins.config.dock.position!="undefined"){_model.plugins.config.dock.align=_model.plugins.config.dock.position;_model.plugins.config.dock.position=jwplayer.html5.view.positions.OVER}}function _loadExternal(playlistfile){var loader=new jwplayer.html5.playlistloader();loader.addEventListener(jwplayer.api.events.JWPLAYER_PLAYLIST_LOADED,function(evt){_model.playlist=new jwplayer.html5.playlist(evt);_loadComplete(true)});loader.addEventListener(jwplayer.api.events.JWPLAYER_ERROR,function(evt){_model.playlist=new jwplayer.html5.playlist({playlist:[]});_loadComplete(false)});loader.load(playlistfile)}function _loadComplete(){if(_model.config.shuffle){_model.item=_getShuffleItem()}else{if(_model.config.item>=_model.playlist.length){_model.config.item=_model.playlist.length-1}else{if(_model.config.item<0){_model.config.item=0}}_model.item=_model.config.item}_eventDispatcher.sendEvent(jwplayer.api.events.JWPLAYER_PLAYLIST_LOADED,{playlist:_model.playlist});_eventDispatcher.sendEvent(jwplayer.api.events.JWPLAYER_PLAYLIST_ITEM,{index:_model.item})}_model.loadPlaylist=function(arg){var input;if(typeof arg=="string"){if(arg.indexOf("[")==0||arg.indexOf("{")=="0"){try{input=eval(arg)}catch(err){input=arg}}else{input=arg}}else{input=arg}var config;switch(jwplayer.utils.typeOf(input)){case"object":config=input;break;case"array":config={playlist:input};break;default:_loadExternal(input);return;break}_model.playlist=new jwplayer.html5.playlist(config);if(jwplayer.utils.extension(_model.playlist[0].file)=="xml"){_loadExternal(_model.playlist[0].file)}else{_loadComplete()}};function _getShuffleItem(){var result=null;if(_model.playlist.length>1){while(!jwplayer.utils.exists(result)){result=Math.floor(Math.random()*_model.playlist.length);if(result==_model.item){result=null}}}else{result=0}return result}function forward(evt){if(evt.type==jwplayer.api.events.JWPLAYER_MEDIA_LOADED){_container=_media.getDisplayElement()}_eventDispatcher.sendEvent(evt.type,evt)}var _mediaProviders={};_model.setActiveMediaProvider=function(playlistItem){if(playlistItem.provider=="audio"){playlistItem.provider="sound"}var provider=playlistItem.provider;var current=_media?_media.getDisplayElement():null;if(provider=="sound"||provider=="http"||provider==""){provider="video"}if(!jwplayer.utils.exists(_mediaProviders[provider])){switch(provider){case"video":_media=new jwplayer.html5.mediavideo(_model,current?current:_container);break;case"youtube":_media=new jwplayer.html5.mediayoutube(_model,current?current:_container);break}if(!jwplayer.utils.exists(_media)){return false}_media.addGlobalListener(forward);_mediaProviders[provider]=_media}else{if(_media!=_mediaProviders[provider]){if(_media){_media.stop()}_media=_mediaProviders[provider]}}return true};_model.getMedia=function(){return _media};_model.seek=function(pos){_eventDispatcher.sendEvent(jwplayer.api.events.JWPLAYER_MEDIA_SEEK,{position:_model.position,offset:pos});return _media.seek(pos)};_model.setupPlugins=function(){if(!jwplayer.utils.exists(_model.plugins)||!jwplayer.utils.exists(_model.plugins.order)||_model.plugins.order.length==0){jwplayer.utils.log("No plugins to set up");return _model}for(var i=0;i<_model.plugins.order.length;i++){try{var pluginName=_model.plugins.order[i];if(jwplayer.utils.exists(jwplayer.html5[pluginName])){if(pluginName=="playlist"){_model.plugins.object[pluginName]=new jwplayer.html5.playlistcomponent(_api,_model.plugins.config[pluginName])}else{_model.plugins.object[pluginName]=new jwplayer.html5[pluginName](_api,_model.plugins.config[pluginName])}}else{_model.plugins.order.splice(plugin,plugin+1)}if(typeof _model.plugins.object[pluginName].addGlobalListener=="function"){_model.plugins.object[pluginName].addGlobalListener(forward)}}catch(err){jwplayer.utils.log("Could not setup "+pluginName)}}};return _model}})(jwplayer);(function(a){a.html5.playlist=function(b){var d=[];if(b.playlist&&b.playlist instanceof Array&&b.playlist.length>0){for(var c in b.playlist){if(!isNaN(parseInt(c))){d.push(new a.html5.playlistitem(b.playlist[c]))}}}else{d.push(new a.html5.playlistitem(b))}return d}})(jwplayer);(function(a){var c={size:180,position:a.html5.view.positions.NONE,itemheight:60,thumbs:true,fontcolor:"#000000",overcolor:"",activecolor:"",backgroundcolor:"#f8f8f8",font:"_sans",fontsize:"",fontstyle:"",fontweight:""};var b={_sans:"Arial, Helvetica, sans-serif",_serif:"Times, Times New Roman, serif",_typewriter:"Courier New, Courier, monospace"};_utils=a.utils;_css=_utils.css;_hide=function(d){_css(d,{display:"none"})};_show=function(d){_css(d,{display:"block"})};a.html5.playlistcomponent=function(r,B){var w=r;var e=a.utils.extend({},c,w.skin.getComponentSettings("playlist"),B);if(e.position==a.html5.view.positions.NONE||typeof a.html5.view.positions[e.position]=="undefined"){return}var x;var l;var C;var d;var g;var f;var k=-1;var h={background:undefined,item:undefined,itemOver:undefined,itemImage:undefined,itemActive:undefined};this.getDisplayElement=function(){return x};this.resize=function(F,D){l=F;C=D;if(w.jwGetFullscreen()){_hide(x)}else{var E={display:"block",width:l,height:C};_css(x,E)}};this.show=function(){_show(x)};this.hide=function(){_hide(x)};function j(){x=document.createElement("div");x.id=w.id+"_jwplayer_playlistcomponent";switch(e.position){case a.html5.view.positions.RIGHT:case a.html5.view.positions.LEFT:x.style.width=e.size+"px";break;case a.html5.view.positions.TOP:case a.html5.view.positions.BOTTOM:x.style.height=e.size+"px";break}A();if(h.item){e.itemheight=h.item.height}x.style.backgroundColor="#C6C6C6";w.jwAddEventListener(a.api.events.JWPLAYER_PLAYLIST_LOADED,s);w.jwAddEventListener(a.api.events.JWPLAYER_PLAYLIST_ITEM,u);w.jwAddEventListener(a.api.events.JWPLAYER_PLAYER_STATE,m)}function p(){var D=document.createElement("ul");_css(D,{width:x.style.width,minWidth:x.style.width,height:x.style.height,backgroundColor:e.backgroundcolor,backgroundImage:h.background?"url("+h.background.src+")":"",color:e.fontcolor,listStyle:"none",margin:0,padding:0,fontFamily:b[e.font]?b[e.font]:b._sans,fontSize:(e.fontsize?e.fontsize:11)+"px",fontStyle:e.fontstyle,fontWeight:e.fontweight,overflowY:"auto"});return D}function y(D){return function(){var E=f.getElementsByClassName("item")[D];var F=e.fontcolor;var G=h.item?"url("+h.item.src+")":"";if(D==w.jwGetPlaylistIndex()){if(e.activecolor!==""){F=e.activecolor}if(h.itemActive){G="url("+h.itemActive.src+")"}}_css(E,{color:e.overcolor!==""?e.overcolor:F,backgroundImage:h.itemOver?"url("+h.itemOver.src+")":G})}}function o(D){return function(){var E=f.getElementsByClassName("item")[D];var F=e.fontcolor;var G=h.item?"url("+h.item.src+")":"";if(D==w.jwGetPlaylistIndex()){if(e.activecolor!==""){F=e.activecolor}if(h.itemActive){G="url("+h.itemActive.src+")"}}_css(E,{color:F,backgroundImage:G})}}function q(I){var P=d[I];var O=document.createElement("li");O.className="item";_css(O,{height:e.itemheight,display:"block",cursor:"pointer",backgroundImage:h.item?"url("+h.item.src+")":"",backgroundSize:"100% "+e.itemheight+"px"});O.onmouseover=y(I);O.onmouseout=o(I);var J=document.createElement("div");var F=new Image();var K=0;var L=0;var M=0;if(v()&&(P.image||P["playlist.image"]||h.itemImage)){F.className="image";if(h.itemImage){K=(e.itemheight-h.itemImage.height)/2;L=h.itemImage.width;M=h.itemImage.height}else{L=e.itemheight*4/3;M=e.itemheight}_css(J,{height:M,width:L,"float":"left",styleFloat:"left",cssFloat:"left",margin:"0 5px 0 0",background:"black",overflow:"hidden",margin:K+"px",position:"relative"});_css(F,{position:"relative"});J.appendChild(F);F.onload=function(){a.utils.stretch(a.utils.stretching.FILL,F,L,M,this.naturalWidth,this.naturalHeight)};if(P["playlist.image"]){F.src=P["playlist.image"]}else{if(P.image){F.src=P.image}else{if(h.itemImage){F.src=h.itemImage.src}}}O.appendChild(J)}var E=l-L-K*2;if(C<e.itemheight*d.length){E-=15}var D=document.createElement("div");_css(D,{position:"relative",height:"100%",overflow:"hidden"});var G=document.createElement("span");if(P.duration>0){G.className="duration";_css(G,{fontSize:(e.fontsize?e.fontsize:11)+"px",fontWeight:(e.fontweight?e.fontweight:"bold"),width:"40px",height:e.fontsize?e.fontsize+10:20,lineHeight:24,"float":"right",styleFloat:"right",cssFloat:"right"});G.innerHTML=_utils.timeFormat(P.duration);D.appendChild(G)}var N=document.createElement("span");N.className="title";_css(N,{padding:"5px 5px 0 "+(K?0:"5px"),height:e.fontsize?e.fontsize+10:20,lineHeight:e.fontsize?e.fontsize+10:20,overflow:"hidden","float":"left",styleFloat:"left",cssFloat:"left",width:((P.duration>0)?E-50:E)-10+"px",fontSize:(e.fontsize?e.fontsize:13)+"px",fontWeight:(e.fontweight?e.fontweight:"bold")});N.innerHTML=P?P.title:"";D.appendChild(N);if(P.description){var H=document.createElement("span");H.className="description";_css(H,{display:"block","float":"left",styleFloat:"left",cssFloat:"left",margin:0,paddingLeft:N.style.paddingLeft,paddingRight:N.style.paddingRight,lineHeight:(e.fontsize?e.fontsize+4:16)+"px",overflow:"hidden",position:"relative"});H.innerHTML=P.description;D.appendChild(H)}O.appendChild(D);return O}function s(E){x.innerHTML="";d=w.jwGetPlaylist();if(!d){return}items=[];f=p();for(var F=0;F<d.length;F++){var D=q(F);D.onclick=z(F);f.appendChild(D);items.push(D)}k=w.jwGetPlaylistIndex();o(k)();x.appendChild(f);if(_utils.isIOS()&&window.iScroll){f.style.height=e.itemheight*d.length+"px";var G=new iScroll(x.id)}}function z(D){return function(){w.jwPlaylistItem(D);w.jwPlay(true)}}function n(){f.scrollTop=w.jwGetPlaylistIndex()*e.itemheight}function v(){return e.thumbs.toString().toLowerCase()=="true"}function u(D){if(k>=0){o(k)();k=D.index}o(D.index)();n()}function m(){if(e.position==a.html5.view.positions.OVER){switch(w.jwGetState()){case a.api.events.state.IDLE:_show(x);break;default:_hide(x);break}}}function A(){for(var D in h){h[D]=t(D)}}function t(D){return w.skin.getSkinElement("playlist",D)}j();return this}})(jwplayer);(function(b){b.html5.playlistitem=function(d){var e={author:"",date:"",description:"",image:"",link:"",mediaid:"",tags:"",title:"",provider:"",file:"",streamer:"",duration:-1,start:0,currentLevel:-1,levels:[]};var c=b.utils.extend({},e,d);if(c.type){c.provider=c.type;delete c.type}if(c.levels.length===0){c.levels[0]=new b.html5.playlistitemlevel(c)}if(!c.provider){c.provider=a(c.levels[0])}else{c.provider=c.provider.toLowerCase()}return c};function a(e){if(b.utils.isYouTube(e.file)){return"youtube"}else{var f=b.utils.extension(e.file);var c;if(f&&b.utils.extensionmap[f]){if(f=="m3u8"){return"video"}c=b.utils.extensionmap[f].html5}else{if(e.type){c=e.type}}if(c){var d=c.split("/")[0];if(d=="audio"){return"sound"}else{if(d=="video"){return d}}}}return""}})(jwplayer);(function(a){a.html5.playlistitemlevel=function(b){var d={file:"",streamer:"",bitrate:0,width:0};for(var c in d){if(a.utils.exists(b[c])){d[c]=b[c]}}return d}})(jwplayer);(function(a){a.html5.playlistloader=function(){var c=new a.html5.eventdispatcher();a.utils.extend(this,c);this.load=function(e){a.utils.ajax(e,d,b)};function d(g){var f=[];try{var f=a.utils.parsers.rssparser.parse(g.responseXML.firstChild);c.sendEvent(a.api.events.JWPLAYER_PLAYLIST_LOADED,{playlist:new a.html5.playlist({playlist:f})})}catch(h){b("Could not parse the playlist")}}function b(e){c.sendEvent(a.api.events.JWPLAYER_ERROR,{error:e?e:"could not load playlist for whatever reason. too bad"})}}})(jwplayer);(function(a){a.html5.skin=function(){var b={};var c=false;this.load=function(d,e){new a.html5.skinloader(d,function(f){c=true;b=f;e()},function(){new a.html5.skinloader("",function(f){c=true;b=f;e()})})};this.getSkinElement=function(d,e){if(c){try{return b[d].elements[e]}catch(f){a.utils.log("No such skin component / element: ",[d,e])}}return null};this.getComponentSettings=function(d){if(c){return b[d].settings}return null};this.getComponentLayout=function(d){if(c){return b[d].layout}return null}}})(jwplayer);(function(a){a.html5.skinloader=function(f,p,k){var o={};var c=p;var l=k;var e=true;var j;var n=f;var s=false;function m(){if(typeof n!="string"||n===""){d(a.html5.defaultSkin().xml)}else{a.utils.ajax(a.utils.getAbsolutePath(n),function(t){try{if(a.utils.exists(t.responseXML)){d(t.responseXML);return}}catch(u){h()}d(a.html5.defaultSkin().xml)},function(t){d(a.html5.defaultSkin().xml)})}}function d(y){var E=y.getElementsByTagName("component");if(E.length===0){return}for(var H=0;H<E.length;H++){var C=E[H].getAttribute("name");var B={settings:{},elements:{},layout:{}};o[C]=B;var G=E[H].getElementsByTagName("elements")[0].getElementsByTagName("element");for(var F=0;F<G.length;F++){b(G[F],C)}var z=E[H].getElementsByTagName("settings")[0];if(z&&z.childNodes.length>0){var K=z.getElementsByTagName("setting");for(var P=0;P<K.length;P++){var Q=K[P].getAttribute("name");var I=K[P].getAttribute("value");var x=/color$/.test(Q)?"color":null;o[C].settings[Q]=a.utils.typechecker(I,x)}}var L=E[H].getElementsByTagName("layout")[0];if(L&&L.childNodes.length>0){var M=L.getElementsByTagName("group");for(var w=0;w<M.length;w++){var A=M[w];o[C].layout[A.getAttribute("position")]={elements:[]};for(var O=0;O<A.attributes.length;O++){var D=A.attributes[O];o[C].layout[A.getAttribute("position")][D.name]=D.value}var N=A.getElementsByTagName("*");for(var v=0;v<N.length;v++){var t=N[v];o[C].layout[A.getAttribute("position")].elements.push({type:t.tagName});for(var u=0;u<t.attributes.length;u++){var J=t.attributes[u];o[C].layout[A.getAttribute("position")].elements[v][J.name]=J.value}if(!a.utils.exists(o[C].layout[A.getAttribute("position")].elements[v].name)){o[C].layout[A.getAttribute("position")].elements[v].name=t.tagName}}}}e=false;r()}}function r(){clearInterval(j);if(!s){j=setInterval(function(){q()},100)}}function b(y,x){var w=new Image();var t=y.getAttribute("name");var v=y.getAttribute("src");var A;if(v.indexOf("data:image/png;base64,")===0){A=v}else{var u=a.utils.getAbsolutePath(n);var z=u.substr(0,u.lastIndexOf("/"));A=[z,x,v].join("/")}o[x].elements[t]={height:0,width:0,src:"",ready:false,image:w};w.onload=function(B){g(w,t,x)};w.onerror=function(B){s=true;r();l()};w.src=A}function h(){for(var u in o){var w=o[u];for(var t in w.elements){var x=w.elements[t];var v=x.image;v.onload=null;v.onerror=null;delete x.image;delete w.elements[t]}delete o[u]}}function q(){for(var t in o){if(t!="properties"){for(var u in o[t].elements){if(!o[t].elements[u].ready){return}}}}if(e===false){clearInterval(j);c(o)}}function g(t,v,u){if(o[u]&&o[u].elements[v]){o[u].elements[v].height=t.height;o[u].elements[v].width=t.width;o[u].elements[v].src=t.src;o[u].elements[v].ready=true;r()}else{a.utils.log("Loaded an image for a missing element: "+u+"."+v)}}m()}})(jwplayer);(function(a){a.html5.api=function(c,n){var m={};var f=document.createElement("div");c.parentNode.replaceChild(f,c);f.id=c.id;m.version=a.version;m.id=f.id;var l=new a.html5.model(m,f,n);var j=new a.html5.view(m,f,l);var k=new a.html5.controller(m,f,l,j);m.skin=new a.html5.skin();m.jwPlay=function(o){if(typeof o=="undefined"){e()}else{if(o.toString().toLowerCase()=="true"){k.play()}else{k.pause()}}};m.jwPause=function(o){if(typeof o=="undefined"){e()}else{if(o.toString().toLowerCase()=="true"){k.pause()}else{k.play()}}};function e(){if(l.state==a.api.events.state.PLAYING||l.state==a.api.events.state.BUFFERING){k.pause()}else{k.play()}}m.jwStop=k.stop;m.jwSeek=k.seek;m.jwPlaylistItem=k.item;m.jwPlaylistNext=k.next;m.jwPlaylistPrev=k.prev;m.jwResize=k.resize;m.jwLoad=k.load;function h(o){return function(){return l[o]}}function d(o,q,p){return function(){var r=l.plugins.object[o];if(r&&r[q]&&typeof r[q]=="function"){r[q].apply(r,p)}}}m.jwGetItem=h("item");m.jwGetPosition=h("position");m.jwGetDuration=h("duration");m.jwGetBuffer=h("buffer");m.jwGetWidth=h("width");m.jwGetHeight=h("height");m.jwGetFullscreen=h("fullscreen");m.jwSetFullscreen=k.setFullscreen;m.jwGetVolume=h("volume");m.jwSetVolume=k.setVolume;m.jwGetMute=h("mute");m.jwSetMute=k.setMute;m.jwGetStretching=h("stretching");m.jwGetState=h("state");m.jwGetVersion=function(){return m.version};m.jwGetPlaylist=function(){return l.playlist};m.jwGetPlaylistIndex=m.jwGetItem;m.jwAddEventListener=k.addEventListener;m.jwRemoveEventListener=k.removeEventListener;m.jwSendEvent=k.sendEvent;m.jwDockSetButton=function(r,o,p,q){if(l.plugins.object.dock&&l.plugins.object.dock.setButton){l.plugins.object.dock.setButton(r,o,p,q)}};m.jwControlbarShow=d("controlbar","show");m.jwControlbarHide=d("controlbar","hide");m.jwDockShow=d("dock","show");m.jwDockHide=d("dock","hide");m.jwDisplayShow=d("display","show");m.jwDisplayHide=d("display","hide");m.jwGetLevel=function(){};m.jwGetBandwidth=function(){};m.jwGetLockState=function(){};m.jwLock=function(){};m.jwUnlock=function(){};function b(){if(l.config.playlistfile){l.addEventListener(a.api.events.JWPLAYER_PLAYLIST_LOADED,g);l.loadPlaylist(l.config.playlistfile)}else{if(typeof l.config.playlist=="string"){l.addEventListener(a.api.events.JWPLAYER_PLAYLIST_LOADED,g);l.loadPlaylist(l.config.playlist)}else{l.loadPlaylist(l.config);setTimeout(g,25)}}}function g(o){l.removeEventListener(a.api.events.JWPLAYER_PLAYLIST_LOADED,g);l.setupPlugins();j.setup();var o={id:m.id,version:m.version};k.playerReady(o)}if(l.config.chromeless&&!a.utils.isIOS()){b()}else{m.skin.load(l.config.skin,b)}return m}})(jwplayer)};/*
|
|
|
2782 |
mustache.js — Logic-less templates in JavaScript
|
|
|
2783 |
|
|
|
2784 |
See http://mustache.github.com/ for more info.
|
|
|
2785 |
*/
|
|
|
2786 |
|
|
|
2787 |
var Mustache = function() {
|
|
|
2788 |
var Renderer = function() {};
|
|
|
2789 |
|
|
|
2790 |
Renderer.prototype = {
|
|
|
2791 |
otag: "{{",
|
|
|
2792 |
ctag: "}}",
|
|
|
2793 |
pragmas: {},
|
|
|
2794 |
buffer: [],
|
|
|
2795 |
pragmas_implemented: {
|
|
|
2796 |
"IMPLICIT-ITERATOR": true
|
|
|
2797 |
},
|
|
|
2798 |
context: {},
|
|
|
2799 |
|
|
|
2800 |
render: function(template, context, partials, in_recursion) {
|
|
|
2801 |
// reset buffer & set context
|
|
|
2802 |
if(!in_recursion) {
|
|
|
2803 |
this.context = context;
|
|
|
2804 |
this.buffer = []; // TODO: make this non-lazy
|
|
|
2805 |
}
|
|
|
2806 |
|
|
|
2807 |
// fail fast
|
|
|
2808 |
if(!this.includes("", template)) {
|
|
|
2809 |
if(in_recursion) {
|
|
|
2810 |
return template;
|
|
|
2811 |
} else {
|
|
|
2812 |
this.send(template);
|
|
|
2813 |
return;
|
|
|
2814 |
}
|
|
|
2815 |
}
|
|
|
2816 |
|
|
|
2817 |
template = this.render_pragmas(template);
|
|
|
2818 |
var html = this.render_section(template, context, partials);
|
|
|
2819 |
if(in_recursion) {
|
|
|
2820 |
return this.render_tags(html, context, partials, in_recursion);
|
|
|
2821 |
}
|
|
|
2822 |
|
|
|
2823 |
this.render_tags(html, context, partials, in_recursion);
|
|
|
2824 |
},
|
|
|
2825 |
|
|
|
2826 |
/*
|
|
|
2827 |
Sends parsed lines
|
|
|
2828 |
*/
|
|
|
2829 |
send: function(line) {
|
|
|
2830 |
if(line !== "") {
|
|
|
2831 |
this.buffer.push(line);
|
|
|
2832 |
}
|
|
|
2833 |
},
|
|
|
2834 |
|
|
|
2835 |
/*
|
|
|
2836 |
Looks for %PRAGMAS
|
|
|
2837 |
*/
|
|
|
2838 |
render_pragmas: function(template) {
|
|
|
2839 |
// no pragmas
|
|
|
2840 |
if(!this.includes("%", template)) {
|
|
|
2841 |
return template;
|
|
|
2842 |
}
|
|
|
2843 |
|
|
|
2844 |
var that = this;
|
|
|
2845 |
var regex = new RegExp(this.otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" +
|
|
|
2846 |
this.ctag, "g");
|
|
|
2847 |
return template.replace(regex, function(match, pragma, options) {
|
|
|
2848 |
if(!that.pragmas_implemented[pragma]) {
|
|
|
2849 |
throw({message:
|
|
|
2850 |
"This implementation of mustache doesn't understand the '" +
|
|
|
2851 |
pragma + "' pragma"});
|
|
|
2852 |
}
|
|
|
2853 |
that.pragmas[pragma] = {};
|
|
|
2854 |
if(options) {
|
|
|
2855 |
var opts = options.split("=");
|
|
|
2856 |
that.pragmas[pragma][opts[0]] = opts[1];
|
|
|
2857 |
}
|
|
|
2858 |
return "";
|
|
|
2859 |
// ignore unknown pragmas silently
|
|
|
2860 |
});
|
|
|
2861 |
},
|
|
|
2862 |
|
|
|
2863 |
/*
|
|
|
2864 |
Tries to find a partial in the curent scope and render it
|
|
|
2865 |
*/
|
|
|
2866 |
render_partial: function(name, context, partials) {
|
|
|
2867 |
name = this.trim(name);
|
|
|
2868 |
if(!partials || partials[name] === undefined) {
|
|
|
2869 |
throw({message: "unknown_partial '" + name + "'"});
|
|
|
2870 |
}
|
|
|
2871 |
if(typeof(context[name]) != "object") {
|
|
|
2872 |
return this.render(partials[name], context, partials, true);
|
|
|
2873 |
}
|
|
|
2874 |
return this.render(partials[name], context[name], partials, true);
|
|
|
2875 |
},
|
|
|
2876 |
|
|
|
2877 |
/*
|
|
|
2878 |
Renders inverted (^) and normal (#) sections
|
|
|
2879 |
*/
|
|
|
2880 |
render_section: function(template, context, partials) {
|
|
|
2881 |
if(!this.includes("#", template) && !this.includes("^", template)) {
|
|
|
2882 |
return template;
|
|
|
2883 |
}
|
|
|
2884 |
|
|
|
2885 |
var that = this;
|
|
|
2886 |
// CSW - Added "+?" so it finds the tighest bound, not the widest
|
|
|
2887 |
var regex = new RegExp(this.otag + "(\\^|\\#)\\s*(.+)\\s*" + this.ctag +
|
|
|
2888 |
"\n*([\\s\\S]+?)" + this.otag + "\\/\\s*\\2\\s*" + this.ctag +
|
|
|
2889 |
"\\s*", "mg");
|
|
|
2890 |
|
|
|
2891 |
// for each {{#foo}}{{/foo}} section do...
|
|
|
2892 |
return template.replace(regex, function(match, type, name, content) {
|
|
|
2893 |
var value = that.find(name, context);
|
|
|
2894 |
if(type == "^") { // inverted section
|
|
|
2895 |
if(!value || that.is_array(value) && value.length === 0) {
|
|
|
2896 |
// false or empty list, render it
|
|
|
2897 |
return that.render(content, context, partials, true);
|
|
|
2898 |
} else {
|
|
|
2899 |
return "";
|
|
|
2900 |
}
|
|
|
2901 |
} else if(type == "#") { // normal section
|
|
|
2902 |
if(that.is_array(value)) { // Enumerable, Let's loop!
|
|
|
2903 |
return that.map(value, function(row) {
|
|
|
2904 |
return that.render(content, that.create_context(row),
|
|
|
2905 |
partials, true);
|
|
|
2906 |
}).join("");
|
|
|
2907 |
} else if(that.is_object(value)) { // Object, Use it as subcontext!
|
|
|
2908 |
return that.render(content, that.create_context(value),
|
|
|
2909 |
partials, true);
|
|
|
2910 |
} else if(typeof value === "function") {
|
|
|
2911 |
// higher order section
|
|
|
2912 |
return value.call(context, content, function(text) {
|
|
|
2913 |
return that.render(text, context, partials, true);
|
|
|
2914 |
});
|
|
|
2915 |
} else if(value) { // boolean section
|
|
|
2916 |
return that.render(content, context, partials, true);
|
|
|
2917 |
} else {
|
|
|
2918 |
return "";
|
|
|
2919 |
}
|
|
|
2920 |
}
|
|
|
2921 |
});
|
|
|
2922 |
},
|
|
|
2923 |
|
|
|
2924 |
/*
|
|
|
2925 |
Replace {{foo}} and friends with values from our view
|
|
|
2926 |
*/
|
|
|
2927 |
render_tags: function(template, context, partials, in_recursion) {
|
|
|
2928 |
// tit for tat
|
|
|
2929 |
var that = this;
|
|
|
2930 |
|
|
|
2931 |
var new_regex = function() {
|
|
|
2932 |
return new RegExp(that.otag + "(=|!|>|\\{|%)?([^\\/#\\^]+?)\\1?" +
|
|
|
2933 |
that.ctag + "+", "g");
|
|
|
2934 |
};
|
|
|
2935 |
|
|
|
2936 |
var regex = new_regex();
|
|
|
2937 |
var tag_replace_callback = function(match, operator, name) {
|
|
|
2938 |
switch(operator) {
|
|
|
2939 |
case "!": // ignore comments
|
|
|
2940 |
return "";
|
|
|
2941 |
case "=": // set new delimiters, rebuild the replace regexp
|
|
|
2942 |
that.set_delimiters(name);
|
|
|
2943 |
regex = new_regex();
|
|
|
2944 |
return "";
|
|
|
2945 |
case ">": // render partial
|
|
|
2946 |
return that.render_partial(name, context, partials);
|
|
|
2947 |
case "{": // the triple mustache is unescaped
|
|
|
2948 |
return that.find(name, context);
|
|
|
2949 |
default: // escape the value
|
|
|
2950 |
return that.escape(that.find(name, context));
|
|
|
2951 |
}
|
|
|
2952 |
};
|
|
|
2953 |
var lines = template.split("\n");
|
|
|
2954 |
for(var i = 0; i < lines.length; i++) {
|
|
|
2955 |
lines[i] = lines[i].replace(regex, tag_replace_callback, this);
|
|
|
2956 |
if(!in_recursion) {
|
|
|
2957 |
this.send(lines[i]);
|
|
|
2958 |
}
|
|
|
2959 |
}
|
|
|
2960 |
|
|
|
2961 |
if(in_recursion) {
|
|
|
2962 |
return lines.join("\n");
|
|
|
2963 |
}
|
|
|
2964 |
},
|
|
|
2965 |
|
|
|
2966 |
set_delimiters: function(delimiters) {
|
|
|
2967 |
var dels = delimiters.split(" ");
|
|
|
2968 |
this.otag = this.escape_regex(dels[0]);
|
|
|
2969 |
this.ctag = this.escape_regex(dels[1]);
|
|
|
2970 |
},
|
|
|
2971 |
|
|
|
2972 |
escape_regex: function(text) {
|
|
|
2973 |
// thank you Simon Willison
|
|
|
2974 |
if(!arguments.callee.sRE) {
|
|
|
2975 |
var specials = [
|
|
|
2976 |
'/', '.', '*', '+', '?', '|',
|
|
|
2977 |
'(', ')', '[', ']', '{', '}', '\\'
|
|
|
2978 |
];
|
|
|
2979 |
arguments.callee.sRE = new RegExp(
|
|
|
2980 |
'(\\' + specials.join('|\\') + ')', 'g'
|
|
|
2981 |
);
|
|
|
2982 |
}
|
|
|
2983 |
return text.replace(arguments.callee.sRE, '\\$1');
|
|
|
2984 |
},
|
|
|
2985 |
|
|
|
2986 |
/*
|
|
|
2987 |
find `name` in current `context`. That is find me a value
|
|
|
2988 |
from the view object
|
|
|
2989 |
*/
|
|
|
2990 |
find: function(name, context) {
|
|
|
2991 |
name = this.trim(name);
|
|
|
2992 |
|
|
|
2993 |
// Checks whether a value is thruthy or false or 0
|
|
|
2994 |
function is_kinda_truthy(bool) {
|
|
|
2995 |
return bool === false || bool === 0 || bool;
|
|
|
2996 |
}
|
|
|
2997 |
|
|
|
2998 |
var value;
|
|
|
2999 |
if(is_kinda_truthy(context[name])) {
|
|
|
3000 |
value = context[name];
|
|
|
3001 |
} else if(is_kinda_truthy(this.context[name])) {
|
|
|
3002 |
value = this.context[name];
|
|
|
3003 |
}
|
|
|
3004 |
|
|
|
3005 |
if(typeof value === "function") {
|
|
|
3006 |
return value.apply(context);
|
|
|
3007 |
}
|
|
|
3008 |
if(value !== undefined) {
|
|
|
3009 |
return value;
|
|
|
3010 |
}
|
|
|
3011 |
// silently ignore unkown variables
|
|
|
3012 |
return "";
|
|
|
3013 |
},
|
|
|
3014 |
|
|
|
3015 |
// Utility methods
|
|
|
3016 |
|
|
|
3017 |
/* includes tag */
|
|
|
3018 |
includes: function(needle, haystack) {
|
|
|
3019 |
return haystack.indexOf(this.otag + needle) != -1;
|
|
|
3020 |
},
|
|
|
3021 |
|
|
|
3022 |
/*
|
|
|
3023 |
Does away with nasty characters
|
|
|
3024 |
*/
|
|
|
3025 |
escape: function(s) {
|
|
|
3026 |
s = String(s === null ? "" : s);
|
|
|
3027 |
return s.replace(/&(?!\w+;)|["'<>\\]/g, function(s) {
|
|
|
3028 |
switch(s) {
|
|
|
3029 |
case "&": return "&";
|
|
|
3030 |
case "\\": return "\\\\";
|
|
|
3031 |
case '"': return '"';
|
|
|
3032 |
case "'": return ''';
|
|
|
3033 |
case "<": return "<";
|
|
|
3034 |
case ">": return ">";
|
|
|
3035 |
default: return s;
|
|
|
3036 |
}
|
|
|
3037 |
});
|
|
|
3038 |
},
|
|
|
3039 |
|
|
|
3040 |
// by @langalex, support for arrays of strings
|
|
|
3041 |
create_context: function(_context) {
|
|
|
3042 |
if(this.is_object(_context)) {
|
|
|
3043 |
return _context;
|
|
|
3044 |
} else {
|
|
|
3045 |
var iterator = ".";
|
|
|
3046 |
if(this.pragmas["IMPLICIT-ITERATOR"]) {
|
|
|
3047 |
iterator = this.pragmas["IMPLICIT-ITERATOR"].iterator;
|
|
|
3048 |
}
|
|
|
3049 |
var ctx = {};
|
|
|
3050 |
ctx[iterator] = _context;
|
|
|
3051 |
return ctx;
|
|
|
3052 |
}
|
|
|
3053 |
},
|
|
|
3054 |
|
|
|
3055 |
is_object: function(a) {
|
|
|
3056 |
return a && typeof a == "object";
|
|
|
3057 |
},
|
|
|
3058 |
|
|
|
3059 |
is_array: function(a) {
|
|
|
3060 |
return Object.prototype.toString.call(a) === '[object Array]';
|
|
|
3061 |
},
|
|
|
3062 |
|
|
|
3063 |
/*
|
|
|
3064 |
Gets rid of leading and trailing whitespace
|
|
|
3065 |
*/
|
|
|
3066 |
trim: function(s) {
|
|
|
3067 |
return s.replace(/^\s*|\s*$/g, "");
|
|
|
3068 |
},
|
|
|
3069 |
|
|
|
3070 |
/*
|
|
|
3071 |
Why, why, why? Because IE. Cry, cry cry.
|
|
|
3072 |
*/
|
|
|
3073 |
map: function(array, fn) {
|
|
|
3074 |
if (typeof array.map == "function") {
|
|
|
3075 |
return array.map(fn);
|
|
|
3076 |
} else {
|
|
|
3077 |
var r = [];
|
|
|
3078 |
var l = array.length;
|
|
|
3079 |
for(var i = 0; i < l; i++) {
|
|
|
3080 |
r.push(fn(array[i]));
|
|
|
3081 |
}
|
|
|
3082 |
return r;
|
|
|
3083 |
}
|
|
|
3084 |
}
|
|
|
3085 |
};
|
|
|
3086 |
|
|
|
3087 |
return({
|
|
|
3088 |
name: "mustache.js",
|
|
|
3089 |
version: "0.3.1-dev",
|
|
|
3090 |
|
|
|
3091 |
/*
|
|
|
3092 |
Turns a template and view into HTML
|
|
|
3093 |
*/
|
|
|
3094 |
to_html: function(template, view, partials, send_fun) {
|
|
|
3095 |
var renderer = new Renderer();
|
|
|
3096 |
if(send_fun) {
|
|
|
3097 |
renderer.send = send_fun;
|
|
|
3098 |
}
|
|
|
3099 |
renderer.render(template, view, partials);
|
|
|
3100 |
if(!send_fun) {
|
|
|
3101 |
return renderer.buffer.join("\n");
|
|
|
3102 |
}
|
|
|
3103 |
}
|
|
|
3104 |
});
|
|
|
3105 |
}();
|
|
|
3106 |
// ┌─────────────────────────────────────────────────────────────────────┐ \\
|
|
|
3107 |
// │ Raphaël 2.0 - JavaScript Vector Library │ \\
|
|
|
3108 |
// ├─────────────────────────────────────────────────────────────────────┤ \\
|
|
|
3109 |
// │ Copyright (c) 2008-2011 Dmitry Baranovskiy (http://raphaeljs.com) │ \\
|
|
|
3110 |
// │ Copyright (c) 2008-2011 Sencha Labs (http://sencha.com) │ \\
|
|
|
3111 |
// │ Licensed under the MIT (http://raphaeljs.com/license.html) license. │ \\
|
|
|
3112 |
// └─────────────────────────────────────────────────────────────────────┘ \\
|
|
|
3113 |
|
|
|
3114 |
// ┌──────────────────────────────────────────────────────────────────────────────────────┐ \\
|
|
|
3115 |
// │ Eve 0.3.2 - JavaScript Events Library │ \\
|
|
|
3116 |
// ├──────────────────────────────────────────────────────────────────────────────────────┤ \\
|
|
|
3117 |
// │ Copyright (c) 2008-2011 Dmitry Baranovskiy (http://dmitry.baranovskiy.com/) │ \\
|
|
|
3118 |
// │ Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license. │ \\
|
|
|
3119 |
// └──────────────────────────────────────────────────────────────────────────────────────┘ \\
|
|
|
3120 |
|
|
|
3121 |
(function (glob) {
|
|
|
3122 |
var version = "0.3.2",
|
|
|
3123 |
has = "hasOwnProperty",
|
|
|
3124 |
separator = /[\.\/]/,
|
|
|
3125 |
wildcard = "*",
|
|
|
3126 |
fun = function () {},
|
|
|
3127 |
numsort = function (a, b) {
|
|
|
3128 |
return a - b;
|
|
|
3129 |
},
|
|
|
3130 |
current_event,
|
|
|
3131 |
stop,
|
|
|
3132 |
events = {n: {}},
|
|
|
3133 |
|
|
|
3134 |
eve = function (name, scope) {
|
|
|
3135 |
var e = events,
|
|
|
3136 |
oldstop = stop,
|
|
|
3137 |
args = Array.prototype.slice.call(arguments, 2),
|
|
|
3138 |
listeners = eve.listeners(name),
|
|
|
3139 |
z = 0,
|
|
|
3140 |
f = false,
|
|
|
3141 |
l,
|
|
|
3142 |
indexed = [],
|
|
|
3143 |
queue = {},
|
|
|
3144 |
out = [],
|
|
|
3145 |
errors = [];
|
|
|
3146 |
current_event = name;
|
|
|
3147 |
stop = 0;
|
|
|
3148 |
for (var i = 0, ii = listeners.length; i < ii; i++) if ("zIndex" in listeners[i]) {
|
|
|
3149 |
indexed.push(listeners[i].zIndex);
|
|
|
3150 |
if (listeners[i].zIndex < 0) {
|
|
|
3151 |
queue[listeners[i].zIndex] = listeners[i];
|
|
|
3152 |
}
|
|
|
3153 |
}
|
|
|
3154 |
indexed.sort(numsort);
|
|
|
3155 |
while (indexed[z] < 0) {
|
|
|
3156 |
l = queue[indexed[z++]];
|
|
|
3157 |
out.push(l.apply(scope, args));
|
|
|
3158 |
if (stop) {
|
|
|
3159 |
stop = oldstop;
|
|
|
3160 |
return out;
|
|
|
3161 |
}
|
|
|
3162 |
}
|
|
|
3163 |
for (i = 0; i < ii; i++) {
|
|
|
3164 |
l = listeners[i];
|
|
|
3165 |
if ("zIndex" in l) {
|
|
|
3166 |
if (l.zIndex == indexed[z]) {
|
|
|
3167 |
out.push(l.apply(scope, args));
|
|
|
3168 |
if (stop) {
|
|
|
3169 |
stop = oldstop;
|
|
|
3170 |
return out;
|
|
|
3171 |
}
|
|
|
3172 |
do {
|
|
|
3173 |
z++;
|
|
|
3174 |
l = queue[indexed[z]];
|
|
|
3175 |
l && out.push(l.apply(scope, args));
|
|
|
3176 |
if (stop) {
|
|
|
3177 |
stop = oldstop;
|
|
|
3178 |
return out;
|
|
|
3179 |
}
|
|
|
3180 |
} while (l)
|
|
|
3181 |
} else {
|
|
|
3182 |
queue[l.zIndex] = l;
|
|
|
3183 |
}
|
|
|
3184 |
} else {
|
|
|
3185 |
out.push(l.apply(scope, args));
|
|
|
3186 |
if (stop) {
|
|
|
3187 |
stop = oldstop;
|
|
|
3188 |
return out;
|
|
|
3189 |
}
|
|
|
3190 |
}
|
|
|
3191 |
}
|
|
|
3192 |
stop = oldstop;
|
|
|
3193 |
return out.length ? out : null;
|
|
|
3194 |
};
|
|
|
3195 |
|
|
|
3196 |
eve.listeners = function (name) {
|
|
|
3197 |
var names = name.split(separator),
|
|
|
3198 |
e = events,
|
|
|
3199 |
item,
|
|
|
3200 |
items,
|
|
|
3201 |
k,
|
|
|
3202 |
i,
|
|
|
3203 |
ii,
|
|
|
3204 |
j,
|
|
|
3205 |
jj,
|
|
|
3206 |
nes,
|
|
|
3207 |
es = [e],
|
|
|
3208 |
out = [];
|
|
|
3209 |
for (i = 0, ii = names.length; i < ii; i++) {
|
|
|
3210 |
nes = [];
|
|
|
3211 |
for (j = 0, jj = es.length; j < jj; j++) {
|
|
|
3212 |
e = es[j].n;
|
|
|
3213 |
items = [e[names[i]], e[wildcard]];
|
|
|
3214 |
k = 2;
|
|
|
3215 |
while (k--) {
|
|
|
3216 |
item = items[k];
|
|
|
3217 |
if (item) {
|
|
|
3218 |
nes.push(item);
|
|
|
3219 |
out = out.concat(item.f || []);
|
|
|
3220 |
}
|
|
|
3221 |
}
|
|
|
3222 |
}
|
|
|
3223 |
es = nes;
|
|
|
3224 |
}
|
|
|
3225 |
return out;
|
|
|
3226 |
};
|
|
|
3227 |
|
|
|
3228 |
|
|
|
3229 |
eve.on = function (name, f) {
|
|
|
3230 |
var names = name.split(separator),
|
|
|
3231 |
e = events;
|
|
|
3232 |
for (var i = 0, ii = names.length; i < ii; i++) {
|
|
|
3233 |
e = e.n;
|
|
|
3234 |
!e[names[i]] && (e[names[i]] = {n: {}});
|
|
|
3235 |
e = e[names[i]];
|
|
|
3236 |
}
|
|
|
3237 |
e.f = e.f || [];
|
|
|
3238 |
for (i = 0, ii = e.f.length; i < ii; i++) if (e.f[i] == f) {
|
|
|
3239 |
return fun;
|
|
|
3240 |
}
|
|
|
3241 |
e.f.push(f);
|
|
|
3242 |
return function (zIndex) {
|
|
|
3243 |
if (+zIndex == +zIndex) {
|
|
|
3244 |
f.zIndex = +zIndex;
|
|
|
3245 |
}
|
|
|
3246 |
};
|
|
|
3247 |
};
|
|
|
3248 |
|
|
|
3249 |
eve.stop = function () {
|
|
|
3250 |
stop = 1;
|
|
|
3251 |
};
|
|
|
3252 |
|
|
|
3253 |
eve.nt = function (subname) {
|
|
|
3254 |
if (subname) {
|
|
|
3255 |
return new RegExp("(?:\\.|\\/|^)" + subname + "(?:\\.|\\/|$)").test(current_event);
|
|
|
3256 |
}
|
|
|
3257 |
return current_event;
|
|
|
3258 |
};
|
|
|
3259 |
|
|
|
3260 |
eve.unbind = function (name, f) {
|
|
|
3261 |
var names = name.split(separator),
|
|
|
3262 |
e,
|
|
|
3263 |
key,
|
|
|
3264 |
splice,
|
|
|
3265 |
cur = [events];
|
|
|
3266 |
for (var i = 0, ii = names.length; i < ii; i++) {
|
|
|
3267 |
for (var j = 0; j < cur.length; j += splice.length - 2) {
|
|
|
3268 |
splice = [j, 1];
|
|
|
3269 |
e = cur[j].n;
|
|
|
3270 |
if (names[i] != wildcard) {
|
|
|
3271 |
if (e[names[i]]) {
|
|
|
3272 |
splice.push(e[names[i]]);
|
|
|
3273 |
}
|
|
|
3274 |
} else {
|
|
|
3275 |
for (key in e) if (e[has](key)) {
|
|
|
3276 |
splice.push(e[key]);
|
|
|
3277 |
}
|
|
|
3278 |
}
|
|
|
3279 |
cur.splice.apply(cur, splice);
|
|
|
3280 |
}
|
|
|
3281 |
}
|
|
|
3282 |
for (i = 0, ii = cur.length; i < ii; i++) {
|
|
|
3283 |
e = cur[i];
|
|
|
3284 |
while (e.n) {
|
|
|
3285 |
if (f) {
|
|
|
3286 |
if (e.f) {
|
|
|
3287 |
for (j = 0, jj = e.f.length; j < jj; j++) if (e.f[j] == f) {
|
|
|
3288 |
e.f.splice(j, 1);
|
|
|
3289 |
break;
|
|
|
3290 |
}
|
|
|
3291 |
!e.f.length && delete e.f;
|
|
|
3292 |
}
|
|
|
3293 |
for (key in e.n) if (e.n[has](key) && e.n[key].f) {
|
|
|
3294 |
var funcs = e.n[key].f;
|
|
|
3295 |
for (j = 0, jj = funcs.length; j < jj; j++) if (funcs[j] == f) {
|
|
|
3296 |
funcs.splice(j, 1);
|
|
|
3297 |
break;
|
|
|
3298 |
}
|
|
|
3299 |
!funcs.length && delete e.n[key].f;
|
|
|
3300 |
}
|
|
|
3301 |
} else {
|
|
|
3302 |
delete e.f;
|
|
|
3303 |
for (key in e.n) if (e.n[has](key) && e.n[key].f) {
|
|
|
3304 |
delete e.n[key].f;
|
|
|
3305 |
}
|
|
|
3306 |
}
|
|
|
3307 |
e = e.n;
|
|
|
3308 |
}
|
|
|
3309 |
}
|
|
|
3310 |
};
|
|
|
3311 |
|
|
|
3312 |
eve.version = version;
|
|
|
3313 |
eve.toString = function () {
|
|
|
3314 |
return "You are running Eve " + version;
|
|
|
3315 |
};
|
|
|
3316 |
(typeof module != "undefined" && module.exports) ? (module.exports = eve) : (glob.eve = eve);
|
|
|
3317 |
})(this);
|
|
|
3318 |
|
|
|
3319 |
// ┌─────────────────────────────────────────────────────────────────────┐ \\
|
|
|
3320 |
// │ "Raphaël 2.0" - JavaScript Vector Library │ \\
|
|
|
3321 |
// ├─────────────────────────────────────────────────────────────────────┤ \\
|
|
|
3322 |
// │ Copyright (c) 2008-2011 Dmitry Baranovskiy (http://raphaeljs.com) │ \\
|
|
|
3323 |
// │ Copyright (c) 2008-2011 Sencha Labs (http://sencha.com) │ \\
|
|
|
3324 |
// │ Licensed under the MIT (http://raphaeljs.com/license.html) license. │ \\
|
|
|
3325 |
// └─────────────────────────────────────────────────────────────────────┘ \\
|
|
|
3326 |
(function () {
|
|
|
3327 |
|
|
|
3328 |
function R(first) {
|
|
|
3329 |
if (R.is(first, "function")) {
|
|
|
3330 |
return loaded ? first() : eve.on("DOMload", first);
|
|
|
3331 |
} else if (R.is(first, array)) {
|
|
|
3332 |
var a = first,
|
|
|
3333 |
cnv = R._engine.create[apply](R, a.splice(0, 3 + R.is(a[0], nu))),
|
|
|
3334 |
res = cnv.set(),
|
|
|
3335 |
i = 0,
|
|
|
3336 |
ii = a.length,
|
|
|
3337 |
j;
|
|
|
3338 |
for (; i < ii; i++) {
|
|
|
3339 |
j = a[i] || {};
|
|
|
3340 |
elements[has](j.type) && res.push(cnv[j.type]().attr(j));
|
|
|
3341 |
}
|
|
|
3342 |
return res;
|
|
|
3343 |
} else {
|
|
|
3344 |
var args = Array.prototype.slice.call(arguments, 0);
|
|
|
3345 |
if (R.is(args[args.length - 1], "function")) {
|
|
|
3346 |
var f = args.pop();
|
|
|
3347 |
return loaded ? f.call(R._engine.create[apply](R, args)) : eve.on("DOMload", function () {
|
|
|
3348 |
f.call(R._engine.create[apply](R, args));
|
|
|
3349 |
});
|
|
|
3350 |
} else {
|
|
|
3351 |
return R._engine.create[apply](R, arguments);
|
|
|
3352 |
}
|
|
|
3353 |
}
|
|
|
3354 |
}
|
|
|
3355 |
R.version = "2.0.0";
|
|
|
3356 |
R.eve = eve;
|
|
|
3357 |
var loaded,
|
|
|
3358 |
separator = /[, ]+/,
|
|
|
3359 |
elements = {circle: 1, rect: 1, path: 1, ellipse: 1, text: 1, image: 1},
|
|
|
3360 |
formatrg = /\{(\d+)\}/g,
|
|
|
3361 |
proto = "prototype",
|
|
|
3362 |
has = "hasOwnProperty",
|
|
|
3363 |
g = {
|
|
|
3364 |
doc: document,
|
|
|
3365 |
win: window
|
|
|
3366 |
},
|
|
|
3367 |
oldRaphael = {
|
|
|
3368 |
was: Object.prototype[has].call(g.win, "Raphael"),
|
|
|
3369 |
is: g.win.Raphael
|
|
|
3370 |
},
|
|
|
3371 |
Paper = function () {
|
|
|
3372 |
|
|
|
3373 |
|
|
|
3374 |
this.ca = this.customAttributes = {};
|
|
|
3375 |
},
|
|
|
3376 |
paperproto,
|
|
|
3377 |
appendChild = "appendChild",
|
|
|
3378 |
apply = "apply",
|
|
|
3379 |
concat = "concat",
|
|
|
3380 |
supportsTouch = "createTouch" in g.doc,
|
|
|
3381 |
E = "",
|
|
|
3382 |
S = " ",
|
|
|
3383 |
Str = String,
|
|
|
3384 |
split = "split",
|
|
|
3385 |
events = "click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend touchcancel"[split](S),
|
|
|
3386 |
touchMap = {
|
|
|
3387 |
mousedown: "touchstart",
|
|
|
3388 |
mousemove: "touchmove",
|
|
|
3389 |
mouseup: "touchend"
|
|
|
3390 |
},
|
|
|
3391 |
lowerCase = Str.prototype.toLowerCase,
|
|
|
3392 |
math = Math,
|
|
|
3393 |
mmax = math.max,
|
|
|
3394 |
mmin = math.min,
|
|
|
3395 |
abs = math.abs,
|
|
|
3396 |
pow = math.pow,
|
|
|
3397 |
PI = math.PI,
|
|
|
3398 |
nu = "number",
|
|
|
3399 |
string = "string",
|
|
|
3400 |
array = "array",
|
|
|
3401 |
toString = "toString",
|
|
|
3402 |
fillString = "fill",
|
|
|
3403 |
objectToString = Object.prototype.toString,
|
|
|
3404 |
paper = {},
|
|
|
3405 |
push = "push",
|
|
|
3406 |
ISURL = R._ISURL = /^url\(['"]?([^\)]+?)['"]?\)$/i,
|
|
|
3407 |
colourRegExp = /^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\))\s*$/i,
|
|
|
3408 |
isnan = {"NaN": 1, "Infinity": 1, "-Infinity": 1},
|
|
|
3409 |
bezierrg = /^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,
|
|
|
3410 |
round = math.round,
|
|
|
3411 |
setAttribute = "setAttribute",
|
|
|
3412 |
toFloat = parseFloat,
|
|
|
3413 |
toInt = parseInt,
|
|
|
3414 |
upperCase = Str.prototype.toUpperCase,
|
|
|
3415 |
availableAttrs = R._availableAttrs = {
|
|
|
3416 |
"arrow-end": "none",
|
|
|
3417 |
"arrow-start": "none",
|
|
|
3418 |
blur: 0,
|
|
|
3419 |
"clip-rect": "0 0 1e9 1e9",
|
|
|
3420 |
cursor: "default",
|
|
|
3421 |
cx: 0,
|
|
|
3422 |
cy: 0,
|
|
|
3423 |
fill: "#fff",
|
|
|
3424 |
"fill-opacity": 1,
|
|
|
3425 |
font: '10px "Arial"',
|
|
|
3426 |
"font-family": '"Arial"',
|
|
|
3427 |
"font-size": "10",
|
|
|
3428 |
"font-style": "normal",
|
|
|
3429 |
"font-weight": 400,
|
|
|
3430 |
gradient: 0,
|
|
|
3431 |
height: 0,
|
|
|
3432 |
href: "http://raphaeljs.com/",
|
|
|
3433 |
opacity: 1,
|
|
|
3434 |
path: "M0,0",
|
|
|
3435 |
r: 0,
|
|
|
3436 |
rx: 0,
|
|
|
3437 |
ry: 0,
|
|
|
3438 |
src: "",
|
|
|
3439 |
stroke: "#000",
|
|
|
3440 |
"stroke-dasharray": "",
|
|
|
3441 |
"stroke-linecap": "butt",
|
|
|
3442 |
"stroke-linejoin": "butt",
|
|
|
3443 |
"stroke-miterlimit": 0,
|
|
|
3444 |
"stroke-opacity": 1,
|
|
|
3445 |
"stroke-width": 1,
|
|
|
3446 |
target: "_blank",
|
|
|
3447 |
"text-anchor": "middle",
|
|
|
3448 |
title: "Raphael",
|
|
|
3449 |
transform: "",
|
|
|
3450 |
width: 0,
|
|
|
3451 |
x: 0,
|
|
|
3452 |
y: 0
|
|
|
3453 |
},
|
|
|
3454 |
availableAnimAttrs = R._availableAnimAttrs = {
|
|
|
3455 |
blur: nu,
|
|
|
3456 |
"clip-rect": "csv",
|
|
|
3457 |
cx: nu,
|
|
|
3458 |
cy: nu,
|
|
|
3459 |
fill: "colour",
|
|
|
3460 |
"fill-opacity": nu,
|
|
|
3461 |
"font-size": nu,
|
|
|
3462 |
height: nu,
|
|
|
3463 |
opacity: nu,
|
|
|
3464 |
path: "path",
|
|
|
3465 |
r: nu,
|
|
|
3466 |
rx: nu,
|
|
|
3467 |
ry: nu,
|
|
|
3468 |
stroke: "colour",
|
|
|
3469 |
"stroke-opacity": nu,
|
|
|
3470 |
"stroke-width": nu,
|
|
|
3471 |
transform: "transform",
|
|
|
3472 |
width: nu,
|
|
|
3473 |
x: nu,
|
|
|
3474 |
y: nu
|
|
|
3475 |
},
|
|
|
3476 |
commaSpaces = /\s*,\s*/,
|
|
|
3477 |
hsrg = {hs: 1, rg: 1},
|
|
|
3478 |
p2s = /,?([achlmqrstvxz]),?/gi,
|
|
|
3479 |
pathCommand = /([achlmrqstvz])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?\s*,?\s*)+)/ig,
|
|
|
3480 |
tCommand = /([rstm])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?\s*,?\s*)+)/ig,
|
|
|
3481 |
pathValues = /(-?\d*\.?\d*(?:e[\-+]?\d+)?)\s*,?\s*/ig,
|
|
|
3482 |
radial_gradient = R._radial_gradient = /^r(?:\(([^,]+?)\s*,\s*([^\)]+?)\))?/,
|
|
|
3483 |
eldata = {},
|
|
|
3484 |
sortByKey = function (a, b) {
|
|
|
3485 |
return a.key - b.key;
|
|
|
3486 |
},
|
|
|
3487 |
sortByNumber = function (a, b) {
|
|
|
3488 |
return toFloat(a) - toFloat(b);
|
|
|
3489 |
},
|
|
|
3490 |
fun = function () {},
|
|
|
3491 |
pipe = function (x) {
|
|
|
3492 |
return x;
|
|
|
3493 |
},
|
|
|
3494 |
rectPath = R._rectPath = function (x, y, w, h, r) {
|
|
|
3495 |
if (r) {
|
|
|
3496 |
return [["M", x + r, y], ["l", w - r * 2, 0], ["a", r, r, 0, 0, 1, r, r], ["l", 0, h - r * 2], ["a", r, r, 0, 0, 1, -r, r], ["l", r * 2 - w, 0], ["a", r, r, 0, 0, 1, -r, -r], ["l", 0, r * 2 - h], ["a", r, r, 0, 0, 1, r, -r], ["z"]];
|
|
|
3497 |
}
|
|
|
3498 |
return [["M", x, y], ["l", w, 0], ["l", 0, h], ["l", -w, 0], ["z"]];
|
|
|
3499 |
},
|
|
|
3500 |
ellipsePath = function (x, y, rx, ry) {
|
|
|
3501 |
if (ry == null) {
|
|
|
3502 |
ry = rx;
|
|
|
3503 |
}
|
|
|
3504 |
return [["M", x, y], ["m", 0, -ry], ["a", rx, ry, 0, 1, 1, 0, 2 * ry], ["a", rx, ry, 0, 1, 1, 0, -2 * ry], ["z"]];
|
|
|
3505 |
},
|
|
|
3506 |
getPath = R._getPath = {
|
|
|
3507 |
path: function (el) {
|
|
|
3508 |
return el.attr("path");
|
|
|
3509 |
},
|
|
|
3510 |
circle: function (el) {
|
|
|
3511 |
var a = el.attrs;
|
|
|
3512 |
return ellipsePath(a.cx, a.cy, a.r);
|
|
|
3513 |
},
|
|
|
3514 |
ellipse: function (el) {
|
|
|
3515 |
var a = el.attrs;
|
|
|
3516 |
return ellipsePath(a.cx, a.cy, a.rx, a.ry);
|
|
|
3517 |
},
|
|
|
3518 |
rect: function (el) {
|
|
|
3519 |
var a = el.attrs;
|
|
|
3520 |
return rectPath(a.x, a.y, a.width, a.height, a.r);
|
|
|
3521 |
},
|
|
|
3522 |
image: function (el) {
|
|
|
3523 |
var a = el.attrs;
|
|
|
3524 |
return rectPath(a.x, a.y, a.width, a.height);
|
|
|
3525 |
},
|
|
|
3526 |
text: function (el) {
|
|
|
3527 |
var bbox = el._getBBox();
|
|
|
3528 |
return rectPath(bbox.x, bbox.y, bbox.width, bbox.height);
|
|
|
3529 |
}
|
|
|
3530 |
},
|
|
|
3531 |
mapPath = R.mapPath = function (path, matrix) {
|
|
|
3532 |
if (!matrix) {
|
|
|
3533 |
return path;
|
|
|
3534 |
}
|
|
|
3535 |
var x, y, i, j, pathi;
|
|
|
3536 |
path = path2curve(path);
|
|
|
3537 |
for (i = 0, ii = path.length; i < ii; i++) {
|
|
|
3538 |
pathi = path[i];
|
|
|
3539 |
for (j = 1, jj = pathi.length; j < jj; j += 2) {
|
|
|
3540 |
x = matrix.x(pathi[j], pathi[j + 1]);
|
|
|
3541 |
y = matrix.y(pathi[j], pathi[j + 1]);
|
|
|
3542 |
pathi[j] = x;
|
|
|
3543 |
pathi[j + 1] = y;
|
|
|
3544 |
}
|
|
|
3545 |
}
|
|
|
3546 |
return path;
|
|
|
3547 |
};
|
|
|
3548 |
|
|
|
3549 |
R._g = g;
|
|
|
3550 |
|
|
|
3551 |
R.type = (g.win.SVGAngle || g.doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") ? "SVG" : "VML");
|
|
|
3552 |
if (R.type == "VML") {
|
|
|
3553 |
var d = g.doc.createElement("div"),
|
|
|
3554 |
b;
|
|
|
3555 |
d.innerHTML = '<v:shape adj="1"/>';
|
|
|
3556 |
b = d.firstChild;
|
|
|
3557 |
b.style.behavior = "url(#default#VML)";
|
|
|
3558 |
if (!(b && typeof b.adj == "object")) {
|
|
|
3559 |
return (R.type = E);
|
|
|
3560 |
}
|
|
|
3561 |
d = null;
|
|
|
3562 |
}
|
|
|
3563 |
|
|
|
3564 |
|
|
|
3565 |
R.svg = !(R.vml = R.type == "VML");
|
|
|
3566 |
R._Paper = Paper;
|
|
|
3567 |
|
|
|
3568 |
R.fn = paperproto = Paper.prototype = R.prototype;
|
|
|
3569 |
R._id = 0;
|
|
|
3570 |
R._oid = 0;
|
|
|
3571 |
|
|
|
3572 |
R.is = function (o, type) {
|
|
|
3573 |
type = lowerCase.call(type);
|
|
|
3574 |
if (type == "finite") {
|
|
|
3575 |
return !isnan[has](+o);
|
|
|
3576 |
}
|
|
|
3577 |
if (type == "array") {
|
|
|
3578 |
return o instanceof Array;
|
|
|
3579 |
}
|
|
|
3580 |
return (type == "null" && o === null) ||
|
|
|
3581 |
(type == typeof o && o !== null) ||
|
|
|
3582 |
(type == "object" && o === Object(o)) ||
|
|
|
3583 |
(type == "array" && Array.isArray && Array.isArray(o)) ||
|
|
|
3584 |
objectToString.call(o).slice(8, -1).toLowerCase() == type;
|
|
|
3585 |
};
|
|
|
3586 |
|
|
|
3587 |
R.angle = function (x1, y1, x2, y2, x3, y3) {
|
|
|
3588 |
if (x3 == null) {
|
|
|
3589 |
var x = x1 - x2,
|
|
|
3590 |
y = y1 - y2;
|
|
|
3591 |
if (!x && !y) {
|
|
|
3592 |
return 0;
|
|
|
3593 |
}
|
|
|
3594 |
return (180 + math.atan2(-y, -x) * 180 / PI + 360) % 360;
|
|
|
3595 |
} else {
|
|
|
3596 |
return R.angle(x1, y1, x3, y3) - R.angle(x2, y2, x3, y3);
|
|
|
3597 |
}
|
|
|
3598 |
};
|
|
|
3599 |
|
|
|
3600 |
R.rad = function (deg) {
|
|
|
3601 |
return deg % 360 * PI / 180;
|
|
|
3602 |
};
|
|
|
3603 |
|
|
|
3604 |
R.deg = function (rad) {
|
|
|
3605 |
return rad * 180 / PI % 360;
|
|
|
3606 |
};
|
|
|
3607 |
|
|
|
3608 |
R.snapTo = function (values, value, tolerance) {
|
|
|
3609 |
tolerance = R.is(tolerance, "finite") ? tolerance : 10;
|
|
|
3610 |
if (R.is(values, array)) {
|
|
|
3611 |
var i = values.length;
|
|
|
3612 |
while (i--) if (abs(values[i] - value) <= tolerance) {
|
|
|
3613 |
return values[i];
|
|
|
3614 |
}
|
|
|
3615 |
} else {
|
|
|
3616 |
values = +values;
|
|
|
3617 |
var rem = value % values;
|
|
|
3618 |
if (rem < tolerance) {
|
|
|
3619 |
return value - rem;
|
|
|
3620 |
}
|
|
|
3621 |
if (rem > values - tolerance) {
|
|
|
3622 |
return value - rem + values;
|
|
|
3623 |
}
|
|
|
3624 |
}
|
|
|
3625 |
return value;
|
|
|
3626 |
};
|
|
|
3627 |
|
|
|
3628 |
|
|
|
3629 |
var createUUID = R.createUUID = (function (uuidRegEx, uuidReplacer) {
|
|
|
3630 |
return function () {
|
|
|
3631 |
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(uuidRegEx, uuidReplacer).toUpperCase();
|
|
|
3632 |
};
|
|
|
3633 |
})(/[xy]/g, function (c) {
|
|
|
3634 |
var r = math.random() * 16 | 0,
|
|
|
3635 |
v = c == "x" ? r : (r & 3 | 8);
|
|
|
3636 |
return v.toString(16);
|
|
|
3637 |
});
|
|
|
3638 |
|
|
|
3639 |
|
|
|
3640 |
R.setWindow = function (newwin) {
|
|
|
3641 |
eve("setWindow", R, g.win, newwin);
|
|
|
3642 |
g.win = newwin;
|
|
|
3643 |
g.doc = g.win.document;
|
|
|
3644 |
if (initWin) {
|
|
|
3645 |
initWin(g.win);
|
|
|
3646 |
}
|
|
|
3647 |
};
|
|
|
3648 |
var toHex = function (color) {
|
|
|
3649 |
if (R.vml) {
|
|
|
3650 |
// http://dean.edwards.name/weblog/2009/10/convert-any-colour-value-to-hex-in-msie/
|
|
|
3651 |
var trim = /^\s+|\s+$/g;
|
|
|
3652 |
var bod;
|
|
|
3653 |
try {
|
|
|
3654 |
var docum = new ActiveXObject("htmlfile");
|
|
|
3655 |
docum.write("<body>");
|
|
|
3656 |
docum.close();
|
|
|
3657 |
bod = docum.body;
|
|
|
3658 |
} catch(e) {
|
|
|
3659 |
bod = createPopup().document.body;
|
|
|
3660 |
}
|
|
|
3661 |
var range = bod.createTextRange();
|
|
|
3662 |
toHex = cacher(function (color) {
|
|
|
3663 |
try {
|
|
|
3664 |
bod.style.color = Str(color).replace(trim, E);
|
|
|
3665 |
var value = range.queryCommandValue("ForeColor");
|
|
|
3666 |
value = ((value & 255) << 16) | (value & 65280) | ((value & 16711680) >>> 16);
|
|
|
3667 |
return "#" + ("000000" + value.toString(16)).slice(-6);
|
|
|
3668 |
} catch(e) {
|
|
|
3669 |
return "none";
|
|
|
3670 |
}
|
|
|
3671 |
});
|
|
|
3672 |
} else {
|
|
|
3673 |
var i = g.doc.createElement("i");
|
|
|
3674 |
i.title = "Rapha\xebl Colour Picker";
|
|
|
3675 |
i.style.display = "none";
|
|
|
3676 |
g.doc.body.appendChild(i);
|
|
|
3677 |
toHex = cacher(function (color) {
|
|
|
3678 |
i.style.color = color;
|
|
|
3679 |
return g.doc.defaultView.getComputedStyle(i, E).getPropertyValue("color");
|
|
|
3680 |
});
|
|
|
3681 |
}
|
|
|
3682 |
return toHex(color);
|
|
|
3683 |
},
|
|
|
3684 |
hsbtoString = function () {
|
|
|
3685 |
return "hsb(" + [this.h, this.s, this.b] + ")";
|
|
|
3686 |
},
|
|
|
3687 |
hsltoString = function () {
|
|
|
3688 |
return "hsl(" + [this.h, this.s, this.l] + ")";
|
|
|
3689 |
},
|
|
|
3690 |
rgbtoString = function () {
|
|
|
3691 |
return this.hex;
|
|
|
3692 |
},
|
|
|
3693 |
prepareRGB = function (r, g, b) {
|
|
|
3694 |
if (g == null && R.is(r, "object") && "r" in r && "g" in r && "b" in r) {
|
|
|
3695 |
b = r.b;
|
|
|
3696 |
g = r.g;
|
|
|
3697 |
r = r.r;
|
|
|
3698 |
}
|
|
|
3699 |
if (g == null && R.is(r, string)) {
|
|
|
3700 |
var clr = R.getRGB(r);
|
|
|
3701 |
r = clr.r;
|
|
|
3702 |
g = clr.g;
|
|
|
3703 |
b = clr.b;
|
|
|
3704 |
}
|
|
|
3705 |
if (r > 1 || g > 1 || b > 1) {
|
|
|
3706 |
r /= 255;
|
|
|
3707 |
g /= 255;
|
|
|
3708 |
b /= 255;
|
|
|
3709 |
}
|
|
|
3710 |
|
|
|
3711 |
return [r, g, b];
|
|
|
3712 |
},
|
|
|
3713 |
packageRGB = function (r, g, b, o) {
|
|
|
3714 |
r *= 255;
|
|
|
3715 |
g *= 255;
|
|
|
3716 |
b *= 255;
|
|
|
3717 |
var rgb = {
|
|
|
3718 |
r: r,
|
|
|
3719 |
g: g,
|
|
|
3720 |
b: b,
|
|
|
3721 |
hex: R.rgb(r, g, b),
|
|
|
3722 |
toString: rgbtoString
|
|
|
3723 |
};
|
|
|
3724 |
R.is(o, "finite") && (rgb.opacity = o);
|
|
|
3725 |
return rgb;
|
|
|
3726 |
};
|
|
|
3727 |
|
|
|
3728 |
|
|
|
3729 |
R.color = function (clr) {
|
|
|
3730 |
var rgb;
|
|
|
3731 |
if (R.is(clr, "object") && "h" in clr && "s" in clr && "b" in clr) {
|
|
|
3732 |
rgb = R.hsb2rgb(clr);
|
|
|
3733 |
clr.r = rgb.r;
|
|
|
3734 |
clr.g = rgb.g;
|
|
|
3735 |
clr.b = rgb.b;
|
|
|
3736 |
clr.hex = rgb.hex;
|
|
|
3737 |
} else if (R.is(clr, "object") && "h" in clr && "s" in clr && "l" in clr) {
|
|
|
3738 |
rgb = R.hsl2rgb(clr);
|
|
|
3739 |
clr.r = rgb.r;
|
|
|
3740 |
clr.g = rgb.g;
|
|
|
3741 |
clr.b = rgb.b;
|
|
|
3742 |
clr.hex = rgb.hex;
|
|
|
3743 |
} else {
|
|
|
3744 |
if (R.is(clr, "string")) {
|
|
|
3745 |
clr = R.getRGB(clr);
|
|
|
3746 |
}
|
|
|
3747 |
if (R.is(clr, "object") && "r" in clr && "g" in clr && "b" in clr) {
|
|
|
3748 |
rgb = R.rgb2hsl(clr);
|
|
|
3749 |
clr.h = rgb.h;
|
|
|
3750 |
clr.s = rgb.s;
|
|
|
3751 |
clr.l = rgb.l;
|
|
|
3752 |
rgb = R.rgb2hsb(clr);
|
|
|
3753 |
clr.v = rgb.b;
|
|
|
3754 |
} else {
|
|
|
3755 |
clr = {hex: "none"};
|
|
|
3756 |
crl.r = clr.g = clr.b = clr.h = clr.s = clr.v = clr.l = -1;
|
|
|
3757 |
}
|
|
|
3758 |
}
|
|
|
3759 |
clr.toString = rgbtoString;
|
|
|
3760 |
return clr;
|
|
|
3761 |
};
|
|
|
3762 |
|
|
|
3763 |
R.hsb2rgb = function (h, s, v, o) {
|
|
|
3764 |
if (this.is(h, "object") && "h" in h && "s" in h && "b" in h) {
|
|
|
3765 |
v = h.b;
|
|
|
3766 |
s = h.s;
|
|
|
3767 |
h = h.h;
|
|
|
3768 |
o = h.o;
|
|
|
3769 |
}
|
|
|
3770 |
h *= 360;
|
|
|
3771 |
var R, G, B, X, C;
|
|
|
3772 |
h = (h % 360) / 60;
|
|
|
3773 |
C = v * s;
|
|
|
3774 |
X = C * (1 - abs(h % 2 - 1));
|
|
|
3775 |
R = G = B = v - C;
|
|
|
3776 |
|
|
|
3777 |
h = ~~h;
|
|
|
3778 |
R += [C, X, 0, 0, X, C][h];
|
|
|
3779 |
G += [X, C, C, X, 0, 0][h];
|
|
|
3780 |
B += [0, 0, X, C, C, X][h];
|
|
|
3781 |
return packageRGB(R, G, B, o);
|
|
|
3782 |
};
|
|
|
3783 |
|
|
|
3784 |
R.hsl2rgb = function (h, s, l, o) {
|
|
|
3785 |
if (this.is(h, "object") && "h" in h && "s" in h && "l" in h) {
|
|
|
3786 |
l = h.l;
|
|
|
3787 |
s = h.s;
|
|
|
3788 |
h = h.h;
|
|
|
3789 |
}
|
|
|
3790 |
if (h > 1 || s > 1 || l > 1) {
|
|
|
3791 |
h /= 360;
|
|
|
3792 |
s /= 100;
|
|
|
3793 |
l /= 100;
|
|
|
3794 |
}
|
|
|
3795 |
h *= 360;
|
|
|
3796 |
var R, G, B, X, C;
|
|
|
3797 |
h = (h % 360) / 60;
|
|
|
3798 |
C = 2 * s * (l < .5 ? l : 1 - l);
|
|
|
3799 |
X = C * (1 - abs(h % 2 - 1));
|
|
|
3800 |
R = G = B = l - C / 2;
|
|
|
3801 |
|
|
|
3802 |
h = ~~h;
|
|
|
3803 |
R += [C, X, 0, 0, X, C][h];
|
|
|
3804 |
G += [X, C, C, X, 0, 0][h];
|
|
|
3805 |
B += [0, 0, X, C, C, X][h];
|
|
|
3806 |
return packageRGB(R, G, B, o);
|
|
|
3807 |
};
|
|
|
3808 |
|
|
|
3809 |
R.rgb2hsb = function (r, g, b) {
|
|
|
3810 |
b = prepareRGB(r, g, b);
|
|
|
3811 |
r = b[0];
|
|
|
3812 |
g = b[1];
|
|
|
3813 |
b = b[2];
|
|
|
3814 |
|
|
|
3815 |
var H, S, V, C;
|
|
|
3816 |
V = mmax(r, g, b);
|
|
|
3817 |
C = V - mmin(r, g, b);
|
|
|
3818 |
H = (C == 0 ? null :
|
|
|
3819 |
V == r ? (g - b) / C :
|
|
|
3820 |
V == g ? (b - r) / C + 2 :
|
|
|
3821 |
(r - g) / C + 4
|
|
|
3822 |
);
|
|
|
3823 |
H = ((H + 360) % 6) * 60 / 360;
|
|
|
3824 |
S = C == 0 ? 0 : C / V;
|
|
|
3825 |
return {h: H, s: S, b: V, toString: hsbtoString};
|
|
|
3826 |
};
|
|
|
3827 |
|
|
|
3828 |
R.rgb2hsl = function (r, g, b) {
|
|
|
3829 |
b = prepareRGB(r, g, b);
|
|
|
3830 |
r = b[0];
|
|
|
3831 |
g = b[1];
|
|
|
3832 |
b = b[2];
|
|
|
3833 |
|
|
|
3834 |
var H, S, L, M, m, C;
|
|
|
3835 |
M = mmax(r, g, b);
|
|
|
3836 |
m = mmin(r, g, b);
|
|
|
3837 |
C = M - m;
|
|
|
3838 |
H = (C == 0 ? null :
|
|
|
3839 |
M == r ? (g - b) / C :
|
|
|
3840 |
M == g ? (b - r) / C + 2 :
|
|
|
3841 |
(r - g) / C + 4);
|
|
|
3842 |
H = ((H + 360) % 6) * 60 / 360;
|
|
|
3843 |
L = (M + m) / 2;
|
|
|
3844 |
S = (C == 0 ? 0 :
|
|
|
3845 |
L < .5 ? C / (2 * L) :
|
|
|
3846 |
C / (2 - 2 * L));
|
|
|
3847 |
return {h: H, s: S, l: L, toString: hsltoString};
|
|
|
3848 |
};
|
|
|
3849 |
R._path2string = function () {
|
|
|
3850 |
return this.join(",").replace(p2s, "$1");
|
|
|
3851 |
};
|
|
|
3852 |
function repush(array, item) {
|
|
|
3853 |
for (var i = 0, ii = array.length; i < ii; i++) if (array[i] === item) {
|
|
|
3854 |
return array.push(array.splice(i, 1)[0]);
|
|
|
3855 |
}
|
|
|
3856 |
}
|
|
|
3857 |
function cacher(f, scope, postprocessor) {
|
|
|
3858 |
function newf() {
|
|
|
3859 |
var arg = Array.prototype.slice.call(arguments, 0),
|
|
|
3860 |
args = arg.join("\u2400"),
|
|
|
3861 |
cache = newf.cache = newf.cache || {},
|
|
|
3862 |
count = newf.count = newf.count || [];
|
|
|
3863 |
if (cache[has](args)) {
|
|
|
3864 |
repush(count, args);
|
|
|
3865 |
return postprocessor ? postprocessor(cache[args]) : cache[args];
|
|
|
3866 |
}
|
|
|
3867 |
count.length >= 1e3 && delete cache[count.shift()];
|
|
|
3868 |
count.push(args);
|
|
|
3869 |
cache[args] = f[apply](scope, arg);
|
|
|
3870 |
return postprocessor ? postprocessor(cache[args]) : cache[args];
|
|
|
3871 |
}
|
|
|
3872 |
return newf;
|
|
|
3873 |
}
|
|
|
3874 |
|
|
|
3875 |
var preload = R._preload = function (src, f) {
|
|
|
3876 |
var img = g.doc.createElement("img");
|
|
|
3877 |
img.style.cssText = "position:absolute;left:-9999em;top-9999em";
|
|
|
3878 |
img.onload = function () {
|
|
|
3879 |
f.call(this);
|
|
|
3880 |
this.onload = null;
|
|
|
3881 |
g.doc.body.removeChild(this);
|
|
|
3882 |
};
|
|
|
3883 |
img.onerror = function () {
|
|
|
3884 |
g.doc.body.removeChild(this);
|
|
|
3885 |
};
|
|
|
3886 |
g.doc.body.appendChild(img);
|
|
|
3887 |
img.src = src;
|
|
|
3888 |
};
|
|
|
3889 |
|
|
|
3890 |
function clrToString() {
|
|
|
3891 |
return this.hex;
|
|
|
3892 |
}
|
|
|
3893 |
|
|
|
3894 |
|
|
|
3895 |
R.getRGB = cacher(function (colour) {
|
|
|
3896 |
if (!colour || !!((colour = Str(colour)).indexOf("-") + 1)) {
|
|
|
3897 |
return {r: -1, g: -1, b: -1, hex: "none", error: 1, toString: clrToString};
|
|
|
3898 |
}
|
|
|
3899 |
if (colour == "none") {
|
|
|
3900 |
return {r: -1, g: -1, b: -1, hex: "none", toString: clrToString};
|
|
|
3901 |
}
|
|
|
3902 |
!(hsrg[has](colour.toLowerCase().substring(0, 2)) || colour.charAt() == "#") && (colour = toHex(colour));
|
|
|
3903 |
var res,
|
|
|
3904 |
red,
|
|
|
3905 |
green,
|
|
|
3906 |
blue,
|
|
|
3907 |
opacity,
|
|
|
3908 |
t,
|
|
|
3909 |
values,
|
|
|
3910 |
rgb = colour.match(colourRegExp);
|
|
|
3911 |
if (rgb) {
|
|
|
3912 |
if (rgb[2]) {
|
|
|
3913 |
blue = toInt(rgb[2].substring(5), 16);
|
|
|
3914 |
green = toInt(rgb[2].substring(3, 5), 16);
|
|
|
3915 |
red = toInt(rgb[2].substring(1, 3), 16);
|
|
|
3916 |
}
|
|
|
3917 |
if (rgb[3]) {
|
|
|
3918 |
blue = toInt((t = rgb[3].charAt(3)) + t, 16);
|
|
|
3919 |
green = toInt((t = rgb[3].charAt(2)) + t, 16);
|
|
|
3920 |
red = toInt((t = rgb[3].charAt(1)) + t, 16);
|
|
|
3921 |
}
|
|
|
3922 |
if (rgb[4]) {
|
|
|
3923 |
values = rgb[4][split](commaSpaces);
|
|
|
3924 |
red = toFloat(values[0]);
|
|
|
3925 |
values[0].slice(-1) == "%" && (red *= 2.55);
|
|
|
3926 |
green = toFloat(values[1]);
|
|
|
3927 |
values[1].slice(-1) == "%" && (green *= 2.55);
|
|
|
3928 |
blue = toFloat(values[2]);
|
|
|
3929 |
values[2].slice(-1) == "%" && (blue *= 2.55);
|
|
|
3930 |
rgb[1].toLowerCase().slice(0, 4) == "rgba" && (opacity = toFloat(values[3]));
|
|
|
3931 |
values[3] && values[3].slice(-1) == "%" && (opacity /= 100);
|
|
|
3932 |
}
|
|
|
3933 |
if (rgb[5]) {
|
|
|
3934 |
values = rgb[5][split](commaSpaces);
|
|
|
3935 |
red = toFloat(values[0]);
|
|
|
3936 |
values[0].slice(-1) == "%" && (red *= 2.55);
|
|
|
3937 |
green = toFloat(values[1]);
|
|
|
3938 |
values[1].slice(-1) == "%" && (green *= 2.55);
|
|
|
3939 |
blue = toFloat(values[2]);
|
|
|
3940 |
values[2].slice(-1) == "%" && (blue *= 2.55);
|
|
|
3941 |
(values[0].slice(-3) == "deg" || values[0].slice(-1) == "\xb0") && (red /= 360);
|
|
|
3942 |
rgb[1].toLowerCase().slice(0, 4) == "hsba" && (opacity = toFloat(values[3]));
|
|
|
3943 |
values[3] && values[3].slice(-1) == "%" && (opacity /= 100);
|
|
|
3944 |
return R.hsb2rgb(red, green, blue, opacity);
|
|
|
3945 |
}
|
|
|
3946 |
if (rgb[6]) {
|
|
|
3947 |
values = rgb[6][split](commaSpaces);
|
|
|
3948 |
red = toFloat(values[0]);
|
|
|
3949 |
values[0].slice(-1) == "%" && (red *= 2.55);
|
|
|
3950 |
green = toFloat(values[1]);
|
|
|
3951 |
values[1].slice(-1) == "%" && (green *= 2.55);
|
|
|
3952 |
blue = toFloat(values[2]);
|
|
|
3953 |
values[2].slice(-1) == "%" && (blue *= 2.55);
|
|
|
3954 |
(values[0].slice(-3) == "deg" || values[0].slice(-1) == "\xb0") && (red /= 360);
|
|
|
3955 |
rgb[1].toLowerCase().slice(0, 4) == "hsla" && (opacity = toFloat(values[3]));
|
|
|
3956 |
values[3] && values[3].slice(-1) == "%" && (opacity /= 100);
|
|
|
3957 |
return R.hsl2rgb(red, green, blue, opacity);
|
|
|
3958 |
}
|
|
|
3959 |
rgb = {r: red, g: green, b: blue, toString: clrToString};
|
|
|
3960 |
rgb.hex = "#" + (16777216 | blue | (green << 8) | (red << 16)).toString(16).slice(1);
|
|
|
3961 |
R.is(opacity, "finite") && (rgb.opacity = opacity);
|
|
|
3962 |
return rgb;
|
|
|
3963 |
}
|
|
|
3964 |
return {r: -1, g: -1, b: -1, hex: "none", error: 1, toString: clrToString};
|
|
|
3965 |
}, R);
|
|
|
3966 |
|
|
|
3967 |
R.hsb = cacher(function (h, s, b) {
|
|
|
3968 |
return R.hsb2rgb(h, s, b).hex;
|
|
|
3969 |
});
|
|
|
3970 |
|
|
|
3971 |
R.hsl = cacher(function (h, s, l) {
|
|
|
3972 |
return R.hsl2rgb(h, s, l).hex;
|
|
|
3973 |
});
|
|
|
3974 |
|
|
|
3975 |
R.rgb = cacher(function (r, g, b) {
|
|
|
3976 |
return "#" + (16777216 | b | (g << 8) | (r << 16)).toString(16).slice(1);
|
|
|
3977 |
});
|
|
|
3978 |
|
|
|
3979 |
R.getColor = function (value) {
|
|
|
3980 |
var start = this.getColor.start = this.getColor.start || {h: 0, s: 1, b: value || .75},
|
|
|
3981 |
rgb = this.hsb2rgb(start.h, start.s, start.b);
|
|
|
3982 |
start.h += .075;
|
|
|
3983 |
if (start.h > 1) {
|
|
|
3984 |
start.h = 0;
|
|
|
3985 |
start.s -= .2;
|
|
|
3986 |
start.s <= 0 && (this.getColor.start = {h: 0, s: 1, b: start.b});
|
|
|
3987 |
}
|
|
|
3988 |
return rgb.hex;
|
|
|
3989 |
};
|
|
|
3990 |
|
|
|
3991 |
R.getColor.reset = function () {
|
|
|
3992 |
delete this.start;
|
|
|
3993 |
};
|
|
|
3994 |
|
|
|
3995 |
// http://schepers.cc/getting-to-the-point
|
|
|
3996 |
function catmullRom2bezier(crp) {
|
|
|
3997 |
var d = [];
|
|
|
3998 |
for (var i = 0, iLen = crp.length; iLen - 2 > i; i += 2) {
|
|
|
3999 |
var p = [{x: +crp[i], y: +crp[i + 1]},
|
|
|
4000 |
{x: +crp[i], y: +crp[i + 1]},
|
|
|
4001 |
{x: +crp[i + 2], y: +crp[i + 3]},
|
|
|
4002 |
{x: +crp[i + 4], y: +crp[i + 5]}];
|
|
|
4003 |
if (iLen - 4 == i) {
|
|
|
4004 |
p[0] = {x: +crp[i - 2], y: +crp[i - 1]};
|
|
|
4005 |
p[3] = p[2];
|
|
|
4006 |
} else if (i) {
|
|
|
4007 |
p[0] = {x: +crp[i - 2], y: +crp[i - 1]};
|
|
|
4008 |
}
|
|
|
4009 |
d.push(["C",
|
|
|
4010 |
(-p[0].x + 6 * p[1].x + p[2].x) / 6,
|
|
|
4011 |
(-p[0].y + 6 * p[1].y + p[2].y) / 6,
|
|
|
4012 |
(p[1].x + 6 * p[2].x - p[3].x) / 6,
|
|
|
4013 |
(p[1].y + 6*p[2].y - p[3].y) / 6,
|
|
|
4014 |
p[2].x,
|
|
|
4015 |
p[2].y
|
|
|
4016 |
]);
|
|
|
4017 |
}
|
|
|
4018 |
|
|
|
4019 |
return d;
|
|
|
4020 |
}
|
|
|
4021 |
|
|
|
4022 |
R.parsePathString = cacher(function (pathString) {
|
|
|
4023 |
if (!pathString) {
|
|
|
4024 |
return null;
|
|
|
4025 |
}
|
|
|
4026 |
var paramCounts = {a: 7, c: 6, h: 1, l: 2, m: 2, r: 4, q: 4, s: 4, t: 2, v: 1, z: 0},
|
|
|
4027 |
data = [];
|
|
|
4028 |
if (R.is(pathString, array) && R.is(pathString[0], array)) { // rough assumption
|
|
|
4029 |
data = pathClone(pathString);
|
|
|
4030 |
}
|
|
|
4031 |
if (!data.length) {
|
|
|
4032 |
Str(pathString).replace(pathCommand, function (a, b, c) {
|
|
|
4033 |
var params = [],
|
|
|
4034 |
name = b.toLowerCase();
|
|
|
4035 |
c.replace(pathValues, function (a, b) {
|
|
|
4036 |
b && params.push(+b);
|
|
|
4037 |
});
|
|
|
4038 |
if (name == "m" && params.length > 2) {
|
|
|
4039 |
data.push([b][concat](params.splice(0, 2)));
|
|
|
4040 |
name = "l";
|
|
|
4041 |
b = b == "m" ? "l" : "L";
|
|
|
4042 |
}
|
|
|
4043 |
if (name == "r") {
|
|
|
4044 |
data.push([b][concat](params));
|
|
|
4045 |
} else while (params.length >= paramCounts[name]) {
|
|
|
4046 |
data.push([b][concat](params.splice(0, paramCounts[name])));
|
|
|
4047 |
if (!paramCounts[name]) {
|
|
|
4048 |
break;
|
|
|
4049 |
}
|
|
|
4050 |
}
|
|
|
4051 |
});
|
|
|
4052 |
}
|
|
|
4053 |
data.toString = R._path2string;
|
|
|
4054 |
return data;
|
|
|
4055 |
});
|
|
|
4056 |
|
|
|
4057 |
R.parseTransformString = cacher(function (TString) {
|
|
|
4058 |
if (!TString) {
|
|
|
4059 |
return null;
|
|
|
4060 |
}
|
|
|
4061 |
var paramCounts = {r: 3, s: 4, t: 2, m: 6},
|
|
|
4062 |
data = [];
|
|
|
4063 |
if (R.is(TString, array) && R.is(TString[0], array)) { // rough assumption
|
|
|
4064 |
data = pathClone(TString);
|
|
|
4065 |
}
|
|
|
4066 |
if (!data.length) {
|
|
|
4067 |
Str(TString).replace(tCommand, function (a, b, c) {
|
|
|
4068 |
var params = [],
|
|
|
4069 |
name = lowerCase.call(b);
|
|
|
4070 |
c.replace(pathValues, function (a, b) {
|
|
|
4071 |
b && params.push(+b);
|
|
|
4072 |
});
|
|
|
4073 |
data.push([b][concat](params));
|
|
|
4074 |
});
|
|
|
4075 |
}
|
|
|
4076 |
data.toString = R._path2string;
|
|
|
4077 |
return data;
|
|
|
4078 |
});
|
|
|
4079 |
|
|
|
4080 |
R.findDotsAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {
|
|
|
4081 |
var t1 = 1 - t,
|
|
|
4082 |
t13 = pow(t1, 3),
|
|
|
4083 |
t12 = pow(t1, 2),
|
|
|
4084 |
t2 = t * t,
|
|
|
4085 |
t3 = t2 * t,
|
|
|
4086 |
x = t13 * p1x + t12 * 3 * t * c1x + t1 * 3 * t * t * c2x + t3 * p2x,
|
|
|
4087 |
y = t13 * p1y + t12 * 3 * t * c1y + t1 * 3 * t * t * c2y + t3 * p2y,
|
|
|
4088 |
mx = p1x + 2 * t * (c1x - p1x) + t2 * (c2x - 2 * c1x + p1x),
|
|
|
4089 |
my = p1y + 2 * t * (c1y - p1y) + t2 * (c2y - 2 * c1y + p1y),
|
|
|
4090 |
nx = c1x + 2 * t * (c2x - c1x) + t2 * (p2x - 2 * c2x + c1x),
|
|
|
4091 |
ny = c1y + 2 * t * (c2y - c1y) + t2 * (p2y - 2 * c2y + c1y),
|
|
|
4092 |
ax = t1 * p1x + t * c1x,
|
|
|
4093 |
ay = t1 * p1y + t * c1y,
|
|
|
4094 |
cx = t1 * c2x + t * p2x,
|
|
|
4095 |
cy = t1 * c2y + t * p2y,
|
|
|
4096 |
alpha = (90 - math.atan2(mx - nx, my - ny) * 180 / PI);
|
|
|
4097 |
(mx > nx || my < ny) && (alpha += 180);
|
|
|
4098 |
return {
|
|
|
4099 |
x: x,
|
|
|
4100 |
y: y,
|
|
|
4101 |
m: {x: mx, y: my},
|
|
|
4102 |
n: {x: nx, y: ny},
|
|
|
4103 |
start: {x: ax, y: ay},
|
|
|
4104 |
end: {x: cx, y: cy},
|
|
|
4105 |
alpha: alpha
|
|
|
4106 |
};
|
|
|
4107 |
};
|
|
|
4108 |
var pathDimensions = cacher(function (path) {
|
|
|
4109 |
if (!path) {
|
|
|
4110 |
return {x: 0, y: 0, width: 0, height: 0};
|
|
|
4111 |
}
|
|
|
4112 |
path = path2curve(path);
|
|
|
4113 |
var x = 0,
|
|
|
4114 |
y = 0,
|
|
|
4115 |
X = [],
|
|
|
4116 |
Y = [],
|
|
|
4117 |
p;
|
|
|
4118 |
for (var i = 0, ii = path.length; i < ii; i++) {
|
|
|
4119 |
p = path[i];
|
|
|
4120 |
if (p[0] == "M") {
|
|
|
4121 |
x = p[1];
|
|
|
4122 |
y = p[2];
|
|
|
4123 |
X.push(x);
|
|
|
4124 |
Y.push(y);
|
|
|
4125 |
} else {
|
|
|
4126 |
var dim = curveDim(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);
|
|
|
4127 |
X = X[concat](dim.min.x, dim.max.x);
|
|
|
4128 |
Y = Y[concat](dim.min.y, dim.max.y);
|
|
|
4129 |
x = p[5];
|
|
|
4130 |
y = p[6];
|
|
|
4131 |
}
|
|
|
4132 |
}
|
|
|
4133 |
var xmin = mmin[apply](0, X),
|
|
|
4134 |
ymin = mmin[apply](0, Y);
|
|
|
4135 |
return {
|
|
|
4136 |
x: xmin,
|
|
|
4137 |
y: ymin,
|
|
|
4138 |
width: mmax[apply](0, X) - xmin,
|
|
|
4139 |
height: mmax[apply](0, Y) - ymin
|
|
|
4140 |
};
|
|
|
4141 |
}, null, function (o) {
|
|
|
4142 |
return {
|
|
|
4143 |
x: o.x,
|
|
|
4144 |
y: o.y,
|
|
|
4145 |
width: o.width,
|
|
|
4146 |
height: o.height
|
|
|
4147 |
};
|
|
|
4148 |
}),
|
|
|
4149 |
pathClone = function (pathArray) {
|
|
|
4150 |
var res = [];
|
|
|
4151 |
if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption
|
|
|
4152 |
pathArray = R.parsePathString(pathArray);
|
|
|
4153 |
}
|
|
|
4154 |
for (var i = 0, ii = pathArray.length; i < ii; i++) {
|
|
|
4155 |
res[i] = [];
|
|
|
4156 |
for (var j = 0, jj = pathArray[i].length; j < jj; j++) {
|
|
|
4157 |
res[i][j] = pathArray[i][j];
|
|
|
4158 |
}
|
|
|
4159 |
}
|
|
|
4160 |
res.toString = R._path2string;
|
|
|
4161 |
return res;
|
|
|
4162 |
},
|
|
|
4163 |
pathToRelative = R._pathToRelative = cacher(function (pathArray) {
|
|
|
4164 |
if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption
|
|
|
4165 |
pathArray = R.parsePathString(pathArray);
|
|
|
4166 |
}
|
|
|
4167 |
var res = [],
|
|
|
4168 |
x = 0,
|
|
|
4169 |
y = 0,
|
|
|
4170 |
mx = 0,
|
|
|
4171 |
my = 0,
|
|
|
4172 |
start = 0;
|
|
|
4173 |
if (pathArray[0][0] == "M") {
|
|
|
4174 |
x = pathArray[0][1];
|
|
|
4175 |
y = pathArray[0][2];
|
|
|
4176 |
mx = x;
|
|
|
4177 |
my = y;
|
|
|
4178 |
start++;
|
|
|
4179 |
res.push(["M", x, y]);
|
|
|
4180 |
}
|
|
|
4181 |
for (var i = start, ii = pathArray.length; i < ii; i++) {
|
|
|
4182 |
var r = res[i] = [],
|
|
|
4183 |
pa = pathArray[i];
|
|
|
4184 |
if (pa[0] != lowerCase.call(pa[0])) {
|
|
|
4185 |
r[0] = lowerCase.call(pa[0]);
|
|
|
4186 |
switch (r[0]) {
|
|
|
4187 |
case "a":
|
|
|
4188 |
r[1] = pa[1];
|
|
|
4189 |
r[2] = pa[2];
|
|
|
4190 |
r[3] = pa[3];
|
|
|
4191 |
r[4] = pa[4];
|
|
|
4192 |
r[5] = pa[5];
|
|
|
4193 |
r[6] = +(pa[6] - x).toFixed(3);
|
|
|
4194 |
r[7] = +(pa[7] - y).toFixed(3);
|
|
|
4195 |
break;
|
|
|
4196 |
case "v":
|
|
|
4197 |
r[1] = +(pa[1] - y).toFixed(3);
|
|
|
4198 |
break;
|
|
|
4199 |
case "m":
|
|
|
4200 |
mx = pa[1];
|
|
|
4201 |
my = pa[2];
|
|
|
4202 |
default:
|
|
|
4203 |
for (var j = 1, jj = pa.length; j < jj; j++) {
|
|
|
4204 |
r[j] = +(pa[j] - ((j % 2) ? x : y)).toFixed(3);
|
|
|
4205 |
}
|
|
|
4206 |
}
|
|
|
4207 |
} else {
|
|
|
4208 |
r = res[i] = [];
|
|
|
4209 |
if (pa[0] == "m") {
|
|
|
4210 |
mx = pa[1] + x;
|
|
|
4211 |
my = pa[2] + y;
|
|
|
4212 |
}
|
|
|
4213 |
for (var k = 0, kk = pa.length; k < kk; k++) {
|
|
|
4214 |
res[i][k] = pa[k];
|
|
|
4215 |
}
|
|
|
4216 |
}
|
|
|
4217 |
var len = res[i].length;
|
|
|
4218 |
switch (res[i][0]) {
|
|
|
4219 |
case "z":
|
|
|
4220 |
x = mx;
|
|
|
4221 |
y = my;
|
|
|
4222 |
break;
|
|
|
4223 |
case "h":
|
|
|
4224 |
x += +res[i][len - 1];
|
|
|
4225 |
break;
|
|
|
4226 |
case "v":
|
|
|
4227 |
y += +res[i][len - 1];
|
|
|
4228 |
break;
|
|
|
4229 |
default:
|
|
|
4230 |
x += +res[i][len - 2];
|
|
|
4231 |
y += +res[i][len - 1];
|
|
|
4232 |
}
|
|
|
4233 |
}
|
|
|
4234 |
res.toString = R._path2string;
|
|
|
4235 |
return res;
|
|
|
4236 |
}, 0, pathClone),
|
|
|
4237 |
pathToAbsolute = R._pathToAbsolute = cacher(function (pathArray) {
|
|
|
4238 |
if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption
|
|
|
4239 |
pathArray = R.parsePathString(pathArray);
|
|
|
4240 |
}
|
|
|
4241 |
if (!pathArray || !pathArray.length) {
|
|
|
4242 |
return [["M", 0, 0]];
|
|
|
4243 |
}
|
|
|
4244 |
var res = [],
|
|
|
4245 |
x = 0,
|
|
|
4246 |
y = 0,
|
|
|
4247 |
mx = 0,
|
|
|
4248 |
my = 0,
|
|
|
4249 |
start = 0;
|
|
|
4250 |
if (pathArray[0][0] == "M") {
|
|
|
4251 |
x = +pathArray[0][1];
|
|
|
4252 |
y = +pathArray[0][2];
|
|
|
4253 |
mx = x;
|
|
|
4254 |
my = y;
|
|
|
4255 |
start++;
|
|
|
4256 |
res[0] = ["M", x, y];
|
|
|
4257 |
}
|
|
|
4258 |
for (var r, pa, i = start, ii = pathArray.length; i < ii; i++) {
|
|
|
4259 |
res.push(r = []);
|
|
|
4260 |
pa = pathArray[i];
|
|
|
4261 |
if (pa[0] != upperCase.call(pa[0])) {
|
|
|
4262 |
r[0] = upperCase.call(pa[0]);
|
|
|
4263 |
switch (r[0]) {
|
|
|
4264 |
case "A":
|
|
|
4265 |
r[1] = pa[1];
|
|
|
4266 |
r[2] = pa[2];
|
|
|
4267 |
r[3] = pa[3];
|
|
|
4268 |
r[4] = pa[4];
|
|
|
4269 |
r[5] = pa[5];
|
|
|
4270 |
r[6] = +(pa[6] + x);
|
|
|
4271 |
r[7] = +(pa[7] + y);
|
|
|
4272 |
break;
|
|
|
4273 |
case "V":
|
|
|
4274 |
r[1] = +pa[1] + y;
|
|
|
4275 |
break;
|
|
|
4276 |
case "H":
|
|
|
4277 |
r[1] = +pa[1] + x;
|
|
|
4278 |
break;
|
|
|
4279 |
case "R":
|
|
|
4280 |
var dots = [x, y][concat](pa.slice(1));
|
|
|
4281 |
for (var j = 2, jj = dots.length; j < jj; j++) {
|
|
|
4282 |
dots[j] = +dots[j] + x;
|
|
|
4283 |
dots[++j] = +dots[j] + y;
|
|
|
4284 |
}
|
|
|
4285 |
res.pop();
|
|
|
4286 |
res = res[concat](catmullRom2bezier(dots));
|
|
|
4287 |
break;
|
|
|
4288 |
case "M":
|
|
|
4289 |
mx = +pa[1] + x;
|
|
|
4290 |
my = +pa[2] + y;
|
|
|
4291 |
default:
|
|
|
4292 |
for (j = 1, jj = pa.length; j < jj; j++) {
|
|
|
4293 |
r[j] = +pa[j] + ((j % 2) ? x : y);
|
|
|
4294 |
}
|
|
|
4295 |
}
|
|
|
4296 |
} else if (pa[0] == "R") {
|
|
|
4297 |
dots = [x, y][concat](pa.slice(1));
|
|
|
4298 |
res.pop();
|
|
|
4299 |
res = res[concat](catmullRom2bezier(dots));
|
|
|
4300 |
r = ["R"][concat](pa.slice(-2));
|
|
|
4301 |
} else {
|
|
|
4302 |
for (var k = 0, kk = pa.length; k < kk; k++) {
|
|
|
4303 |
r[k] = pa[k];
|
|
|
4304 |
}
|
|
|
4305 |
}
|
|
|
4306 |
switch (r[0]) {
|
|
|
4307 |
case "Z":
|
|
|
4308 |
x = mx;
|
|
|
4309 |
y = my;
|
|
|
4310 |
break;
|
|
|
4311 |
case "H":
|
|
|
4312 |
x = r[1];
|
|
|
4313 |
break;
|
|
|
4314 |
case "V":
|
|
|
4315 |
y = r[1];
|
|
|
4316 |
break;
|
|
|
4317 |
case "M":
|
|
|
4318 |
mx = r[r.length - 2];
|
|
|
4319 |
my = r[r.length - 1];
|
|
|
4320 |
default:
|
|
|
4321 |
x = r[r.length - 2];
|
|
|
4322 |
y = r[r.length - 1];
|
|
|
4323 |
}
|
|
|
4324 |
}
|
|
|
4325 |
res.toString = R._path2string;
|
|
|
4326 |
return res;
|
|
|
4327 |
}, null, pathClone),
|
|
|
4328 |
l2c = function (x1, y1, x2, y2) {
|
|
|
4329 |
return [x1, y1, x2, y2, x2, y2];
|
|
|
4330 |
},
|
|
|
4331 |
q2c = function (x1, y1, ax, ay, x2, y2) {
|
|
|
4332 |
var _13 = 1 / 3,
|
|
|
4333 |
_23 = 2 / 3;
|
|
|
4334 |
return [
|
|
|
4335 |
_13 * x1 + _23 * ax,
|
|
|
4336 |
_13 * y1 + _23 * ay,
|
|
|
4337 |
_13 * x2 + _23 * ax,
|
|
|
4338 |
_13 * y2 + _23 * ay,
|
|
|
4339 |
x2,
|
|
|
4340 |
y2
|
|
|
4341 |
];
|
|
|
4342 |
},
|
|
|
4343 |
a2c = function (x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) {
|
|
|
4344 |
// for more information of where this math came from visit:
|
|
|
4345 |
// http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
|
|
|
4346 |
var _120 = PI * 120 / 180,
|
|
|
4347 |
rad = PI / 180 * (+angle || 0),
|
|
|
4348 |
res = [],
|
|
|
4349 |
xy,
|
|
|
4350 |
rotate = cacher(function (x, y, rad) {
|
|
|
4351 |
var X = x * math.cos(rad) - y * math.sin(rad),
|
|
|
4352 |
Y = x * math.sin(rad) + y * math.cos(rad);
|
|
|
4353 |
return {x: X, y: Y};
|
|
|
4354 |
});
|
|
|
4355 |
if (!recursive) {
|
|
|
4356 |
xy = rotate(x1, y1, -rad);
|
|
|
4357 |
x1 = xy.x;
|
|
|
4358 |
y1 = xy.y;
|
|
|
4359 |
xy = rotate(x2, y2, -rad);
|
|
|
4360 |
x2 = xy.x;
|
|
|
4361 |
y2 = xy.y;
|
|
|
4362 |
var cos = math.cos(PI / 180 * angle),
|
|
|
4363 |
sin = math.sin(PI / 180 * angle),
|
|
|
4364 |
x = (x1 - x2) / 2,
|
|
|
4365 |
y = (y1 - y2) / 2;
|
|
|
4366 |
var h = (x * x) / (rx * rx) + (y * y) / (ry * ry);
|
|
|
4367 |
if (h > 1) {
|
|
|
4368 |
h = math.sqrt(h);
|
|
|
4369 |
rx = h * rx;
|
|
|
4370 |
ry = h * ry;
|
|
|
4371 |
}
|
|
|
4372 |
var rx2 = rx * rx,
|
|
|
4373 |
ry2 = ry * ry,
|
|
|
4374 |
k = (large_arc_flag == sweep_flag ? -1 : 1) *
|
|
|
4375 |
math.sqrt(abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))),
|
|
|
4376 |
cx = k * rx * y / ry + (x1 + x2) / 2,
|
|
|
4377 |
cy = k * -ry * x / rx + (y1 + y2) / 2,
|
|
|
4378 |
f1 = math.asin(((y1 - cy) / ry).toFixed(9)),
|
|
|
4379 |
f2 = math.asin(((y2 - cy) / ry).toFixed(9));
|
|
|
4380 |
|
|
|
4381 |
f1 = x1 < cx ? PI - f1 : f1;
|
|
|
4382 |
f2 = x2 < cx ? PI - f2 : f2;
|
|
|
4383 |
f1 < 0 && (f1 = PI * 2 + f1);
|
|
|
4384 |
f2 < 0 && (f2 = PI * 2 + f2);
|
|
|
4385 |
if (sweep_flag && f1 > f2) {
|
|
|
4386 |
f1 = f1 - PI * 2;
|
|
|
4387 |
}
|
|
|
4388 |
if (!sweep_flag && f2 > f1) {
|
|
|
4389 |
f2 = f2 - PI * 2;
|
|
|
4390 |
}
|
|
|
4391 |
} else {
|
|
|
4392 |
f1 = recursive[0];
|
|
|
4393 |
f2 = recursive[1];
|
|
|
4394 |
cx = recursive[2];
|
|
|
4395 |
cy = recursive[3];
|
|
|
4396 |
}
|
|
|
4397 |
var df = f2 - f1;
|
|
|
4398 |
if (abs(df) > _120) {
|
|
|
4399 |
var f2old = f2,
|
|
|
4400 |
x2old = x2,
|
|
|
4401 |
y2old = y2;
|
|
|
4402 |
f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1);
|
|
|
4403 |
x2 = cx + rx * math.cos(f2);
|
|
|
4404 |
y2 = cy + ry * math.sin(f2);
|
|
|
4405 |
res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]);
|
|
|
4406 |
}
|
|
|
4407 |
df = f2 - f1;
|
|
|
4408 |
var c1 = math.cos(f1),
|
|
|
4409 |
s1 = math.sin(f1),
|
|
|
4410 |
c2 = math.cos(f2),
|
|
|
4411 |
s2 = math.sin(f2),
|
|
|
4412 |
t = math.tan(df / 4),
|
|
|
4413 |
hx = 4 / 3 * rx * t,
|
|
|
4414 |
hy = 4 / 3 * ry * t,
|
|
|
4415 |
m1 = [x1, y1],
|
|
|
4416 |
m2 = [x1 + hx * s1, y1 - hy * c1],
|
|
|
4417 |
m3 = [x2 + hx * s2, y2 - hy * c2],
|
|
|
4418 |
m4 = [x2, y2];
|
|
|
4419 |
m2[0] = 2 * m1[0] - m2[0];
|
|
|
4420 |
m2[1] = 2 * m1[1] - m2[1];
|
|
|
4421 |
if (recursive) {
|
|
|
4422 |
return [m2, m3, m4][concat](res);
|
|
|
4423 |
} else {
|
|
|
4424 |
res = [m2, m3, m4][concat](res).join()[split](",");
|
|
|
4425 |
var newres = [];
|
|
|
4426 |
for (var i = 0, ii = res.length; i < ii; i++) {
|
|
|
4427 |
newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x;
|
|
|
4428 |
}
|
|
|
4429 |
return newres;
|
|
|
4430 |
}
|
|
|
4431 |
},
|
|
|
4432 |
findDotAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {
|
|
|
4433 |
var t1 = 1 - t;
|
|
|
4434 |
return {
|
|
|
4435 |
x: pow(t1, 3) * p1x + pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + pow(t, 3) * p2x,
|
|
|
4436 |
y: pow(t1, 3) * p1y + pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + pow(t, 3) * p2y
|
|
|
4437 |
};
|
|
|
4438 |
},
|
|
|
4439 |
curveDim = cacher(function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {
|
|
|
4440 |
var a = (c2x - 2 * c1x + p1x) - (p2x - 2 * c2x + c1x),
|
|
|
4441 |
b = 2 * (c1x - p1x) - 2 * (c2x - c1x),
|
|
|
4442 |
c = p1x - c1x,
|
|
|
4443 |
t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a,
|
|
|
4444 |
t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a,
|
|
|
4445 |
y = [p1y, p2y],
|
|
|
4446 |
x = [p1x, p2x],
|
|
|
4447 |
dot;
|
|
|
4448 |
abs(t1) > "1e12" && (t1 = .5);
|
|
|
4449 |
abs(t2) > "1e12" && (t2 = .5);
|
|
|
4450 |
if (t1 > 0 && t1 < 1) {
|
|
|
4451 |
dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1);
|
|
|
4452 |
x.push(dot.x);
|
|
|
4453 |
y.push(dot.y);
|
|
|
4454 |
}
|
|
|
4455 |
if (t2 > 0 && t2 < 1) {
|
|
|
4456 |
dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2);
|
|
|
4457 |
x.push(dot.x);
|
|
|
4458 |
y.push(dot.y);
|
|
|
4459 |
}
|
|
|
4460 |
a = (c2y - 2 * c1y + p1y) - (p2y - 2 * c2y + c1y);
|
|
|
4461 |
b = 2 * (c1y - p1y) - 2 * (c2y - c1y);
|
|
|
4462 |
c = p1y - c1y;
|
|
|
4463 |
t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a;
|
|
|
4464 |
t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a;
|
|
|
4465 |
abs(t1) > "1e12" && (t1 = .5);
|
|
|
4466 |
abs(t2) > "1e12" && (t2 = .5);
|
|
|
4467 |
if (t1 > 0 && t1 < 1) {
|
|
|
4468 |
dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1);
|
|
|
4469 |
x.push(dot.x);
|
|
|
4470 |
y.push(dot.y);
|
|
|
4471 |
}
|
|
|
4472 |
if (t2 > 0 && t2 < 1) {
|
|
|
4473 |
dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2);
|
|
|
4474 |
x.push(dot.x);
|
|
|
4475 |
y.push(dot.y);
|
|
|
4476 |
}
|
|
|
4477 |
return {
|
|
|
4478 |
min: {x: mmin[apply](0, x), y: mmin[apply](0, y)},
|
|
|
4479 |
max: {x: mmax[apply](0, x), y: mmax[apply](0, y)}
|
|
|
4480 |
};
|
|
|
4481 |
}),
|
|
|
4482 |
path2curve = R._path2curve = cacher(function (path, path2) {
|
|
|
4483 |
var p = pathToAbsolute(path),
|
|
|
4484 |
p2 = path2 && pathToAbsolute(path2),
|
|
|
4485 |
attrs = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null},
|
|
|
4486 |
attrs2 = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null},
|
|
|
4487 |
processPath = function (path, d) {
|
|
|
4488 |
var nx, ny;
|
|
|
4489 |
if (!path) {
|
|
|
4490 |
return ["C", d.x, d.y, d.x, d.y, d.x, d.y];
|
|
|
4491 |
}
|
|
|
4492 |
!(path[0] in {T:1, Q:1}) && (d.qx = d.qy = null);
|
|
|
4493 |
switch (path[0]) {
|
|
|
4494 |
case "M":
|
|
|
4495 |
d.X = path[1];
|
|
|
4496 |
d.Y = path[2];
|
|
|
4497 |
break;
|
|
|
4498 |
case "A":
|
|
|
4499 |
path = ["C"][concat](a2c[apply](0, [d.x, d.y][concat](path.slice(1))));
|
|
|
4500 |
break;
|
|
|
4501 |
case "S":
|
|
|
4502 |
nx = d.x + (d.x - (d.bx || d.x));
|
|
|
4503 |
ny = d.y + (d.y - (d.by || d.y));
|
|
|
4504 |
path = ["C", nx, ny][concat](path.slice(1));
|
|
|
4505 |
break;
|
|
|
4506 |
case "T":
|
|
|
4507 |
d.qx = d.x + (d.x - (d.qx || d.x));
|
|
|
4508 |
d.qy = d.y + (d.y - (d.qy || d.y));
|
|
|
4509 |
path = ["C"][concat](q2c(d.x, d.y, d.qx, d.qy, path[1], path[2]));
|
|
|
4510 |
break;
|
|
|
4511 |
case "Q":
|
|
|
4512 |
d.qx = path[1];
|
|
|
4513 |
d.qy = path[2];
|
|
|
4514 |
path = ["C"][concat](q2c(d.x, d.y, path[1], path[2], path[3], path[4]));
|
|
|
4515 |
break;
|
|
|
4516 |
case "L":
|
|
|
4517 |
path = ["C"][concat](l2c(d.x, d.y, path[1], path[2]));
|
|
|
4518 |
break;
|
|
|
4519 |
case "H":
|
|
|
4520 |
path = ["C"][concat](l2c(d.x, d.y, path[1], d.y));
|
|
|
4521 |
break;
|
|
|
4522 |
case "V":
|
|
|
4523 |
path = ["C"][concat](l2c(d.x, d.y, d.x, path[1]));
|
|
|
4524 |
break;
|
|
|
4525 |
case "Z":
|
|
|
4526 |
path = ["C"][concat](l2c(d.x, d.y, d.X, d.Y));
|
|
|
4527 |
break;
|
|
|
4528 |
}
|
|
|
4529 |
return path;
|
|
|
4530 |
},
|
|
|
4531 |
fixArc = function (pp, i) {
|
|
|
4532 |
if (pp[i].length > 7) {
|
|
|
4533 |
pp[i].shift();
|
|
|
4534 |
var pi = pp[i];
|
|
|
4535 |
while (pi.length) {
|
|
|
4536 |
pp.splice(i++, 0, ["C"][concat](pi.splice(0, 6)));
|
|
|
4537 |
}
|
|
|
4538 |
pp.splice(i, 1);
|
|
|
4539 |
ii = mmax(p.length, p2 && p2.length || 0);
|
|
|
4540 |
}
|
|
|
4541 |
},
|
|
|
4542 |
fixM = function (path1, path2, a1, a2, i) {
|
|
|
4543 |
if (path1 && path2 && path1[i][0] == "M" && path2[i][0] != "M") {
|
|
|
4544 |
path2.splice(i, 0, ["M", a2.x, a2.y]);
|
|
|
4545 |
a1.bx = 0;
|
|
|
4546 |
a1.by = 0;
|
|
|
4547 |
a1.x = path1[i][1];
|
|
|
4548 |
a1.y = path1[i][2];
|
|
|
4549 |
ii = mmax(p.length, p2 && p2.length || 0);
|
|
|
4550 |
}
|
|
|
4551 |
};
|
|
|
4552 |
for (var i = 0, ii = mmax(p.length, p2 && p2.length || 0); i < ii; i++) {
|
|
|
4553 |
p[i] = processPath(p[i], attrs);
|
|
|
4554 |
fixArc(p, i);
|
|
|
4555 |
p2 && (p2[i] = processPath(p2[i], attrs2));
|
|
|
4556 |
p2 && fixArc(p2, i);
|
|
|
4557 |
fixM(p, p2, attrs, attrs2, i);
|
|
|
4558 |
fixM(p2, p, attrs2, attrs, i);
|
|
|
4559 |
var seg = p[i],
|
|
|
4560 |
seg2 = p2 && p2[i],
|
|
|
4561 |
seglen = seg.length,
|
|
|
4562 |
seg2len = p2 && seg2.length;
|
|
|
4563 |
attrs.x = seg[seglen - 2];
|
|
|
4564 |
attrs.y = seg[seglen - 1];
|
|
|
4565 |
attrs.bx = toFloat(seg[seglen - 4]) || attrs.x;
|
|
|
4566 |
attrs.by = toFloat(seg[seglen - 3]) || attrs.y;
|
|
|
4567 |
attrs2.bx = p2 && (toFloat(seg2[seg2len - 4]) || attrs2.x);
|
|
|
4568 |
attrs2.by = p2 && (toFloat(seg2[seg2len - 3]) || attrs2.y);
|
|
|
4569 |
attrs2.x = p2 && seg2[seg2len - 2];
|
|
|
4570 |
attrs2.y = p2 && seg2[seg2len - 1];
|
|
|
4571 |
}
|
|
|
4572 |
return p2 ? [p, p2] : p;
|
|
|
4573 |
}, null, pathClone),
|
|
|
4574 |
parseDots = R._parseDots = cacher(function (gradient) {
|
|
|
4575 |
var dots = [];
|
|
|
4576 |
for (var i = 0, ii = gradient.length; i < ii; i++) {
|
|
|
4577 |
var dot = {},
|
|
|
4578 |
par = gradient[i].match(/^([^:]*):?([\d\.]*)/);
|
|
|
4579 |
dot.color = R.getRGB(par[1]);
|
|
|
4580 |
if (dot.color.error) {
|
|
|
4581 |
return null;
|
|
|
4582 |
}
|
|
|
4583 |
dot.color = dot.color.hex;
|
|
|
4584 |
par[2] && (dot.offset = par[2] + "%");
|
|
|
4585 |
dots.push(dot);
|
|
|
4586 |
}
|
|
|
4587 |
for (i = 1, ii = dots.length - 1; i < ii; i++) {
|
|
|
4588 |
if (!dots[i].offset) {
|
|
|
4589 |
var start = toFloat(dots[i - 1].offset || 0),
|
|
|
4590 |
end = 0;
|
|
|
4591 |
for (var j = i + 1; j < ii; j++) {
|
|
|
4592 |
if (dots[j].offset) {
|
|
|
4593 |
end = dots[j].offset;
|
|
|
4594 |
break;
|
|
|
4595 |
}
|
|
|
4596 |
}
|
|
|
4597 |
if (!end) {
|
|
|
4598 |
end = 100;
|
|
|
4599 |
j = ii;
|
|
|
4600 |
}
|
|
|
4601 |
end = toFloat(end);
|
|
|
4602 |
var d = (end - start) / (j - i + 1);
|
|
|
4603 |
for (; i < j; i++) {
|
|
|
4604 |
start += d;
|
|
|
4605 |
dots[i].offset = start + "%";
|
|
|
4606 |
}
|
|
|
4607 |
}
|
|
|
4608 |
}
|
|
|
4609 |
return dots;
|
|
|
4610 |
}),
|
|
|
4611 |
tear = R._tear = function (el, paper) {
|
|
|
4612 |
el == paper.top && (paper.top = el.prev);
|
|
|
4613 |
el == paper.bottom && (paper.bottom = el.next);
|
|
|
4614 |
el.next && (el.next.prev = el.prev);
|
|
|
4615 |
el.prev && (el.prev.next = el.next);
|
|
|
4616 |
},
|
|
|
4617 |
tofront = R._tofront = function (el, paper) {
|
|
|
4618 |
if (paper.top === el) {
|
|
|
4619 |
return;
|
|
|
4620 |
}
|
|
|
4621 |
tear(el, paper);
|
|
|
4622 |
el.next = null;
|
|
|
4623 |
el.prev = paper.top;
|
|
|
4624 |
paper.top.next = el;
|
|
|
4625 |
paper.top = el;
|
|
|
4626 |
},
|
|
|
4627 |
toback = R._toback = function (el, paper) {
|
|
|
4628 |
if (paper.bottom === el) {
|
|
|
4629 |
return;
|
|
|
4630 |
}
|
|
|
4631 |
tear(el, paper);
|
|
|
4632 |
el.next = paper.bottom;
|
|
|
4633 |
el.prev = null;
|
|
|
4634 |
paper.bottom.prev = el;
|
|
|
4635 |
paper.bottom = el;
|
|
|
4636 |
},
|
|
|
4637 |
insertafter = R._insertafter = function (el, el2, paper) {
|
|
|
4638 |
tear(el, paper);
|
|
|
4639 |
el2 == paper.top && (paper.top = el);
|
|
|
4640 |
el2.next && (el2.next.prev = el);
|
|
|
4641 |
el.next = el2.next;
|
|
|
4642 |
el.prev = el2;
|
|
|
4643 |
el2.next = el;
|
|
|
4644 |
},
|
|
|
4645 |
insertbefore = R._insertbefore = function (el, el2, paper) {
|
|
|
4646 |
tear(el, paper);
|
|
|
4647 |
el2 == paper.bottom && (paper.bottom = el);
|
|
|
4648 |
el2.prev && (el2.prev.next = el);
|
|
|
4649 |
el.prev = el2.prev;
|
|
|
4650 |
el2.prev = el;
|
|
|
4651 |
el.next = el2;
|
|
|
4652 |
},
|
|
|
4653 |
removed = function (methodname) {
|
|
|
4654 |
return function () {
|
|
|
4655 |
throw new Error("Rapha\xebl: you are calling to method \u201c" + methodname + "\u201d of removed object");
|
|
|
4656 |
};
|
|
|
4657 |
},
|
|
|
4658 |
extractTransform = R._extractTransform = function (el, tstr) {
|
|
|
4659 |
if (tstr == null) {
|
|
|
4660 |
return el._.transform;
|
|
|
4661 |
}
|
|
|
4662 |
tstr = Str(tstr).replace(/\.{3}|\u2026/g, el._.transform || E);
|
|
|
4663 |
var tdata = R.parseTransformString(tstr),
|
|
|
4664 |
deg = 0,
|
|
|
4665 |
dx = 0,
|
|
|
4666 |
dy = 0,
|
|
|
4667 |
sx = 1,
|
|
|
4668 |
sy = 1,
|
|
|
4669 |
_ = el._,
|
|
|
4670 |
m = new Matrix;
|
|
|
4671 |
_.transform = tdata || [];
|
|
|
4672 |
if (tdata) {
|
|
|
4673 |
for (var i = 0, ii = tdata.length; i < ii; i++) {
|
|
|
4674 |
var t = tdata[i],
|
|
|
4675 |
tlen = t.length,
|
|
|
4676 |
command = Str(t[0]).toLowerCase(),
|
|
|
4677 |
absolute = t[0] != command,
|
|
|
4678 |
inver = absolute ? m.invert() : 0,
|
|
|
4679 |
x1,
|
|
|
4680 |
y1,
|
|
|
4681 |
x2,
|
|
|
4682 |
y2,
|
|
|
4683 |
bb;
|
|
|
4684 |
if (command == "t" && tlen == 3) {
|
|
|
4685 |
if (absolute) {
|
|
|
4686 |
x1 = inver.x(0, 0);
|
|
|
4687 |
y1 = inver.y(0, 0);
|
|
|
4688 |
x2 = inver.x(t[1], t[2]);
|
|
|
4689 |
y2 = inver.y(t[1], t[2]);
|
|
|
4690 |
m.translate(x2 - x1, y2 - y1);
|
|
|
4691 |
} else {
|
|
|
4692 |
m.translate(t[1], t[2]);
|
|
|
4693 |
}
|
|
|
4694 |
} else if (command == "r") {
|
|
|
4695 |
if (tlen == 2) {
|
|
|
4696 |
bb = bb || el.getBBox(1);
|
|
|
4697 |
m.rotate(t[1], bb.x + bb.width / 2, bb.y + bb.height / 2);
|
|
|
4698 |
deg += t[1];
|
|
|
4699 |
} else if (tlen == 4) {
|
|
|
4700 |
if (absolute) {
|
|
|
4701 |
x2 = inver.x(t[2], t[3]);
|
|
|
4702 |
y2 = inver.y(t[2], t[3]);
|
|
|
4703 |
m.rotate(t[1], x2, y2);
|
|
|
4704 |
} else {
|
|
|
4705 |
m.rotate(t[1], t[2], t[3]);
|
|
|
4706 |
}
|
|
|
4707 |
deg += t[1];
|
|
|
4708 |
}
|
|
|
4709 |
} else if (command == "s") {
|
|
|
4710 |
if (tlen == 2 || tlen == 3) {
|
|
|
4711 |
bb = bb || el.getBBox(1);
|
|
|
4712 |
m.scale(t[1], t[tlen - 1], bb.x + bb.width / 2, bb.y + bb.height / 2);
|
|
|
4713 |
sx *= t[1];
|
|
|
4714 |
sy *= t[tlen - 1];
|
|
|
4715 |
} else if (tlen == 5) {
|
|
|
4716 |
if (absolute) {
|
|
|
4717 |
x2 = inver.x(t[3], t[4]);
|
|
|
4718 |
y2 = inver.y(t[3], t[4]);
|
|
|
4719 |
m.scale(t[1], t[2], x2, y2);
|
|
|
4720 |
} else {
|
|
|
4721 |
m.scale(t[1], t[2], t[3], t[4]);
|
|
|
4722 |
}
|
|
|
4723 |
sx *= t[1];
|
|
|
4724 |
sy *= t[2];
|
|
|
4725 |
}
|
|
|
4726 |
} else if (command == "m" && tlen == 7) {
|
|
|
4727 |
m.add(t[1], t[2], t[3], t[4], t[5], t[6]);
|
|
|
4728 |
}
|
|
|
4729 |
_.dirtyT = 1;
|
|
|
4730 |
el.matrix = m;
|
|
|
4731 |
}
|
|
|
4732 |
}
|
|
|
4733 |
|
|
|
4734 |
el.matrix = m;
|
|
|
4735 |
|
|
|
4736 |
_.sx = sx;
|
|
|
4737 |
_.sy = sy;
|
|
|
4738 |
_.deg = deg;
|
|
|
4739 |
_.dx = dx = m.e;
|
|
|
4740 |
_.dy = dy = m.f;
|
|
|
4741 |
|
|
|
4742 |
if (sx == 1 && sy == 1 && !deg && _.bbox) {
|
|
|
4743 |
_.bbox.x += +dx;
|
|
|
4744 |
_.bbox.y += +dy;
|
|
|
4745 |
} else {
|
|
|
4746 |
_.dirtyT = 1;
|
|
|
4747 |
}
|
|
|
4748 |
},
|
|
|
4749 |
getEmpty = function (item) {
|
|
|
4750 |
var l = item[0];
|
|
|
4751 |
switch (l.toLowerCase()) {
|
|
|
4752 |
case "t": return [l, 0, 0];
|
|
|
4753 |
case "m": return [l, 1, 0, 0, 1, 0, 0];
|
|
|
4754 |
case "r": if (item.length == 4) {
|
|
|
4755 |
return [l, 0, item[2], item[3]];
|
|
|
4756 |
} else {
|
|
|
4757 |
return [l, 0];
|
|
|
4758 |
}
|
|
|
4759 |
case "s": if (item.length == 5) {
|
|
|
4760 |
return [l, 1, 1, item[3], item[4]];
|
|
|
4761 |
} else if (item.length == 3) {
|
|
|
4762 |
return [l, 1, 1];
|
|
|
4763 |
} else {
|
|
|
4764 |
return [l, 1];
|
|
|
4765 |
}
|
|
|
4766 |
}
|
|
|
4767 |
},
|
|
|
4768 |
equaliseTransform = R._equaliseTransform = function (t1, t2) {
|
|
|
4769 |
t2 = Str(t2).replace(/\.{3}|\u2026/g, t1);
|
|
|
4770 |
t1 = R.parseTransformString(t1) || [];
|
|
|
4771 |
t2 = R.parseTransformString(t2) || [];
|
|
|
4772 |
var maxlength = mmax(t1.length, t2.length),
|
|
|
4773 |
from = [],
|
|
|
4774 |
to = [],
|
|
|
4775 |
i = 0, j, jj,
|
|
|
4776 |
tt1, tt2;
|
|
|
4777 |
for (; i < maxlength; i++) {
|
|
|
4778 |
tt1 = t1[i] || getEmpty(t2[i]);
|
|
|
4779 |
tt2 = t2[i] || getEmpty(tt1);
|
|
|
4780 |
if ((tt1[0] != tt2[0]) ||
|
|
|
4781 |
(tt1[0].toLowerCase() == "r" && (tt1[2] != tt2[2] || tt1[3] != tt2[3])) ||
|
|
|
4782 |
(tt1[0].toLowerCase() == "s" && (tt1[3] != tt2[3] || tt1[4] != tt2[4]))
|
|
|
4783 |
) {
|
|
|
4784 |
return;
|
|
|
4785 |
}
|
|
|
4786 |
from[i] = [];
|
|
|
4787 |
to[i] = [];
|
|
|
4788 |
for (j = 0, jj = mmax(tt1.length, tt2.length); j < jj; j++) {
|
|
|
4789 |
j in tt1 && (from[i][j] = tt1[j]);
|
|
|
4790 |
j in tt2 && (to[i][j] = tt2[j]);
|
|
|
4791 |
}
|
|
|
4792 |
}
|
|
|
4793 |
return {
|
|
|
4794 |
from: from,
|
|
|
4795 |
to: to
|
|
|
4796 |
};
|
|
|
4797 |
};
|
|
|
4798 |
R._getContainer = function (x, y, w, h) {
|
|
|
4799 |
var container;
|
|
|
4800 |
container = h == null && !R.is(x, "object") ? g.doc.getElementById(x) : x;
|
|
|
4801 |
if (container == null) {
|
|
|
4802 |
return;
|
|
|
4803 |
}
|
|
|
4804 |
if (container.tagName) {
|
|
|
4805 |
if (y == null) {
|
|
|
4806 |
return {
|
|
|
4807 |
container: container,
|
|
|
4808 |
width: container.style.pixelWidth || container.offsetWidth,
|
|
|
4809 |
height: container.style.pixelHeight || container.offsetHeight
|
|
|
4810 |
};
|
|
|
4811 |
} else {
|
|
|
4812 |
return {
|
|
|
4813 |
container: container,
|
|
|
4814 |
width: y,
|
|
|
4815 |
height: w
|
|
|
4816 |
};
|
|
|
4817 |
}
|
|
|
4818 |
}
|
|
|
4819 |
return {
|
|
|
4820 |
container: 1,
|
|
|
4821 |
x: x,
|
|
|
4822 |
y: y,
|
|
|
4823 |
width: w,
|
|
|
4824 |
height: h
|
|
|
4825 |
};
|
|
|
4826 |
};
|
|
|
4827 |
|
|
|
4828 |
R.pathToRelative = pathToRelative;
|
|
|
4829 |
R._engine = {};
|
|
|
4830 |
|
|
|
4831 |
R.path2curve = path2curve;
|
|
|
4832 |
|
|
|
4833 |
R.matrix = function (a, b, c, d, e, f) {
|
|
|
4834 |
return new Matrix(a, b, c, d, e, f);
|
|
|
4835 |
};
|
|
|
4836 |
function Matrix(a, b, c, d, e, f) {
|
|
|
4837 |
if (a != null) {
|
|
|
4838 |
this.a = +a;
|
|
|
4839 |
this.b = +b;
|
|
|
4840 |
this.c = +c;
|
|
|
4841 |
this.d = +d;
|
|
|
4842 |
this.e = +e;
|
|
|
4843 |
this.f = +f;
|
|
|
4844 |
} else {
|
|
|
4845 |
this.a = 1;
|
|
|
4846 |
this.b = 0;
|
|
|
4847 |
this.c = 0;
|
|
|
4848 |
this.d = 1;
|
|
|
4849 |
this.e = 0;
|
|
|
4850 |
this.f = 0;
|
|
|
4851 |
}
|
|
|
4852 |
}
|
|
|
4853 |
(function (matrixproto) {
|
|
|
4854 |
|
|
|
4855 |
matrixproto.add = function (a, b, c, d, e, f) {
|
|
|
4856 |
var out = [[], [], []],
|
|
|
4857 |
m = [[this.a, this.c, this.e], [this.b, this.d, this.f], [0, 0, 1]],
|
|
|
4858 |
matrix = [[a, c, e], [b, d, f], [0, 0, 1]],
|
|
|
4859 |
x, y, z, res;
|
|
|
4860 |
|
|
|
4861 |
if (a && a instanceof Matrix) {
|
|
|
4862 |
matrix = [[a.a, a.c, a.e], [a.b, a.d, a.f], [0, 0, 1]];
|
|
|
4863 |
}
|
|
|
4864 |
|
|
|
4865 |
for (x = 0; x < 3; x++) {
|
|
|
4866 |
for (y = 0; y < 3; y++) {
|
|
|
4867 |
res = 0;
|
|
|
4868 |
for (z = 0; z < 3; z++) {
|
|
|
4869 |
res += m[x][z] * matrix[z][y];
|
|
|
4870 |
}
|
|
|
4871 |
out[x][y] = res;
|
|
|
4872 |
}
|
|
|
4873 |
}
|
|
|
4874 |
this.a = out[0][0];
|
|
|
4875 |
this.b = out[1][0];
|
|
|
4876 |
this.c = out[0][1];
|
|
|
4877 |
this.d = out[1][1];
|
|
|
4878 |
this.e = out[0][2];
|
|
|
4879 |
this.f = out[1][2];
|
|
|
4880 |
};
|
|
|
4881 |
|
|
|
4882 |
matrixproto.invert = function () {
|
|
|
4883 |
var me = this,
|
|
|
4884 |
x = me.a * me.d - me.b * me.c;
|
|
|
4885 |
return new Matrix(me.d / x, -me.b / x, -me.c / x, me.a / x, (me.c * me.f - me.d * me.e) / x, (me.b * me.e - me.a * me.f) / x);
|
|
|
4886 |
};
|
|
|
4887 |
|
|
|
4888 |
matrixproto.clone = function () {
|
|
|
4889 |
return new Matrix(this.a, this.b, this.c, this.d, this.e, this.f);
|
|
|
4890 |
};
|
|
|
4891 |
|
|
|
4892 |
matrixproto.translate = function (x, y) {
|
|
|
4893 |
this.add(1, 0, 0, 1, x, y);
|
|
|
4894 |
};
|
|
|
4895 |
|
|
|
4896 |
matrixproto.scale = function (x, y, cx, cy) {
|
|
|
4897 |
y == null && (y = x);
|
|
|
4898 |
(cx || cy) && this.add(1, 0, 0, 1, cx, cy);
|
|
|
4899 |
this.add(x, 0, 0, y, 0, 0);
|
|
|
4900 |
(cx || cy) && this.add(1, 0, 0, 1, -cx, -cy);
|
|
|
4901 |
};
|
|
|
4902 |
|
|
|
4903 |
matrixproto.rotate = function (a, x, y) {
|
|
|
4904 |
a = R.rad(a);
|
|
|
4905 |
x = x || 0;
|
|
|
4906 |
y = y || 0;
|
|
|
4907 |
var cos = +math.cos(a).toFixed(9),
|
|
|
4908 |
sin = +math.sin(a).toFixed(9);
|
|
|
4909 |
this.add(cos, sin, -sin, cos, x, y);
|
|
|
4910 |
this.add(1, 0, 0, 1, -x, -y);
|
|
|
4911 |
};
|
|
|
4912 |
|
|
|
4913 |
matrixproto.x = function (x, y) {
|
|
|
4914 |
return x * this.a + y * this.c + this.e;
|
|
|
4915 |
};
|
|
|
4916 |
|
|
|
4917 |
matrixproto.y = function (x, y) {
|
|
|
4918 |
return x * this.b + y * this.d + this.f;
|
|
|
4919 |
};
|
|
|
4920 |
matrixproto.get = function (i) {
|
|
|
4921 |
return +this[Str.fromCharCode(97 + i)].toFixed(4);
|
|
|
4922 |
};
|
|
|
4923 |
matrixproto.toString = function () {
|
|
|
4924 |
return R.svg ?
|
|
|
4925 |
"matrix(" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)].join() + ")" :
|
|
|
4926 |
[this.get(0), this.get(2), this.get(1), this.get(3), 0, 0].join();
|
|
|
4927 |
};
|
|
|
4928 |
matrixproto.toFilter = function () {
|
|
|
4929 |
return "progid:DXImageTransform.Microsoft.Matrix(M11=" + this.get(0) +
|
|
|
4930 |
", M12=" + this.get(2) + ", M21=" + this.get(1) + ", M22=" + this.get(3) +
|
|
|
4931 |
", Dx=" + this.get(4) + ", Dy=" + this.get(5) + ", sizingmethod='auto expand')";
|
|
|
4932 |
};
|
|
|
4933 |
matrixproto.offset = function () {
|
|
|
4934 |
return [this.e.toFixed(4), this.f.toFixed(4)];
|
|
|
4935 |
};
|
|
|
4936 |
function norm(a) {
|
|
|
4937 |
return a[0] * a[0] + a[1] * a[1];
|
|
|
4938 |
}
|
|
|
4939 |
function normalize(a) {
|
|
|
4940 |
var mag = math.sqrt(norm(a));
|
|
|
4941 |
a[0] && (a[0] /= mag);
|
|
|
4942 |
a[1] && (a[1] /= mag);
|
|
|
4943 |
}
|
|
|
4944 |
|
|
|
4945 |
matrixproto.split = function () {
|
|
|
4946 |
var out = {};
|
|
|
4947 |
// translation
|
|
|
4948 |
out.dx = this.e;
|
|
|
4949 |
out.dy = this.f;
|
|
|
4950 |
|
|
|
4951 |
// scale and shear
|
|
|
4952 |
var row = [[this.a, this.c], [this.b, this.d]];
|
|
|
4953 |
out.scalex = math.sqrt(norm(row[0]));
|
|
|
4954 |
normalize(row[0]);
|
|
|
4955 |
|
|
|
4956 |
out.shear = row[0][0] * row[1][0] + row[0][1] * row[1][1];
|
|
|
4957 |
row[1] = [row[1][0] - row[0][0] * out.shear, row[1][1] - row[0][1] * out.shear];
|
|
|
4958 |
|
|
|
4959 |
out.scaley = math.sqrt(norm(row[1]));
|
|
|
4960 |
normalize(row[1]);
|
|
|
4961 |
out.shear /= out.scaley;
|
|
|
4962 |
|
|
|
4963 |
// rotation
|
|
|
4964 |
var sin = -row[0][1],
|
|
|
4965 |
cos = row[1][1];
|
|
|
4966 |
if (cos < 0) {
|
|
|
4967 |
out.rotate = R.deg(math.acos(cos));
|
|
|
4968 |
if (sin < 0) {
|
|
|
4969 |
out.rotate = 360 - out.rotate;
|
|
|
4970 |
}
|
|
|
4971 |
} else {
|
|
|
4972 |
out.rotate = R.deg(math.asin(sin));
|
|
|
4973 |
}
|
|
|
4974 |
|
|
|
4975 |
out.isSimple = !+out.shear.toFixed(9) && (out.scalex.toFixed(9) == out.scaley.toFixed(9) || !out.rotate);
|
|
|
4976 |
out.isSuperSimple = !+out.shear.toFixed(9) && out.scalex.toFixed(9) == out.scaley.toFixed(9) && !out.rotate;
|
|
|
4977 |
out.noRotation = !+out.shear.toFixed(9) && !out.rotate;
|
|
|
4978 |
return out;
|
|
|
4979 |
};
|
|
|
4980 |
|
|
|
4981 |
matrixproto.toTransformString = function (shorter) {
|
|
|
4982 |
var s = shorter || this[split]();
|
|
|
4983 |
if (s.isSimple) {
|
|
|
4984 |
return "t" + [s.dx, s.dy] + "s" + [s.scalex, s.scaley, 0, 0] + "r" + [s.rotate, 0, 0];
|
|
|
4985 |
} else {
|
|
|
4986 |
return "m" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)];
|
|
|
4987 |
}
|
|
|
4988 |
};
|
|
|
4989 |
})(Matrix.prototype);
|
|
|
4990 |
|
|
|
4991 |
// WebKit rendering bug workaround method
|
|
|
4992 |
var version = navigator.userAgent.match(/Version\/(.*?)\s/) || navigator.userAgent.match(/Chrome\/(\d+)/);
|
|
|
4993 |
if ((navigator.vendor == "Apple Computer, Inc.") && (version && version[1] < 4 || navigator.platform.slice(0, 2) == "iP") ||
|
|
|
4994 |
(navigator.vendor == "Google Inc." && version && version[1] < 8)) {
|
|
|
4995 |
|
|
|
4996 |
paperproto.safari = function () {
|
|
|
4997 |
var rect = this.rect(-99, -99, this.width + 99, this.height + 99).attr({stroke: "none"});
|
|
|
4998 |
setTimeout(function () {rect.remove();});
|
|
|
4999 |
};
|
|
|
5000 |
} else {
|
|
|
5001 |
paperproto.safari = fun;
|
|
|
5002 |
}
|
|
|
5003 |
|
|
|
5004 |
var preventDefault = function () {
|
|
|
5005 |
this.returnValue = false;
|
|
|
5006 |
},
|
|
|
5007 |
preventTouch = function () {
|
|
|
5008 |
return this.originalEvent.preventDefault();
|
|
|
5009 |
},
|
|
|
5010 |
stopPropagation = function () {
|
|
|
5011 |
this.cancelBubble = true;
|
|
|
5012 |
},
|
|
|
5013 |
stopTouch = function () {
|
|
|
5014 |
return this.originalEvent.stopPropagation();
|
|
|
5015 |
},
|
|
|
5016 |
addEvent = (function () {
|
|
|
5017 |
if (g.doc.addEventListener) {
|
|
|
5018 |
return function (obj, type, fn, element) {
|
|
|
5019 |
var realName = supportsTouch && touchMap[type] ? touchMap[type] : type,
|
|
|
5020 |
f = function (e) {
|
|
|
5021 |
var scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop,
|
|
|
5022 |
scrollX = g.doc.documentElement.scrollLeft || g.doc.body.scrollLeft,
|
|
|
5023 |
x = e.clientX + scrollX,
|
|
|
5024 |
y = e.clientY + scrollY;
|
|
|
5025 |
if (supportsTouch && touchMap[has](type)) {
|
|
|
5026 |
for (var i = 0, ii = e.targetTouches && e.targetTouches.length; i < ii; i++) {
|
|
|
5027 |
if (e.targetTouches[i].target == obj) {
|
|
|
5028 |
var olde = e;
|
|
|
5029 |
e = e.targetTouches[i];
|
|
|
5030 |
e.originalEvent = olde;
|
|
|
5031 |
e.preventDefault = preventTouch;
|
|
|
5032 |
e.stopPropagation = stopTouch;
|
|
|
5033 |
break;
|
|
|
5034 |
}
|
|
|
5035 |
}
|
|
|
5036 |
}
|
|
|
5037 |
return fn.call(element, e, x, y);
|
|
|
5038 |
};
|
|
|
5039 |
obj.addEventListener(realName, f, false);
|
|
|
5040 |
return function () {
|
|
|
5041 |
obj.removeEventListener(realName, f, false);
|
|
|
5042 |
return true;
|
|
|
5043 |
};
|
|
|
5044 |
};
|
|
|
5045 |
} else if (g.doc.attachEvent) {
|
|
|
5046 |
return function (obj, type, fn, element) {
|
|
|
5047 |
var f = function (e) {
|
|
|
5048 |
e = e || g.win.event;
|
|
|
5049 |
var scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop,
|
|
|
5050 |
scrollX = g.doc.documentElement.scrollLeft || g.doc.body.scrollLeft,
|
|
|
5051 |
x = e.clientX + scrollX,
|
|
|
5052 |
y = e.clientY + scrollY;
|
|
|
5053 |
e.preventDefault = e.preventDefault || preventDefault;
|
|
|
5054 |
e.stopPropagation = e.stopPropagation || stopPropagation;
|
|
|
5055 |
return fn.call(element, e, x, y);
|
|
|
5056 |
};
|
|
|
5057 |
obj.attachEvent("on" + type, f);
|
|
|
5058 |
var detacher = function () {
|
|
|
5059 |
obj.detachEvent("on" + type, f);
|
|
|
5060 |
return true;
|
|
|
5061 |
};
|
|
|
5062 |
return detacher;
|
|
|
5063 |
};
|
|
|
5064 |
}
|
|
|
5065 |
})(),
|
|
|
5066 |
drag = [],
|
|
|
5067 |
dragMove = function (e) {
|
|
|
5068 |
var x = e.clientX,
|
|
|
5069 |
y = e.clientY,
|
|
|
5070 |
scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop,
|
|
|
5071 |
scrollX = g.doc.documentElement.scrollLeft || g.doc.body.scrollLeft,
|
|
|
5072 |
dragi,
|
|
|
5073 |
j = drag.length;
|
|
|
5074 |
while (j--) {
|
|
|
5075 |
dragi = drag[j];
|
|
|
5076 |
if (supportsTouch) {
|
|
|
5077 |
var i = e.touches.length,
|
|
|
5078 |
touch;
|
|
|
5079 |
while (i--) {
|
|
|
5080 |
touch = e.touches[i];
|
|
|
5081 |
if (touch.identifier == dragi.el._drag.id) {
|
|
|
5082 |
x = touch.clientX;
|
|
|
5083 |
y = touch.clientY;
|
|
|
5084 |
(e.originalEvent ? e.originalEvent : e).preventDefault();
|
|
|
5085 |
break;
|
|
|
5086 |
}
|
|
|
5087 |
}
|
|
|
5088 |
} else {
|
|
|
5089 |
e.preventDefault();
|
|
|
5090 |
}
|
|
|
5091 |
var node = dragi.el.node,
|
|
|
5092 |
o,
|
|
|
5093 |
next = node.nextSibling,
|
|
|
5094 |
parent = node.parentNode,
|
|
|
5095 |
display = node.style.display;
|
|
|
5096 |
g.win.opera && parent.removeChild(node);
|
|
|
5097 |
node.style.display = "none";
|
|
|
5098 |
o = dragi.el.paper.getElementByPoint(x, y);
|
|
|
5099 |
node.style.display = display;
|
|
|
5100 |
g.win.opera && (next ? parent.insertBefore(node, next) : parent.appendChild(node));
|
|
|
5101 |
o && eve("drag.over." + dragi.el.id, dragi.el, o);
|
|
|
5102 |
x += scrollX;
|
|
|
5103 |
y += scrollY;
|
|
|
5104 |
eve("drag.move." + dragi.el.id, dragi.move_scope || dragi.el, x - dragi.el._drag.x, y - dragi.el._drag.y, x, y, e);
|
|
|
5105 |
}
|
|
|
5106 |
},
|
|
|
5107 |
dragUp = function (e) {
|
|
|
5108 |
R.unmousemove(dragMove).unmouseup(dragUp);
|
|
|
5109 |
var i = drag.length,
|
|
|
5110 |
dragi;
|
|
|
5111 |
while (i--) {
|
|
|
5112 |
dragi = drag[i];
|
|
|
5113 |
dragi.el._drag = {};
|
|
|
5114 |
eve("drag.end." + dragi.el.id, dragi.end_scope || dragi.start_scope || dragi.move_scope || dragi.el, e);
|
|
|
5115 |
}
|
|
|
5116 |
drag = [];
|
|
|
5117 |
},
|
|
|
5118 |
|
|
|
5119 |
elproto = R.el = {};
|
|
|
5120 |
|
|
|
5121 |
|
|
|
5122 |
|
|
|
5123 |
|
|
|
5124 |
|
|
|
5125 |
|
|
|
5126 |
|
|
|
5127 |
|
|
|
5128 |
|
|
|
5129 |
|
|
|
5130 |
|
|
|
5131 |
|
|
|
5132 |
|
|
|
5133 |
|
|
|
5134 |
|
|
|
5135 |
|
|
|
5136 |
|
|
|
5137 |
|
|
|
5138 |
|
|
|
5139 |
|
|
|
5140 |
|
|
|
5141 |
|
|
|
5142 |
|
|
|
5143 |
|
|
|
5144 |
|
|
|
5145 |
|
|
|
5146 |
|
|
|
5147 |
|
|
|
5148 |
|
|
|
5149 |
|
|
|
5150 |
|
|
|
5151 |
|
|
|
5152 |
for (var i = events.length; i--;) {
|
|
|
5153 |
(function (eventName) {
|
|
|
5154 |
R[eventName] = elproto[eventName] = function (fn, scope) {
|
|
|
5155 |
if (R.is(fn, "function")) {
|
|
|
5156 |
this.events = this.events || [];
|
|
|
5157 |
this.events.push({name: eventName, f: fn, unbind: addEvent(this.shape || this.node || g.doc, eventName, fn, scope || this)});
|
|
|
5158 |
}
|
|
|
5159 |
return this;
|
|
|
5160 |
};
|
|
|
5161 |
R["un" + eventName] = elproto["un" + eventName] = function (fn) {
|
|
|
5162 |
var events = this.events,
|
|
|
5163 |
l = events.length;
|
|
|
5164 |
while (l--) if (events[l].name == eventName && events[l].f == fn) {
|
|
|
5165 |
events[l].unbind();
|
|
|
5166 |
events.splice(l, 1);
|
|
|
5167 |
!events.length && delete this.events;
|
|
|
5168 |
return this;
|
|
|
5169 |
}
|
|
|
5170 |
return this;
|
|
|
5171 |
};
|
|
|
5172 |
})(events[i]);
|
|
|
5173 |
}
|
|
|
5174 |
|
|
|
5175 |
|
|
|
5176 |
elproto.data = function (key, value) {
|
|
|
5177 |
var data = eldata[this.id] = eldata[this.id] || {};
|
|
|
5178 |
if (arguments.length == 1) {
|
|
|
5179 |
if (R.is(key, "object")) {
|
|
|
5180 |
for (var i in key) if (key[has](i)) {
|
|
|
5181 |
this.data(i, key[i]);
|
|
|
5182 |
}
|
|
|
5183 |
return this;
|
|
|
5184 |
}
|
|
|
5185 |
eve("data.get." + this.id, this, data[key], key);
|
|
|
5186 |
return data[key];
|
|
|
5187 |
}
|
|
|
5188 |
data[key] = value;
|
|
|
5189 |
eve("data.set." + this.id, this, value, key);
|
|
|
5190 |
return this;
|
|
|
5191 |
};
|
|
|
5192 |
|
|
|
5193 |
elproto.removeData = function (key) {
|
|
|
5194 |
if (key == null) {
|
|
|
5195 |
eldata[this.id] = {};
|
|
|
5196 |
} else {
|
|
|
5197 |
eldata[this.id] && delete eldata[this.id][key];
|
|
|
5198 |
}
|
|
|
5199 |
return this;
|
|
|
5200 |
};
|
|
|
5201 |
|
|
|
5202 |
elproto.hover = function (f_in, f_out, scope_in, scope_out) {
|
|
|
5203 |
return this.mouseover(f_in, scope_in).mouseout(f_out, scope_out || scope_in);
|
|
|
5204 |
};
|
|
|
5205 |
|
|
|
5206 |
elproto.unhover = function (f_in, f_out) {
|
|
|
5207 |
return this.unmouseover(f_in).unmouseout(f_out);
|
|
|
5208 |
};
|
|
|
5209 |
|
|
|
5210 |
elproto.drag = function (onmove, onstart, onend, move_scope, start_scope, end_scope) {
|
|
|
5211 |
function start(e) {
|
|
|
5212 |
(e.originalEvent || e).preventDefault();
|
|
|
5213 |
var scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop,
|
|
|
5214 |
scrollX = g.doc.documentElement.scrollLeft || g.doc.body.scrollLeft;
|
|
|
5215 |
this._drag.x = e.clientX + scrollX;
|
|
|
5216 |
this._drag.y = e.clientY + scrollY;
|
|
|
5217 |
this._drag.id = e.identifier;
|
|
|
5218 |
!drag.length && R.mousemove(dragMove).mouseup(dragUp);
|
|
|
5219 |
drag.push({el: this, move_scope: move_scope, start_scope: start_scope, end_scope: end_scope});
|
|
|
5220 |
onstart && eve.on("drag.start." + this.id, onstart);
|
|
|
5221 |
onmove && eve.on("drag.move." + this.id, onmove);
|
|
|
5222 |
onend && eve.on("drag.end." + this.id, onend);
|
|
|
5223 |
eve("drag.start." + this.id, start_scope || move_scope || this, e.clientX + scrollX, e.clientY + scrollY, e);
|
|
|
5224 |
}
|
|
|
5225 |
this._drag = {};
|
|
|
5226 |
this.mousedown(start);
|
|
|
5227 |
return this;
|
|
|
5228 |
};
|
|
|
5229 |
|
|
|
5230 |
elproto.onDragOver = function (f) {
|
|
|
5231 |
f ? eve.on("drag.over." + this.id, f) : eve.unbind("drag.over." + this.id);
|
|
|
5232 |
};
|
|
|
5233 |
|
|
|
5234 |
elproto.undrag = function () {
|
|
|
5235 |
var i = drag.length;
|
|
|
5236 |
while (i--) if (drag[i].el == this) {
|
|
|
5237 |
R.unmousedown(drag[i].start);
|
|
|
5238 |
drag.splice(i++, 1);
|
|
|
5239 |
eve.unbind("drag.*." + this.id);
|
|
|
5240 |
}
|
|
|
5241 |
!drag.length && R.unmousemove(dragMove).unmouseup(dragUp);
|
|
|
5242 |
};
|
|
|
5243 |
|
|
|
5244 |
paperproto.circle = function (x, y, r) {
|
|
|
5245 |
var out = R._engine.circle(this, x || 0, y || 0, r || 0);
|
|
|
5246 |
this.__set__ && this.__set__.push(out);
|
|
|
5247 |
return out;
|
|
|
5248 |
};
|
|
|
5249 |
|
|
|
5250 |
paperproto.rect = function (x, y, w, h, r) {
|
|
|
5251 |
var out = R._engine.rect(this, x || 0, y || 0, w || 0, h || 0, r || 0);
|
|
|
5252 |
this.__set__ && this.__set__.push(out);
|
|
|
5253 |
return out;
|
|
|
5254 |
};
|
|
|
5255 |
|
|
|
5256 |
paperproto.ellipse = function (x, y, rx, ry) {
|
|
|
5257 |
var out = R._engine.ellipse(this, x || 0, y || 0, rx || 0, ry || 0);
|
|
|
5258 |
this.__set__ && this.__set__.push(out);
|
|
|
5259 |
return out;
|
|
|
5260 |
};
|
|
|
5261 |
|
|
|
5262 |
paperproto.path = function (pathString) {
|
|
|
5263 |
pathString && !R.is(pathString, string) && !R.is(pathString[0], array) && (pathString += E);
|
|
|
5264 |
var out = R._engine.path(R.format[apply](R, arguments), this);
|
|
|
5265 |
this.__set__ && this.__set__.push(out);
|
|
|
5266 |
return out;
|
|
|
5267 |
};
|
|
|
5268 |
|
|
|
5269 |
paperproto.image = function (src, x, y, w, h) {
|
|
|
5270 |
var out = R._engine.image(this, src || "about:blank", x || 0, y || 0, w || 0, h || 0);
|
|
|
5271 |
this.__set__ && this.__set__.push(out);
|
|
|
5272 |
return out;
|
|
|
5273 |
};
|
|
|
5274 |
|
|
|
5275 |
paperproto.text = function (x, y, text) {
|
|
|
5276 |
var out = R._engine.text(this, x || 0, y || 0, Str(text));
|
|
|
5277 |
this.__set__ && this.__set__.push(out);
|
|
|
5278 |
return out;
|
|
|
5279 |
};
|
|
|
5280 |
|
|
|
5281 |
paperproto.set = function (itemsArray) {
|
|
|
5282 |
!R.is(itemsArray, "array") && (itemsArray = Array.prototype.splice.call(arguments, 0, arguments.length));
|
|
|
5283 |
var out = new Set(itemsArray);
|
|
|
5284 |
this.__set__ && this.__set__.push(out);
|
|
|
5285 |
return out;
|
|
|
5286 |
};
|
|
|
5287 |
|
|
|
5288 |
paperproto.setStart = function (set) {
|
|
|
5289 |
this.__set__ = set || this.set();
|
|
|
5290 |
};
|
|
|
5291 |
|
|
|
5292 |
paperproto.setFinish = function (set) {
|
|
|
5293 |
var out = this.__set__;
|
|
|
5294 |
delete this.__set__;
|
|
|
5295 |
return out;
|
|
|
5296 |
};
|
|
|
5297 |
|
|
|
5298 |
paperproto.setSize = function (width, height) {
|
|
|
5299 |
return R._engine.setSize.call(this, width, height);
|
|
|
5300 |
};
|
|
|
5301 |
|
|
|
5302 |
paperproto.setViewBox = function (x, y, w, h, fit) {
|
|
|
5303 |
return R._engine.setViewBox.call(this, x, y, w, h, fit);
|
|
|
5304 |
};
|
|
|
5305 |
|
|
|
5306 |
|
|
|
5307 |
paperproto.top = paperproto.bottom = null;
|
|
|
5308 |
|
|
|
5309 |
paperproto.raphael = R;
|
|
|
5310 |
var getOffset = function (elem) {
|
|
|
5311 |
var box = elem.getBoundingClientRect(),
|
|
|
5312 |
doc = elem.ownerDocument,
|
|
|
5313 |
body = doc.body,
|
|
|
5314 |
docElem = doc.documentElement,
|
|
|
5315 |
clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
|
|
|
5316 |
top = box.top + (g.win.pageYOffset || docElem.scrollTop || body.scrollTop ) - clientTop,
|
|
|
5317 |
left = box.left + (g.win.pageXOffset || docElem.scrollLeft || body.scrollLeft) - clientLeft;
|
|
|
5318 |
return {
|
|
|
5319 |
y: top,
|
|
|
5320 |
x: left
|
|
|
5321 |
};
|
|
|
5322 |
};
|
|
|
5323 |
|
|
|
5324 |
paperproto.getElementByPoint = function (x, y) {
|
|
|
5325 |
var paper = this,
|
|
|
5326 |
svg = paper.canvas,
|
|
|
5327 |
target = g.doc.elementFromPoint(x, y);
|
|
|
5328 |
if (g.win.opera && target.tagName == "svg") {
|
|
|
5329 |
var so = getOffset(svg),
|
|
|
5330 |
sr = svg.createSVGRect();
|
|
|
5331 |
sr.x = x - so.x;
|
|
|
5332 |
sr.y = y - so.y;
|
|
|
5333 |
sr.width = sr.height = 1;
|
|
|
5334 |
var hits = svg.getIntersectionList(sr, null);
|
|
|
5335 |
if (hits.length) {
|
|
|
5336 |
target = hits[hits.length - 1];
|
|
|
5337 |
}
|
|
|
5338 |
}
|
|
|
5339 |
if (!target) {
|
|
|
5340 |
return null;
|
|
|
5341 |
}
|
|
|
5342 |
while (target.parentNode && target != svg.parentNode && !target.raphael) {
|
|
|
5343 |
target = target.parentNode;
|
|
|
5344 |
}
|
|
|
5345 |
target == paper.canvas.parentNode && (target = svg);
|
|
|
5346 |
target = target && target.raphael ? paper.getById(target.raphaelid) : null;
|
|
|
5347 |
return target;
|
|
|
5348 |
};
|
|
|
5349 |
|
|
|
5350 |
paperproto.getById = function (id) {
|
|
|
5351 |
var bot = this.bottom;
|
|
|
5352 |
while (bot) {
|
|
|
5353 |
if (bot.id == id) {
|
|
|
5354 |
return bot;
|
|
|
5355 |
}
|
|
|
5356 |
bot = bot.next;
|
|
|
5357 |
}
|
|
|
5358 |
return null;
|
|
|
5359 |
};
|
|
|
5360 |
|
|
|
5361 |
paperproto.forEach = function (callback, thisArg) {
|
|
|
5362 |
var bot = this.bottom;
|
|
|
5363 |
while (bot) {
|
|
|
5364 |
if (callback.call(thisArg, bot) === false) {
|
|
|
5365 |
return this;
|
|
|
5366 |
}
|
|
|
5367 |
bot = bot.next;
|
|
|
5368 |
}
|
|
|
5369 |
return this;
|
|
|
5370 |
};
|
|
|
5371 |
function x_y() {
|
|
|
5372 |
return this.x + S + this.y;
|
|
|
5373 |
}
|
|
|
5374 |
function x_y_w_h() {
|
|
|
5375 |
return this.x + S + this.y + S + this.width + " \xd7 " + this.height;
|
|
|
5376 |
}
|
|
|
5377 |
|
|
|
5378 |
elproto.getBBox = function (isWithoutTransform) {
|
|
|
5379 |
if (this.removed) {
|
|
|
5380 |
return {};
|
|
|
5381 |
}
|
|
|
5382 |
var _ = this._;
|
|
|
5383 |
if (isWithoutTransform) {
|
|
|
5384 |
if (_.dirty || !_.bboxwt) {
|
|
|
5385 |
this.realPath = getPath[this.type](this);
|
|
|
5386 |
_.bboxwt = pathDimensions(this.realPath);
|
|
|
5387 |
_.bboxwt.toString = x_y_w_h;
|
|
|
5388 |
_.dirty = 0;
|
|
|
5389 |
}
|
|
|
5390 |
return _.bboxwt;
|
|
|
5391 |
}
|
|
|
5392 |
if (_.dirty || _.dirtyT || !_.bbox) {
|
|
|
5393 |
if (_.dirty || !this.realPath) {
|
|
|
5394 |
_.bboxwt = 0;
|
|
|
5395 |
this.realPath = getPath[this.type](this);
|
|
|
5396 |
}
|
|
|
5397 |
_.bbox = pathDimensions(mapPath(this.realPath, this.matrix));
|
|
|
5398 |
_.bbox.toString = x_y_w_h;
|
|
|
5399 |
_.dirty = _.dirtyT = 0;
|
|
|
5400 |
}
|
|
|
5401 |
return _.bbox;
|
|
|
5402 |
};
|
|
|
5403 |
|
|
|
5404 |
elproto.clone = function () {
|
|
|
5405 |
if (this.removed) {
|
|
|
5406 |
return null;
|
|
|
5407 |
}
|
|
|
5408 |
var out = this.paper[this.type]().attr(this.attr());
|
|
|
5409 |
this.__set__ && this.__set__.push(out);
|
|
|
5410 |
return out;
|
|
|
5411 |
};
|
|
|
5412 |
|
|
|
5413 |
elproto.glow = function (glow) {
|
|
|
5414 |
if (this.type == "text") {
|
|
|
5415 |
return null;
|
|
|
5416 |
}
|
|
|
5417 |
glow = glow || {};
|
|
|
5418 |
var s = {
|
|
|
5419 |
width: (glow.width || 10) + (+this.attr("stroke-width") || 1),
|
|
|
5420 |
fill: glow.fill || false,
|
|
|
5421 |
opacity: glow.opacity || .5,
|
|
|
5422 |
offsetx: glow.offsetx || 0,
|
|
|
5423 |
offsety: glow.offsety || 0,
|
|
|
5424 |
color: glow.color || "#000"
|
|
|
5425 |
},
|
|
|
5426 |
c = s.width / 2,
|
|
|
5427 |
r = this.paper,
|
|
|
5428 |
out = r.set(),
|
|
|
5429 |
path = this.realPath || getPath[this.type](this);
|
|
|
5430 |
path = this.matrix ? mapPath(path, this.matrix) : path;
|
|
|
5431 |
for (var i = 1; i < c + 1; i++) {
|
|
|
5432 |
out.push(r.path(path).attr({
|
|
|
5433 |
stroke: s.color,
|
|
|
5434 |
fill: s.fill ? s.color : "none",
|
|
|
5435 |
"stroke-linejoin": "round",
|
|
|
5436 |
"stroke-linecap": "round",
|
|
|
5437 |
"stroke-width": +(s.width / c * i).toFixed(3),
|
|
|
5438 |
opacity: +(s.opacity / c).toFixed(3)
|
|
|
5439 |
}));
|
|
|
5440 |
}
|
|
|
5441 |
return out.insertBefore(this).translate(s.offsetx, s.offsety);
|
|
|
5442 |
};
|
|
|
5443 |
var curveslengths = {},
|
|
|
5444 |
getPointAtSegmentLength = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length) {
|
|
|
5445 |
var len = 0,
|
|
|
5446 |
precision = 100,
|
|
|
5447 |
name = [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y].join(),
|
|
|
5448 |
cache = curveslengths[name],
|
|
|
5449 |
old, dot;
|
|
|
5450 |
!cache && (curveslengths[name] = cache = {data: []});
|
|
|
5451 |
cache.timer && clearTimeout(cache.timer);
|
|
|
5452 |
cache.timer = setTimeout(function () {delete curveslengths[name];}, 2e3);
|
|
|
5453 |
if (length != null && !cache.precision) {
|
|
|
5454 |
var total = getPointAtSegmentLength(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y);
|
|
|
5455 |
cache.precision = ~~total * 10;
|
|
|
5456 |
cache.data = [];
|
|
|
5457 |
}
|
|
|
5458 |
precision = cache.precision || precision;
|
|
|
5459 |
for (var i = 0; i < precision + 1; i++) {
|
|
|
5460 |
if (cache.data[i * precision]) {
|
|
|
5461 |
dot = cache.data[i * precision];
|
|
|
5462 |
} else {
|
|
|
5463 |
dot = R.findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, i / precision);
|
|
|
5464 |
cache.data[i * precision] = dot;
|
|
|
5465 |
}
|
|
|
5466 |
i && (len += pow(pow(old.x - dot.x, 2) + pow(old.y - dot.y, 2), .5));
|
|
|
5467 |
if (length != null && len >= length) {
|
|
|
5468 |
return dot;
|
|
|
5469 |
}
|
|
|
5470 |
old = dot;
|
|
|
5471 |
}
|
|
|
5472 |
if (length == null) {
|
|
|
5473 |
return len;
|
|
|
5474 |
}
|
|
|
5475 |
},
|
|
|
5476 |
getLengthFactory = function (istotal, subpath) {
|
|
|
5477 |
return function (path, length, onlystart) {
|
|
|
5478 |
path = path2curve(path);
|
|
|
5479 |
var x, y, p, l, sp = "", subpaths = {}, point,
|
|
|
5480 |
len = 0;
|
|
|
5481 |
for (var i = 0, ii = path.length; i < ii; i++) {
|
|
|
5482 |
p = path[i];
|
|
|
5483 |
if (p[0] == "M") {
|
|
|
5484 |
x = +p[1];
|
|
|
5485 |
y = +p[2];
|
|
|
5486 |
} else {
|
|
|
5487 |
l = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);
|
|
|
5488 |
if (len + l > length) {
|
|
|
5489 |
if (subpath && !subpaths.start) {
|
|
|
5490 |
point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len);
|
|
|
5491 |
sp += ["C" + point.start.x, point.start.y, point.m.x, point.m.y, point.x, point.y];
|
|
|
5492 |
if (onlystart) {return sp;}
|
|
|
5493 |
subpaths.start = sp;
|
|
|
5494 |
sp = ["M" + point.x, point.y + "C" + point.n.x, point.n.y, point.end.x, point.end.y, p[5], p[6]].join();
|
|
|
5495 |
len += l;
|
|
|
5496 |
x = +p[5];
|
|
|
5497 |
y = +p[6];
|
|
|
5498 |
continue;
|
|
|
5499 |
}
|
|
|
5500 |
if (!istotal && !subpath) {
|
|
|
5501 |
point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len);
|
|
|
5502 |
return {x: point.x, y: point.y, alpha: point.alpha};
|
|
|
5503 |
}
|
|
|
5504 |
}
|
|
|
5505 |
len += l;
|
|
|
5506 |
x = +p[5];
|
|
|
5507 |
y = +p[6];
|
|
|
5508 |
}
|
|
|
5509 |
sp += p.shift() + p;
|
|
|
5510 |
}
|
|
|
5511 |
subpaths.end = sp;
|
|
|
5512 |
point = istotal ? len : subpath ? subpaths : R.findDotsAtSegment(x, y, p[0], p[1], p[2], p[3], p[4], p[5], 1);
|
|
|
5513 |
point.alpha && (point = {x: point.x, y: point.y, alpha: point.alpha});
|
|
|
5514 |
return point;
|
|
|
5515 |
};
|
|
|
5516 |
};
|
|
|
5517 |
var getTotalLength = getLengthFactory(1),
|
|
|
5518 |
getPointAtLength = getLengthFactory(),
|
|
|
5519 |
getSubpathsAtLength = getLengthFactory(0, 1);
|
|
|
5520 |
|
|
|
5521 |
R.getTotalLength = getTotalLength;
|
|
|
5522 |
|
|
|
5523 |
R.getPointAtLength = getPointAtLength;
|
|
|
5524 |
|
|
|
5525 |
R.getSubpath = function (path, from, to) {
|
|
|
5526 |
if (this.getTotalLength(path) - to < 1e-6) {
|
|
|
5527 |
return getSubpathsAtLength(path, from).end;
|
|
|
5528 |
}
|
|
|
5529 |
var a = getSubpathsAtLength(path, to, 1);
|
|
|
5530 |
return from ? getSubpathsAtLength(a, from).end : a;
|
|
|
5531 |
};
|
|
|
5532 |
|
|
|
5533 |
elproto.getTotalLength = function () {
|
|
|
5534 |
if (this.type != "path") {return;}
|
|
|
5535 |
if (this.node.getTotalLength) {
|
|
|
5536 |
return this.node.getTotalLength();
|
|
|
5537 |
}
|
|
|
5538 |
return getTotalLength(this.attrs.path);
|
|
|
5539 |
};
|
|
|
5540 |
|
|
|
5541 |
elproto.getPointAtLength = function (length) {
|
|
|
5542 |
if (this.type != "path") {return;}
|
|
|
5543 |
return getPointAtLength(this.attrs.path, length);
|
|
|
5544 |
};
|
|
|
5545 |
|
|
|
5546 |
elproto.getSubpath = function (from, to) {
|
|
|
5547 |
if (this.type != "path") {return;}
|
|
|
5548 |
return R.getSubpath(this.attrs.path, from, to);
|
|
|
5549 |
};
|
|
|
5550 |
|
|
|
5551 |
var ef = R.easing_formulas = {
|
|
|
5552 |
linear: function (n) {
|
|
|
5553 |
return n;
|
|
|
5554 |
},
|
|
|
5555 |
"<": function (n) {
|
|
|
5556 |
return pow(n, 1.7);
|
|
|
5557 |
},
|
|
|
5558 |
">": function (n) {
|
|
|
5559 |
return pow(n, .48);
|
|
|
5560 |
},
|
|
|
5561 |
"<>": function (n) {
|
|
|
5562 |
var q = .48 - n / 1.04,
|
|
|
5563 |
Q = math.sqrt(.1734 + q * q),
|
|
|
5564 |
x = Q - q,
|
|
|
5565 |
X = pow(abs(x), 1 / 3) * (x < 0 ? -1 : 1),
|
|
|
5566 |
y = -Q - q,
|
|
|
5567 |
Y = pow(abs(y), 1 / 3) * (y < 0 ? -1 : 1),
|
|
|
5568 |
t = X + Y + .5;
|
|
|
5569 |
return (1 - t) * 3 * t * t + t * t * t;
|
|
|
5570 |
},
|
|
|
5571 |
backIn: function (n) {
|
|
|
5572 |
var s = 1.70158;
|
|
|
5573 |
return n * n * ((s + 1) * n - s);
|
|
|
5574 |
},
|
|
|
5575 |
backOut: function (n) {
|
|
|
5576 |
n = n - 1;
|
|
|
5577 |
var s = 1.70158;
|
|
|
5578 |
return n * n * ((s + 1) * n + s) + 1;
|
|
|
5579 |
},
|
|
|
5580 |
elastic: function (n) {
|
|
|
5581 |
if (n == !!n) {
|
|
|
5582 |
return n;
|
|
|
5583 |
}
|
|
|
5584 |
return pow(2, -10 * n) * math.sin((n - .075) * (2 * PI) / .3) + 1;
|
|
|
5585 |
},
|
|
|
5586 |
bounce: function (n) {
|
|
|
5587 |
var s = 7.5625,
|
|
|
5588 |
p = 2.75,
|
|
|
5589 |
l;
|
|
|
5590 |
if (n < (1 / p)) {
|
|
|
5591 |
l = s * n * n;
|
|
|
5592 |
} else {
|
|
|
5593 |
if (n < (2 / p)) {
|
|
|
5594 |
n -= (1.5 / p);
|
|
|
5595 |
l = s * n * n + .75;
|
|
|
5596 |
} else {
|
|
|
5597 |
if (n < (2.5 / p)) {
|
|
|
5598 |
n -= (2.25 / p);
|
|
|
5599 |
l = s * n * n + .9375;
|
|
|
5600 |
} else {
|
|
|
5601 |
n -= (2.625 / p);
|
|
|
5602 |
l = s * n * n + .984375;
|
|
|
5603 |
}
|
|
|
5604 |
}
|
|
|
5605 |
}
|
|
|
5606 |
return l;
|
|
|
5607 |
}
|
|
|
5608 |
};
|
|
|
5609 |
ef.easeIn = ef["ease-in"] = ef["<"];
|
|
|
5610 |
ef.easeOut = ef["ease-out"] = ef[">"];
|
|
|
5611 |
ef.easeInOut = ef["ease-in-out"] = ef["<>"];
|
|
|
5612 |
ef["back-in"] = ef.backIn;
|
|
|
5613 |
ef["back-out"] = ef.backOut;
|
|
|
5614 |
|
|
|
5615 |
var animationElements = [],
|
|
|
5616 |
requestAnimFrame = window.requestAnimationFrame ||
|
|
|
5617 |
window.webkitRequestAnimationFrame ||
|
|
|
5618 |
window.mozRequestAnimationFrame ||
|
|
|
5619 |
window.oRequestAnimationFrame ||
|
|
|
5620 |
window.msRequestAnimationFrame ||
|
|
|
5621 |
function (callback) {
|
|
|
5622 |
setTimeout(callback, 16);
|
|
|
5623 |
},
|
|
|
5624 |
animation = function () {
|
|
|
5625 |
var Now = +new Date,
|
|
|
5626 |
l = 0;
|
|
|
5627 |
for (; l < animationElements.length; l++) {
|
|
|
5628 |
var e = animationElements[l];
|
|
|
5629 |
if (e.el.removed || e.paused) {
|
|
|
5630 |
continue;
|
|
|
5631 |
}
|
|
|
5632 |
var time = Now - e.start,
|
|
|
5633 |
ms = e.ms,
|
|
|
5634 |
easing = e.easing,
|
|
|
5635 |
from = e.from,
|
|
|
5636 |
diff = e.diff,
|
|
|
5637 |
to = e.to,
|
|
|
5638 |
t = e.t,
|
|
|
5639 |
that = e.el,
|
|
|
5640 |
set = {},
|
|
|
5641 |
now,
|
|
|
5642 |
init = {},
|
|
|
5643 |
key;
|
|
|
5644 |
if (e.initstatus) {
|
|
|
5645 |
time = (e.initstatus * e.anim.top - e.prev) / (e.percent - e.prev) * ms;
|
|
|
5646 |
e.status = e.initstatus;
|
|
|
5647 |
delete e.initstatus;
|
|
|
5648 |
e.stop && animationElements.splice(l--, 1);
|
|
|
5649 |
} else {
|
|
|
5650 |
e.status = (e.prev + (e.percent - e.prev) * (time / ms)) / e.anim.top;
|
|
|
5651 |
}
|
|
|
5652 |
if (time < 0) {
|
|
|
5653 |
continue;
|
|
|
5654 |
}
|
|
|
5655 |
if (time < ms) {
|
|
|
5656 |
var pos = easing(time / ms);
|
|
|
5657 |
for (var attr in from) if (from[has](attr)) {
|
|
|
5658 |
switch (availableAnimAttrs[attr]) {
|
|
|
5659 |
case nu:
|
|
|
5660 |
now = +from[attr] + pos * ms * diff[attr];
|
|
|
5661 |
break;
|
|
|
5662 |
case "colour":
|
|
|
5663 |
now = "rgb(" + [
|
|
|
5664 |
upto255(round(from[attr].r + pos * ms * diff[attr].r)),
|
|
|
5665 |
upto255(round(from[attr].g + pos * ms * diff[attr].g)),
|
|
|
5666 |
upto255(round(from[attr].b + pos * ms * diff[attr].b))
|
|
|
5667 |
].join(",") + ")";
|
|
|
5668 |
break;
|
|
|
5669 |
case "path":
|
|
|
5670 |
now = [];
|
|
|
5671 |
for (var i = 0, ii = from[attr].length; i < ii; i++) {
|
|
|
5672 |
now[i] = [from[attr][i][0]];
|
|
|
5673 |
for (var j = 1, jj = from[attr][i].length; j < jj; j++) {
|
|
|
5674 |
now[i][j] = +from[attr][i][j] + pos * ms * diff[attr][i][j];
|
|
|
5675 |
}
|
|
|
5676 |
now[i] = now[i].join(S);
|
|
|
5677 |
}
|
|
|
5678 |
now = now.join(S);
|
|
|
5679 |
break;
|
|
|
5680 |
case "transform":
|
|
|
5681 |
if (diff[attr].real) {
|
|
|
5682 |
now = [];
|
|
|
5683 |
for (i = 0, ii = from[attr].length; i < ii; i++) {
|
|
|
5684 |
now[i] = [from[attr][i][0]];
|
|
|
5685 |
for (j = 1, jj = from[attr][i].length; j < jj; j++) {
|
|
|
5686 |
now[i][j] = from[attr][i][j] + pos * ms * diff[attr][i][j];
|
|
|
5687 |
}
|
|
|
5688 |
}
|
|
|
5689 |
} else {
|
|
|
5690 |
var get = function (i) {
|
|
|
5691 |
return +from[attr][i] + pos * ms * diff[attr][i];
|
|
|
5692 |
};
|
|
|
5693 |
// now = [["r", get(2), 0, 0], ["t", get(3), get(4)], ["s", get(0), get(1), 0, 0]];
|
|
|
5694 |
now = [["m", get(0), get(1), get(2), get(3), get(4), get(5)]];
|
|
|
5695 |
}
|
|
|
5696 |
break;
|
|
|
5697 |
case "csv":
|
|
|
5698 |
if (attr == "clip-rect") {
|
|
|
5699 |
now = [];
|
|
|
5700 |
i = 4;
|
|
|
5701 |
while (i--) {
|
|
|
5702 |
now[i] = +from[attr][i] + pos * ms * diff[attr][i];
|
|
|
5703 |
}
|
|
|
5704 |
}
|
|
|
5705 |
break;
|
|
|
5706 |
default:
|
|
|
5707 |
var from2 = [][concat](from[attr]);
|
|
|
5708 |
now = [];
|
|
|
5709 |
i = that.paper.customAttributes[attr].length;
|
|
|
5710 |
while (i--) {
|
|
|
5711 |
now[i] = +from2[i] + pos * ms * diff[attr][i];
|
|
|
5712 |
}
|
|
|
5713 |
break;
|
|
|
5714 |
}
|
|
|
5715 |
set[attr] = now;
|
|
|
5716 |
}
|
|
|
5717 |
that.attr(set);
|
|
|
5718 |
(function (id, that, anim) {
|
|
|
5719 |
setTimeout(function () {
|
|
|
5720 |
eve("anim.frame." + id, that, anim);
|
|
|
5721 |
});
|
|
|
5722 |
})(that.id, that, e.anim);
|
|
|
5723 |
} else {
|
|
|
5724 |
(function(f, el, a) {
|
|
|
5725 |
setTimeout(function() {
|
|
|
5726 |
eve("anim.frame." + el.id, el, a);
|
|
|
5727 |
eve("anim.finish." + el.id, el, a);
|
|
|
5728 |
R.is(f, "function") && f.call(el);
|
|
|
5729 |
});
|
|
|
5730 |
})(e.callback, that, e.anim);
|
|
|
5731 |
that.attr(to);
|
|
|
5732 |
animationElements.splice(l--, 1);
|
|
|
5733 |
if (e.repeat > 1 && !e.next) {
|
|
|
5734 |
for (key in to) if (to[has](key)) {
|
|
|
5735 |
init[key] = e.totalOrigin[key];
|
|
|
5736 |
}
|
|
|
5737 |
e.el.attr(init);
|
|
|
5738 |
runAnimation(e.anim, e.el, e.anim.percents[0], null, e.totalOrigin, e.repeat - 1);
|
|
|
5739 |
}
|
|
|
5740 |
if (e.next && !e.stop) {
|
|
|
5741 |
runAnimation(e.anim, e.el, e.next, null, e.totalOrigin, e.repeat);
|
|
|
5742 |
}
|
|
|
5743 |
}
|
|
|
5744 |
}
|
|
|
5745 |
R.svg && that && that.paper && that.paper.safari();
|
|
|
5746 |
animationElements.length && requestAnimFrame(animation);
|
|
|
5747 |
},
|
|
|
5748 |
upto255 = function (color) {
|
|
|
5749 |
return color > 255 ? 255 : color < 0 ? 0 : color;
|
|
|
5750 |
};
|
|
|
5751 |
|
|
|
5752 |
elproto.animateWith = function (element, anim, params, ms, easing, callback) {
|
|
|
5753 |
var a = params ? R.animation(params, ms, easing, callback) : anim;
|
|
|
5754 |
status = element.status(anim);
|
|
|
5755 |
return this.animate(a).status(a, status * anim.ms / a.ms);
|
|
|
5756 |
};
|
|
|
5757 |
function CubicBezierAtTime(t, p1x, p1y, p2x, p2y, duration) {
|
|
|
5758 |
var cx = 3 * p1x,
|
|
|
5759 |
bx = 3 * (p2x - p1x) - cx,
|
|
|
5760 |
ax = 1 - cx - bx,
|
|
|
5761 |
cy = 3 * p1y,
|
|
|
5762 |
by = 3 * (p2y - p1y) - cy,
|
|
|
5763 |
ay = 1 - cy - by;
|
|
|
5764 |
function sampleCurveX(t) {
|
|
|
5765 |
return ((ax * t + bx) * t + cx) * t;
|
|
|
5766 |
}
|
|
|
5767 |
function solve(x, epsilon) {
|
|
|
5768 |
var t = solveCurveX(x, epsilon);
|
|
|
5769 |
return ((ay * t + by) * t + cy) * t;
|
|
|
5770 |
}
|
|
|
5771 |
function solveCurveX(x, epsilon) {
|
|
|
5772 |
var t0, t1, t2, x2, d2, i;
|
|
|
5773 |
for(t2 = x, i = 0; i < 8; i++) {
|
|
|
5774 |
x2 = sampleCurveX(t2) - x;
|
|
|
5775 |
if (abs(x2) < epsilon) {
|
|
|
5776 |
return t2;
|
|
|
5777 |
}
|
|
|
5778 |
d2 = (3 * ax * t2 + 2 * bx) * t2 + cx;
|
|
|
5779 |
if (abs(d2) < 1e-6) {
|
|
|
5780 |
break;
|
|
|
5781 |
}
|
|
|
5782 |
t2 = t2 - x2 / d2;
|
|
|
5783 |
}
|
|
|
5784 |
t0 = 0;
|
|
|
5785 |
t1 = 1;
|
|
|
5786 |
t2 = x;
|
|
|
5787 |
if (t2 < t0) {
|
|
|
5788 |
return t0;
|
|
|
5789 |
}
|
|
|
5790 |
if (t2 > t1) {
|
|
|
5791 |
return t1;
|
|
|
5792 |
}
|
|
|
5793 |
while (t0 < t1) {
|
|
|
5794 |
x2 = sampleCurveX(t2);
|
|
|
5795 |
if (abs(x2 - x) < epsilon) {
|
|
|
5796 |
return t2;
|
|
|
5797 |
}
|
|
|
5798 |
if (x > x2) {
|
|
|
5799 |
t0 = t2;
|
|
|
5800 |
} else {
|
|
|
5801 |
t1 = t2;
|
|
|
5802 |
}
|
|
|
5803 |
t2 = (t1 - t0) / 2 + t0;
|
|
|
5804 |
}
|
|
|
5805 |
return t2;
|
|
|
5806 |
}
|
|
|
5807 |
return solve(t, 1 / (200 * duration));
|
|
|
5808 |
}
|
|
|
5809 |
elproto.onAnimation = function (f) {
|
|
|
5810 |
f ? eve.on("anim.frame." + this.id, f) : eve.unbind("anim.frame." + this.id);
|
|
|
5811 |
return this;
|
|
|
5812 |
};
|
|
|
5813 |
function Animation(anim, ms) {
|
|
|
5814 |
var percents = [],
|
|
|
5815 |
newAnim = {};
|
|
|
5816 |
this.ms = ms;
|
|
|
5817 |
this.times = 1;
|
|
|
5818 |
if (anim) {
|
|
|
5819 |
for (var attr in anim) if (anim[has](attr)) {
|
|
|
5820 |
newAnim[toFloat(attr)] = anim[attr];
|
|
|
5821 |
percents.push(toFloat(attr));
|
|
|
5822 |
}
|
|
|
5823 |
percents.sort(sortByNumber);
|
|
|
5824 |
}
|
|
|
5825 |
this.anim = newAnim;
|
|
|
5826 |
this.top = percents[percents.length - 1];
|
|
|
5827 |
this.percents = percents;
|
|
|
5828 |
}
|
|
|
5829 |
|
|
|
5830 |
Animation.prototype.delay = function (delay) {
|
|
|
5831 |
var a = new Animation(this.anim, this.ms);
|
|
|
5832 |
a.times = this.times;
|
|
|
5833 |
a.del = +delay || 0;
|
|
|
5834 |
return a;
|
|
|
5835 |
};
|
|
|
5836 |
|
|
|
5837 |
Animation.prototype.repeat = function (times) {
|
|
|
5838 |
var a = new Animation(this.anim, this.ms);
|
|
|
5839 |
a.del = this.del;
|
|
|
5840 |
a.times = math.floor(mmax(times, 0)) || 1;
|
|
|
5841 |
return a;
|
|
|
5842 |
};
|
|
|
5843 |
function runAnimation(anim, element, percent, status, totalOrigin, times) {
|
|
|
5844 |
percent = toFloat(percent);
|
|
|
5845 |
var params,
|
|
|
5846 |
isInAnim,
|
|
|
5847 |
isInAnimSet,
|
|
|
5848 |
percents = [],
|
|
|
5849 |
next,
|
|
|
5850 |
prev,
|
|
|
5851 |
timestamp,
|
|
|
5852 |
ms = anim.ms,
|
|
|
5853 |
from = {},
|
|
|
5854 |
to = {},
|
|
|
5855 |
diff = {};
|
|
|
5856 |
if (status) {
|
|
|
5857 |
for (i = 0, ii = animationElements.length; i < ii; i++) {
|
|
|
5858 |
var e = animationElements[i];
|
|
|
5859 |
if (e.el.id == element.id && e.anim == anim) {
|
|
|
5860 |
if (e.percent != percent) {
|
|
|
5861 |
animationElements.splice(i, 1);
|
|
|
5862 |
isInAnimSet = 1;
|
|
|
5863 |
} else {
|
|
|
5864 |
isInAnim = e;
|
|
|
5865 |
}
|
|
|
5866 |
element.attr(e.totalOrigin);
|
|
|
5867 |
break;
|
|
|
5868 |
}
|
|
|
5869 |
}
|
|
|
5870 |
} else {
|
|
|
5871 |
status = +to; // NaN
|
|
|
5872 |
}
|
|
|
5873 |
for (var i = 0, ii = anim.percents.length; i < ii; i++) {
|
|
|
5874 |
if (anim.percents[i] == percent || anim.percents[i] > status * anim.top) {
|
|
|
5875 |
percent = anim.percents[i];
|
|
|
5876 |
prev = anim.percents[i - 1] || 0;
|
|
|
5877 |
ms = ms / anim.top * (percent - prev);
|
|
|
5878 |
next = anim.percents[i + 1];
|
|
|
5879 |
params = anim.anim[percent];
|
|
|
5880 |
break;
|
|
|
5881 |
} else if (status) {
|
|
|
5882 |
element.attr(anim.anim[anim.percents[i]]);
|
|
|
5883 |
}
|
|
|
5884 |
}
|
|
|
5885 |
if (!params) {
|
|
|
5886 |
return;
|
|
|
5887 |
}
|
|
|
5888 |
if (!isInAnim) {
|
|
|
5889 |
for (attr in params) if (params[has](attr)) {
|
|
|
5890 |
if (availableAnimAttrs[has](attr) || element.paper.customAttributes[has](attr)) {
|
|
|
5891 |
from[attr] = element.attr(attr);
|
|
|
5892 |
(from[attr] == null) && (from[attr] = availableAttrs[attr]);
|
|
|
5893 |
to[attr] = params[attr];
|
|
|
5894 |
switch (availableAnimAttrs[attr]) {
|
|
|
5895 |
case nu:
|
|
|
5896 |
diff[attr] = (to[attr] - from[attr]) / ms;
|
|
|
5897 |
break;
|
|
|
5898 |
case "colour":
|
|
|
5899 |
from[attr] = R.getRGB(from[attr]);
|
|
|
5900 |
var toColour = R.getRGB(to[attr]);
|
|
|
5901 |
diff[attr] = {
|
|
|
5902 |
r: (toColour.r - from[attr].r) / ms,
|
|
|
5903 |
g: (toColour.g - from[attr].g) / ms,
|
|
|
5904 |
b: (toColour.b - from[attr].b) / ms
|
|
|
5905 |
};
|
|
|
5906 |
break;
|
|
|
5907 |
case "path":
|
|
|
5908 |
var pathes = path2curve(from[attr], to[attr]),
|
|
|
5909 |
toPath = pathes[1];
|
|
|
5910 |
from[attr] = pathes[0];
|
|
|
5911 |
diff[attr] = [];
|
|
|
5912 |
for (i = 0, ii = from[attr].length; i < ii; i++) {
|
|
|
5913 |
diff[attr][i] = [0];
|
|
|
5914 |
for (var j = 1, jj = from[attr][i].length; j < jj; j++) {
|
|
|
5915 |
diff[attr][i][j] = (toPath[i][j] - from[attr][i][j]) / ms;
|
|
|
5916 |
}
|
|
|
5917 |
}
|
|
|
5918 |
break;
|
|
|
5919 |
case "transform":
|
|
|
5920 |
var _ = element._,
|
|
|
5921 |
eq = equaliseTransform(_[attr], to[attr]);
|
|
|
5922 |
if (eq) {
|
|
|
5923 |
from[attr] = eq.from;
|
|
|
5924 |
to[attr] = eq.to;
|
|
|
5925 |
diff[attr] = [];
|
|
|
5926 |
diff[attr].real = true;
|
|
|
5927 |
for (i = 0, ii = from[attr].length; i < ii; i++) {
|
|
|
5928 |
diff[attr][i] = [from[attr][i][0]];
|
|
|
5929 |
for (j = 1, jj = from[attr][i].length; j < jj; j++) {
|
|
|
5930 |
diff[attr][i][j] = (to[attr][i][j] - from[attr][i][j]) / ms;
|
|
|
5931 |
}
|
|
|
5932 |
}
|
|
|
5933 |
} else {
|
|
|
5934 |
var m = (element.matrix || new Matrix),
|
|
|
5935 |
to2 = {
|
|
|
5936 |
_: {transform: _.transform},
|
|
|
5937 |
getBBox: function () {
|
|
|
5938 |
return element.getBBox(1);
|
|
|
5939 |
}
|
|
|
5940 |
};
|
|
|
5941 |
from[attr] = [
|
|
|
5942 |
m.a,
|
|
|
5943 |
m.b,
|
|
|
5944 |
m.c,
|
|
|
5945 |
m.d,
|
|
|
5946 |
m.e,
|
|
|
5947 |
m.f
|
|
|
5948 |
];
|
|
|
5949 |
extractTransform(to2, to[attr]);
|
|
|
5950 |
to[attr] = to2._.transform;
|
|
|
5951 |
diff[attr] = [
|
|
|
5952 |
(to2.matrix.a - m.a) / ms,
|
|
|
5953 |
(to2.matrix.b - m.b) / ms,
|
|
|
5954 |
(to2.matrix.c - m.c) / ms,
|
|
|
5955 |
(to2.matrix.d - m.d) / ms,
|
|
|
5956 |
(to2.matrix.e - m.e) / ms,
|
|
|
5957 |
(to2.matrix.e - m.f) / ms
|
|
|
5958 |
];
|
|
|
5959 |
// from[attr] = [_.sx, _.sy, _.deg, _.dx, _.dy];
|
|
|
5960 |
// var to2 = {_:{}, getBBox: function () { return element.getBBox(); }};
|
|
|
5961 |
// extractTransform(to2, to[attr]);
|
|
|
5962 |
// diff[attr] = [
|
|
|
5963 |
// (to2._.sx - _.sx) / ms,
|
|
|
5964 |
// (to2._.sy - _.sy) / ms,
|
|
|
5965 |
// (to2._.deg - _.deg) / ms,
|
|
|
5966 |
// (to2._.dx - _.dx) / ms,
|
|
|
5967 |
// (to2._.dy - _.dy) / ms
|
|
|
5968 |
// ];
|
|
|
5969 |
}
|
|
|
5970 |
break;
|
|
|
5971 |
case "csv":
|
|
|
5972 |
var values = Str(params[attr])[split](separator),
|
|
|
5973 |
from2 = Str(from[attr])[split](separator);
|
|
|
5974 |
if (attr == "clip-rect") {
|
|
|
5975 |
from[attr] = from2;
|
|
|
5976 |
diff[attr] = [];
|
|
|
5977 |
i = from2.length;
|
|
|
5978 |
while (i--) {
|
|
|
5979 |
diff[attr][i] = (values[i] - from[attr][i]) / ms;
|
|
|
5980 |
}
|
|
|
5981 |
}
|
|
|
5982 |
to[attr] = values;
|
|
|
5983 |
break;
|
|
|
5984 |
default:
|
|
|
5985 |
values = [][concat](params[attr]);
|
|
|
5986 |
from2 = [][concat](from[attr]);
|
|
|
5987 |
diff[attr] = [];
|
|
|
5988 |
i = element.paper.customAttributes[attr].length;
|
|
|
5989 |
while (i--) {
|
|
|
5990 |
diff[attr][i] = ((values[i] || 0) - (from2[i] || 0)) / ms;
|
|
|
5991 |
}
|
|
|
5992 |
break;
|
|
|
5993 |
}
|
|
|
5994 |
}
|
|
|
5995 |
}
|
|
|
5996 |
var easing = params.easing,
|
|
|
5997 |
easyeasy = R.easing_formulas[easing];
|
|
|
5998 |
if (!easyeasy) {
|
|
|
5999 |
easyeasy = Str(easing).match(bezierrg);
|
|
|
6000 |
if (easyeasy && easyeasy.length == 5) {
|
|
|
6001 |
var curve = easyeasy;
|
|
|
6002 |
easyeasy = function (t) {
|
|
|
6003 |
return CubicBezierAtTime(t, +curve[1], +curve[2], +curve[3], +curve[4], ms);
|
|
|
6004 |
};
|
|
|
6005 |
} else {
|
|
|
6006 |
easyeasy = pipe;
|
|
|
6007 |
}
|
|
|
6008 |
}
|
|
|
6009 |
timestamp = params.start || anim.start || +new Date;
|
|
|
6010 |
e = {
|
|
|
6011 |
anim: anim,
|
|
|
6012 |
percent: percent,
|
|
|
6013 |
timestamp: timestamp,
|
|
|
6014 |
start: timestamp + (anim.del || 0),
|
|
|
6015 |
status: 0,
|
|
|
6016 |
initstatus: status || 0,
|
|
|
6017 |
stop: false,
|
|
|
6018 |
ms: ms,
|
|
|
6019 |
easing: easyeasy,
|
|
|
6020 |
from: from,
|
|
|
6021 |
diff: diff,
|
|
|
6022 |
to: to,
|
|
|
6023 |
el: element,
|
|
|
6024 |
callback: params.callback,
|
|
|
6025 |
prev: prev,
|
|
|
6026 |
next: next,
|
|
|
6027 |
repeat: times || anim.times,
|
|
|
6028 |
origin: element.attr(),
|
|
|
6029 |
totalOrigin: totalOrigin
|
|
|
6030 |
};
|
|
|
6031 |
animationElements.push(e);
|
|
|
6032 |
if (status && !isInAnim && !isInAnimSet) {
|
|
|
6033 |
e.stop = true;
|
|
|
6034 |
e.start = new Date - ms * status;
|
|
|
6035 |
if (animationElements.length == 1) {
|
|
|
6036 |
return animation();
|
|
|
6037 |
}
|
|
|
6038 |
}
|
|
|
6039 |
if (isInAnimSet) {
|
|
|
6040 |
e.start = new Date - e.ms * status;
|
|
|
6041 |
}
|
|
|
6042 |
animationElements.length == 1 && requestAnimFrame(animation);
|
|
|
6043 |
} else {
|
|
|
6044 |
isInAnim.initstatus = status;
|
|
|
6045 |
isInAnim.start = new Date - isInAnim.ms * status;
|
|
|
6046 |
}
|
|
|
6047 |
eve("anim.start." + element.id, element, anim);
|
|
|
6048 |
}
|
|
|
6049 |
|
|
|
6050 |
R.animation = function (params, ms, easing, callback) {
|
|
|
6051 |
if (params instanceof Animation) {
|
|
|
6052 |
return params;
|
|
|
6053 |
}
|
|
|
6054 |
if (R.is(easing, "function") || !easing) {
|
|
|
6055 |
callback = callback || easing || null;
|
|
|
6056 |
easing = null;
|
|
|
6057 |
}
|
|
|
6058 |
params = Object(params);
|
|
|
6059 |
ms = +ms || 0;
|
|
|
6060 |
var p = {},
|
|
|
6061 |
json,
|
|
|
6062 |
attr;
|
|
|
6063 |
for (attr in params) if (params[has](attr) && toFloat(attr) != attr && toFloat(attr) + "%" != attr) {
|
|
|
6064 |
json = true;
|
|
|
6065 |
p[attr] = params[attr];
|
|
|
6066 |
}
|
|
|
6067 |
if (!json) {
|
|
|
6068 |
return new Animation(params, ms);
|
|
|
6069 |
} else {
|
|
|
6070 |
easing && (p.easing = easing);
|
|
|
6071 |
callback && (p.callback = callback);
|
|
|
6072 |
return new Animation({100: p}, ms);
|
|
|
6073 |
}
|
|
|
6074 |
};
|
|
|
6075 |
|
|
|
6076 |
elproto.animate = function (params, ms, easing, callback) {
|
|
|
6077 |
var element = this;
|
|
|
6078 |
if (element.removed) {
|
|
|
6079 |
callback && callback.call(element);
|
|
|
6080 |
return element;
|
|
|
6081 |
}
|
|
|
6082 |
var anim = params instanceof Animation ? params : R.animation(params, ms, easing, callback);
|
|
|
6083 |
runAnimation(anim, element, anim.percents[0], null, element.attr());
|
|
|
6084 |
return element;
|
|
|
6085 |
};
|
|
|
6086 |
|
|
|
6087 |
elproto.setTime = function (anim, value) {
|
|
|
6088 |
if (anim && value != null) {
|
|
|
6089 |
this.status(anim, mmin(value, anim.ms) / anim.ms);
|
|
|
6090 |
}
|
|
|
6091 |
return this;
|
|
|
6092 |
};
|
|
|
6093 |
|
|
|
6094 |
elproto.status = function (anim, value) {
|
|
|
6095 |
var out = [],
|
|
|
6096 |
i = 0,
|
|
|
6097 |
len,
|
|
|
6098 |
e;
|
|
|
6099 |
if (value != null) {
|
|
|
6100 |
runAnimation(anim, this, -1, mmin(value, 1));
|
|
|
6101 |
return this;
|
|
|
6102 |
} else {
|
|
|
6103 |
len = animationElements.length;
|
|
|
6104 |
for (; i < len; i++) {
|
|
|
6105 |
e = animationElements[i];
|
|
|
6106 |
if (e.el.id == this.id && (!anim || e.anim == anim)) {
|
|
|
6107 |
if (anim) {
|
|
|
6108 |
return e.status;
|
|
|
6109 |
}
|
|
|
6110 |
out.push({
|
|
|
6111 |
anim: e.anim,
|
|
|
6112 |
status: e.status
|
|
|
6113 |
});
|
|
|
6114 |
}
|
|
|
6115 |
}
|
|
|
6116 |
if (anim) {
|
|
|
6117 |
return 0;
|
|
|
6118 |
}
|
|
|
6119 |
return out;
|
|
|
6120 |
}
|
|
|
6121 |
};
|
|
|
6122 |
|
|
|
6123 |
elproto.pause = function (anim) {
|
|
|
6124 |
for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.id == this.id && (!anim || animationElements[i].anim == anim)) {
|
|
|
6125 |
if (eve("anim.pause." + this.id, this, animationElements[i].anim) !== false) {
|
|
|
6126 |
animationElements[i].paused = true;
|
|
|
6127 |
}
|
|
|
6128 |
}
|
|
|
6129 |
return this;
|
|
|
6130 |
};
|
|
|
6131 |
|
|
|
6132 |
elproto.resume = function (anim) {
|
|
|
6133 |
for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.id == this.id && (!anim || animationElements[i].anim == anim)) {
|
|
|
6134 |
var e = animationElements[i];
|
|
|
6135 |
if (eve("anim.resume." + this.id, this, e.anim) !== false) {
|
|
|
6136 |
delete e.paused;
|
|
|
6137 |
this.status(e.anim, e.status);
|
|
|
6138 |
}
|
|
|
6139 |
}
|
|
|
6140 |
return this;
|
|
|
6141 |
};
|
|
|
6142 |
|
|
|
6143 |
elproto.stop = function (anim) {
|
|
|
6144 |
for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.id == this.id && (!anim || animationElements[i].anim == anim)) {
|
|
|
6145 |
if (eve("anim.stop." + this.id, this, animationElements[i].anim) !== false) {
|
|
|
6146 |
animationElements.splice(i--, 1);
|
|
|
6147 |
}
|
|
|
6148 |
}
|
|
|
6149 |
return this;
|
|
|
6150 |
};
|
|
|
6151 |
elproto.toString = function () {
|
|
|
6152 |
return "Rapha\xebl\u2019s object";
|
|
|
6153 |
};
|
|
|
6154 |
|
|
|
6155 |
// Set
|
|
|
6156 |
var Set = function (items) {
|
|
|
6157 |
this.items = [];
|
|
|
6158 |
this.length = 0;
|
|
|
6159 |
this.type = "set";
|
|
|
6160 |
if (items) {
|
|
|
6161 |
for (var i = 0, ii = items.length; i < ii; i++) {
|
|
|
6162 |
if (items[i] && (items[i].constructor == elproto.constructor || items[i].constructor == Set)) {
|
|
|
6163 |
this[this.items.length] = this.items[this.items.length] = items[i];
|
|
|
6164 |
this.length++;
|
|
|
6165 |
}
|
|
|
6166 |
}
|
|
|
6167 |
}
|
|
|
6168 |
},
|
|
|
6169 |
setproto = Set.prototype;
|
|
|
6170 |
|
|
|
6171 |
setproto.push = function () {
|
|
|
6172 |
var item,
|
|
|
6173 |
len;
|
|
|
6174 |
for (var i = 0, ii = arguments.length; i < ii; i++) {
|
|
|
6175 |
item = arguments[i];
|
|
|
6176 |
if (item && (item.constructor == elproto.constructor || item.constructor == Set)) {
|
|
|
6177 |
len = this.items.length;
|
|
|
6178 |
this[len] = this.items[len] = item;
|
|
|
6179 |
this.length++;
|
|
|
6180 |
}
|
|
|
6181 |
}
|
|
|
6182 |
return this;
|
|
|
6183 |
};
|
|
|
6184 |
|
|
|
6185 |
setproto.pop = function () {
|
|
|
6186 |
this.length && delete this[this.length--];
|
|
|
6187 |
return this.items.pop();
|
|
|
6188 |
};
|
|
|
6189 |
|
|
|
6190 |
setproto.forEach = function (callback, thisArg) {
|
|
|
6191 |
for (var i = 0, ii = this.items.length; i < ii; i++) {
|
|
|
6192 |
if (callback.call(thisArg, this.items[i], i) === false) {
|
|
|
6193 |
return this;
|
|
|
6194 |
}
|
|
|
6195 |
}
|
|
|
6196 |
return this;
|
|
|
6197 |
};
|
|
|
6198 |
for (var method in elproto) if (elproto[has](method)) {
|
|
|
6199 |
setproto[method] = (function (methodname) {
|
|
|
6200 |
return function () {
|
|
|
6201 |
var arg = arguments;
|
|
|
6202 |
return this.forEach(function (el) {
|
|
|
6203 |
el[methodname][apply](el, arg);
|
|
|
6204 |
});
|
|
|
6205 |
};
|
|
|
6206 |
})(method);
|
|
|
6207 |
}
|
|
|
6208 |
setproto.attr = function (name, value) {
|
|
|
6209 |
if (name && R.is(name, array) && R.is(name[0], "object")) {
|
|
|
6210 |
for (var j = 0, jj = name.length; j < jj; j++) {
|
|
|
6211 |
this.items[j].attr(name[j]);
|
|
|
6212 |
}
|
|
|
6213 |
} else {
|
|
|
6214 |
for (var i = 0, ii = this.items.length; i < ii; i++) {
|
|
|
6215 |
this.items[i].attr(name, value);
|
|
|
6216 |
}
|
|
|
6217 |
}
|
|
|
6218 |
return this;
|
|
|
6219 |
};
|
|
|
6220 |
|
|
|
6221 |
setproto.clear = function () {
|
|
|
6222 |
while (this.length) {
|
|
|
6223 |
this.pop();
|
|
|
6224 |
}
|
|
|
6225 |
};
|
|
|
6226 |
|
|
|
6227 |
setproto.splice = function (index, count, insertion) {
|
|
|
6228 |
index = index < 0 ? mmax(this.length + index, 0) : index;
|
|
|
6229 |
count = mmax(0, mmin(this.length - index, count));
|
|
|
6230 |
var tail = [],
|
|
|
6231 |
todel = [],
|
|
|
6232 |
args = [],
|
|
|
6233 |
i;
|
|
|
6234 |
for (i = 2; i < arguments.length; i++) {
|
|
|
6235 |
args.push(arguments[i]);
|
|
|
6236 |
}
|
|
|
6237 |
for (i = 0; i < count; i++) {
|
|
|
6238 |
todel.push(this[index + i]);
|
|
|
6239 |
}
|
|
|
6240 |
for (; i < this.length - index; i++) {
|
|
|
6241 |
tail.push(this[index + i]);
|
|
|
6242 |
}
|
|
|
6243 |
var arglen = args.length;
|
|
|
6244 |
for (i = 0; i < arglen + tail.length; i++) {
|
|
|
6245 |
this.items[index + i] = this[index + i] = i < arglen ? args[i] : tail[i - arglen];
|
|
|
6246 |
}
|
|
|
6247 |
i = this.items.length = this.length -= count - arglen;
|
|
|
6248 |
while (this[i]) {
|
|
|
6249 |
delete this[i++];
|
|
|
6250 |
}
|
|
|
6251 |
return new Set(todel);
|
|
|
6252 |
};
|
|
|
6253 |
|
|
|
6254 |
setproto.exclude = function (el) {
|
|
|
6255 |
for (var i = 0, ii = this.length; i < ii; i++) if (this[i] == el) {
|
|
|
6256 |
this.splice(i, 1);
|
|
|
6257 |
return true;
|
|
|
6258 |
}
|
|
|
6259 |
};
|
|
|
6260 |
setproto.animate = function (params, ms, easing, callback) {
|
|
|
6261 |
(R.is(easing, "function") || !easing) && (callback = easing || null);
|
|
|
6262 |
var len = this.items.length,
|
|
|
6263 |
i = len,
|
|
|
6264 |
item,
|
|
|
6265 |
set = this,
|
|
|
6266 |
collector;
|
|
|
6267 |
if (!len) {
|
|
|
6268 |
return this;
|
|
|
6269 |
}
|
|
|
6270 |
callback && (collector = function () {
|
|
|
6271 |
!--len && callback.call(set);
|
|
|
6272 |
});
|
|
|
6273 |
easing = R.is(easing, string) ? easing : collector;
|
|
|
6274 |
var anim = R.animation(params, ms, easing, collector);
|
|
|
6275 |
item = this.items[--i].animate(anim);
|
|
|
6276 |
while (i--) {
|
|
|
6277 |
this.items[i] && !this.items[i].removed && this.items[i].animateWith(item, anim);
|
|
|
6278 |
}
|
|
|
6279 |
return this;
|
|
|
6280 |
};
|
|
|
6281 |
setproto.insertAfter = function (el) {
|
|
|
6282 |
var i = this.items.length;
|
|
|
6283 |
while (i--) {
|
|
|
6284 |
this.items[i].insertAfter(el);
|
|
|
6285 |
}
|
|
|
6286 |
return this;
|
|
|
6287 |
};
|
|
|
6288 |
setproto.getBBox = function () {
|
|
|
6289 |
var x = [],
|
|
|
6290 |
y = [],
|
|
|
6291 |
w = [],
|
|
|
6292 |
h = [];
|
|
|
6293 |
for (var i = this.items.length; i--;) if (!this.items[i].removed) {
|
|
|
6294 |
var box = this.items[i].getBBox();
|
|
|
6295 |
x.push(box.x);
|
|
|
6296 |
y.push(box.y);
|
|
|
6297 |
w.push(box.x + box.width);
|
|
|
6298 |
h.push(box.y + box.height);
|
|
|
6299 |
}
|
|
|
6300 |
x = mmin[apply](0, x);
|
|
|
6301 |
y = mmin[apply](0, y);
|
|
|
6302 |
return {
|
|
|
6303 |
x: x,
|
|
|
6304 |
y: y,
|
|
|
6305 |
width: mmax[apply](0, w) - x,
|
|
|
6306 |
height: mmax[apply](0, h) - y
|
|
|
6307 |
};
|
|
|
6308 |
};
|
|
|
6309 |
setproto.clone = function (s) {
|
|
|
6310 |
s = new Set;
|
|
|
6311 |
for (var i = 0, ii = this.items.length; i < ii; i++) {
|
|
|
6312 |
s.push(this.items[i].clone());
|
|
|
6313 |
}
|
|
|
6314 |
return s;
|
|
|
6315 |
};
|
|
|
6316 |
setproto.toString = function () {
|
|
|
6317 |
return "Rapha\xebl\u2018s set";
|
|
|
6318 |
};
|
|
|
6319 |
|
|
|
6320 |
|
|
|
6321 |
R.registerFont = function (font) {
|
|
|
6322 |
if (!font.face) {
|
|
|
6323 |
return font;
|
|
|
6324 |
}
|
|
|
6325 |
this.fonts = this.fonts || {};
|
|
|
6326 |
var fontcopy = {
|
|
|
6327 |
w: font.w,
|
|
|
6328 |
face: {},
|
|
|
6329 |
glyphs: {}
|
|
|
6330 |
},
|
|
|
6331 |
family = font.face["font-family"];
|
|
|
6332 |
for (var prop in font.face) if (font.face[has](prop)) {
|
|
|
6333 |
fontcopy.face[prop] = font.face[prop];
|
|
|
6334 |
}
|
|
|
6335 |
if (this.fonts[family]) {
|
|
|
6336 |
this.fonts[family].push(fontcopy);
|
|
|
6337 |
} else {
|
|
|
6338 |
this.fonts[family] = [fontcopy];
|
|
|
6339 |
}
|
|
|
6340 |
if (!font.svg) {
|
|
|
6341 |
fontcopy.face["units-per-em"] = toInt(font.face["units-per-em"], 10);
|
|
|
6342 |
for (var glyph in font.glyphs) if (font.glyphs[has](glyph)) {
|
|
|
6343 |
var path = font.glyphs[glyph];
|
|
|
6344 |
fontcopy.glyphs[glyph] = {
|
|
|
6345 |
w: path.w,
|
|
|
6346 |
k: {},
|
|
|
6347 |
d: path.d && "M" + path.d.replace(/[mlcxtrv]/g, function (command) {
|
|
|
6348 |
return {l: "L", c: "C", x: "z", t: "m", r: "l", v: "c"}[command] || "M";
|
|
|
6349 |
}) + "z"
|
|
|
6350 |
};
|
|
|
6351 |
if (path.k) {
|
|
|
6352 |
for (var k in path.k) if (path[has](k)) {
|
|
|
6353 |
fontcopy.glyphs[glyph].k[k] = path.k[k];
|
|
|
6354 |
}
|
|
|
6355 |
}
|
|
|
6356 |
}
|
|
|
6357 |
}
|
|
|
6358 |
return font;
|
|
|
6359 |
};
|
|
|
6360 |
|
|
|
6361 |
paperproto.getFont = function (family, weight, style, stretch) {
|
|
|
6362 |
stretch = stretch || "normal";
|
|
|
6363 |
style = style || "normal";
|
|
|
6364 |
weight = +weight || {normal: 400, bold: 700, lighter: 300, bolder: 800}[weight] || 400;
|
|
|
6365 |
if (!R.fonts) {
|
|
|
6366 |
return;
|
|
|
6367 |
}
|
|
|
6368 |
var font = R.fonts[family];
|
|
|
6369 |
if (!font) {
|
|
|
6370 |
var name = new RegExp("(^|\\s)" + family.replace(/[^\w\d\s+!~.:_-]/g, E) + "(\\s|$)", "i");
|
|
|
6371 |
for (var fontName in R.fonts) if (R.fonts[has](fontName)) {
|
|
|
6372 |
if (name.test(fontName)) {
|
|
|
6373 |
font = R.fonts[fontName];
|
|
|
6374 |
break;
|
|
|
6375 |
}
|
|
|
6376 |
}
|
|
|
6377 |
}
|
|
|
6378 |
var thefont;
|
|
|
6379 |
if (font) {
|
|
|
6380 |
for (var i = 0, ii = font.length; i < ii; i++) {
|
|
|
6381 |
thefont = font[i];
|
|
|
6382 |
if (thefont.face["font-weight"] == weight && (thefont.face["font-style"] == style || !thefont.face["font-style"]) && thefont.face["font-stretch"] == stretch) {
|
|
|
6383 |
break;
|
|
|
6384 |
}
|
|
|
6385 |
}
|
|
|
6386 |
}
|
|
|
6387 |
return thefont;
|
|
|
6388 |
};
|
|
|
6389 |
|
|
|
6390 |
paperproto.print = function (x, y, string, font, size, origin, letter_spacing) {
|
|
|
6391 |
origin = origin || "middle"; // baseline|middle
|
|
|
6392 |
letter_spacing = mmax(mmin(letter_spacing || 0, 1), -1);
|
|
|
6393 |
var out = this.set(),
|
|
|
6394 |
letters = Str(string)[split](E),
|
|
|
6395 |
shift = 0,
|
|
|
6396 |
path = E,
|
|
|
6397 |
scale;
|
|
|
6398 |
R.is(font, string) && (font = this.getFont(font));
|
|
|
6399 |
if (font) {
|
|
|
6400 |
scale = (size || 16) / font.face["units-per-em"];
|
|
|
6401 |
var bb = font.face.bbox[split](separator),
|
|
|
6402 |
top = +bb[0],
|
|
|
6403 |
height = +bb[1] + (origin == "baseline" ? bb[3] - bb[1] + (+font.face.descent) : (bb[3] - bb[1]) / 2);
|
|
|
6404 |
for (var i = 0, ii = letters.length; i < ii; i++) {
|
|
|
6405 |
var prev = i && font.glyphs[letters[i - 1]] || {},
|
|
|
6406 |
curr = font.glyphs[letters[i]];
|
|
|
6407 |
shift += i ? (prev.w || font.w) + (prev.k && prev.k[letters[i]] || 0) + (font.w * letter_spacing) : 0;
|
|
|
6408 |
curr && curr.d && out.push(this.path(curr.d).attr({
|
|
|
6409 |
fill: "#000",
|
|
|
6410 |
stroke: "none",
|
|
|
6411 |
transform: [["t", shift * scale, 0]]
|
|
|
6412 |
}));
|
|
|
6413 |
}
|
|
|
6414 |
out.transform(["...s", scale, scale, top, height, "t", (x - top) / scale, (y - height) / scale]);
|
|
|
6415 |
}
|
|
|
6416 |
return out;
|
|
|
6417 |
};
|
|
|
6418 |
|
|
|
6419 |
|
|
|
6420 |
R.format = function (token, params) {
|
|
|
6421 |
var args = R.is(params, array) ? [0][concat](params) : arguments;
|
|
|
6422 |
token && R.is(token, string) && args.length - 1 && (token = token.replace(formatrg, function (str, i) {
|
|
|
6423 |
return args[++i] == null ? E : args[i];
|
|
|
6424 |
}));
|
|
|
6425 |
return token || E;
|
|
|
6426 |
};
|
|
|
6427 |
|
|
|
6428 |
R.fullfill = (function () {
|
|
|
6429 |
var tokenRegex = /\{([^\}]+)\}/g,
|
|
|
6430 |
objNotationRegex = /(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g, // matches .xxxxx or ["xxxxx"] to run over object properties
|
|
|
6431 |
replacer = function (all, key, obj) {
|
|
|
6432 |
var res = obj;
|
|
|
6433 |
key.replace(objNotationRegex, function (all, name, quote, quotedName, isFunc) {
|
|
|
6434 |
name = name || quotedName;
|
|
|
6435 |
if (res) {
|
|
|
6436 |
if (name in res) {
|
|
|
6437 |
res = res[name];
|
|
|
6438 |
}
|
|
|
6439 |
typeof res == "function" && isFunc && (res = res());
|
|
|
6440 |
}
|
|
|
6441 |
});
|
|
|
6442 |
res = (res == null || res == obj ? all : res) + "";
|
|
|
6443 |
return res;
|
|
|
6444 |
};
|
|
|
6445 |
return function (str, obj) {
|
|
|
6446 |
return String(str).replace(tokenRegex, function (all, key) {
|
|
|
6447 |
return replacer(all, key, obj);
|
|
|
6448 |
});
|
|
|
6449 |
};
|
|
|
6450 |
})();
|
|
|
6451 |
|
|
|
6452 |
R.ninja = function () {
|
|
|
6453 |
oldRaphael.was ? (g.win.Raphael = oldRaphael.is) : delete Raphael;
|
|
|
6454 |
return R;
|
|
|
6455 |
};
|
|
|
6456 |
|
|
|
6457 |
R.st = setproto;
|
|
|
6458 |
// Firefox <3.6 fix: http://webreflection.blogspot.com/2009/11/195-chars-to-help-lazy-loading.html
|
|
|
6459 |
(function (doc, loaded, f) {
|
|
|
6460 |
if (doc.readyState == null && doc.addEventListener){
|
|
|
6461 |
doc.addEventListener(loaded, f = function () {
|
|
|
6462 |
doc.removeEventListener(loaded, f, false);
|
|
|
6463 |
doc.readyState = "complete";
|
|
|
6464 |
}, false);
|
|
|
6465 |
doc.readyState = "loading";
|
|
|
6466 |
}
|
|
|
6467 |
function isLoaded() {
|
|
|
6468 |
(/in/).test(doc.readyState) ? setTimeout(isLoaded, 9) : R.eve("DOMload");
|
|
|
6469 |
}
|
|
|
6470 |
isLoaded();
|
|
|
6471 |
})(document, "DOMContentLoaded");
|
|
|
6472 |
|
|
|
6473 |
oldRaphael.was ? (g.win.Raphael = R) : (Raphael = R);
|
|
|
6474 |
|
|
|
6475 |
eve.on("DOMload", function () {
|
|
|
6476 |
loaded = true;
|
|
|
6477 |
});
|
|
|
6478 |
})();
|
|
|
6479 |
|
|
|
6480 |
// ┌─────────────────────────────────────────────────────────────────────┐ \\
|
|
|
6481 |
// │ Raphaël 2 - JavaScript Vector Library │ \\
|
|
|
6482 |
// ├─────────────────────────────────────────────────────────────────────┤ \\
|
|
|
6483 |
// │ SVG Module │ \\
|
|
|
6484 |
// ├─────────────────────────────────────────────────────────────────────┤ \\
|
|
|
6485 |
// │ Copyright (c) 2008-2011 Dmitry Baranovskiy (http://raphaeljs.com) │ \\
|
|
|
6486 |
// │ Copyright (c) 2008-2011 Sencha Labs (http://sencha.com) │ \\
|
|
|
6487 |
// │ Licensed under the MIT (http://raphaeljs.com/license.html) license. │ \\
|
|
|
6488 |
// └─────────────────────────────────────────────────────────────────────┘ \\
|
|
|
6489 |
window.Raphael.svg && function (R) {
|
|
|
6490 |
var has = "hasOwnProperty",
|
|
|
6491 |
Str = String,
|
|
|
6492 |
toFloat = parseFloat,
|
|
|
6493 |
toInt = parseInt,
|
|
|
6494 |
math = Math,
|
|
|
6495 |
mmax = math.max,
|
|
|
6496 |
abs = math.abs,
|
|
|
6497 |
pow = math.pow,
|
|
|
6498 |
separator = /[, ]+/,
|
|
|
6499 |
eve = R.eve,
|
|
|
6500 |
E = "",
|
|
|
6501 |
S = " ";
|
|
|
6502 |
var xlink = "http://www.w3.org/1999/xlink",
|
|
|
6503 |
markers = {
|
|
|
6504 |
block: "M5,0 0,2.5 5,5z",
|
|
|
6505 |
classic: "M5,0 0,2.5 5,5 3.5,3 3.5,2z",
|
|
|
6506 |
diamond: "M2.5,0 5,2.5 2.5,5 0,2.5z",
|
|
|
6507 |
open: "M6,1 1,3.5 6,6",
|
|
|
6508 |
oval: "M2.5,0A2.5,2.5,0,0,1,2.5,5 2.5,2.5,0,0,1,2.5,0z"
|
|
|
6509 |
},
|
|
|
6510 |
markerCounter = {};
|
|
|
6511 |
R.toString = function () {
|
|
|
6512 |
return "Your browser supports SVG.\nYou are running Rapha\xebl " + this.version;
|
|
|
6513 |
};
|
|
|
6514 |
var $ = function (el, attr) {
|
|
|
6515 |
if (attr) {
|
|
|
6516 |
if (typeof el == "string") {
|
|
|
6517 |
el = $(el);
|
|
|
6518 |
}
|
|
|
6519 |
for (var key in attr) if (attr[has](key)) {
|
|
|
6520 |
if (key.substring(0, 6) == "xlink:") {
|
|
|
6521 |
el.setAttributeNS(xlink, key.substring(6), Str(attr[key]));
|
|
|
6522 |
} else {
|
|
|
6523 |
el.setAttribute(key, Str(attr[key]));
|
|
|
6524 |
}
|
|
|
6525 |
}
|
|
|
6526 |
} else {
|
|
|
6527 |
el = R._g.doc.createElementNS("http://www.w3.org/2000/svg", el);
|
|
|
6528 |
el.style && (el.style.webkitTapHighlightColor = "rgba(0,0,0,0)");
|
|
|
6529 |
}
|
|
|
6530 |
return el;
|
|
|
6531 |
},
|
|
|
6532 |
gradients = {},
|
|
|
6533 |
rgGrad = /^url\(#(.*)\)$/,
|
|
|
6534 |
removeGradientFill = function (node, paper) {
|
|
|
6535 |
var oid = node.getAttribute("fill");
|
|
|
6536 |
oid = oid && oid.match(rgGrad);
|
|
|
6537 |
if (oid && !--gradients[oid[1]]) {
|
|
|
6538 |
delete gradients[oid[1]];
|
|
|
6539 |
paper.defs.removeChild(R._g.doc.getElementById(oid[1]));
|
|
|
6540 |
}
|
|
|
6541 |
},
|
|
|
6542 |
addGradientFill = function (element, gradient) {
|
|
|
6543 |
var type = "linear",
|
|
|
6544 |
id = element.id + gradient,
|
|
|
6545 |
fx = .5, fy = .5,
|
|
|
6546 |
o = element.node,
|
|
|
6547 |
SVG = element.paper,
|
|
|
6548 |
s = o.style,
|
|
|
6549 |
el = R._g.doc.getElementById(id);
|
|
|
6550 |
if (!el) {
|
|
|
6551 |
gradient = Str(gradient).replace(R._radial_gradient, function (all, _fx, _fy) {
|
|
|
6552 |
type = "radial";
|
|
|
6553 |
if (_fx && _fy) {
|
|
|
6554 |
fx = toFloat(_fx);
|
|
|
6555 |
fy = toFloat(_fy);
|
|
|
6556 |
var dir = ((fy > .5) * 2 - 1);
|
|
|
6557 |
pow(fx - .5, 2) + pow(fy - .5, 2) > .25 &&
|
|
|
6558 |
(fy = math.sqrt(.25 - pow(fx - .5, 2)) * dir + .5) &&
|
|
|
6559 |
fy != .5 &&
|
|
|
6560 |
(fy = fy.toFixed(5) - 1e-5 * dir);
|
|
|
6561 |
}
|
|
|
6562 |
return E;
|
|
|
6563 |
});
|
|
|
6564 |
gradient = gradient.split(/\s*\-\s*/);
|
|
|
6565 |
if (type == "linear") {
|
|
|
6566 |
var angle = gradient.shift();
|
|
|
6567 |
angle = -toFloat(angle);
|
|
|
6568 |
if (isNaN(angle)) {
|
|
|
6569 |
return null;
|
|
|
6570 |
}
|
|
|
6571 |
var vector = [0, 0, math.cos(R.rad(angle)), math.sin(R.rad(angle))],
|
|
|
6572 |
max = 1 / (mmax(abs(vector[2]), abs(vector[3])) || 1);
|
|
|
6573 |
vector[2] *= max;
|
|
|
6574 |
vector[3] *= max;
|
|
|
6575 |
if (vector[2] < 0) {
|
|
|
6576 |
vector[0] = -vector[2];
|
|
|
6577 |
vector[2] = 0;
|
|
|
6578 |
}
|
|
|
6579 |
if (vector[3] < 0) {
|
|
|
6580 |
vector[1] = -vector[3];
|
|
|
6581 |
vector[3] = 0;
|
|
|
6582 |
}
|
|
|
6583 |
}
|
|
|
6584 |
var dots = R._parseDots(gradient);
|
|
|
6585 |
if (!dots) {
|
|
|
6586 |
return null;
|
|
|
6587 |
}
|
|
|
6588 |
if (element.gradient) {
|
|
|
6589 |
SVG.defs.removeChild(element.gradient);
|
|
|
6590 |
delete element.gradient;
|
|
|
6591 |
}
|
|
|
6592 |
|
|
|
6593 |
id = id.replace(/[\(\)\s,\xb0#]/g, "-");
|
|
|
6594 |
el = $(type + "Gradient", {id: id});
|
|
|
6595 |
element.gradient = el;
|
|
|
6596 |
$(el, type == "radial" ? {
|
|
|
6597 |
fx: fx,
|
|
|
6598 |
fy: fy
|
|
|
6599 |
} : {
|
|
|
6600 |
x1: vector[0],
|
|
|
6601 |
y1: vector[1],
|
|
|
6602 |
x2: vector[2],
|
|
|
6603 |
y2: vector[3],
|
|
|
6604 |
gradientTransform: element.matrix.invert()
|
|
|
6605 |
});
|
|
|
6606 |
SVG.defs.appendChild(el);
|
|
|
6607 |
for (var i = 0, ii = dots.length; i < ii; i++) {
|
|
|
6608 |
el.appendChild($("stop", {
|
|
|
6609 |
offset: dots[i].offset ? dots[i].offset : i ? "100%" : "0%",
|
|
|
6610 |
"stop-color": dots[i].color || "#fff"
|
|
|
6611 |
}));
|
|
|
6612 |
}
|
|
|
6613 |
}
|
|
|
6614 |
$(o, {
|
|
|
6615 |
fill: "url(#" + id + ")",
|
|
|
6616 |
opacity: 1,
|
|
|
6617 |
"fill-opacity": 1
|
|
|
6618 |
});
|
|
|
6619 |
s.fill = E;
|
|
|
6620 |
s.opacity = 1;
|
|
|
6621 |
s.fillOpacity = 1;
|
|
|
6622 |
return 1;
|
|
|
6623 |
},
|
|
|
6624 |
updatePosition = function (o) {
|
|
|
6625 |
var bbox = o.getBBox(1);
|
|
|
6626 |
$(o.pattern, {patternTransform: o.matrix.invert() + " translate(" + bbox.x + "," + bbox.y + ")"});
|
|
|
6627 |
},
|
|
|
6628 |
addArrow = function (o, value, isEnd) {
|
|
|
6629 |
if (o.type == "path") {
|
|
|
6630 |
var values = Str(value).toLowerCase().split("-"),
|
|
|
6631 |
p = o.paper,
|
|
|
6632 |
se = isEnd ? "end" : "start",
|
|
|
6633 |
node = o.node,
|
|
|
6634 |
attrs = o.attrs,
|
|
|
6635 |
stroke = attrs["stroke-width"],
|
|
|
6636 |
i = values.length,
|
|
|
6637 |
type = "classic",
|
|
|
6638 |
from,
|
|
|
6639 |
to,
|
|
|
6640 |
dx,
|
|
|
6641 |
refX,
|
|
|
6642 |
attr,
|
|
|
6643 |
w = 3,
|
|
|
6644 |
h = 3,
|
|
|
6645 |
t = 5;
|
|
|
6646 |
while (i--) {
|
|
|
6647 |
switch (values[i]) {
|
|
|
6648 |
case "block":
|
|
|
6649 |
case "classic":
|
|
|
6650 |
case "oval":
|
|
|
6651 |
case "diamond":
|
|
|
6652 |
case "open":
|
|
|
6653 |
case "none":
|
|
|
6654 |
type = values[i];
|
|
|
6655 |
break;
|
|
|
6656 |
case "wide": h = 5; break;
|
|
|
6657 |
case "narrow": h = 2; break;
|
|
|
6658 |
case "long": w = 5; break;
|
|
|
6659 |
case "short": w = 2; break;
|
|
|
6660 |
}
|
|
|
6661 |
}
|
|
|
6662 |
if (type == "open") {
|
|
|
6663 |
w += 2;
|
|
|
6664 |
h += 2;
|
|
|
6665 |
t += 2;
|
|
|
6666 |
dx = 1;
|
|
|
6667 |
refX = isEnd ? 4 : 1;
|
|
|
6668 |
attr = {
|
|
|
6669 |
fill: "none",
|
|
|
6670 |
stroke: attrs.stroke
|
|
|
6671 |
};
|
|
|
6672 |
} else {
|
|
|
6673 |
refX = dx = w / 2;
|
|
|
6674 |
attr = {
|
|
|
6675 |
fill: attrs.stroke,
|
|
|
6676 |
stroke: "none"
|
|
|
6677 |
};
|
|
|
6678 |
}
|
|
|
6679 |
if (o._.arrows) {
|
|
|
6680 |
if (isEnd) {
|
|
|
6681 |
o._.arrows.endPath && markerCounter[o._.arrows.endPath]--;
|
|
|
6682 |
o._.arrows.endMarker && markerCounter[o._.arrows.endMarker]--;
|
|
|
6683 |
} else {
|
|
|
6684 |
o._.arrows.startPath && markerCounter[o._.arrows.startPath]--;
|
|
|
6685 |
o._.arrows.startMarker && markerCounter[o._.arrows.startMarker]--;
|
|
|
6686 |
}
|
|
|
6687 |
} else {
|
|
|
6688 |
o._.arrows = {};
|
|
|
6689 |
}
|
|
|
6690 |
if (type != "none") {
|
|
|
6691 |
var pathId = "raphael-marker-" + type,
|
|
|
6692 |
markerId = "raphael-marker-" + se + type + w + h;
|
|
|
6693 |
if (!R._g.doc.getElementById(pathId)) {
|
|
|
6694 |
p.defs.appendChild($($("path"), {
|
|
|
6695 |
"stroke-linecap": "round",
|
|
|
6696 |
d: markers[type],
|
|
|
6697 |
id: pathId
|
|
|
6698 |
}));
|
|
|
6699 |
markerCounter[pathId] = 1;
|
|
|
6700 |
} else {
|
|
|
6701 |
markerCounter[pathId]++;
|
|
|
6702 |
}
|
|
|
6703 |
var marker = R._g.doc.getElementById(markerId),
|
|
|
6704 |
use;
|
|
|
6705 |
if (!marker) {
|
|
|
6706 |
marker = $($("marker"), {
|
|
|
6707 |
id: markerId,
|
|
|
6708 |
markerHeight: h,
|
|
|
6709 |
markerWidth: w,
|
|
|
6710 |
orient: "auto",
|
|
|
6711 |
refX: refX,
|
|
|
6712 |
refY: h / 2
|
|
|
6713 |
});
|
|
|
6714 |
use = $($("use"), {
|
|
|
6715 |
"xlink:href": "#" + pathId,
|
|
|
6716 |
transform: (isEnd ? " rotate(180 " + w / 2 + " " + h / 2 + ") " : S) + "scale(" + w / t + "," + h / t + ")",
|
|
|
6717 |
"stroke-width": 1 / ((w / t + h / t) / 2)
|
|
|
6718 |
});
|
|
|
6719 |
marker.appendChild(use);
|
|
|
6720 |
p.defs.appendChild(marker);
|
|
|
6721 |
markerCounter[markerId] = 1;
|
|
|
6722 |
} else {
|
|
|
6723 |
markerCounter[markerId]++;
|
|
|
6724 |
use = marker.getElementsByTagName("use")[0];
|
|
|
6725 |
}
|
|
|
6726 |
$(use, attr);
|
|
|
6727 |
var delta = dx * (type != "diamond" && type != "oval");
|
|
|
6728 |
if (isEnd) {
|
|
|
6729 |
from = o._.arrows.startdx * stroke || 0;
|
|
|
6730 |
to = R.getTotalLength(attrs.path) - delta * stroke;
|
|
|
6731 |
} else {
|
|
|
6732 |
from = delta * stroke;
|
|
|
6733 |
to = R.getTotalLength(attrs.path) - (o._.arrows.enddx * stroke || 0);
|
|
|
6734 |
}
|
|
|
6735 |
attr = {};
|
|
|
6736 |
attr["marker-" + se] = "url(#" + markerId + ")";
|
|
|
6737 |
if (to || from) {
|
|
|
6738 |
attr.d = Raphael.getSubpath(attrs.path, from, to);
|
|
|
6739 |
}
|
|
|
6740 |
$(node, attr);
|
|
|
6741 |
o._.arrows[se + "Path"] = pathId;
|
|
|
6742 |
o._.arrows[se + "Marker"] = markerId;
|
|
|
6743 |
o._.arrows[se + "dx"] = delta;
|
|
|
6744 |
o._.arrows[se + "Type"] = type;
|
|
|
6745 |
o._.arrows[se + "String"] = value;
|
|
|
6746 |
} else {
|
|
|
6747 |
if (isEnd) {
|
|
|
6748 |
from = o._.arrows.startdx * stroke || 0;
|
|
|
6749 |
to = R.getTotalLength(attrs.path) - from;
|
|
|
6750 |
} else {
|
|
|
6751 |
from = 0;
|
|
|
6752 |
to = R.getTotalLength(attrs.path) - (o._.arrows.enddx * stroke || 0);
|
|
|
6753 |
}
|
|
|
6754 |
o._.arrows[se + "Path"] && $(node, {d: Raphael.getSubpath(attrs.path, from, to)});
|
|
|
6755 |
delete o._.arrows[se + "Path"];
|
|
|
6756 |
delete o._.arrows[se + "Marker"];
|
|
|
6757 |
delete o._.arrows[se + "dx"];
|
|
|
6758 |
delete o._.arrows[se + "Type"];
|
|
|
6759 |
delete o._.arrows[se + "String"];
|
|
|
6760 |
}
|
|
|
6761 |
for (attr in markerCounter) if (markerCounter[has](attr) && !markerCounter[attr]) {
|
|
|
6762 |
var item = R._g.doc.getElementById(attr);
|
|
|
6763 |
item && item.parentNode.removeChild(item);
|
|
|
6764 |
}
|
|
|
6765 |
}
|
|
|
6766 |
},
|
|
|
6767 |
dasharray = {
|
|
|
6768 |
"": [0],
|
|
|
6769 |
"none": [0],
|
|
|
6770 |
"-": [3, 1],
|
|
|
6771 |
".": [1, 1],
|
|
|
6772 |
"-.": [3, 1, 1, 1],
|
|
|
6773 |
"-..": [3, 1, 1, 1, 1, 1],
|
|
|
6774 |
". ": [1, 3],
|
|
|
6775 |
"- ": [4, 3],
|
|
|
6776 |
"--": [8, 3],
|
|
|
6777 |
"- .": [4, 3, 1, 3],
|
|
|
6778 |
"--.": [8, 3, 1, 3],
|
|
|
6779 |
"--..": [8, 3, 1, 3, 1, 3]
|
|
|
6780 |
},
|
|
|
6781 |
addDashes = function (o, value, params) {
|
|
|
6782 |
value = dasharray[Str(value).toLowerCase()];
|
|
|
6783 |
if (value) {
|
|
|
6784 |
var width = o.attrs["stroke-width"] || "1",
|
|
|
6785 |
butt = {round: width, square: width, butt: 0}[o.attrs["stroke-linecap"] || params["stroke-linecap"]] || 0,
|
|
|
6786 |
dashes = [],
|
|
|
6787 |
i = value.length;
|
|
|
6788 |
while (i--) {
|
|
|
6789 |
dashes[i] = value[i] * width + ((i % 2) ? 1 : -1) * butt;
|
|
|
6790 |
}
|
|
|
6791 |
$(o.node, {"stroke-dasharray": dashes.join(",")});
|
|
|
6792 |
}
|
|
|
6793 |
},
|
|
|
6794 |
setFillAndStroke = function (o, params) {
|
|
|
6795 |
var node = o.node,
|
|
|
6796 |
attrs = o.attrs,
|
|
|
6797 |
vis = node.style.visibility;
|
|
|
6798 |
node.style.visibility = "hidden";
|
|
|
6799 |
for (var att in params) {
|
|
|
6800 |
if (params[has](att)) {
|
|
|
6801 |
if (!R._availableAttrs[has](att)) {
|
|
|
6802 |
continue;
|
|
|
6803 |
}
|
|
|
6804 |
var value = params[att];
|
|
|
6805 |
attrs[att] = value;
|
|
|
6806 |
switch (att) {
|
|
|
6807 |
case "blur":
|
|
|
6808 |
o.blur(value);
|
|
|
6809 |
break;
|
|
|
6810 |
case "href":
|
|
|
6811 |
case "title":
|
|
|
6812 |
case "target":
|
|
|
6813 |
var pn = node.parentNode;
|
|
|
6814 |
if (pn.tagName.toLowerCase() != "a") {
|
|
|
6815 |
var hl = $("a");
|
|
|
6816 |
pn.insertBefore(hl, node);
|
|
|
6817 |
hl.appendChild(node);
|
|
|
6818 |
pn = hl;
|
|
|
6819 |
}
|
|
|
6820 |
if (att == "target" && value == "blank") {
|
|
|
6821 |
pn.setAttributeNS(xlink, "show", "new");
|
|
|
6822 |
} else {
|
|
|
6823 |
pn.setAttributeNS(xlink, att, value);
|
|
|
6824 |
}
|
|
|
6825 |
break;
|
|
|
6826 |
case "cursor":
|
|
|
6827 |
node.style.cursor = value;
|
|
|
6828 |
break;
|
|
|
6829 |
case "transform":
|
|
|
6830 |
o.transform(value);
|
|
|
6831 |
break;
|
|
|
6832 |
case "arrow-start":
|
|
|
6833 |
addArrow(o, value);
|
|
|
6834 |
break;
|
|
|
6835 |
case "arrow-end":
|
|
|
6836 |
addArrow(o, value, 1);
|
|
|
6837 |
break;
|
|
|
6838 |
case "clip-rect":
|
|
|
6839 |
var rect = Str(value).split(separator);
|
|
|
6840 |
if (rect.length == 4) {
|
|
|
6841 |
o.clip && o.clip.parentNode.parentNode.removeChild(o.clip.parentNode);
|
|
|
6842 |
var el = $("clipPath"),
|
|
|
6843 |
rc = $("rect");
|
|
|
6844 |
el.id = R.createUUID();
|
|
|
6845 |
$(rc, {
|
|
|
6846 |
x: rect[0],
|
|
|
6847 |
y: rect[1],
|
|
|
6848 |
width: rect[2],
|
|
|
6849 |
height: rect[3]
|
|
|
6850 |
});
|
|
|
6851 |
el.appendChild(rc);
|
|
|
6852 |
o.paper.defs.appendChild(el);
|
|
|
6853 |
$(node, {"clip-path": "url(#" + el.id + ")"});
|
|
|
6854 |
o.clip = rc;
|
|
|
6855 |
}
|
|
|
6856 |
if (!value) {
|
|
|
6857 |
var clip = R._g.doc.getElementById(node.getAttribute("clip-path").replace(/(^url\(#|\)$)/g, E));
|
|
|
6858 |
clip && clip.parentNode.removeChild(clip);
|
|
|
6859 |
$(node, {"clip-path": E});
|
|
|
6860 |
delete o.clip;
|
|
|
6861 |
}
|
|
|
6862 |
break;
|
|
|
6863 |
case "path":
|
|
|
6864 |
if (o.type == "path") {
|
|
|
6865 |
$(node, {d: value ? attrs.path = R._pathToAbsolute(value) : "M0,0"});
|
|
|
6866 |
o._.dirty = 1;
|
|
|
6867 |
if (o._.arrows) {
|
|
|
6868 |
"startString" in o._.arrows && addArrow(o, o._.arrows.startString);
|
|
|
6869 |
"endString" in o._.arrows && addArrow(o, o._.arrows.endString, 1);
|
|
|
6870 |
}
|
|
|
6871 |
}
|
|
|
6872 |
break;
|
|
|
6873 |
case "width":
|
|
|
6874 |
node.setAttribute(att, value);
|
|
|
6875 |
o._.dirty = 1;
|
|
|
6876 |
if (attrs.fx) {
|
|
|
6877 |
att = "x";
|
|
|
6878 |
value = attrs.x;
|
|
|
6879 |
} else {
|
|
|
6880 |
break;
|
|
|
6881 |
}
|
|
|
6882 |
case "x":
|
|
|
6883 |
if (attrs.fx) {
|
|
|
6884 |
value = -attrs.x - (attrs.width || 0);
|
|
|
6885 |
}
|
|
|
6886 |
case "rx":
|
|
|
6887 |
if (att == "rx" && o.type == "rect") {
|
|
|
6888 |
break;
|
|
|
6889 |
}
|
|
|
6890 |
case "cx":
|
|
|
6891 |
node.setAttribute(att, value);
|
|
|
6892 |
o.pattern && updatePosition(o);
|
|
|
6893 |
o._.dirty = 1;
|
|
|
6894 |
break;
|
|
|
6895 |
case "height":
|
|
|
6896 |
node.setAttribute(att, value);
|
|
|
6897 |
o._.dirty = 1;
|
|
|
6898 |
if (attrs.fy) {
|
|
|
6899 |
att = "y";
|
|
|
6900 |
value = attrs.y;
|
|
|
6901 |
} else {
|
|
|
6902 |
break;
|
|
|
6903 |
}
|
|
|
6904 |
case "y":
|
|
|
6905 |
if (attrs.fy) {
|
|
|
6906 |
value = -attrs.y - (attrs.height || 0);
|
|
|
6907 |
}
|
|
|
6908 |
case "ry":
|
|
|
6909 |
if (att == "ry" && o.type == "rect") {
|
|
|
6910 |
break;
|
|
|
6911 |
}
|
|
|
6912 |
case "cy":
|
|
|
6913 |
node.setAttribute(att, value);
|
|
|
6914 |
o.pattern && updatePosition(o);
|
|
|
6915 |
o._.dirty = 1;
|
|
|
6916 |
break;
|
|
|
6917 |
case "r":
|
|
|
6918 |
if (o.type == "rect") {
|
|
|
6919 |
$(node, {rx: value, ry: value});
|
|
|
6920 |
} else {
|
|
|
6921 |
node.setAttribute(att, value);
|
|
|
6922 |
}
|
|
|
6923 |
o._.dirty = 1;
|
|
|
6924 |
break;
|
|
|
6925 |
case "src":
|
|
|
6926 |
if (o.type == "image") {
|
|
|
6927 |
node.setAttributeNS(xlink, "href", value);
|
|
|
6928 |
}
|
|
|
6929 |
break;
|
|
|
6930 |
case "stroke-width":
|
|
|
6931 |
if (o._.sx != 1 || o._.sy != 1) {
|
|
|
6932 |
value /= mmax(abs(o._.sx), abs(o._.sy)) || 1;
|
|
|
6933 |
}
|
|
|
6934 |
if (o.paper._vbSize) {
|
|
|
6935 |
value *= o.paper._vbSize;
|
|
|
6936 |
}
|
|
|
6937 |
node.setAttribute(att, value);
|
|
|
6938 |
if (attrs["stroke-dasharray"]) {
|
|
|
6939 |
addDashes(o, attrs["stroke-dasharray"], params);
|
|
|
6940 |
}
|
|
|
6941 |
if (o._.arrows) {
|
|
|
6942 |
"startString" in o._.arrows && addArrow(o, o._.arrows.startString);
|
|
|
6943 |
"endString" in o._.arrows && addArrow(o, o._.arrows.endString, 1);
|
|
|
6944 |
}
|
|
|
6945 |
break;
|
|
|
6946 |
case "stroke-dasharray":
|
|
|
6947 |
addDashes(o, value, params);
|
|
|
6948 |
break;
|
|
|
6949 |
case "fill":
|
|
|
6950 |
var isURL = Str(value).match(R._ISURL);
|
|
|
6951 |
if (isURL) {
|
|
|
6952 |
el = $("pattern");
|
|
|
6953 |
var ig = $("image");
|
|
|
6954 |
el.id = R.createUUID();
|
|
|
6955 |
$(el, {x: 0, y: 0, patternUnits: "userSpaceOnUse", height: 1, width: 1});
|
|
|
6956 |
$(ig, {x: 0, y: 0, "xlink:href": isURL[1]});
|
|
|
6957 |
el.appendChild(ig);
|
|
|
6958 |
|
|
|
6959 |
(function (el) {
|
|
|
6960 |
R._preload(isURL[1], function () {
|
|
|
6961 |
var w = this.offsetWidth,
|
|
|
6962 |
h = this.offsetHeight;
|
|
|
6963 |
$(el, {width: w, height: h});
|
|
|
6964 |
$(ig, {width: w, height: h});
|
|
|
6965 |
o.paper.safari();
|
|
|
6966 |
});
|
|
|
6967 |
})(el);
|
|
|
6968 |
o.paper.defs.appendChild(el);
|
|
|
6969 |
node.style.fill = "url(#" + el.id + ")";
|
|
|
6970 |
$(node, {fill: "url(#" + el.id + ")"});
|
|
|
6971 |
o.pattern = el;
|
|
|
6972 |
o.pattern && updatePosition(o);
|
|
|
6973 |
break;
|
|
|
6974 |
}
|
|
|
6975 |
var clr = R.getRGB(value);
|
|
|
6976 |
if (!clr.error) {
|
|
|
6977 |
delete params.gradient;
|
|
|
6978 |
delete attrs.gradient;
|
|
|
6979 |
!R.is(attrs.opacity, "undefined") &&
|
|
|
6980 |
R.is(params.opacity, "undefined") &&
|
|
|
6981 |
$(node, {opacity: attrs.opacity});
|
|
|
6982 |
!R.is(attrs["fill-opacity"], "undefined") &&
|
|
|
6983 |
R.is(params["fill-opacity"], "undefined") &&
|
|
|
6984 |
$(node, {"fill-opacity": attrs["fill-opacity"]});
|
|
|
6985 |
} else if ((o.type == "circle" || o.type == "ellipse" || Str(value).charAt() != "r") && addGradientFill(o, value)) {
|
|
|
6986 |
if ("opacity" in attrs || "fill-opacity" in attrs) {
|
|
|
6987 |
var gradient = R._g.doc.getElementById(node.getAttribute("fill").replace(/^url\(#|\)$/g, E));
|
|
|
6988 |
if (gradient) {
|
|
|
6989 |
var stops = gradient.getElementsByTagName("stop");
|
|
|
6990 |
$(stops[stops.length - 1], {"stop-opacity": ("opacity" in attrs ? attrs.opacity : 1) * ("fill-opacity" in attrs ? attrs["fill-opacity"] : 1)});
|
|
|
6991 |
}
|
|
|
6992 |
}
|
|
|
6993 |
attrs.gradient = value;
|
|
|
6994 |
attrs.fill = "none";
|
|
|
6995 |
break;
|
|
|
6996 |
}
|
|
|
6997 |
clr[has]("opacity") && $(node, {"fill-opacity": clr.opacity > 1 ? clr.opacity / 100 : clr.opacity});
|
|
|
6998 |
case "stroke":
|
|
|
6999 |
clr = R.getRGB(value);
|
|
|
7000 |
node.setAttribute(att, clr.hex);
|
|
|
7001 |
att == "stroke" && clr[has]("opacity") && $(node, {"stroke-opacity": clr.opacity > 1 ? clr.opacity / 100 : clr.opacity});
|
|
|
7002 |
if (att == "stroke" && o._.arrows) {
|
|
|
7003 |
"startString" in o._.arrows && addArrow(o, o._.arrows.startString);
|
|
|
7004 |
"endString" in o._.arrows && addArrow(o, o._.arrows.endString, 1);
|
|
|
7005 |
}
|
|
|
7006 |
break;
|
|
|
7007 |
case "gradient":
|
|
|
7008 |
(o.type == "circle" || o.type == "ellipse" || Str(value).charAt() != "r") && addGradientFill(o, value);
|
|
|
7009 |
break;
|
|
|
7010 |
case "opacity":
|
|
|
7011 |
if (attrs.gradient && !attrs[has]("stroke-opacity")) {
|
|
|
7012 |
$(node, {"stroke-opacity": value > 1 ? value / 100 : value});
|
|
|
7013 |
}
|
|
|
7014 |
// fall
|
|
|
7015 |
case "fill-opacity":
|
|
|
7016 |
if (attrs.gradient) {
|
|
|
7017 |
gradient = R._g.doc.getElementById(node.getAttribute("fill").replace(/^url\(#|\)$/g, E));
|
|
|
7018 |
if (gradient) {
|
|
|
7019 |
stops = gradient.getElementsByTagName("stop");
|
|
|
7020 |
$(stops[stops.length - 1], {"stop-opacity": value});
|
|
|
7021 |
}
|
|
|
7022 |
break;
|
|
|
7023 |
}
|
|
|
7024 |
default:
|
|
|
7025 |
att == "font-size" && (value = toInt(value, 10) + "px");
|
|
|
7026 |
var cssrule = att.replace(/(\-.)/g, function (w) {
|
|
|
7027 |
return w.substring(1).toUpperCase();
|
|
|
7028 |
});
|
|
|
7029 |
node.style[cssrule] = value;
|
|
|
7030 |
o._.dirty = 1;
|
|
|
7031 |
node.setAttribute(att, value);
|
|
|
7032 |
break;
|
|
|
7033 |
}
|
|
|
7034 |
}
|
|
|
7035 |
}
|
|
|
7036 |
|
|
|
7037 |
tuneText(o, params);
|
|
|
7038 |
node.style.visibility = vis;
|
|
|
7039 |
},
|
|
|
7040 |
leading = 1.2,
|
|
|
7041 |
tuneText = function (el, params) {
|
|
|
7042 |
if (el.type != "text" || !(params[has]("text") || params[has]("font") || params[has]("font-size") || params[has]("x") || params[has]("y"))) {
|
|
|
7043 |
return;
|
|
|
7044 |
}
|
|
|
7045 |
var a = el.attrs,
|
|
|
7046 |
node = el.node,
|
|
|
7047 |
fontSize = node.firstChild ? toInt(R._g.doc.defaultView.getComputedStyle(node.firstChild, E).getPropertyValue("font-size"), 10) : 10;
|
|
|
7048 |
|
|
|
7049 |
if (params[has]("text")) {
|
|
|
7050 |
a.text = params.text;
|
|
|
7051 |
while (node.firstChild) {
|
|
|
7052 |
node.removeChild(node.firstChild);
|
|
|
7053 |
}
|
|
|
7054 |
var texts = Str(params.text).split("\n"),
|
|
|
7055 |
tspans = [],
|
|
|
7056 |
tspan;
|
|
|
7057 |
for (var i = 0, ii = texts.length; i < ii; i++) {
|
|
|
7058 |
tspan = $("tspan");
|
|
|
7059 |
i && $(tspan, {dy: fontSize * leading, x: a.x});
|
|
|
7060 |
tspan.appendChild(R._g.doc.createTextNode(texts[i]));
|
|
|
7061 |
node.appendChild(tspan);
|
|
|
7062 |
tspans[i] = tspan;
|
|
|
7063 |
}
|
|
|
7064 |
} else {
|
|
|
7065 |
tspans = node.getElementsByTagName("tspan");
|
|
|
7066 |
for (i = 0, ii = tspans.length; i < ii; i++) if (i) {
|
|
|
7067 |
$(tspans[i], {dy: fontSize * leading, x: a.x});
|
|
|
7068 |
} else {
|
|
|
7069 |
$(tspans[0], {dy: 0});
|
|
|
7070 |
}
|
|
|
7071 |
}
|
|
|
7072 |
$(node, {x: a.x, y: a.y});
|
|
|
7073 |
el._.dirty = 1;
|
|
|
7074 |
var bb = el._getBBox(),
|
|
|
7075 |
dif = a.y - (bb.y + bb.height / 2);
|
|
|
7076 |
dif && R.is(dif, "finite") && $(tspans[0], {dy: dif});
|
|
|
7077 |
},
|
|
|
7078 |
Element = function (node, svg) {
|
|
|
7079 |
var X = 0,
|
|
|
7080 |
Y = 0;
|
|
|
7081 |
|
|
|
7082 |
this[0] = this.node = node;
|
|
|
7083 |
|
|
|
7084 |
node.raphael = true;
|
|
|
7085 |
|
|
|
7086 |
this.id = R._oid++;
|
|
|
7087 |
node.raphaelid = this.id;
|
|
|
7088 |
this.matrix = R.matrix();
|
|
|
7089 |
this.realPath = null;
|
|
|
7090 |
|
|
|
7091 |
this.paper = svg;
|
|
|
7092 |
this.attrs = this.attrs || {};
|
|
|
7093 |
this._ = {
|
|
|
7094 |
transform: [],
|
|
|
7095 |
sx: 1,
|
|
|
7096 |
sy: 1,
|
|
|
7097 |
deg: 0,
|
|
|
7098 |
dx: 0,
|
|
|
7099 |
dy: 0,
|
|
|
7100 |
dirty: 1
|
|
|
7101 |
};
|
|
|
7102 |
!svg.bottom && (svg.bottom = this);
|
|
|
7103 |
|
|
|
7104 |
this.prev = svg.top;
|
|
|
7105 |
svg.top && (svg.top.next = this);
|
|
|
7106 |
svg.top = this;
|
|
|
7107 |
|
|
|
7108 |
this.next = null;
|
|
|
7109 |
},
|
|
|
7110 |
elproto = R.el;
|
|
|
7111 |
|
|
|
7112 |
Element.prototype = elproto;
|
|
|
7113 |
elproto.constructor = Element;
|
|
|
7114 |
|
|
|
7115 |
R._engine.path = function (pathString, SVG) {
|
|
|
7116 |
var el = $("path");
|
|
|
7117 |
SVG.canvas && SVG.canvas.appendChild(el);
|
|
|
7118 |
var p = new Element(el, SVG);
|
|
|
7119 |
p.type = "path";
|
|
|
7120 |
setFillAndStroke(p, {
|
|
|
7121 |
fill: "none",
|
|
|
7122 |
stroke: "#000",
|
|
|
7123 |
path: pathString
|
|
|
7124 |
});
|
|
|
7125 |
return p;
|
|
|
7126 |
};
|
|
|
7127 |
|
|
|
7128 |
elproto.rotate = function (deg, cx, cy) {
|
|
|
7129 |
if (this.removed) {
|
|
|
7130 |
return this;
|
|
|
7131 |
}
|
|
|
7132 |
deg = Str(deg).split(separator);
|
|
|
7133 |
if (deg.length - 1) {
|
|
|
7134 |
cx = toFloat(deg[1]);
|
|
|
7135 |
cy = toFloat(deg[2]);
|
|
|
7136 |
}
|
|
|
7137 |
deg = toFloat(deg[0]);
|
|
|
7138 |
(cy == null) && (cx = cy);
|
|
|
7139 |
if (cx == null || cy == null) {
|
|
|
7140 |
var bbox = this.getBBox(1);
|
|
|
7141 |
cx = bbox.x + bbox.width / 2;
|
|
|
7142 |
cy = bbox.y + bbox.height / 2;
|
|
|
7143 |
}
|
|
|
7144 |
this.transform(this._.transform.concat([["r", deg, cx, cy]]));
|
|
|
7145 |
return this;
|
|
|
7146 |
};
|
|
|
7147 |
|
|
|
7148 |
elproto.scale = function (sx, sy, cx, cy) {
|
|
|
7149 |
if (this.removed) {
|
|
|
7150 |
return this;
|
|
|
7151 |
}
|
|
|
7152 |
sx = Str(sx).split(separator);
|
|
|
7153 |
if (sx.length - 1) {
|
|
|
7154 |
sy = toFloat(sx[1]);
|
|
|
7155 |
cx = toFloat(sx[2]);
|
|
|
7156 |
cy = toFloat(sx[3]);
|
|
|
7157 |
}
|
|
|
7158 |
sx = toFloat(sx[0]);
|
|
|
7159 |
(sy == null) && (sy = sx);
|
|
|
7160 |
(cy == null) && (cx = cy);
|
|
|
7161 |
if (cx == null || cy == null) {
|
|
|
7162 |
var bbox = this.getBBox(1);
|
|
|
7163 |
}
|
|
|
7164 |
cx = cx == null ? bbox.x + bbox.width / 2 : cx;
|
|
|
7165 |
cy = cy == null ? bbox.y + bbox.height / 2 : cy;
|
|
|
7166 |
this.transform(this._.transform.concat([["s", sx, sy, cx, cy]]));
|
|
|
7167 |
return this;
|
|
|
7168 |
};
|
|
|
7169 |
|
|
|
7170 |
elproto.translate = function (dx, dy) {
|
|
|
7171 |
if (this.removed) {
|
|
|
7172 |
return this;
|
|
|
7173 |
}
|
|
|
7174 |
dx = Str(dx).split(separator);
|
|
|
7175 |
if (dx.length - 1) {
|
|
|
7176 |
dy = toFloat(dx[1]);
|
|
|
7177 |
}
|
|
|
7178 |
dx = toFloat(dx[0]) || 0;
|
|
|
7179 |
dy = +dy || 0;
|
|
|
7180 |
this.transform(this._.transform.concat([["t", dx, dy]]));
|
|
|
7181 |
return this;
|
|
|
7182 |
};
|
|
|
7183 |
|
|
|
7184 |
elproto.transform = function (tstr) {
|
|
|
7185 |
var _ = this._;
|
|
|
7186 |
if (tstr == null) {
|
|
|
7187 |
return _.transform;
|
|
|
7188 |
}
|
|
|
7189 |
R._extractTransform(this, tstr);
|
|
|
7190 |
|
|
|
7191 |
this.clip && $(this.clip, {transform: this.matrix.invert()});
|
|
|
7192 |
this.pattern && updatePosition(this);
|
|
|
7193 |
this.node && $(this.node, {transform: this.matrix});
|
|
|
7194 |
|
|
|
7195 |
if (_.sx != 1 || _.sy != 1) {
|
|
|
7196 |
var sw = this.attrs[has]("stroke-width") ? this.attrs["stroke-width"] : 1;
|
|
|
7197 |
this.attr({"stroke-width": sw});
|
|
|
7198 |
}
|
|
|
7199 |
|
|
|
7200 |
return this;
|
|
|
7201 |
};
|
|
|
7202 |
|
|
|
7203 |
elproto.hide = function () {
|
|
|
7204 |
!this.removed && this.paper.safari(this.node.style.display = "none");
|
|
|
7205 |
return this;
|
|
|
7206 |
};
|
|
|
7207 |
|
|
|
7208 |
elproto.show = function () {
|
|
|
7209 |
!this.removed && this.paper.safari(this.node.style.display = "");
|
|
|
7210 |
return this;
|
|
|
7211 |
};
|
|
|
7212 |
|
|
|
7213 |
elproto.remove = function () {
|
|
|
7214 |
if (this.removed) {
|
|
|
7215 |
return;
|
|
|
7216 |
}
|
|
|
7217 |
this.paper.__set__ && this.paper.__set__.exclude(this);
|
|
|
7218 |
eve.unbind("*.*." + this.id);
|
|
|
7219 |
R._tear(this, this.paper);
|
|
|
7220 |
this.node.parentNode.removeChild(this.node);
|
|
|
7221 |
for (var i in this) {
|
|
|
7222 |
delete this[i];
|
|
|
7223 |
}
|
|
|
7224 |
this.removed = true;
|
|
|
7225 |
};
|
|
|
7226 |
elproto._getBBox = function () {
|
|
|
7227 |
if (this.node.style.display == "none") {
|
|
|
7228 |
this.show();
|
|
|
7229 |
var hide = true;
|
|
|
7230 |
}
|
|
|
7231 |
var bbox = {};
|
|
|
7232 |
try {
|
|
|
7233 |
bbox = this.node.getBBox();
|
|
|
7234 |
} catch(e) {
|
|
|
7235 |
// Firefox 3.0.x plays badly here
|
|
|
7236 |
} finally {
|
|
|
7237 |
bbox = bbox || {};
|
|
|
7238 |
}
|
|
|
7239 |
hide && this.hide();
|
|
|
7240 |
return bbox;
|
|
|
7241 |
};
|
|
|
7242 |
|
|
|
7243 |
elproto.attr = function (name, value) {
|
|
|
7244 |
if (this.removed) {
|
|
|
7245 |
return this;
|
|
|
7246 |
}
|
|
|
7247 |
if (name == null) {
|
|
|
7248 |
var res = {};
|
|
|
7249 |
for (var a in this.attrs) if (this.attrs[has](a)) {
|
|
|
7250 |
res[a] = this.attrs[a];
|
|
|
7251 |
}
|
|
|
7252 |
res.gradient && res.fill == "none" && (res.fill = res.gradient) && delete res.gradient;
|
|
|
7253 |
res.transform = this._.transform;
|
|
|
7254 |
return res;
|
|
|
7255 |
}
|
|
|
7256 |
if (value == null && R.is(name, "string")) {
|
|
|
7257 |
if (name == "fill" && this.attrs.fill == "none" && this.attrs.gradient) {
|
|
|
7258 |
return this.attrs.gradient;
|
|
|
7259 |
}
|
|
|
7260 |
if (name == "transform") {
|
|
|
7261 |
return this._.transform;
|
|
|
7262 |
}
|
|
|
7263 |
var names = name.split(separator),
|
|
|
7264 |
out = {};
|
|
|
7265 |
for (var i = 0, ii = names.length; i < ii; i++) {
|
|
|
7266 |
name = names[i];
|
|
|
7267 |
if (name in this.attrs) {
|
|
|
7268 |
out[name] = this.attrs[name];
|
|
|
7269 |
} else if (R.is(this.paper.customAttributes[name], "function")) {
|
|
|
7270 |
out[name] = this.paper.customAttributes[name].def;
|
|
|
7271 |
} else {
|
|
|
7272 |
out[name] = R._availableAttrs[name];
|
|
|
7273 |
}
|
|
|
7274 |
}
|
|
|
7275 |
return ii - 1 ? out : out[names[0]];
|
|
|
7276 |
}
|
|
|
7277 |
if (value == null && R.is(name, "array")) {
|
|
|
7278 |
out = {};
|
|
|
7279 |
for (i = 0, ii = name.length; i < ii; i++) {
|
|
|
7280 |
out[name[i]] = this.attr(name[i]);
|
|
|
7281 |
}
|
|
|
7282 |
return out;
|
|
|
7283 |
}
|
|
|
7284 |
if (value != null) {
|
|
|
7285 |
var params = {};
|
|
|
7286 |
params[name] = value;
|
|
|
7287 |
} else if (name != null && R.is(name, "object")) {
|
|
|
7288 |
params = name;
|
|
|
7289 |
}
|
|
|
7290 |
for (var key in params) {
|
|
|
7291 |
eve("attr." + key + "." + this.id, this, params[key]);
|
|
|
7292 |
}
|
|
|
7293 |
for (key in this.paper.customAttributes) if (this.paper.customAttributes[has](key) && params[has](key) && R.is(this.paper.customAttributes[key], "function")) {
|
|
|
7294 |
var par = this.paper.customAttributes[key].apply(this, [].concat(params[key]));
|
|
|
7295 |
this.attrs[key] = params[key];
|
|
|
7296 |
for (var subkey in par) if (par[has](subkey)) {
|
|
|
7297 |
params[subkey] = par[subkey];
|
|
|
7298 |
}
|
|
|
7299 |
}
|
|
|
7300 |
setFillAndStroke(this, params);
|
|
|
7301 |
return this;
|
|
|
7302 |
};
|
|
|
7303 |
|
|
|
7304 |
elproto.toFront = function () {
|
|
|
7305 |
if (this.removed) {
|
|
|
7306 |
return this;
|
|
|
7307 |
}
|
|
|
7308 |
this.node.parentNode.appendChild(this.node);
|
|
|
7309 |
var svg = this.paper;
|
|
|
7310 |
svg.top != this && R._tofront(this, svg);
|
|
|
7311 |
return this;
|
|
|
7312 |
};
|
|
|
7313 |
|
|
|
7314 |
elproto.toBack = function () {
|
|
|
7315 |
if (this.removed) {
|
|
|
7316 |
return this;
|
|
|
7317 |
}
|
|
|
7318 |
if (this.node.parentNode.firstChild != this.node) {
|
|
|
7319 |
this.node.parentNode.insertBefore(this.node, this.node.parentNode.firstChild);
|
|
|
7320 |
R._toback(this, this.paper);
|
|
|
7321 |
var svg = this.paper;
|
|
|
7322 |
}
|
|
|
7323 |
return this;
|
|
|
7324 |
};
|
|
|
7325 |
|
|
|
7326 |
elproto.insertAfter = function (element) {
|
|
|
7327 |
if (this.removed) {
|
|
|
7328 |
return this;
|
|
|
7329 |
}
|
|
|
7330 |
var node = element.node || element[element.length - 1].node;
|
|
|
7331 |
if (node.nextSibling) {
|
|
|
7332 |
node.parentNode.insertBefore(this.node, node.nextSibling);
|
|
|
7333 |
} else {
|
|
|
7334 |
node.parentNode.appendChild(this.node);
|
|
|
7335 |
}
|
|
|
7336 |
R._insertafter(this, element, this.paper);
|
|
|
7337 |
return this;
|
|
|
7338 |
};
|
|
|
7339 |
|
|
|
7340 |
elproto.insertBefore = function (element) {
|
|
|
7341 |
if (this.removed) {
|
|
|
7342 |
return this;
|
|
|
7343 |
}
|
|
|
7344 |
var node = element.node || element[0].node;
|
|
|
7345 |
node.parentNode.insertBefore(this.node, node);
|
|
|
7346 |
R._insertbefore(this, element, this.paper);
|
|
|
7347 |
return this;
|
|
|
7348 |
};
|
|
|
7349 |
elproto.blur = function (size) {
|
|
|
7350 |
// Experimental. No Safari support. Use it on your own risk.
|
|
|
7351 |
var t = this;
|
|
|
7352 |
if (+size !== 0) {
|
|
|
7353 |
var fltr = $("filter"),
|
|
|
7354 |
blur = $("feGaussianBlur");
|
|
|
7355 |
t.attrs.blur = size;
|
|
|
7356 |
fltr.id = R.createUUID();
|
|
|
7357 |
$(blur, {stdDeviation: +size || 1.5});
|
|
|
7358 |
fltr.appendChild(blur);
|
|
|
7359 |
t.paper.defs.appendChild(fltr);
|
|
|
7360 |
t._blur = fltr;
|
|
|
7361 |
$(t.node, {filter: "url(#" + fltr.id + ")"});
|
|
|
7362 |
} else {
|
|
|
7363 |
if (t._blur) {
|
|
|
7364 |
t._blur.parentNode.removeChild(t._blur);
|
|
|
7365 |
delete t._blur;
|
|
|
7366 |
delete t.attrs.blur;
|
|
|
7367 |
}
|
|
|
7368 |
t.node.removeAttribute("filter");
|
|
|
7369 |
}
|
|
|
7370 |
};
|
|
|
7371 |
R._engine.circle = function (svg, x, y, r) {
|
|
|
7372 |
var el = $("circle");
|
|
|
7373 |
svg.canvas && svg.canvas.appendChild(el);
|
|
|
7374 |
var res = new Element(el, svg);
|
|
|
7375 |
res.attrs = {cx: x, cy: y, r: r, fill: "none", stroke: "#000"};
|
|
|
7376 |
res.type = "circle";
|
|
|
7377 |
$(el, res.attrs);
|
|
|
7378 |
return res;
|
|
|
7379 |
};
|
|
|
7380 |
R._engine.rect = function (svg, x, y, w, h, r) {
|
|
|
7381 |
var el = $("rect");
|
|
|
7382 |
svg.canvas && svg.canvas.appendChild(el);
|
|
|
7383 |
var res = new Element(el, svg);
|
|
|
7384 |
res.attrs = {x: x, y: y, width: w, height: h, r: r || 0, rx: r || 0, ry: r || 0, fill: "none", stroke: "#000"};
|
|
|
7385 |
res.type = "rect";
|
|
|
7386 |
$(el, res.attrs);
|
|
|
7387 |
return res;
|
|
|
7388 |
};
|
|
|
7389 |
R._engine.ellipse = function (svg, x, y, rx, ry) {
|
|
|
7390 |
var el = $("ellipse");
|
|
|
7391 |
svg.canvas && svg.canvas.appendChild(el);
|
|
|
7392 |
var res = new Element(el, svg);
|
|
|
7393 |
res.attrs = {cx: x, cy: y, rx: rx, ry: ry, fill: "none", stroke: "#000"};
|
|
|
7394 |
res.type = "ellipse";
|
|
|
7395 |
$(el, res.attrs);
|
|
|
7396 |
return res;
|
|
|
7397 |
};
|
|
|
7398 |
R._engine.image = function (svg, src, x, y, w, h) {
|
|
|
7399 |
var el = $("image");
|
|
|
7400 |
$(el, {x: x, y: y, width: w, height: h, preserveAspectRatio: "none"});
|
|
|
7401 |
el.setAttributeNS(xlink, "href", src);
|
|
|
7402 |
svg.canvas && svg.canvas.appendChild(el);
|
|
|
7403 |
var res = new Element(el, svg);
|
|
|
7404 |
res.attrs = {x: x, y: y, width: w, height: h, src: src};
|
|
|
7405 |
res.type = "image";
|
|
|
7406 |
return res;
|
|
|
7407 |
};
|
|
|
7408 |
R._engine.text = function (svg, x, y, text) {
|
|
|
7409 |
var el = $("text");
|
|
|
7410 |
// $(el, {x: x, y: y, "text-anchor": "middle"});
|
|
|
7411 |
svg.canvas && svg.canvas.appendChild(el);
|
|
|
7412 |
var res = new Element(el, svg);
|
|
|
7413 |
res.attrs = {
|
|
|
7414 |
x: x,
|
|
|
7415 |
y: y,
|
|
|
7416 |
"text-anchor": "middle",
|
|
|
7417 |
text: text,
|
|
|
7418 |
font: R._availableAttrs.font,
|
|
|
7419 |
stroke: "none",
|
|
|
7420 |
fill: "#000"
|
|
|
7421 |
};
|
|
|
7422 |
res.type = "text";
|
|
|
7423 |
setFillAndStroke(res, res.attrs);
|
|
|
7424 |
return res;
|
|
|
7425 |
};
|
|
|
7426 |
R._engine.setSize = function (width, height) {
|
|
|
7427 |
this.width = width || this.width;
|
|
|
7428 |
this.height = height || this.height;
|
|
|
7429 |
this.canvas.setAttribute("width", this.width);
|
|
|
7430 |
this.canvas.setAttribute("height", this.height);
|
|
|
7431 |
if (this._viewBox) {
|
|
|
7432 |
this.setViewBox.apply(this, this._viewBox);
|
|
|
7433 |
}
|
|
|
7434 |
return this;
|
|
|
7435 |
};
|
|
|
7436 |
R._engine.create = function () {
|
|
|
7437 |
var con = R._getContainer.apply(0, arguments),
|
|
|
7438 |
container = con && con.container,
|
|
|
7439 |
x = con.x,
|
|
|
7440 |
y = con.y,
|
|
|
7441 |
width = con.width,
|
|
|
7442 |
height = con.height;
|
|
|
7443 |
if (!container) {
|
|
|
7444 |
throw new Error("SVG container not found.");
|
|
|
7445 |
}
|
|
|
7446 |
var cnvs = $("svg"),
|
|
|
7447 |
css = "overflow:hidden;",
|
|
|
7448 |
isFloating;
|
|
|
7449 |
x = x || 0;
|
|
|
7450 |
y = y || 0;
|
|
|
7451 |
width = width || 512;
|
|
|
7452 |
height = height || 342;
|
|
|
7453 |
$(cnvs, {
|
|
|
7454 |
height: height,
|
|
|
7455 |
version: 1.1,
|
|
|
7456 |
width: width,
|
|
|
7457 |
xmlns: "http://www.w3.org/2000/svg"
|
|
|
7458 |
});
|
|
|
7459 |
if (container == 1) {
|
|
|
7460 |
cnvs.style.cssText = css + "position:absolute;left:" + x + "px;top:" + y + "px";
|
|
|
7461 |
R._g.doc.body.appendChild(cnvs);
|
|
|
7462 |
isFloating = 1;
|
|
|
7463 |
} else {
|
|
|
7464 |
cnvs.style.cssText = css + "position:relative";
|
|
|
7465 |
if (container.firstChild) {
|
|
|
7466 |
container.insertBefore(cnvs, container.firstChild);
|
|
|
7467 |
} else {
|
|
|
7468 |
container.appendChild(cnvs);
|
|
|
7469 |
}
|
|
|
7470 |
}
|
|
|
7471 |
container = new R._Paper;
|
|
|
7472 |
container.width = width;
|
|
|
7473 |
container.height = height;
|
|
|
7474 |
container.canvas = cnvs;
|
|
|
7475 |
// plugins.call(container, container, R.fn);
|
|
|
7476 |
container.clear();
|
|
|
7477 |
container._left = container._top = 0;
|
|
|
7478 |
isFloating && (container.renderfix = function () {});
|
|
|
7479 |
container.renderfix();
|
|
|
7480 |
return container;
|
|
|
7481 |
};
|
|
|
7482 |
R._engine.setViewBox = function (x, y, w, h, fit) {
|
|
|
7483 |
eve("setViewBox", this, this._viewBox, [x, y, w, h, fit]);
|
|
|
7484 |
var size = mmax(w / this.width, h / this.height),
|
|
|
7485 |
top = this.top,
|
|
|
7486 |
aspectRatio = fit ? "meet" : "xMinYMin",
|
|
|
7487 |
vb,
|
|
|
7488 |
sw;
|
|
|
7489 |
if (x == null) {
|
|
|
7490 |
if (this._vbSize) {
|
|
|
7491 |
size = 1;
|
|
|
7492 |
}
|
|
|
7493 |
delete this._vbSize;
|
|
|
7494 |
vb = "0 0 " + this.width + S + this.height;
|
|
|
7495 |
} else {
|
|
|
7496 |
this._vbSize = size;
|
|
|
7497 |
vb = x + S + y + S + w + S + h;
|
|
|
7498 |
}
|
|
|
7499 |
$(this.canvas, {
|
|
|
7500 |
viewBox: vb,
|
|
|
7501 |
preserveAspectRatio: aspectRatio
|
|
|
7502 |
});
|
|
|
7503 |
while (size && top) {
|
|
|
7504 |
sw = "stroke-width" in top.attrs ? top.attrs["stroke-width"] : 1;
|
|
|
7505 |
top.attr({"stroke-width": sw});
|
|
|
7506 |
top._.dirty = 1;
|
|
|
7507 |
top._.dirtyT = 1;
|
|
|
7508 |
top = top.prev;
|
|
|
7509 |
}
|
|
|
7510 |
this._viewBox = [x, y, w, h, !!fit];
|
|
|
7511 |
return this;
|
|
|
7512 |
};
|
|
|
7513 |
|
|
|
7514 |
R.prototype.renderfix = function () {
|
|
|
7515 |
var cnvs = this.canvas,
|
|
|
7516 |
s = cnvs.style,
|
|
|
7517 |
pos = cnvs.getScreenCTM() || cnvs.createSVGMatrix(),
|
|
|
7518 |
left = -pos.e % 1,
|
|
|
7519 |
top = -pos.f % 1;
|
|
|
7520 |
if (left || top) {
|
|
|
7521 |
if (left) {
|
|
|
7522 |
this._left = (this._left + left) % 1;
|
|
|
7523 |
s.left = this._left + "px";
|
|
|
7524 |
}
|
|
|
7525 |
if (top) {
|
|
|
7526 |
this._top = (this._top + top) % 1;
|
|
|
7527 |
s.top = this._top + "px";
|
|
|
7528 |
}
|
|
|
7529 |
}
|
|
|
7530 |
};
|
|
|
7531 |
|
|
|
7532 |
R.prototype.clear = function () {
|
|
|
7533 |
R.eve("clear", this);
|
|
|
7534 |
var c = this.canvas;
|
|
|
7535 |
while (c.firstChild) {
|
|
|
7536 |
c.removeChild(c.firstChild);
|
|
|
7537 |
}
|
|
|
7538 |
this.bottom = this.top = null;
|
|
|
7539 |
(this.desc = $("desc")).appendChild(R._g.doc.createTextNode("Created with Rapha\xebl " + R.version));
|
|
|
7540 |
c.appendChild(this.desc);
|
|
|
7541 |
c.appendChild(this.defs = $("defs"));
|
|
|
7542 |
};
|
|
|
7543 |
|
|
|
7544 |
R.prototype.remove = function () {
|
|
|
7545 |
eve("remove", this);
|
|
|
7546 |
this.canvas.parentNode && this.canvas.parentNode.removeChild(this.canvas);
|
|
|
7547 |
for (var i in this) {
|
|
|
7548 |
this[i] = removed(i);
|
|
|
7549 |
}
|
|
|
7550 |
};
|
|
|
7551 |
var setproto = R.st;
|
|
|
7552 |
for (var method in elproto) if (elproto[has](method) && !setproto[has](method)) {
|
|
|
7553 |
setproto[method] = (function (methodname) {
|
|
|
7554 |
return function () {
|
|
|
7555 |
var arg = arguments;
|
|
|
7556 |
return this.forEach(function (el) {
|
|
|
7557 |
el[methodname].apply(el, arg);
|
|
|
7558 |
});
|
|
|
7559 |
};
|
|
|
7560 |
})(method);
|
|
|
7561 |
}
|
|
|
7562 |
}(window.Raphael);
|
|
|
7563 |
|
|
|
7564 |
// ┌─────────────────────────────────────────────────────────────────────┐ \\
|
|
|
7565 |
// │ Raphaël 2 - JavaScript Vector Library │ \\
|
|
|
7566 |
// ├─────────────────────────────────────────────────────────────────────┤ \\
|
|
|
7567 |
// │ VML Module │ \\
|
|
|
7568 |
// ├─────────────────────────────────────────────────────────────────────┤ \\
|
|
|
7569 |
// │ Copyright (c) 2008-2011 Dmitry Baranovskiy (http://raphaeljs.com) │ \\
|
|
|
7570 |
// │ Copyright (c) 2008-2011 Sencha Labs (http://sencha.com) │ \\
|
|
|
7571 |
// │ Licensed under the MIT (http://raphaeljs.com/license.html) license. │ \\
|
|
|
7572 |
// └─────────────────────────────────────────────────────────────────────┘ \\
|
|
|
7573 |
window.Raphael.vml && function (R) {
|
|
|
7574 |
var has = "hasOwnProperty",
|
|
|
7575 |
Str = String,
|
|
|
7576 |
toFloat = parseFloat,
|
|
|
7577 |
math = Math,
|
|
|
7578 |
round = math.round,
|
|
|
7579 |
mmax = math.max,
|
|
|
7580 |
mmin = math.min,
|
|
|
7581 |
abs = math.abs,
|
|
|
7582 |
fillString = "fill",
|
|
|
7583 |
separator = /[, ]+/,
|
|
|
7584 |
eve = R.eve,
|
|
|
7585 |
ms = " progid:DXImageTransform.Microsoft",
|
|
|
7586 |
S = " ",
|
|
|
7587 |
E = "",
|
|
|
7588 |
map = {M: "m", L: "l", C: "c", Z: "x", m: "t", l: "r", c: "v", z: "x"},
|
|
|
7589 |
bites = /([clmz]),?([^clmz]*)/gi,
|
|
|
7590 |
blurregexp = / progid:\S+Blur\([^\)]+\)/g,
|
|
|
7591 |
val = /-?[^,\s-]+/g,
|
|
|
7592 |
cssDot = "position:absolute;left:0;top:0;width:1px;height:1px",
|
|
|
7593 |
zoom = 21600,
|
|
|
7594 |
pathTypes = {path: 1, rect: 1, image: 1},
|
|
|
7595 |
ovalTypes = {circle: 1, ellipse: 1},
|
|
|
7596 |
path2vml = function (path) {
|
|
|
7597 |
var total = /[ahqstv]/ig,
|
|
|
7598 |
command = R._pathToAbsolute;
|
|
|
7599 |
Str(path).match(total) && (command = R._path2curve);
|
|
|
7600 |
total = /[clmz]/g;
|
|
|
7601 |
if (command == R._pathToAbsolute && !Str(path).match(total)) {
|
|
|
7602 |
var res = Str(path).replace(bites, function (all, command, args) {
|
|
|
7603 |
var vals = [],
|
|
|
7604 |
isMove = command.toLowerCase() == "m",
|
|
|
7605 |
res = map[command];
|
|
|
7606 |
args.replace(val, function (value) {
|
|
|
7607 |
if (isMove && vals.length == 2) {
|
|
|
7608 |
res += vals + map[command == "m" ? "l" : "L"];
|
|
|
7609 |
vals = [];
|
|
|
7610 |
}
|
|
|
7611 |
vals.push(round(value * zoom));
|
|
|
7612 |
});
|
|
|
7613 |
return res + vals;
|
|
|
7614 |
});
|
|
|
7615 |
return res;
|
|
|
7616 |
}
|
|
|
7617 |
var pa = command(path), p, r;
|
|
|
7618 |
res = [];
|
|
|
7619 |
for (var i = 0, ii = pa.length; i < ii; i++) {
|
|
|
7620 |
p = pa[i];
|
|
|
7621 |
r = pa[i][0].toLowerCase();
|
|
|
7622 |
r == "z" && (r = "x");
|
|
|
7623 |
for (var j = 1, jj = p.length; j < jj; j++) {
|
|
|
7624 |
r += round(p[j] * zoom) + (j != jj - 1 ? "," : E);
|
|
|
7625 |
}
|
|
|
7626 |
res.push(r);
|
|
|
7627 |
}
|
|
|
7628 |
return res.join(S);
|
|
|
7629 |
},
|
|
|
7630 |
compensation = function (deg, dx, dy) {
|
|
|
7631 |
var m = R.matrix();
|
|
|
7632 |
m.rotate(-deg, .5, .5);
|
|
|
7633 |
return {
|
|
|
7634 |
dx: m.x(dx, dy),
|
|
|
7635 |
dy: m.y(dx, dy)
|
|
|
7636 |
};
|
|
|
7637 |
},
|
|
|
7638 |
setCoords = function (p, sx, sy, dx, dy, deg) {
|
|
|
7639 |
var _ = p._,
|
|
|
7640 |
m = p.matrix,
|
|
|
7641 |
fillpos = _.fillpos,
|
|
|
7642 |
o = p.node,
|
|
|
7643 |
s = o.style,
|
|
|
7644 |
y = 1,
|
|
|
7645 |
flip = "",
|
|
|
7646 |
dxdy,
|
|
|
7647 |
kx = zoom / sx,
|
|
|
7648 |
ky = zoom / sy;
|
|
|
7649 |
s.visibility = "hidden";
|
|
|
7650 |
if (!sx || !sy) {
|
|
|
7651 |
return;
|
|
|
7652 |
}
|
|
|
7653 |
o.coordsize = abs(kx) + S + abs(ky);
|
|
|
7654 |
s.rotation = deg * (sx * sy < 0 ? -1 : 1);
|
|
|
7655 |
if (deg) {
|
|
|
7656 |
var c = compensation(deg, dx, dy);
|
|
|
7657 |
dx = c.dx;
|
|
|
7658 |
dy = c.dy;
|
|
|
7659 |
}
|
|
|
7660 |
sx < 0 && (flip += "x");
|
|
|
7661 |
sy < 0 && (flip += " y") && (y = -1);
|
|
|
7662 |
s.flip = flip;
|
|
|
7663 |
o.coordorigin = (dx * -kx) + S + (dy * -ky);
|
|
|
7664 |
if (fillpos || _.fillsize) {
|
|
|
7665 |
var fill = o.getElementsByTagName(fillString);
|
|
|
7666 |
fill = fill && fill[0];
|
|
|
7667 |
o.removeChild(fill);
|
|
|
7668 |
if (fillpos) {
|
|
|
7669 |
c = compensation(deg, m.x(fillpos[0], fillpos[1]), m.y(fillpos[0], fillpos[1]));
|
|
|
7670 |
fill.position = c.dx * y + S + c.dy * y;
|
|
|
7671 |
}
|
|
|
7672 |
if (_.fillsize) {
|
|
|
7673 |
fill.size = _.fillsize[0] * abs(sx) + S + _.fillsize[1] * abs(sy);
|
|
|
7674 |
}
|
|
|
7675 |
o.appendChild(fill);
|
|
|
7676 |
}
|
|
|
7677 |
s.visibility = "visible";
|
|
|
7678 |
};
|
|
|
7679 |
R.toString = function () {
|
|
|
7680 |
return "Your browser doesn\u2019t support SVG. Falling down to VML.\nYou are running Rapha\xebl " + this.version;
|
|
|
7681 |
};
|
|
|
7682 |
addArrow = function (o, value, isEnd) {
|
|
|
7683 |
var values = Str(value).toLowerCase().split("-"),
|
|
|
7684 |
se = isEnd ? "end" : "start",
|
|
|
7685 |
i = values.length,
|
|
|
7686 |
type = "classic",
|
|
|
7687 |
w = "medium",
|
|
|
7688 |
h = "medium";
|
|
|
7689 |
while (i--) {
|
|
|
7690 |
switch (values[i]) {
|
|
|
7691 |
case "block":
|
|
|
7692 |
case "classic":
|
|
|
7693 |
case "oval":
|
|
|
7694 |
case "diamond":
|
|
|
7695 |
case "open":
|
|
|
7696 |
case "none":
|
|
|
7697 |
type = values[i];
|
|
|
7698 |
break;
|
|
|
7699 |
case "wide":
|
|
|
7700 |
case "narrow": h = values[i]; break;
|
|
|
7701 |
case "long":
|
|
|
7702 |
case "short": w = values[i]; break;
|
|
|
7703 |
}
|
|
|
7704 |
}
|
|
|
7705 |
var stroke = o.node.getElementsByTagName("stroke")[0];
|
|
|
7706 |
stroke[se + "arrow"] = type;
|
|
|
7707 |
stroke[se + "arrowlength"] = w;
|
|
|
7708 |
stroke[se + "arrowwidth"] = h;
|
|
|
7709 |
};
|
|
|
7710 |
setFillAndStroke = function (o, params) {
|
|
|
7711 |
// o.paper.canvas.style.display = "none";
|
|
|
7712 |
o.attrs = o.attrs || {};
|
|
|
7713 |
var node = o.node,
|
|
|
7714 |
a = o.attrs,
|
|
|
7715 |
s = node.style,
|
|
|
7716 |
xy,
|
|
|
7717 |
newpath = pathTypes[o.type] && (params.x != a.x || params.y != a.y || params.width != a.width || params.height != a.height || params.cx != a.cx || params.cy != a.cy || params.rx != a.rx || params.ry != a.ry || params.r != a.r),
|
|
|
7718 |
isOval = ovalTypes[o.type] && (a.cx != params.cx || a.cy != params.cy || a.r != params.r || a.rx != params.rx || a.ry != params.ry),
|
|
|
7719 |
res = o;
|
|
|
7720 |
|
|
|
7721 |
|
|
|
7722 |
for (var par in params) if (params[has](par)) {
|
|
|
7723 |
a[par] = params[par];
|
|
|
7724 |
}
|
|
|
7725 |
if (newpath) {
|
|
|
7726 |
a.path = R._getPath[o.type](o);
|
|
|
7727 |
o._.dirty = 1;
|
|
|
7728 |
}
|
|
|
7729 |
params.href && (node.href = params.href);
|
|
|
7730 |
params.title && (node.title = params.title);
|
|
|
7731 |
params.target && (node.target = params.target);
|
|
|
7732 |
params.cursor && (s.cursor = params.cursor);
|
|
|
7733 |
"blur" in params && o.blur(params.blur);
|
|
|
7734 |
if (params.path && o.type == "path" || newpath) {
|
|
|
7735 |
node.path = path2vml(~Str(a.path).toLowerCase().indexOf("r") ? R._pathToAbsolute(a.path) : a.path);
|
|
|
7736 |
if (o.type == "image") {
|
|
|
7737 |
o._.fillpos = [a.x, a.y];
|
|
|
7738 |
o._.fillsize = [a.width, a.height];
|
|
|
7739 |
setCoords(o, 1, 1, 0, 0, 0);
|
|
|
7740 |
}
|
|
|
7741 |
}
|
|
|
7742 |
"transform" in params && o.transform(params.transform);
|
|
|
7743 |
if (isOval) {
|
|
|
7744 |
var cx = +a.cx,
|
|
|
7745 |
cy = +a.cy,
|
|
|
7746 |
rx = +a.rx || +a.r || 0,
|
|
|
7747 |
ry = +a.ry || +a.r || 0;
|
|
|
7748 |
node.path = R.format("ar{0},{1},{2},{3},{4},{1},{4},{1}x", round((cx - rx) * zoom), round((cy - ry) * zoom), round((cx + rx) * zoom), round((cy + ry) * zoom), round(cx * zoom));
|
|
|
7749 |
}
|
|
|
7750 |
if ("clip-rect" in params) {
|
|
|
7751 |
var rect = Str(params["clip-rect"]).split(separator);
|
|
|
7752 |
if (rect.length == 4) {
|
|
|
7753 |
rect[2] = +rect[2] + (+rect[0]);
|
|
|
7754 |
rect[3] = +rect[3] + (+rect[1]);
|
|
|
7755 |
var div = node.clipRect || R._g.doc.createElement("div"),
|
|
|
7756 |
dstyle = div.style;
|
|
|
7757 |
dstyle.clip = R.format("rect({1}px {2}px {3}px {0}px)", rect);
|
|
|
7758 |
if (!node.clipRect) {
|
|
|
7759 |
dstyle.position = "absolute";
|
|
|
7760 |
dstyle.top = 0;
|
|
|
7761 |
dstyle.left = 0;
|
|
|
7762 |
dstyle.width = o.paper.width + "px";
|
|
|
7763 |
dstyle.height = o.paper.height + "px";
|
|
|
7764 |
node.parentNode.insertBefore(div, node);
|
|
|
7765 |
div.appendChild(node);
|
|
|
7766 |
node.clipRect = div;
|
|
|
7767 |
}
|
|
|
7768 |
}
|
|
|
7769 |
if (!params["clip-rect"]) {
|
|
|
7770 |
node.clipRect && (node.clipRect.style.clip = E);
|
|
|
7771 |
}
|
|
|
7772 |
}
|
|
|
7773 |
if (o.textpath) {
|
|
|
7774 |
var textpathStyle = o.textpath.style;
|
|
|
7775 |
params.font && (textpathStyle.font = params.font);
|
|
|
7776 |
params["font-family"] && (textpathStyle.fontFamily = '"' + params["font-family"].split(",")[0].replace(/^['"]+|['"]+$/g, E) + '"');
|
|
|
7777 |
params["font-size"] && (textpathStyle.fontSize = params["font-size"]);
|
|
|
7778 |
params["font-weight"] && (textpathStyle.fontWeight = params["font-weight"]);
|
|
|
7779 |
params["font-style"] && (textpathStyle.fontStyle = params["font-style"]);
|
|
|
7780 |
}
|
|
|
7781 |
if ("arrow-start" in params) {
|
|
|
7782 |
addArrow(res, params["arrow-start"]);
|
|
|
7783 |
}
|
|
|
7784 |
if ("arrow-end" in params) {
|
|
|
7785 |
addArrow(res, params["arrow-end"], 1);
|
|
|
7786 |
}
|
|
|
7787 |
if (params.opacity != null ||
|
|
|
7788 |
params["stroke-width"] != null ||
|
|
|
7789 |
params.fill != null ||
|
|
|
7790 |
params.src != null ||
|
|
|
7791 |
params.stroke != null ||
|
|
|
7792 |
params["stroke-width"] != null ||
|
|
|
7793 |
params["stroke-opacity"] != null ||
|
|
|
7794 |
params["fill-opacity"] != null ||
|
|
|
7795 |
params["stroke-dasharray"] != null ||
|
|
|
7796 |
params["stroke-miterlimit"] != null ||
|
|
|
7797 |
params["stroke-linejoin"] != null ||
|
|
|
7798 |
params["stroke-linecap"] != null) {
|
|
|
7799 |
var fill = node.getElementsByTagName(fillString),
|
|
|
7800 |
newfill = false;
|
|
|
7801 |
fill = fill && fill[0];
|
|
|
7802 |
!fill && (newfill = fill = createNode(fillString));
|
|
|
7803 |
if (o.type == "image" && params.src) {
|
|
|
7804 |
fill.src = params.src;
|
|
|
7805 |
}
|
|
|
7806 |
params.fill && (fill.on = true);
|
|
|
7807 |
if (fill.on == null || params.fill == "none" || params.fill === null) {
|
|
|
7808 |
fill.on = false;
|
|
|
7809 |
}
|
|
|
7810 |
if (fill.on && params.fill) {
|
|
|
7811 |
var isURL = Str(params.fill).match(R._ISURL);
|
|
|
7812 |
if (isURL) {
|
|
|
7813 |
fill.parentNode == node && node.removeChild(fill);
|
|
|
7814 |
fill.rotate = true;
|
|
|
7815 |
fill.src = isURL[1];
|
|
|
7816 |
fill.type = "tile";
|
|
|
7817 |
var bbox = o.getBBox(1);
|
|
|
7818 |
fill.position = bbox.x + S + bbox.y;
|
|
|
7819 |
o._.fillpos = [bbox.x, bbox.y];
|
|
|
7820 |
|
|
|
7821 |
R._preload(isURL[1], function () {
|
|
|
7822 |
o._.fillsize = [this.offsetWidth, this.offsetHeight];
|
|
|
7823 |
});
|
|
|
7824 |
} else {
|
|
|
7825 |
fill.color = R.getRGB(params.fill).hex;
|
|
|
7826 |
fill.src = E;
|
|
|
7827 |
fill.type = "solid";
|
|
|
7828 |
if (R.getRGB(params.fill).error && (res.type in {circle: 1, ellipse: 1} || Str(params.fill).charAt() != "r") && addGradientFill(res, params.fill, fill)) {
|
|
|
7829 |
a.fill = "none";
|
|
|
7830 |
a.gradient = params.fill;
|
|
|
7831 |
fill.rotate = false;
|
|
|
7832 |
}
|
|
|
7833 |
}
|
|
|
7834 |
}
|
|
|
7835 |
if ("fill-opacity" in params || "opacity" in params) {
|
|
|
7836 |
var opacity = ((+a["fill-opacity"] + 1 || 2) - 1) * ((+a.opacity + 1 || 2) - 1) * ((+R.getRGB(params.fill).o + 1 || 2) - 1);
|
|
|
7837 |
opacity = mmin(mmax(opacity, 0), 1);
|
|
|
7838 |
fill.opacity = opacity;
|
|
|
7839 |
if (fill.src) {
|
|
|
7840 |
fill.color = "none";
|
|
|
7841 |
}
|
|
|
7842 |
}
|
|
|
7843 |
node.appendChild(fill);
|
|
|
7844 |
var stroke = (node.getElementsByTagName("stroke") && node.getElementsByTagName("stroke")[0]),
|
|
|
7845 |
newstroke = false;
|
|
|
7846 |
!stroke && (newstroke = stroke = createNode("stroke"));
|
|
|
7847 |
if ((params.stroke && params.stroke != "none") ||
|
|
|
7848 |
params["stroke-width"] ||
|
|
|
7849 |
params["stroke-opacity"] != null ||
|
|
|
7850 |
params["stroke-dasharray"] ||
|
|
|
7851 |
params["stroke-miterlimit"] ||
|
|
|
7852 |
params["stroke-linejoin"] ||
|
|
|
7853 |
params["stroke-linecap"]) {
|
|
|
7854 |
stroke.on = true;
|
|
|
7855 |
}
|
|
|
7856 |
(params.stroke == "none" || params.stroke === null || stroke.on == null || params.stroke == 0 || params["stroke-width"] == 0) && (stroke.on = false);
|
|
|
7857 |
var strokeColor = R.getRGB(params.stroke);
|
|
|
7858 |
stroke.on && params.stroke && (stroke.color = strokeColor.hex);
|
|
|
7859 |
opacity = ((+a["stroke-opacity"] + 1 || 2) - 1) * ((+a.opacity + 1 || 2) - 1) * ((+strokeColor.o + 1 || 2) - 1);
|
|
|
7860 |
var width = (toFloat(params["stroke-width"]) || 1) * .75;
|
|
|
7861 |
opacity = mmin(mmax(opacity, 0), 1);
|
|
|
7862 |
params["stroke-width"] == null && (width = a["stroke-width"]);
|
|
|
7863 |
params["stroke-width"] && (stroke.weight = width);
|
|
|
7864 |
width && width < 1 && (opacity *= width) && (stroke.weight = 1);
|
|
|
7865 |
stroke.opacity = opacity;
|
|
|
7866 |
|
|
|
7867 |
params["stroke-linejoin"] && (stroke.joinstyle = params["stroke-linejoin"] || "miter");
|
|
|
7868 |
stroke.miterlimit = params["stroke-miterlimit"] || 8;
|
|
|
7869 |
params["stroke-linecap"] && (stroke.endcap = params["stroke-linecap"] == "butt" ? "flat" : params["stroke-linecap"] == "square" ? "square" : "round");
|
|
|
7870 |
if (params["stroke-dasharray"]) {
|
|
|
7871 |
var dasharray = {
|
|
|
7872 |
"-": "shortdash",
|
|
|
7873 |
".": "shortdot",
|
|
|
7874 |
"-.": "shortdashdot",
|
|
|
7875 |
"-..": "shortdashdotdot",
|
|
|
7876 |
". ": "dot",
|
|
|
7877 |
"- ": "dash",
|
|
|
7878 |
"--": "longdash",
|
|
|
7879 |
"- .": "dashdot",
|
|
|
7880 |
"--.": "longdashdot",
|
|
|
7881 |
"--..": "longdashdotdot"
|
|
|
7882 |
};
|
|
|
7883 |
stroke.dashstyle = dasharray[has](params["stroke-dasharray"]) ? dasharray[params["stroke-dasharray"]] : E;
|
|
|
7884 |
}
|
|
|
7885 |
newstroke && node.appendChild(stroke);
|
|
|
7886 |
}
|
|
|
7887 |
if (res.type == "text") {
|
|
|
7888 |
res.paper.canvas.style.display = E;
|
|
|
7889 |
var span = res.paper.span,
|
|
|
7890 |
m = 100,
|
|
|
7891 |
fontSize = a.font && a.font.match(/\d+(?:\.\d*)?(?=px)/);
|
|
|
7892 |
s = span.style;
|
|
|
7893 |
a.font && (s.font = a.font);
|
|
|
7894 |
a["font-family"] && (s.fontFamily = a["font-family"]);
|
|
|
7895 |
a["font-weight"] && (s.fontWeight = a["font-weight"]);
|
|
|
7896 |
a["font-style"] && (s.fontStyle = a["font-style"]);
|
|
|
7897 |
fontSize = toFloat(fontSize ? fontSize[0] : a["font-size"]);
|
|
|
7898 |
s.fontSize = fontSize * m + "px";
|
|
|
7899 |
res.textpath.string && (span.innerHTML = Str(res.textpath.string).replace(/</g, "<").replace(/&/g, "&").replace(/\n/g, "<br>"));
|
|
|
7900 |
var brect = span.getBoundingClientRect();
|
|
|
7901 |
res.W = a.w = (brect.right - brect.left) / m;
|
|
|
7902 |
res.H = a.h = (brect.bottom - brect.top) / m;
|
|
|
7903 |
// res.paper.canvas.style.display = "none";
|
|
|
7904 |
res.X = a.x;
|
|
|
7905 |
res.Y = a.y + res.H / 2;
|
|
|
7906 |
|
|
|
7907 |
("x" in params || "y" in params) && (res.path.v = R.format("m{0},{1}l{2},{1}", round(a.x * zoom), round(a.y * zoom), round(a.x * zoom) + 1));
|
|
|
7908 |
var dirtyattrs = ["x", "y", "text", "font", "font-family", "font-weight", "font-style", "font-size"];
|
|
|
7909 |
for (var d = 0, dd = dirtyattrs.length; d < dd; d++) if (dirtyattrs[d] in params) {
|
|
|
7910 |
res._.dirty = 1;
|
|
|
7911 |
break;
|
|
|
7912 |
}
|
|
|
7913 |
|
|
|
7914 |
// text-anchor emulation
|
|
|
7915 |
switch (a["text-anchor"]) {
|
|
|
7916 |
case "start":
|
|
|
7917 |
res.textpath.style["v-text-align"] = "left";
|
|
|
7918 |
res.bbx = res.W / 2;
|
|
|
7919 |
break;
|
|
|
7920 |
case "end":
|
|
|
7921 |
res.textpath.style["v-text-align"] = "right";
|
|
|
7922 |
res.bbx = -res.W / 2;
|
|
|
7923 |
break;
|
|
|
7924 |
default:
|
|
|
7925 |
res.textpath.style["v-text-align"] = "center";
|
|
|
7926 |
res.bbx = 0;
|
|
|
7927 |
break;
|
|
|
7928 |
}
|
|
|
7929 |
res.textpath.style["v-text-kern"] = true;
|
|
|
7930 |
}
|
|
|
7931 |
// res.paper.canvas.style.display = E;
|
|
|
7932 |
};
|
|
|
7933 |
addGradientFill = function (o, gradient, fill) {
|
|
|
7934 |
o.attrs = o.attrs || {};
|
|
|
7935 |
var attrs = o.attrs,
|
|
|
7936 |
pow = Math.pow,
|
|
|
7937 |
opacity,
|
|
|
7938 |
oindex,
|
|
|
7939 |
type = "linear",
|
|
|
7940 |
fxfy = ".5 .5";
|
|
|
7941 |
o.attrs.gradient = gradient;
|
|
|
7942 |
gradient = Str(gradient).replace(R._radial_gradient, function (all, fx, fy) {
|
|
|
7943 |
type = "radial";
|
|
|
7944 |
if (fx && fy) {
|
|
|
7945 |
fx = toFloat(fx);
|
|
|
7946 |
fy = toFloat(fy);
|
|
|
7947 |
pow(fx - .5, 2) + pow(fy - .5, 2) > .25 && (fy = math.sqrt(.25 - pow(fx - .5, 2)) * ((fy > .5) * 2 - 1) + .5);
|
|
|
7948 |
fxfy = fx + S + fy;
|
|
|
7949 |
}
|
|
|
7950 |
return E;
|
|
|
7951 |
});
|
|
|
7952 |
gradient = gradient.split(/\s*\-\s*/);
|
|
|
7953 |
if (type == "linear") {
|
|
|
7954 |
var angle = gradient.shift();
|
|
|
7955 |
angle = -toFloat(angle);
|
|
|
7956 |
if (isNaN(angle)) {
|
|
|
7957 |
return null;
|
|
|
7958 |
}
|
|
|
7959 |
}
|
|
|
7960 |
var dots = R._parseDots(gradient);
|
|
|
7961 |
if (!dots) {
|
|
|
7962 |
return null;
|
|
|
7963 |
}
|
|
|
7964 |
o = o.shape || o.node;
|
|
|
7965 |
if (dots.length) {
|
|
|
7966 |
o.removeChild(fill);
|
|
|
7967 |
fill.on = true;
|
|
|
7968 |
fill.method = "none";
|
|
|
7969 |
fill.color = dots[0].color;
|
|
|
7970 |
fill.color2 = dots[dots.length - 1].color;
|
|
|
7971 |
var clrs = [];
|
|
|
7972 |
for (var i = 0, ii = dots.length; i < ii; i++) {
|
|
|
7973 |
dots[i].offset && clrs.push(dots[i].offset + S + dots[i].color);
|
|
|
7974 |
}
|
|
|
7975 |
fill.colors = clrs.length ? clrs.join() : "0% " + fill.color;
|
|
|
7976 |
if (type == "radial") {
|
|
|
7977 |
fill.type = "gradientTitle";
|
|
|
7978 |
fill.focus = "100%";
|
|
|
7979 |
fill.focussize = "0 0";
|
|
|
7980 |
fill.focusposition = fxfy;
|
|
|
7981 |
fill.angle = 0;
|
|
|
7982 |
} else {
|
|
|
7983 |
// fill.rotate= true;
|
|
|
7984 |
fill.type = "gradient";
|
|
|
7985 |
fill.angle = (270 - angle) % 360;
|
|
|
7986 |
}
|
|
|
7987 |
o.appendChild(fill);
|
|
|
7988 |
}
|
|
|
7989 |
return 1;
|
|
|
7990 |
};
|
|
|
7991 |
Element = function (node, vml) {
|
|
|
7992 |
this[0] = this.node = node;
|
|
|
7993 |
node.raphael = true;
|
|
|
7994 |
this.id = R._oid++;
|
|
|
7995 |
node.raphaelid = this.id;
|
|
|
7996 |
this.X = 0;
|
|
|
7997 |
this.Y = 0;
|
|
|
7998 |
this.attrs = {};
|
|
|
7999 |
this.paper = vml;
|
|
|
8000 |
this.matrix = R.matrix();
|
|
|
8001 |
this._ = {
|
|
|
8002 |
transform: [],
|
|
|
8003 |
sx: 1,
|
|
|
8004 |
sy: 1,
|
|
|
8005 |
dx: 0,
|
|
|
8006 |
dy: 0,
|
|
|
8007 |
deg: 0,
|
|
|
8008 |
dirty: 1,
|
|
|
8009 |
dirtyT: 1
|
|
|
8010 |
};
|
|
|
8011 |
!vml.bottom && (vml.bottom = this);
|
|
|
8012 |
this.prev = vml.top;
|
|
|
8013 |
vml.top && (vml.top.next = this);
|
|
|
8014 |
vml.top = this;
|
|
|
8015 |
this.next = null;
|
|
|
8016 |
};
|
|
|
8017 |
var elproto = R.el;
|
|
|
8018 |
|
|
|
8019 |
Element.prototype = elproto;
|
|
|
8020 |
elproto.constructor = Element;
|
|
|
8021 |
elproto.transform = function (tstr) {
|
|
|
8022 |
if (tstr == null) {
|
|
|
8023 |
return this._.transform;
|
|
|
8024 |
}
|
|
|
8025 |
var vbs = this.paper._viewBoxShift,
|
|
|
8026 |
vbt = vbs ? "s" + [vbs.scale, vbs.scale] + "-1-1t" + [vbs.dx, vbs.dy] : E,
|
|
|
8027 |
oldt;
|
|
|
8028 |
if (vbs) {
|
|
|
8029 |
oldt = tstr = Str(tstr).replace(/\.{3}|\u2026/g, this._.transform || E);
|
|
|
8030 |
}
|
|
|
8031 |
R._extractTransform(this, vbt + tstr);
|
|
|
8032 |
var matrix = this.matrix.clone(),
|
|
|
8033 |
skew = this.skew,
|
|
|
8034 |
o = this.node,
|
|
|
8035 |
split,
|
|
|
8036 |
isGrad = ~Str(this.attrs.fill).indexOf("-"),
|
|
|
8037 |
isPatt = !Str(this.attrs.fill).indexOf("url(");
|
|
|
8038 |
matrix.translate(-.5, -.5);
|
|
|
8039 |
if (isPatt || isGrad || this.type == "image") {
|
|
|
8040 |
skew.matrix = "1 0 0 1";
|
|
|
8041 |
skew.offset = "0 0";
|
|
|
8042 |
split = matrix.split();
|
|
|
8043 |
if ((isGrad && split.noRotation) || !split.isSimple) {
|
|
|
8044 |
o.style.filter = matrix.toFilter();
|
|
|
8045 |
var bb = this.getBBox(),
|
|
|
8046 |
bbt = this.getBBox(1),
|
|
|
8047 |
dx = bb.x - bbt.x,
|
|
|
8048 |
dy = bb.y - bbt.y;
|
|
|
8049 |
o.coordorigin = (dx * -zoom) + S + (dy * -zoom);
|
|
|
8050 |
setCoords(this, 1, 1, dx, dy, 0);
|
|
|
8051 |
} else {
|
|
|
8052 |
o.style.filter = E;
|
|
|
8053 |
setCoords(this, split.scalex, split.scaley, split.dx, split.dy, split.rotate);
|
|
|
8054 |
}
|
|
|
8055 |
} else {
|
|
|
8056 |
o.style.filter = E;
|
|
|
8057 |
skew.matrix = Str(matrix);
|
|
|
8058 |
skew.offset = matrix.offset();
|
|
|
8059 |
}
|
|
|
8060 |
oldt && (this._.transform = oldt);
|
|
|
8061 |
return this;
|
|
|
8062 |
};
|
|
|
8063 |
elproto.rotate = function (deg, cx, cy) {
|
|
|
8064 |
if (this.removed) {
|
|
|
8065 |
return this;
|
|
|
8066 |
}
|
|
|
8067 |
if (deg == null) {
|
|
|
8068 |
return;
|
|
|
8069 |
}
|
|
|
8070 |
deg = Str(deg).split(separator);
|
|
|
8071 |
if (deg.length - 1) {
|
|
|
8072 |
cx = toFloat(deg[1]);
|
|
|
8073 |
cy = toFloat(deg[2]);
|
|
|
8074 |
}
|
|
|
8075 |
deg = toFloat(deg[0]);
|
|
|
8076 |
(cy == null) && (cx = cy);
|
|
|
8077 |
if (cx == null || cy == null) {
|
|
|
8078 |
var bbox = this.getBBox(1);
|
|
|
8079 |
cx = bbox.x + bbox.width / 2;
|
|
|
8080 |
cy = bbox.y + bbox.height / 2;
|
|
|
8081 |
}
|
|
|
8082 |
this._.dirtyT = 1;
|
|
|
8083 |
this.transform(this._.transform.concat([["r", deg, cx, cy]]));
|
|
|
8084 |
return this;
|
|
|
8085 |
};
|
|
|
8086 |
elproto.translate = function (dx, dy) {
|
|
|
8087 |
if (this.removed) {
|
|
|
8088 |
return this;
|
|
|
8089 |
}
|
|
|
8090 |
dx = Str(dx).split(separator);
|
|
|
8091 |
if (dx.length - 1) {
|
|
|
8092 |
dy = toFloat(dx[1]);
|
|
|
8093 |
}
|
|
|
8094 |
dx = toFloat(dx[0]) || 0;
|
|
|
8095 |
dy = +dy || 0;
|
|
|
8096 |
if (this._.bbox) {
|
|
|
8097 |
this._.bbox.x += dx;
|
|
|
8098 |
this._.bbox.y += dy;
|
|
|
8099 |
}
|
|
|
8100 |
this.transform(this._.transform.concat([["t", dx, dy]]));
|
|
|
8101 |
return this;
|
|
|
8102 |
};
|
|
|
8103 |
elproto.scale = function (sx, sy, cx, cy) {
|
|
|
8104 |
if (this.removed) {
|
|
|
8105 |
return this;
|
|
|
8106 |
}
|
|
|
8107 |
sx = Str(sx).split(separator);
|
|
|
8108 |
if (sx.length - 1) {
|
|
|
8109 |
sy = toFloat(sx[1]);
|
|
|
8110 |
cx = toFloat(sx[2]);
|
|
|
8111 |
cy = toFloat(sx[3]);
|
|
|
8112 |
isNaN(cx) && (cx = null);
|
|
|
8113 |
isNaN(cy) && (cy = null);
|
|
|
8114 |
}
|
|
|
8115 |
sx = toFloat(sx[0]);
|
|
|
8116 |
(sy == null) && (sy = sx);
|
|
|
8117 |
(cy == null) && (cx = cy);
|
|
|
8118 |
if (cx == null || cy == null) {
|
|
|
8119 |
var bbox = this.getBBox(1);
|
|
|
8120 |
}
|
|
|
8121 |
cx = cx == null ? bbox.x + bbox.width / 2 : cx;
|
|
|
8122 |
cy = cy == null ? bbox.y + bbox.height / 2 : cy;
|
|
|
8123 |
|
|
|
8124 |
this.transform(this._.transform.concat([["s", sx, sy, cx, cy]]));
|
|
|
8125 |
this._.dirtyT = 1;
|
|
|
8126 |
return this;
|
|
|
8127 |
};
|
|
|
8128 |
elproto.hide = function () {
|
|
|
8129 |
!this.removed && (this.node.style.display = "none");
|
|
|
8130 |
return this;
|
|
|
8131 |
};
|
|
|
8132 |
elproto.show = function () {
|
|
|
8133 |
!this.removed && (this.node.style.display = E);
|
|
|
8134 |
return this;
|
|
|
8135 |
};
|
|
|
8136 |
elproto._getBBox = function () {
|
|
|
8137 |
if (this.removed) {
|
|
|
8138 |
return {};
|
|
|
8139 |
}
|
|
|
8140 |
if (this.type == "text") {
|
|
|
8141 |
return {
|
|
|
8142 |
x: this.X + (this.bbx || 0) - this.W / 2,
|
|
|
8143 |
y: this.Y - this.H,
|
|
|
8144 |
width: this.W,
|
|
|
8145 |
height: this.H
|
|
|
8146 |
};
|
|
|
8147 |
} else {
|
|
|
8148 |
return pathDimensions(this.attrs.path);
|
|
|
8149 |
}
|
|
|
8150 |
};
|
|
|
8151 |
elproto.remove = function () {
|
|
|
8152 |
if (this.removed) {
|
|
|
8153 |
return;
|
|
|
8154 |
}
|
|
|
8155 |
this.paper.__set__ && this.paper.__set__.exclude(this);
|
|
|
8156 |
R.eve.unbind("*.*." + this.id);
|
|
|
8157 |
R._tear(this, this.paper);
|
|
|
8158 |
this.node.parentNode.removeChild(this.node);
|
|
|
8159 |
this.shape && this.shape.parentNode.removeChild(this.shape);
|
|
|
8160 |
for (var i in this) {
|
|
|
8161 |
delete this[i];
|
|
|
8162 |
}
|
|
|
8163 |
this.removed = true;
|
|
|
8164 |
};
|
|
|
8165 |
elproto.attr = function (name, value) {
|
|
|
8166 |
if (this.removed) {
|
|
|
8167 |
return this;
|
|
|
8168 |
}
|
|
|
8169 |
if (name == null) {
|
|
|
8170 |
var res = {};
|
|
|
8171 |
for (var a in this.attrs) if (this.attrs[has](a)) {
|
|
|
8172 |
res[a] = this.attrs[a];
|
|
|
8173 |
}
|
|
|
8174 |
res.gradient && res.fill == "none" && (res.fill = res.gradient) && delete res.gradient;
|
|
|
8175 |
res.transform = this._.transform;
|
|
|
8176 |
return res;
|
|
|
8177 |
}
|
|
|
8178 |
if (value == null && R.is(name, "string")) {
|
|
|
8179 |
if (name == fillString && this.attrs.fill == "none" && this.attrs.gradient) {
|
|
|
8180 |
return this.attrs.gradient;
|
|
|
8181 |
}
|
|
|
8182 |
var names = name.split(separator),
|
|
|
8183 |
out = {};
|
|
|
8184 |
for (var i = 0, ii = names.length; i < ii; i++) {
|
|
|
8185 |
name = names[i];
|
|
|
8186 |
if (name in this.attrs) {
|
|
|
8187 |
out[name] = this.attrs[name];
|
|
|
8188 |
} else if (R.is(this.paper.customAttributes[name], "function")) {
|
|
|
8189 |
out[name] = this.paper.customAttributes[name].def;
|
|
|
8190 |
} else {
|
|
|
8191 |
out[name] = R._availableAttrs[name];
|
|
|
8192 |
}
|
|
|
8193 |
}
|
|
|
8194 |
return ii - 1 ? out : out[names[0]];
|
|
|
8195 |
}
|
|
|
8196 |
if (this.attrs && value == null && R.is(name, "array")) {
|
|
|
8197 |
out = {};
|
|
|
8198 |
for (i = 0, ii = name.length; i < ii; i++) {
|
|
|
8199 |
out[name[i]] = this.attr(name[i]);
|
|
|
8200 |
}
|
|
|
8201 |
return out;
|
|
|
8202 |
}
|
|
|
8203 |
var params;
|
|
|
8204 |
if (value != null) {
|
|
|
8205 |
params = {};
|
|
|
8206 |
params[name] = value;
|
|
|
8207 |
}
|
|
|
8208 |
value == null && R.is(name, "object") && (params = name);
|
|
|
8209 |
for (var key in params) {
|
|
|
8210 |
eve("attr." + key + "." + this.id, this, params[key]);
|
|
|
8211 |
}
|
|
|
8212 |
if (params) {
|
|
|
8213 |
for (key in this.paper.customAttributes) if (this.paper.customAttributes[has](key) && params[has](key) && R.is(this.paper.customAttributes[key], "function")) {
|
|
|
8214 |
var par = this.paper.customAttributes[key].apply(this, [].concat(params[key]));
|
|
|
8215 |
this.attrs[key] = params[key];
|
|
|
8216 |
for (var subkey in par) if (par[has](subkey)) {
|
|
|
8217 |
params[subkey] = par[subkey];
|
|
|
8218 |
}
|
|
|
8219 |
}
|
|
|
8220 |
// this.paper.canvas.style.display = "none";
|
|
|
8221 |
if (params.text && this.type == "text") {
|
|
|
8222 |
this.textpath.string = params.text;
|
|
|
8223 |
}
|
|
|
8224 |
setFillAndStroke(this, params);
|
|
|
8225 |
// this.paper.canvas.style.display = E;
|
|
|
8226 |
}
|
|
|
8227 |
return this;
|
|
|
8228 |
};
|
|
|
8229 |
elproto.toFront = function () {
|
|
|
8230 |
!this.removed && this.node.parentNode.appendChild(this.node);
|
|
|
8231 |
this.paper && this.paper.top != this && R._tofront(this, this.paper);
|
|
|
8232 |
return this;
|
|
|
8233 |
};
|
|
|
8234 |
elproto.toBack = function () {
|
|
|
8235 |
if (this.removed) {
|
|
|
8236 |
return this;
|
|
|
8237 |
}
|
|
|
8238 |
if (this.node.parentNode.firstChild != this.node) {
|
|
|
8239 |
this.node.parentNode.insertBefore(this.node, this.node.parentNode.firstChild);
|
|
|
8240 |
R._toback(this, this.paper);
|
|
|
8241 |
}
|
|
|
8242 |
return this;
|
|
|
8243 |
};
|
|
|
8244 |
elproto.insertAfter = function (element) {
|
|
|
8245 |
if (this.removed) {
|
|
|
8246 |
return this;
|
|
|
8247 |
}
|
|
|
8248 |
if (element.constructor == R.st.constructor) {
|
|
|
8249 |
element = element[element.length - 1];
|
|
|
8250 |
}
|
|
|
8251 |
if (element.node.nextSibling) {
|
|
|
8252 |
element.node.parentNode.insertBefore(this.node, element.node.nextSibling);
|
|
|
8253 |
} else {
|
|
|
8254 |
element.node.parentNode.appendChild(this.node);
|
|
|
8255 |
}
|
|
|
8256 |
R._insertafter(this, element, this.paper);
|
|
|
8257 |
return this;
|
|
|
8258 |
};
|
|
|
8259 |
elproto.insertBefore = function (element) {
|
|
|
8260 |
if (this.removed) {
|
|
|
8261 |
return this;
|
|
|
8262 |
}
|
|
|
8263 |
if (element.constructor == R.st.constructor) {
|
|
|
8264 |
element = element[0];
|
|
|
8265 |
}
|
|
|
8266 |
element.node.parentNode.insertBefore(this.node, element.node);
|
|
|
8267 |
R._insertbefore(this, element, this.paper);
|
|
|
8268 |
return this;
|
|
|
8269 |
};
|
|
|
8270 |
elproto.blur = function (size) {
|
|
|
8271 |
var s = this.node.runtimeStyle,
|
|
|
8272 |
f = s.filter;
|
|
|
8273 |
f = f.replace(blurregexp, E);
|
|
|
8274 |
if (+size !== 0) {
|
|
|
8275 |
this.attrs.blur = size;
|
|
|
8276 |
s.filter = f + S + ms + ".Blur(pixelradius=" + (+size || 1.5) + ")";
|
|
|
8277 |
s.margin = R.format("-{0}px 0 0 -{0}px", round(+size || 1.5));
|
|
|
8278 |
} else {
|
|
|
8279 |
s.filter = f;
|
|
|
8280 |
s.margin = 0;
|
|
|
8281 |
delete this.attrs.blur;
|
|
|
8282 |
}
|
|
|
8283 |
};
|
|
|
8284 |
|
|
|
8285 |
R._engine.path = function (pathString, vml) {
|
|
|
8286 |
var el = createNode("shape");
|
|
|
8287 |
el.style.cssText = cssDot;
|
|
|
8288 |
el.coordsize = zoom + S + zoom;
|
|
|
8289 |
el.coordorigin = vml.coordorigin;
|
|
|
8290 |
var p = new Element(el, vml),
|
|
|
8291 |
attr = {fill: "none", stroke: "#000"};
|
|
|
8292 |
pathString && (attr.path = pathString);
|
|
|
8293 |
p.type = "path";
|
|
|
8294 |
p.path = [];
|
|
|
8295 |
p.Path = E;
|
|
|
8296 |
setFillAndStroke(p, attr);
|
|
|
8297 |
vml.canvas.appendChild(el);
|
|
|
8298 |
var skew = createNode("skew");
|
|
|
8299 |
skew.on = true;
|
|
|
8300 |
el.appendChild(skew);
|
|
|
8301 |
p.skew = skew;
|
|
|
8302 |
p.transform(E);
|
|
|
8303 |
return p;
|
|
|
8304 |
};
|
|
|
8305 |
R._engine.rect = function (vml, x, y, w, h, r) {
|
|
|
8306 |
var path = R._rectPath(x, y, w, h, r),
|
|
|
8307 |
res = vml.path(path),
|
|
|
8308 |
a = res.attrs;
|
|
|
8309 |
res.X = a.x = x;
|
|
|
8310 |
res.Y = a.y = y;
|
|
|
8311 |
res.W = a.width = w;
|
|
|
8312 |
res.H = a.height = h;
|
|
|
8313 |
a.r = r;
|
|
|
8314 |
a.path = path;
|
|
|
8315 |
res.type = "rect";
|
|
|
8316 |
return res;
|
|
|
8317 |
};
|
|
|
8318 |
R._engine.ellipse = function (vml, x, y, rx, ry) {
|
|
|
8319 |
var res = vml.path(),
|
|
|
8320 |
a = res.attrs;
|
|
|
8321 |
res.X = x - rx;
|
|
|
8322 |
res.Y = y - ry;
|
|
|
8323 |
res.W = rx * 2;
|
|
|
8324 |
res.H = ry * 2;
|
|
|
8325 |
res.type = "ellipse";
|
|
|
8326 |
setFillAndStroke(res, {
|
|
|
8327 |
cx: x,
|
|
|
8328 |
cy: y,
|
|
|
8329 |
rx: rx,
|
|
|
8330 |
ry: ry
|
|
|
8331 |
});
|
|
|
8332 |
return res;
|
|
|
8333 |
};
|
|
|
8334 |
R._engine.circle = function (vml, x, y, r) {
|
|
|
8335 |
var res = vml.path(),
|
|
|
8336 |
a = res.attrs;
|
|
|
8337 |
res.X = x - r;
|
|
|
8338 |
res.Y = y - r;
|
|
|
8339 |
res.W = res.H = r * 2;
|
|
|
8340 |
res.type = "circle";
|
|
|
8341 |
setFillAndStroke(res, {
|
|
|
8342 |
cx: x,
|
|
|
8343 |
cy: y,
|
|
|
8344 |
r: r
|
|
|
8345 |
});
|
|
|
8346 |
return res;
|
|
|
8347 |
};
|
|
|
8348 |
R._engine.image = function (vml, src, x, y, w, h) {
|
|
|
8349 |
var path = R._rectPath(x, y, w, h),
|
|
|
8350 |
res = vml.path(path).attr({stroke: "none"}),
|
|
|
8351 |
a = res.attrs,
|
|
|
8352 |
node = res.node,
|
|
|
8353 |
fill = node.getElementsByTagName(fillString)[0];
|
|
|
8354 |
a.src = src;
|
|
|
8355 |
res.X = a.x = x;
|
|
|
8356 |
res.Y = a.y = y;
|
|
|
8357 |
res.W = a.width = w;
|
|
|
8358 |
res.H = a.height = h;
|
|
|
8359 |
a.path = path;
|
|
|
8360 |
res.type = "image";
|
|
|
8361 |
fill.parentNode == node && node.removeChild(fill);
|
|
|
8362 |
fill.rotate = true;
|
|
|
8363 |
fill.src = src;
|
|
|
8364 |
fill.type = "tile";
|
|
|
8365 |
res._.fillpos = [x, y];
|
|
|
8366 |
res._.fillsize = [w, h];
|
|
|
8367 |
node.appendChild(fill);
|
|
|
8368 |
setCoords(res, 1, 1, 0, 0, 0);
|
|
|
8369 |
return res;
|
|
|
8370 |
};
|
|
|
8371 |
R._engine.text = function (vml, x, y, text) {
|
|
|
8372 |
var el = createNode("shape"),
|
|
|
8373 |
path = createNode("path"),
|
|
|
8374 |
o = createNode("textpath");
|
|
|
8375 |
x = x || 0;
|
|
|
8376 |
y = y || 0;
|
|
|
8377 |
text = text || "";
|
|
|
8378 |
path.v = R.format("m{0},{1}l{2},{1}", round(x * zoom), round(y * zoom), round(x * zoom) + 1);
|
|
|
8379 |
path.textpathok = true;
|
|
|
8380 |
o.string = Str(text);
|
|
|
8381 |
o.on = true;
|
|
|
8382 |
el.style.cssText = cssDot;
|
|
|
8383 |
el.coordsize = zoom + S + zoom;
|
|
|
8384 |
el.coordorigin = "0 0";
|
|
|
8385 |
var p = new Element(el, vml),
|
|
|
8386 |
attr = {
|
|
|
8387 |
fill: "#000",
|
|
|
8388 |
stroke: "none",
|
|
|
8389 |
font: R._availableAttrs.font,
|
|
|
8390 |
text: text
|
|
|
8391 |
};
|
|
|
8392 |
p.shape = el;
|
|
|
8393 |
p.path = path;
|
|
|
8394 |
p.textpath = o;
|
|
|
8395 |
p.type = "text";
|
|
|
8396 |
p.attrs.text = Str(text);
|
|
|
8397 |
p.attrs.x = x;
|
|
|
8398 |
p.attrs.y = y;
|
|
|
8399 |
p.attrs.w = 1;
|
|
|
8400 |
p.attrs.h = 1;
|
|
|
8401 |
setFillAndStroke(p, attr);
|
|
|
8402 |
el.appendChild(o);
|
|
|
8403 |
el.appendChild(path);
|
|
|
8404 |
vml.canvas.appendChild(el);
|
|
|
8405 |
var skew = createNode("skew");
|
|
|
8406 |
skew.on = true;
|
|
|
8407 |
el.appendChild(skew);
|
|
|
8408 |
p.skew = skew;
|
|
|
8409 |
p.transform(E);
|
|
|
8410 |
return p;
|
|
|
8411 |
};
|
|
|
8412 |
R._engine.setSize = function (width, height) {
|
|
|
8413 |
var cs = this.canvas.style;
|
|
|
8414 |
this.width = width;
|
|
|
8415 |
this.height = height;
|
|
|
8416 |
width == +width && (width += "px");
|
|
|
8417 |
height == +height && (height += "px");
|
|
|
8418 |
cs.width = width;
|
|
|
8419 |
cs.height = height;
|
|
|
8420 |
cs.clip = "rect(0 " + width + " " + height + " 0)";
|
|
|
8421 |
if (this._viewBox) {
|
|
|
8422 |
setViewBox.apply(this, this._viewBox);
|
|
|
8423 |
}
|
|
|
8424 |
return this;
|
|
|
8425 |
};
|
|
|
8426 |
R._engine.setViewBox = function (x, y, w, h, fit) {
|
|
|
8427 |
R.eve("setViewBox", this, this._viewBox, [x, y, w, h, fit]);
|
|
|
8428 |
var width = this.width,
|
|
|
8429 |
height = this.height,
|
|
|
8430 |
size = 1 / mmax(w / width, h / height),
|
|
|
8431 |
H, W;
|
|
|
8432 |
if (fit) {
|
|
|
8433 |
H = height / h;
|
|
|
8434 |
W = width / w;
|
|
|
8435 |
if (w * H < width) {
|
|
|
8436 |
x -= (width - w * H) / 2 / H;
|
|
|
8437 |
}
|
|
|
8438 |
if (h * W < height) {
|
|
|
8439 |
y -= (height - h * W) / 2 / W;
|
|
|
8440 |
}
|
|
|
8441 |
}
|
|
|
8442 |
this._viewBox = [x, y, w, h, !!fit];
|
|
|
8443 |
this._viewBoxShift = {
|
|
|
8444 |
dx: -x,
|
|
|
8445 |
dy: -y,
|
|
|
8446 |
scale: size
|
|
|
8447 |
};
|
|
|
8448 |
this.forEach(function (el) {
|
|
|
8449 |
el.transform("...");
|
|
|
8450 |
});
|
|
|
8451 |
return this;
|
|
|
8452 |
};
|
|
|
8453 |
var createNode,
|
|
|
8454 |
initWin = function (win) {
|
|
|
8455 |
var doc = win.document;
|
|
|
8456 |
doc.createStyleSheet().addRule(".rvml", "behavior:url(#default#VML)");
|
|
|
8457 |
try {
|
|
|
8458 |
!doc.namespaces.rvml && doc.namespaces.add("rvml", "urn:schemas-microsoft-com:vml");
|
|
|
8459 |
createNode = function (tagName) {
|
|
|
8460 |
return doc.createElement('<rvml:' + tagName + ' class="rvml">');
|
|
|
8461 |
};
|
|
|
8462 |
} catch (e) {
|
|
|
8463 |
createNode = function (tagName) {
|
|
|
8464 |
return doc.createElement('<' + tagName + ' xmlns="urn:schemas-microsoft.com:vml" class="rvml">');
|
|
|
8465 |
};
|
|
|
8466 |
}
|
|
|
8467 |
};
|
|
|
8468 |
initWin(R._g.win);
|
|
|
8469 |
R._engine.create = function () {
|
|
|
8470 |
var con = R._getContainer.apply(0, arguments),
|
|
|
8471 |
container = con.container,
|
|
|
8472 |
height = con.height,
|
|
|
8473 |
s,
|
|
|
8474 |
width = con.width,
|
|
|
8475 |
x = con.x,
|
|
|
8476 |
y = con.y;
|
|
|
8477 |
if (!container) {
|
|
|
8478 |
throw new Error("VML container not found.");
|
|
|
8479 |
}
|
|
|
8480 |
var res = new R._Paper,
|
|
|
8481 |
c = res.canvas = R._g.doc.createElement("div"),
|
|
|
8482 |
cs = c.style;
|
|
|
8483 |
x = x || 0;
|
|
|
8484 |
y = y || 0;
|
|
|
8485 |
width = width || 512;
|
|
|
8486 |
height = height || 342;
|
|
|
8487 |
res.width = width;
|
|
|
8488 |
res.height = height;
|
|
|
8489 |
width == +width && (width += "px");
|
|
|
8490 |
height == +height && (height += "px");
|
|
|
8491 |
res.coordsize = zoom * 1e3 + S + zoom * 1e3;
|
|
|
8492 |
res.coordorigin = "0 0";
|
|
|
8493 |
res.span = R._g.doc.createElement("span");
|
|
|
8494 |
res.span.style.cssText = "position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;";
|
|
|
8495 |
c.appendChild(res.span);
|
|
|
8496 |
cs.cssText = R.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden", width, height);
|
|
|
8497 |
if (container == 1) {
|
|
|
8498 |
R._g.doc.body.appendChild(c);
|
|
|
8499 |
cs.left = x + "px";
|
|
|
8500 |
cs.top = y + "px";
|
|
|
8501 |
cs.position = "absolute";
|
|
|
8502 |
} else {
|
|
|
8503 |
if (container.firstChild) {
|
|
|
8504 |
container.insertBefore(c, container.firstChild);
|
|
|
8505 |
} else {
|
|
|
8506 |
container.appendChild(c);
|
|
|
8507 |
}
|
|
|
8508 |
}
|
|
|
8509 |
// plugins.call(res, res, R.fn);
|
|
|
8510 |
res.renderfix = function () {};
|
|
|
8511 |
return res;
|
|
|
8512 |
};
|
|
|
8513 |
R.prototype.clear = function () {
|
|
|
8514 |
R.eve("clear", this);
|
|
|
8515 |
this.canvas.innerHTML = E;
|
|
|
8516 |
this.span = R._g.doc.createElement("span");
|
|
|
8517 |
this.span.style.cssText = "position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";
|
|
|
8518 |
this.canvas.appendChild(this.span);
|
|
|
8519 |
this.bottom = this.top = null;
|
|
|
8520 |
};
|
|
|
8521 |
R.prototype.remove = function () {
|
|
|
8522 |
R.eve("remove", this);
|
|
|
8523 |
this.canvas.parentNode.removeChild(this.canvas);
|
|
|
8524 |
for (var i in this) {
|
|
|
8525 |
this[i] = removed(i);
|
|
|
8526 |
}
|
|
|
8527 |
return true;
|
|
|
8528 |
};
|
|
|
8529 |
|
|
|
8530 |
var setproto = R.st;
|
|
|
8531 |
for (var method in elproto) if (elproto[has](method) && !setproto[has](method)) {
|
|
|
8532 |
setproto[method] = (function (methodname) {
|
|
|
8533 |
return function () {
|
|
|
8534 |
var arg = arguments;
|
|
|
8535 |
return this.forEach(function (el) {
|
|
|
8536 |
el[methodname].apply(el, arg);
|
|
|
8537 |
});
|
|
|
8538 |
};
|
|
|
8539 |
})(method);
|
|
|
8540 |
}
|
|
|
8541 |
}(window.Raphael);/* main file */
|
|
|
8542 |
|
|
|
8543 |
if ( window.IriSP === undefined && window.__IriSP === undefined ) {
|
|
|
8544 |
var IriSP = {};
|
|
|
8545 |
var __IriSP = IriSP; /* for backward compatibility */
|
|
|
8546 |
}
|
|
|
8547 |
|
|
|
8548 |
/* crap code will be the first against the wall when the
|
|
|
8549 |
revolution comes */
|
|
|
8550 |
IriSP.loadLibs = function( libs, customCssPath, metadata_url, callback ) {
|
|
|
8551 |
// Localize jQuery variable
|
|
|
8552 |
IriSP.jQuery = null;
|
|
|
8553 |
|
|
|
8554 |
/* FIXME : to refactor using popcorn.getscript ? */
|
|
|
8555 |
/******** Load jQuery if not present *********/
|
|
|
8556 |
if ( window.jQuery === undefined || window.jQuery.fn.jquery !== '1.4.2' ) {
|
|
|
8557 |
|
|
|
8558 |
var script_tag = document.createElement( 'script' );
|
|
|
8559 |
script_tag.setAttribute( "type", "text/javascript" );
|
|
|
8560 |
script_tag.setAttribute( "src", libs.jQuery );
|
|
|
8561 |
|
|
|
8562 |
script_tag.onload = scriptLibHandler;
|
|
|
8563 |
script_tag.onreadystatechange = function () { // Same thing but for IE
|
|
|
8564 |
if ( this.readyState == 'complete' || this.readyState == 'loaded' ) {
|
|
|
8565 |
scriptLibHandler();
|
|
|
8566 |
}
|
|
|
8567 |
};
|
|
|
8568 |
|
|
|
8569 |
// Try to find the head, otherwise default to the documentElement
|
|
|
8570 |
( document.getElementsByTagName("head")[0] || document.documentElement ).appendChild( script_tag );
|
|
|
8571 |
} else {
|
|
|
8572 |
// The jQuery version on the window is the one we want to use
|
|
|
8573 |
IriSP.jQuery = window.jQuery;
|
|
|
8574 |
scriptLibHandler();
|
|
|
8575 |
}
|
|
|
8576 |
|
|
|
8577 |
/******** Called once jQuery has loaded ******/
|
|
|
8578 |
function scriptLibHandler() {
|
|
|
8579 |
|
|
|
8580 |
var script_jqUi_tooltip = document.createElement( 'script' );
|
|
|
8581 |
script_jqUi_tooltip.setAttribute( "type", "text/javascript" );
|
|
|
8582 |
script_jqUi_tooltip.setAttribute( "src", libs.jQueryToolTip );
|
|
|
8583 |
script_jqUi_tooltip.onload = scriptLoadHandler;
|
|
|
8584 |
script_jqUi_tooltip.onreadystatechange = function () { // Same thing but for IE
|
|
|
8585 |
if ( this.readyState == 'complete' || this.readyState == 'loaded' ) {
|
|
|
8586 |
scriptLoadHandler( "jquery.tools.min.js loded" );
|
|
|
8587 |
}
|
|
|
8588 |
};
|
|
|
8589 |
|
|
|
8590 |
var script_swfObj = document.createElement('script');
|
|
|
8591 |
script_swfObj.setAttribute( "type","text/javascript" );
|
|
|
8592 |
script_swfObj.setAttribute( "src",libs.swfObject );
|
|
|
8593 |
script_swfObj.onload = scriptLoadHandler;
|
|
|
8594 |
script_swfObj.onreadystatechange = function () { // Same thing but for IE
|
|
|
8595 |
if ( this.readyState == 'complete' || this.readyState == 'loaded' ) {
|
|
|
8596 |
scriptLoadHandler( "swfobject.js loded" );
|
|
|
8597 |
}
|
|
|
8598 |
};
|
|
|
8599 |
|
|
|
8600 |
var script_jqUi = document.createElement( 'script' );
|
|
|
8601 |
script_jqUi.setAttribute( "type","text/javascript" );
|
|
|
8602 |
script_jqUi.setAttribute( "src",libs.jQueryUI );
|
|
|
8603 |
script_jqUi.onload = scriptLoadHandler;
|
|
|
8604 |
script_jqUi.onreadystatechange = function () { // Same thing but for IE
|
|
|
8605 |
if ( this.readyState == 'complete' || this.readyState == 'loaded' ) {
|
|
|
8606 |
scriptLoadHandler( "jquery-ui.min.js loded" );
|
|
|
8607 |
}
|
|
|
8608 |
};
|
|
|
8609 |
|
|
|
8610 |
|
|
|
8611 |
( document.getElementsByTagName("head")[0] || document.documentElement ).appendChild( script_jqUi_tooltip);
|
|
|
8612 |
( document.getElementsByTagName("head")[0] || document.documentElement ).appendChild( script_jqUi );
|
|
|
8613 |
( document.getElementsByTagName("head")[0] || document.documentElement ).appendChild( script_swfObj );
|
|
|
8614 |
|
|
|
8615 |
|
|
|
8616 |
};
|
|
|
8617 |
|
|
|
8618 |
/******** Called once all lib are loaded ******/
|
|
|
8619 |
var loadLib = 0;
|
|
|
8620 |
/* FIXME : ugly */
|
|
|
8621 |
function scriptLoadHandler( Mylib ) {
|
|
|
8622 |
//alert(Mylib);
|
|
|
8623 |
loadLib +=1;
|
|
|
8624 |
if( loadLib===3 ) {
|
|
|
8625 |
main();
|
|
|
8626 |
}
|
|
|
8627 |
};
|
|
|
8628 |
|
|
|
8629 |
/******** Our main function ********/
|
|
|
8630 |
function main() {
|
|
|
8631 |
|
|
|
8632 |
|
|
|
8633 |
// Make our own IriSP.jQuery and restore window.jQuery if there was one.
|
|
|
8634 |
IriSP.jQuery = window.jQuery.noConflict( true );
|
|
|
8635 |
// Call our Jquery
|
|
|
8636 |
IriSP.jQuery( document ).ready( function($) {
|
|
|
8637 |
|
|
|
8638 |
/******* Load CSS *******/
|
|
|
8639 |
var css_link_jquery = IriSP.jQuery( "<link>", {
|
|
|
8640 |
rel: "stylesheet",
|
|
|
8641 |
type: "text/css",
|
|
|
8642 |
href: libs.cssjQueryUI,
|
|
|
8643 |
'class': "dynamic_css"
|
|
|
8644 |
} );
|
|
|
8645 |
var css_link_custom = IriSP.jQuery( "<link>", {
|
|
|
8646 |
rel: "stylesheet",
|
|
|
8647 |
type: "text/css",
|
|
|
8648 |
href: customCssPath,
|
|
|
8649 |
'class': "dynamic_css"
|
|
|
8650 |
} );
|
|
|
8651 |
|
|
|
8652 |
css_link_jquery.appendTo( 'head' );
|
|
|
8653 |
css_link_custom.appendTo( 'head' );
|
|
|
8654 |
|
|
|
8655 |
// to see dynamicly loaded css on IE
|
|
|
8656 |
if ( $.browser.msie ) {
|
|
|
8657 |
$( '.dynamic_css' ).clone().appendTo( 'head' );
|
|
|
8658 |
}
|
|
|
8659 |
|
|
|
8660 |
IriSP.setupDataLoader();
|
|
|
8661 |
IriSP.__dataloader.get(metadata_url,
|
|
|
8662 |
function(data) {
|
|
|
8663 |
/* save the data so that we could re-use it to
|
|
|
8664 |
configure the video
|
|
|
8665 |
*/
|
|
|
8666 |
IriSP.__jsonMetadata = data;
|
|
|
8667 |
callback.call(window) });
|
|
|
8668 |
});
|
|
|
8669 |
}
|
|
|
8670 |
};
|
|
|
8671 |
|
|
|
8672 |
|
|
12
|
8673 |
IriSP.annotation_template = "{{! template for an annotation displayed in a segmentWidget }}<div title='{{divTitle}}' id='{{id}}' class='Ldt-iri-chapter' style='left: {{startPourcent}}%; width: {{endPourcent}}%; background-color:#{{hexa_color}};' ></div>";
|
|
9
|
8674 |
IriSP.annotationWidget_template = "{{! template for the annotation widget }}<div class='Ldt-AnnotationsWidget'> <!-- ugly div because we want to have a double border --> <div class='Ldt-Annotation-DoubleBorder'> <div class='Ldt-AnnotationContent'> <div class='Ldt-AnnotationShareIcons'> <a class='Ldt-fbShare' href=''><img src='{{img_dir}}/facebook.png' alt='share on facebook'></img></a> <a class='Ldt-TwShare' href=''><img src='{{img_dir}}/twitter.png' alt='share on twitter'></img></a> <a class='Ldt-GplusShare' href=''><img src='{{img_dir}}/google.png' alt='share on google+'></img></a> </div> <div class='Ldt-SaTitle'></div> <div class='Ldt-SaDescription'></div> </div> </div></div>";
|
|
0
|
8675 |
IriSP.annotation_loading_template = "{{! template shown while the annotation widget is loading }}<div id='Ldt-load-container'><div id='Ldt-loader'> </div> Chargement... </div>";
|
|
|
8676 |
IriSP.arrowWidget_template = "<div class='Ldt-arrowWidget'></div>";
|
|
|
8677 |
IriSP.overlay_marker_template = "{{! the template for the small white bars which is z-indexed over our segment widget }}<div class='positionMarker'></div>";
|
|
|
8678 |
IriSP.player_template = "{{! template for the radio player }}<div class='Ldt-controler demo'> <div class='Ldt-LeftPlayerControls'> <div class='Ldt-button Ldt-CtrlPlay'></div> <div class='Ldt-button Ldt-CtrlAnnotate'></div> <div class='Ldt-button Ldt-CtrlSearch'></div> </div> <div class='Ldt-RightPlayerControls'> <div class='Ldt-Time'> <div class='Ldt-ElapsedTime'></div> <div class='Ldt-TimeSeparator'>/</div> <div class='Ldt-TotalTime'></div> </div> <div class='Ldt-button Ldt-CtrlSound'></div> </div></div>";
|
|
|
8679 |
IriSP.search_template = "{{! template for the search container }}<div class='LdtSearchContainer' style='margin-left: {{margin_left}}; position: absolute; margin-top: -60px;'> <div class='LdtSearch' style='display: none; background-color: #EEE; width: 165px; boder: 1px; border-color: #CFCFCF; position: absolute; text-align: center;'> <input class='LdtSearchInput' style='margin-top: 2px; margin-bottom: 2px;' /> </div></div><div class='cleaner'></div>";
|
|
|
8680 |
IriSP.share_template = "{{! social network sharing template }}<a onclick='__IriSP.MyApiPlayer.share(\'delicious\');' title='partager avec delicious'><span class='share shareDelicious'> </span></a> <a onclick='__IriSP.MyApiPlayer.share(\'facebook\');' title='partager avec facebook'> <span class='share shareFacebook'> </span></a><a onclick='__IriSP.MyApiPlayer.share(\'twitter\');' title='partager avec twitter'> <span class='share shareTwitter'> </span></a><a onclick='__IriSP.MyApiPlayer.share(\'myspace\');' title='partager avec Myspace'> <span class='share shareMySpace'> </span></a>";
|
|
9
|
8681 |
IriSP.sliderWidget_template = "{{! template for the slider widget - it's composed of two divs we one overlayed on top of the other }}<div class='Ldt-sliderBackground'></div><div class='Ldt-sliderForeground'></div><div class='Ldt-sliderPositionMarker'></div>";
|
|
0
|
8682 |
IriSP.tooltip_template = "{{! template used by the jquery ui tooltip }}<div class='Ldt-tooltip'> <div class='title'>{{title}}</div> <div class='time'>{{begin}} : {{end}} </div> <div class='description'>{{description}}</div></div>";
|
|
|
8683 |
IriSP.tooltipWidget_template = "{{! template for the tooltip widget }}<div class='tip'> <div class='tipcolor' style='height:10px;width:10px'></div> <div class='tiptext'></div>";
|
|
|
8684 |
IriSP.tweetWidget_template = "{{! template for the tweet widget }}<div class='Ldt-tweetWidget'> <div class='Ldt-tweet-DoubleBorder'> <img src='{{img_dir}}/minimize.png' class='Ldt-tweetWidgetKeepOpen' alt='dont minimize automatically'></img> <img src='{{img_dir}}/minimize.png' class='Ldt-tweetWidgetMinimize' alt='minimize window'></img> <div class='Ldt-tweetAvatar'></div> <img src='{{img_dir}}/profile_arrow.png' class='Ldt-tweetAvatar-profileArrow'></img> <div class='Ldt-tweetContents'></div> <a href='' target='_blank' class='Ldt-Retweet'><div class='Ldt-RetweetIcon'></div> - Retweet </a> <a href='' target='_blank' class='Ldt-TweetReply'><div class='Ldt-TweetReplyIcon'></div> - Reply</a> </div></div>";/* wrapper that simulates popcorn.js because
|
|
|
8685 |
popcorn is a bit unstable at the time */
|
|
|
8686 |
|
|
|
8687 |
IriSP.PopcornReplacement = {
|
|
|
8688 |
msgPump : {} /* used by jquery to receive and send messages */
|
|
|
8689 |
};
|
|
|
8690 |
|
|
|
8691 |
IriSP.PopcornReplacement.media = {
|
|
|
8692 |
"paused": true,
|
|
|
8693 |
"muted": false
|
|
|
8694 |
};
|
|
|
8695 |
|
|
|
8696 |
IriSP.PopcornReplacement.listen = function(msg, callback) {
|
|
|
8697 |
// IriSP.jQuery(IriSP.PopcornReplacement.msgPump).bind(msg, function(event, rest) { callback(rest); });
|
|
|
8698 |
if (!IriSP.PopcornReplacement.msgPump.hasOwnProperty(msg))
|
|
|
8699 |
IriSP.PopcornReplacement.msgPump[msg] = [];
|
|
|
8700 |
|
|
|
8701 |
IriSP.PopcornReplacement.msgPump[msg].push(callback);
|
|
|
8702 |
};
|
|
|
8703 |
|
|
|
8704 |
IriSP.PopcornReplacement.trigger = function(msg, params) {
|
|
|
8705 |
// IriSP.jQuery(IriSP.PopcornReplacement.msgPump).trigger(msg, params);
|
|
|
8706 |
|
|
|
8707 |
if (!IriSP.PopcornReplacement.msgPump.hasOwnProperty(msg))
|
|
|
8708 |
return;
|
|
|
8709 |
|
|
|
8710 |
var d = IriSP.PopcornReplacement.msgPump[msg];
|
|
|
8711 |
for(var entry in d) {
|
|
|
8712 |
d[entry].call(window, params);
|
|
|
8713 |
}
|
|
|
8714 |
|
|
|
8715 |
};
|
|
|
8716 |
|
|
|
8717 |
IriSP.PopcornReplacement.guid = function(prefix) {
|
|
|
8718 |
var str = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
|
|
8719 |
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
|
|
|
8720 |
return v.toString(16);
|
|
|
8721 |
});
|
|
|
8722 |
|
|
|
8723 |
return prefix + str;
|
|
|
8724 |
};
|
|
|
8725 |
|
|
|
8726 |
IriSP.PopcornReplacement.__initApi = function() {
|
|
|
8727 |
IriSP.PopcornReplacement.trigger("loadedmetadata"); // we've done more than loading metadata of course,
|
|
|
8728 |
// but popcorn doesn't need to know more.
|
|
|
8729 |
IriSP.PopcornReplacement.media.muted = jwplayer(IriSP.PopcornReplacement._container).getMute();
|
|
|
8730 |
};
|
|
|
8731 |
|
|
|
8732 |
IriSP.PopcornReplacement.jwplayer = function(container, options) {
|
|
|
8733 |
IriSP.PopcornReplacement._container = container.slice(1); //eschew the '#'
|
|
|
8734 |
options.events = {
|
|
|
8735 |
onReady: IriSP.PopcornReplacement.__initApi,
|
|
|
8736 |
onTime: IriSP.PopcornReplacement.__timeHandler,
|
|
|
8737 |
onPlay: IriSP.PopcornReplacement.__playHandler,
|
|
|
8738 |
onPause: IriSP.PopcornReplacement.__pauseHandler,
|
|
|
8739 |
onSeek: IriSP.PopcornReplacement.__seekHandler
|
|
|
8740 |
}
|
|
|
8741 |
|
|
|
8742 |
jwplayer(IriSP.PopcornReplacement._container).setup(options);
|
|
|
8743 |
IriSP.PopcornReplacement.media.duration = options.duration;
|
|
|
8744 |
return IriSP.PopcornReplacement;
|
|
|
8745 |
};
|
|
|
8746 |
|
|
|
8747 |
IriSP.PopcornReplacement.currentTime = function(time) {
|
|
|
8748 |
if (typeof(time) === "undefined") {
|
|
|
8749 |
return jwplayer(IriSP.PopcornReplacement._container).getPosition();
|
|
|
8750 |
} else {
|
|
|
8751 |
var currentTime = +time;
|
|
|
8752 |
jwplayer( IriSP.PopcornReplacement._container ).seek( currentTime );
|
|
|
8753 |
IriSP.PopcornReplacement.trigger("seeked");
|
|
|
8754 |
return jwplayer(IriSP.PopcornReplacement._container).getPosition();
|
|
|
8755 |
}
|
|
|
8756 |
};
|
|
|
8757 |
|
|
|
8758 |
IriSP.PopcornReplacement.play = function() {
|
|
|
8759 |
IriSP.PopcornReplacement.media.paused = false;
|
|
|
8760 |
IriSP.PopcornReplacement.trigger("play");
|
|
|
8761 |
// IriSP.PopcornReplacement.trigger("playing");
|
|
|
8762 |
jwplayer( IriSP.PopcornReplacement._container ).play();
|
|
|
8763 |
};
|
|
|
8764 |
|
|
|
8765 |
IriSP.PopcornReplacement.pause = function() {
|
|
|
8766 |
if ( !IriSP.PopcornReplacement.media.paused ) {
|
|
|
8767 |
IriSP.PopcornReplacement.media.paused = true;
|
|
|
8768 |
IriSP.PopcornReplacement.trigger( "pause" );
|
|
|
8769 |
jwplayer( IriSP.PopcornReplacement._container ).pause();
|
|
|
8770 |
}
|
|
|
8771 |
};
|
|
|
8772 |
|
|
|
8773 |
IriSP.PopcornReplacement.muted = function(val) {
|
|
|
8774 |
if (typeof(val) !== "undefined") {
|
|
|
8775 |
|
|
|
8776 |
if (jwplayer(IriSP.PopcornReplacement._container).getMute() !== val) {
|
|
|
8777 |
if (val) {
|
|
|
8778 |
jwplayer(IriSP.PopcornReplacement._container).setMute(true);
|
|
|
8779 |
IriSP.PopcornReplacement.media.muted = true;
|
|
|
8780 |
} else {
|
|
|
8781 |
jwplayer( IriSP.PopcornReplacement._container ).setMute(false);
|
|
|
8782 |
IriSP.PopcornReplacement.media.muted = false;
|
|
|
8783 |
}
|
|
|
8784 |
|
|
|
8785 |
IriSP.PopcornReplacement.trigger( "volumechange" );
|
|
|
8786 |
}
|
|
|
8787 |
|
|
|
8788 |
return jwplayer( IriSP.PopcornReplacement._container ).getMute();
|
|
|
8789 |
} else {
|
|
|
8790 |
return jwplayer( IriSP.PopcornReplacement._container ).getMute();
|
|
|
8791 |
}
|
|
|
8792 |
};
|
|
|
8793 |
|
|
|
8794 |
IriSP.PopcornReplacement.mute = IriSP.PopcornReplacement.muted;
|
|
|
8795 |
|
|
|
8796 |
IriSP.PopcornReplacement.__codes = [];
|
|
|
8797 |
IriSP.PopcornReplacement.code = function(options) {
|
|
|
8798 |
IriSP.PopcornReplacement.__codes.push(options);
|
|
|
8799 |
return IriSP.PopcornReplacement;
|
|
|
8800 |
};
|
|
|
8801 |
|
|
|
8802 |
IriSP.PopcornReplacement.__runCode = function() {
|
|
|
8803 |
var currentTime = jwplayer(IriSP.PopcornReplacement._container).getPosition();
|
|
|
8804 |
var i = 0;
|
|
|
8805 |
for(i = 0; i < IriSP.PopcornReplacement.__codes.length; i++) {
|
|
|
8806 |
var c = IriSP.PopcornReplacement.__codes[i];
|
|
|
8807 |
if (currentTime == c.start) {
|
|
|
8808 |
c.onStart();
|
|
|
8809 |
}
|
|
|
8810 |
|
|
|
8811 |
if (currentTime == c.end) {
|
|
|
8812 |
c.onEnd();
|
|
|
8813 |
}
|
|
|
8814 |
|
|
|
8815 |
}
|
|
|
8816 |
};
|
|
|
8817 |
|
|
|
8818 |
/* called everytime the player updates itself
|
|
|
8819 |
(onTime event)
|
|
|
8820 |
*/
|
|
|
8821 |
|
|
|
8822 |
IriSP.PopcornReplacement.__timeHandler = function(event) {
|
|
|
8823 |
var pos = event.position;
|
|
|
8824 |
|
|
|
8825 |
var i = 0;
|
|
|
8826 |
for(i = 0; i < IriSP.PopcornReplacement.__codes.length; i++) {
|
|
|
8827 |
var c = IriSP.PopcornReplacement.__codes[i];
|
|
|
8828 |
|
|
|
8829 |
if (pos >= c.start && pos < c.end &&
|
|
|
8830 |
pos - 0.1 <= c.start) {
|
|
|
8831 |
c.onStart();
|
|
|
8832 |
}
|
|
|
8833 |
|
|
|
8834 |
if (pos >= c.start && pos >= c.end &&
|
|
|
8835 |
pos - 0.1 <= c.end) {
|
|
|
8836 |
c.onEnd();
|
|
|
8837 |
}
|
|
|
8838 |
|
|
|
8839 |
}
|
|
|
8840 |
|
|
|
8841 |
IriSP.PopcornReplacement.trigger("timeupdate");
|
|
|
8842 |
};
|
|
|
8843 |
|
|
|
8844 |
IriSP.PopcornReplacement.__seekHandler = function(event) {
|
|
|
8845 |
var i = 0;
|
|
|
8846 |
for(i = 0; i < IriSP.PopcornReplacement.__codes.length; i++) {
|
|
|
8847 |
var c = IriSP.PopcornReplacement.__codes[i];
|
|
|
8848 |
|
|
|
8849 |
if (event.position >= c.start && event.position < c.end) {
|
|
|
8850 |
c.onEnd();
|
|
|
8851 |
}
|
|
|
8852 |
|
|
|
8853 |
if (typeof(event.offset) === "undefined")
|
|
|
8854 |
event.offset = 0;
|
|
|
8855 |
if (event.offset >= c.start && event.offset < c.end) {
|
|
|
8856 |
c.onStart();
|
|
|
8857 |
}
|
|
|
8858 |
|
|
|
8859 |
}
|
|
|
8860 |
|
|
|
8861 |
IriSP.PopcornReplacement.trigger("timeupdate");
|
|
|
8862 |
};
|
|
|
8863 |
|
|
|
8864 |
|
|
|
8865 |
IriSP.PopcornReplacement.__playHandler = function(event) {
|
|
|
8866 |
IriSP.PopcornReplacement.media.paused = false;
|
|
|
8867 |
IriSP.PopcornReplacement.trigger("play");
|
|
|
8868 |
};
|
|
|
8869 |
|
|
|
8870 |
IriSP.PopcornReplacement.__pauseHandler = function(event) {
|
|
|
8871 |
IriSP.PopcornReplacement.media.paused = true;
|
|
|
8872 |
IriSP.PopcornReplacement.trigger("pause");
|
|
|
8873 |
};
|
|
|
8874 |
|
|
|
8875 |
IriSP.PopcornReplacement.roundTime = function() {
|
|
|
8876 |
var currentTime = IriSP.PopcornReplacement.currentTime();
|
|
|
8877 |
return Math.round(currentTime);
|
|
|
8878 |
};
|
|
|
8879 |
/* utils.js - various utils that don't belong anywhere else */
|
|
|
8880 |
|
|
|
8881 |
/* trace function, for debugging */
|
|
|
8882 |
|
|
|
8883 |
IriSP.traceNum = 0;
|
|
|
8884 |
IriSP.trace = function( msg, value ) {
|
|
|
8885 |
/*
|
|
|
8886 |
if( IriSP.config.gui.debug === true ) {
|
|
|
8887 |
IriSP.traceNum += 1;
|
|
|
8888 |
IriSP.jQuery( "<div>"+IriSP.traceNum+" - "+msg+" : "+value+"</div>" ).appendTo( "#Ldt-output" );
|
|
|
8889 |
}
|
|
|
8890 |
*/
|
|
|
8891 |
};
|
|
|
8892 |
|
|
|
8893 |
/* used in callbacks - because in callbacks we lose "this",
|
|
|
8894 |
we need to have a special function which wraps "this" in
|
|
|
8895 |
a closure. This way, the
|
|
|
8896 |
*/
|
|
|
8897 |
IriSP.wrap = function (obj, fn) {
|
|
|
8898 |
return function() {
|
|
|
8899 |
var args = Array.prototype.slice.call(arguments, 0);
|
|
|
8900 |
return fn.apply(obj, args);
|
|
|
8901 |
}
|
|
|
8902 |
}
|
|
|
8903 |
|
|
|
8904 |
/* convert a time to a percentage in the media */
|
|
|
8905 |
IriSP.timeToPourcent = function(time, timetotal){
|
|
|
8906 |
var time = Math.abs(time);
|
|
|
8907 |
var timetotal = Math.abs(timetotal);
|
|
|
8908 |
|
|
|
8909 |
return Math.floor((time/timetotal) * 100);
|
|
|
8910 |
};
|
|
|
8911 |
|
|
|
8912 |
IriSP.padWithZeros = function(num) {
|
|
|
8913 |
if (Math.abs(num) < 10) {
|
|
|
8914 |
return "0" + num.toString();
|
|
|
8915 |
} else {
|
|
|
8916 |
return num.toString();
|
|
|
8917 |
}
|
|
|
8918 |
};
|
|
|
8919 |
/* convert a number of seconds to a tuple of the form
|
|
|
8920 |
[hours, minutes, seconds]
|
|
|
8921 |
*/
|
|
|
8922 |
IriSP.secondsToTime = function(secs) {
|
|
|
8923 |
var hours = Math.abs(parseInt( secs / 3600 ) % 24);
|
|
|
8924 |
var minutes = Math.abs(parseInt( secs / 60 ) % 60);
|
|
|
8925 |
var seconds = parseFloat(Math.abs(secs % 60).toFixed(0));
|
|
|
8926 |
|
|
|
8927 |
var toString_fn = function() {
|
|
|
8928 |
var ret = "";
|
|
|
8929 |
if (hours > 0)
|
|
|
8930 |
ret = IriSP.padWithZeros(this.hours) + ":";
|
|
|
8931 |
ret += IriSP.padWithZeros(this.minutes) + ":" + IriSP.padWithZeros(this.seconds);
|
|
|
8932 |
|
|
|
8933 |
return ret;
|
|
|
8934 |
}
|
|
|
8935 |
return {"hours" : hours, "minutes" : minutes, "seconds" : seconds, toString: toString_fn};
|
|
|
8936 |
};
|
|
|
8937 |
|
|
|
8938 |
IriSP.secondsToString
|
|
|
8939 |
|
|
|
8940 |
/* format a tweet - replaces @name by a link to the profile, #hashtag, etc. */
|
|
|
8941 |
IriSP.formatTweet = function(tweet) {
|
|
|
8942 |
/*
|
|
|
8943 |
an array of arrays which hold a regexp and its replacement.
|
|
|
8944 |
*/
|
|
|
8945 |
var regExps = [
|
|
|
8946 |
/* copied from http://codegolf.stackexchange.com/questions/464/shortest-url-regex-match-in-javascript/480#480 */
|
|
|
8947 |
[/((https?:\/\/)?[\w-]+(\.[\w-]+)+\.?(:\d+)?(\/\S*)?)/gi, "<a href='$1'>$1</a>"],
|
|
|
8948 |
[/@(\w+)/gi, "<a href='http://twitter.com/$1'>@$1</a>"], // matches a @handle
|
|
|
8949 |
[/#(\w+)/gi, "<a href='http://twitter.com/search?q=%23$1'>#$1</a>"],// matches a hashtag
|
|
|
8950 |
[/(\+\+)/gi, "<span class='Ldt-PolemicPlusPlus'>$1</span>"],
|
|
|
8951 |
[/(--)/gi, "<span class='Ldt-PolemicMinusMinus'>$1</span>"],
|
|
|
8952 |
[/(==)/gi, "<span class='Ldt-PolemicEqualEqual'>$1</span>"],
|
|
|
8953 |
[/(\?\?)/gi, "<span class='Ldt-PolemicQuestion'>$1</span>"]
|
|
|
8954 |
];
|
|
|
8955 |
|
|
|
8956 |
var i = 0;
|
|
|
8957 |
for(i = 0; i < regExps.length; i++) {
|
|
|
8958 |
tweet = tweet.replace(regExps[i][0], regExps[i][1]);
|
|
|
8959 |
}
|
|
|
8960 |
|
|
|
8961 |
return tweet;
|
|
|
8962 |
};
|
|
|
8963 |
|
|
|
8964 |
IriSP.countProperties = function(obj) {
|
|
|
8965 |
var count = 0;
|
|
|
8966 |
|
|
|
8967 |
for(var prop in obj) {
|
|
|
8968 |
if(obj.hasOwnProperty(prop))
|
|
|
8969 |
++count;
|
|
|
8970 |
}
|
|
|
8971 |
|
|
|
8972 |
return count;
|
|
|
8973 |
};
|
|
|
8974 |
|
|
|
8975 |
// conversion de couleur Decimal vers HexaDecimal || 000 si fff
|
|
|
8976 |
IriSP.DEC_HEXA_COLOR = function (dec) {
|
|
|
8977 |
var hexa='0123456789ABCDEF',hex='';
|
|
|
8978 |
var tmp;
|
|
|
8979 |
while (dec>15){
|
|
|
8980 |
tmp = dec-(Math.floor(dec/16))*16;
|
|
|
8981 |
hex = hexa.charAt(tmp)+hex;
|
|
|
8982 |
dec = Math.floor(dec/16);
|
|
|
8983 |
}
|
|
12
|
8984 |
hex = hexa.charAt(dec)+hex;
|
|
0
|
8985 |
return(hex);
|
|
|
8986 |
};
|
|
|
8987 |
|
|
|
8988 |
/* shortcut to have global variables in templates */
|
|
|
8989 |
IriSP.templToHTML = function(template, values) {
|
|
|
8990 |
var params = IriSP.jQuery.extend(IriSP.default_templates_vars, values);
|
|
|
8991 |
return Mustache.to_html(template, params);
|
|
|
8992 |
};
|
|
|
8993 |
|
|
|
8994 |
/* we need to be stricter than encodeURIComponent,
|
|
|
8995 |
because of twitter
|
|
|
8996 |
*/
|
|
|
8997 |
IriSP.encodeURI = function(str) {
|
|
|
8998 |
return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').
|
|
|
8999 |
replace(/\)/g, '%29').replace(/\*/g, '%2A');
|
|
|
9000 |
}
|
|
|
9001 |
|
|
|
9002 |
|
|
|
9003 |
/* for ie compatibility
|
|
|
9004 |
if (Object.prototype.__defineGetter__&&!Object.defineProperty) {
|
|
|
9005 |
Object.defineProperty=function(obj,prop,desc) {
|
|
|
9006 |
if ("get" in desc) obj.__defineGetter__(prop,desc.get);
|
|
|
9007 |
if ("set" in desc) obj.__defineSetter__(prop,desc.set);
|
|
|
9008 |
}
|
|
|
9009 |
}
|
|
|
9010 |
*/
|
|
|
9011 |
/* data.js - this file deals with how the players gets and sends data */
|
|
|
9012 |
|
|
|
9013 |
IriSP.DataLoader = function() {
|
|
|
9014 |
this._cache = {};
|
|
|
9015 |
|
|
|
9016 |
/*
|
|
|
9017 |
A structure to hold callbacks for specific urls. We need it because
|
|
|
9018 |
ajax calls are asynchronous, so it means that sometimes we ask
|
|
|
9019 |
multiple times for a ressource because the first call hasn't been
|
|
|
9020 |
received yet.
|
|
|
9021 |
*/
|
|
|
9022 |
this._callbacks = {};
|
|
|
9023 |
};
|
|
|
9024 |
|
|
|
9025 |
IriSP.DataLoader.prototype.get = function(url, callback) {
|
|
|
9026 |
|
|
|
9027 |
var base_url = url.split("&")[0]
|
|
|
9028 |
if (this._cache.hasOwnProperty(base_url)) {
|
|
|
9029 |
callback(this._cache[base_url]);
|
|
|
9030 |
} else {
|
|
|
9031 |
if (!this._callbacks.hasOwnProperty(base_url)) {
|
|
|
9032 |
this._callbacks[base_url] = [];
|
|
|
9033 |
this._callbacks[base_url].push(callback);
|
|
|
9034 |
/* we need a closure because this gets lost when it's called back */
|
|
|
9035 |
|
|
|
9036 |
// uncomment you don't want to use caching.
|
|
|
9037 |
// IriSP.jQuery.get(url, callback);
|
|
|
9038 |
|
|
|
9039 |
var func = function(data) {
|
|
|
9040 |
this._cache[base_url] = data;
|
|
|
9041 |
var i = 0;
|
|
|
9042 |
|
|
|
9043 |
for (i = 0; i < this._callbacks[base_url].length; i++) {
|
|
|
9044 |
this._callbacks[base_url][i](this._cache[base_url]);
|
|
|
9045 |
}
|
|
|
9046 |
};
|
|
|
9047 |
|
|
|
9048 |
/* automagically choose between json and jsonp */
|
|
|
9049 |
if (url.indexOf(document.location.hostname) === -1 &&
|
|
|
9050 |
url.indexOf("http://") !== -1 /* not a relative url */ ) {
|
|
|
9051 |
// we contacting a foreign domain, use JSONP
|
|
|
9052 |
|
|
|
9053 |
IriSP.jQuery.get(url, {}, IriSP.wrap(this, func), "jsonp");
|
|
|
9054 |
} else {
|
|
|
9055 |
|
|
|
9056 |
// otherwise, hey, whatever rows your boat
|
|
|
9057 |
IriSP.jQuery.get(url, IriSP.wrap(this, func));
|
|
|
9058 |
}
|
|
|
9059 |
|
|
|
9060 |
} else {
|
|
|
9061 |
/* simply push the callback - it'll get called when the ressource
|
|
|
9062 |
has been received */
|
|
|
9063 |
|
|
|
9064 |
this._callbacks[base_url].push(callback);
|
|
|
9065 |
|
|
|
9066 |
}
|
|
|
9067 |
}
|
|
|
9068 |
}
|
|
|
9069 |
|
|
|
9070 |
/* the base abstract "class" */
|
|
|
9071 |
IriSP.Serializer = function(DataLoader, url) {
|
|
|
9072 |
this._DataLoader = DataLoader;
|
|
|
9073 |
this._url = url;
|
|
|
9074 |
this._data = [];
|
|
|
9075 |
};
|
|
|
9076 |
|
|
|
9077 |
IriSP.Serializer.prototype.serialize = function(data) { };
|
|
|
9078 |
IriSP.Serializer.prototype.deserialize = function(data) {};
|
|
|
9079 |
|
|
|
9080 |
IriSP.Serializer.prototype.currentMedia = function() {
|
|
|
9081 |
};
|
|
|
9082 |
|
|
|
9083 |
IriSP.Serializer.prototype.sync = function(callback) {
|
|
|
9084 |
callback.call(this, this._data);
|
|
|
9085 |
};
|
|
|
9086 |
|
|
|
9087 |
IriSP.SerializerFactory = function(DataLoader) {
|
|
|
9088 |
this._dataloader = DataLoader;
|
|
|
9089 |
};
|
|
|
9090 |
|
|
|
9091 |
IriSP.SerializerFactory.prototype.getSerializer = function(metadataOptions) {
|
|
|
9092 |
/* This function returns serializer set-up with the correct
|
|
|
9093 |
configuration - takes a metadata struct describing the metadata source
|
|
|
9094 |
*/
|
|
|
9095 |
|
|
|
9096 |
if (metadataOptions === undefined)
|
|
|
9097 |
/* return an empty serializer */
|
|
|
9098 |
return IriSP.Serializer("", "");
|
|
|
9099 |
|
|
|
9100 |
switch(metadataOptions.type) {
|
|
|
9101 |
case "json":
|
|
|
9102 |
return new IriSP.JSONSerializer(this._dataloader, metadataOptions.src);
|
|
|
9103 |
break;
|
|
|
9104 |
|
|
|
9105 |
case "dummy": /* only used for unit testing - not defined in production */
|
|
|
9106 |
return new IriSP.MockSerializer(this._dataloader, metadataOptions.src);
|
|
|
9107 |
break;
|
|
|
9108 |
|
|
|
9109 |
case "empty":
|
|
|
9110 |
return new IriSP.Serializer("", "empty");
|
|
|
9111 |
break;
|
|
|
9112 |
|
|
|
9113 |
default:
|
|
|
9114 |
return undefined;
|
|
|
9115 |
}
|
|
|
9116 |
};
|
|
|
9117 |
/* site.js - all our site-dependent config : player chrome, cdn locations, etc...*/
|
|
|
9118 |
|
|
|
9119 |
IriSP.lib = {
|
|
|
9120 |
jQuery : "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js",
|
|
|
9121 |
jQueryUI : "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.4/jquery-ui.js",
|
|
|
9122 |
jQueryToolTip : "http://cdn.jquerytools.org/1.2.4/all/jquery.tools.min.js",
|
|
|
9123 |
swfObject : "http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js",
|
|
|
9124 |
cssjQueryUI : "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.4/themes/base/jquery-ui.css",
|
|
|
9125 |
popcorn : "src/js/libs/popcorn.js",
|
|
|
9126 |
jwplayer : "src/js/libs/jwplayer.js",
|
|
|
9127 |
"popcorn.mediafragment" : "src/js/libs/popcorn.mediafragment.js",
|
|
|
9128 |
"popcorn.code" : "src/js/libs/popcorn.code.js",
|
|
|
9129 |
"popcorn.jwplayer": "src/js/libs/popcorn.jwplayer.js",
|
|
|
9130 |
"popcorn.youtube": "src/js/libs/popcorn.youtube.js",
|
|
|
9131 |
raphael: "src/js/libs/raphael.js"
|
|
|
9132 |
};
|
|
|
9133 |
|
|
|
9134 |
//Player Configuration
|
|
|
9135 |
IriSP.config = undefined;
|
|
|
9136 |
|
|
|
9137 |
IriSP.widgetsDefaults = {
|
|
|
9138 |
"LayoutManager" : {spacer_div_height : "0px" },
|
|
|
9139 |
"PlayerWidget" : {},
|
|
9
|
9140 |
"AnnotationsWidget": {
|
|
|
9141 |
"share_text" : "I'm watching ",
|
|
|
9142 |
"fb_link" : "http://www.facebook.com/share.php?u=",
|
|
|
9143 |
"tw_link" : "http://twitter.com/home?status=",
|
|
|
9144 |
"gplus_link" : ""
|
|
|
9145 |
},
|
|
0
|
9146 |
"TweetsWidget" : {
|
|
|
9147 |
default_profile_picture : "https://si0.twimg.com/sticky/default_profile_images/default_profile_1_normal.png",
|
|
|
9148 |
tweet_display_period: 10000 // how long do we show a tweet ?
|
|
|
9149 |
},
|
|
|
9150 |
"SliderWidget" : {
|
|
|
9151 |
minimize_period: 850 // how long does the slider stays maximized after the user leaves the zone ?
|
|
|
9152 |
}
|
|
|
9153 |
};
|
|
|
9154 |
|
|
|
9155 |
IriSP.paths = {
|
|
|
9156 |
// "imgs": "/tweetlive/res/metadataplayer/src/css/imgs"
|
|
9
|
9157 |
"imgs": "imgs"
|
|
0
|
9158 |
};
|
|
|
9159 |
IriSP.default_templates_vars = {
|
|
|
9160 |
"img_dir" : IriSP.paths.imgs
|
|
|
9161 |
};
|
|
|
9162 |
|
|
|
9163 |
/* ui.js - ui related functions */
|
|
|
9164 |
|
|
|
9165 |
/* FIXME: use an sharing library */
|
|
|
9166 |
IriSP.LdtShareTool = IriSP.share_template; /* the contents come from share.html */
|
|
|
9167 |
|
|
|
9168 |
IriSP.createPlayerChrome = function(){
|
|
|
9169 |
var width = IriSP.config.gui.width;
|
|
|
9170 |
var height = IriSP.config.gui.height;
|
|
|
9171 |
var heightS = IriSP.config.gui.height-20;
|
|
|
9172 |
|
|
|
9173 |
// AUDIO */
|
|
|
9174 |
// PB dans le html : ;
|
|
|
9175 |
IriSP.trace( "__IriSP.createMyHtml",IriSP.config.gui.container );
|
|
|
9176 |
|
|
|
9177 |
|
|
|
9178 |
/* FIXME : factor this in another file */
|
|
|
9179 |
if( IriSP.config.gui.mode=="radio" ){
|
|
|
9180 |
|
|
|
9181 |
IriSP.jQuery( "#"+IriSP.config.gui.container ).before(IriSP.search_template);
|
|
|
9182 |
var radioPlayer = Mustache.to_html(IriSP.radio_template, {"share_template" : IriSP.share_template});
|
|
|
9183 |
IriSP.jQuery(radioPlayer).appendTo("#"+IriSP.config.gui.container);
|
|
|
9184 |
|
|
|
9185 |
// special tricks for IE 7
|
|
|
9186 |
if (IriSP.jQuery.browser.msie==true && IriSP.jQuery.browser.version=="7.0"){
|
|
|
9187 |
//LdtSearchContainer
|
|
|
9188 |
//__IriSP.jQuery("#LdtPlayer").attr("margin-top","50px");
|
|
|
9189 |
IriSP.jQuery("#Ldt-Root").css("padding-top","25px");
|
|
|
9190 |
IriSP.trace("__IriSP.createHtml","IE7 SPECIAL ");
|
|
|
9191 |
}
|
|
|
9192 |
} else if(IriSP.config.gui.mode=="video") {
|
|
|
9193 |
|
|
|
9194 |
var videoPlayer = Mustache.to_html(IriSP.video_template, {"share_template" : IriSP.share_template, "heightS" : heightS});
|
|
|
9195 |
IriSP.jQuery(videoPlayer).appendTo("#"+IriSP.config.gui.container);
|
|
|
9196 |
}
|
|
|
9197 |
|
|
|
9198 |
IriSP.jQuery("#Ldt-Annotations").width(width-(75*2));
|
|
|
9199 |
IriSP.jQuery("#Ldt-Show-Arrow-container").width(width-(75*2));
|
|
|
9200 |
IriSP.jQuery("#Ldt-ShowAnnotation-audio").width(width-10);
|
|
|
9201 |
IriSP.jQuery("#Ldt-ShowAnnotation-video").width(width-10);
|
|
|
9202 |
IriSP.jQuery("#Ldt-SaKeyword").width(width-10);
|
|
|
9203 |
IriSP.jQuery("#Ldt-controler").width(width-10);
|
|
|
9204 |
IriSP.jQuery("#Ldt-Control").attr("z-index","100");
|
|
|
9205 |
IriSP.jQuery("#Ldt-controler").hide();
|
|
|
9206 |
|
|
|
9207 |
IriSP.jQuery(IriSP.annotation_loading_template).appendTo("#Ldt-ShowAnnotation-audio");
|
|
|
9208 |
|
|
|
9209 |
if(IriSP.config.gui.mode=='radio'){
|
|
|
9210 |
IriSP.jQuery("#Ldt-load-container").attr("width",IriSP.config.gui.width);
|
|
|
9211 |
}
|
|
|
9212 |
// Show or not the output
|
|
|
9213 |
if(IriSP.config.gui.debug===true){
|
|
|
9214 |
IriSP.jQuery("#Ldt-output").show();
|
|
|
9215 |
} else {
|
|
|
9216 |
IriSP.jQuery("#Ldt-output").hide();
|
|
|
9217 |
}
|
|
|
9218 |
|
|
|
9219 |
};
|
|
|
9220 |
|
|
|
9221 |
|
|
|
9222 |
/* create the buttons and the slider */
|
|
|
9223 |
IriSP.createInterface = function( width, height, duration ) {
|
|
|
9224 |
|
|
|
9225 |
IriSP.jQuery( "#Ldt-controler" ).show();
|
|
|
9226 |
//__IriSP.jQuery("#Ldt-Root").css('display','visible');
|
|
|
9227 |
IriSP.trace( "__IriSP.createInterface" , width+","+height+","+duration+"," );
|
|
|
9228 |
|
|
|
9229 |
IriSP.jQuery( "#Ldt-ShowAnnotation").click( function () {
|
|
|
9230 |
//__IriSP.jQuery(this).slideUp();
|
|
|
9231 |
} );
|
|
|
9232 |
|
|
|
9233 |
var LdtpPlayerY = IriSP.jQuery("#Ldt-PlaceHolder").attr("top");
|
|
|
9234 |
var LdtpPlayerX = IriSP.jQuery("#Ldt-PlaceHolder").attr("left");
|
|
|
9235 |
|
|
|
9236 |
IriSP.jQuery( "#slider-range-min" ).slider( { //range: "min",
|
|
|
9237 |
value: 0,
|
|
|
9238 |
min: 1,
|
|
|
9239 |
max: duration/1000,//1:54:52.66 = 3600+3240+
|
|
|
9240 |
step: 0.1,
|
|
|
9241 |
slide: function(event, ui) {
|
|
|
9242 |
|
|
|
9243 |
//__IriSP.jQuery("#amount").val(ui.value+" s");
|
|
|
9244 |
//player.sendEvent('SEEK', ui.value)
|
|
|
9245 |
IriSP.MyApiPlayer.seek(ui.value);
|
|
|
9246 |
//changePageUrlOffset(ui.value);
|
|
|
9247 |
//player.sendEvent('PAUSE')
|
|
|
9248 |
}
|
|
|
9249 |
} );
|
|
|
9250 |
|
|
|
9251 |
IriSP.trace("__IriSP.createInterface","ICI");
|
|
|
9252 |
IriSP.jQuery("#amount").val(IriSP.jQuery("#slider-range-min").slider("value")+" s");
|
|
|
9253 |
IriSP.jQuery(".Ldt-Control1 button:first").button({
|
|
|
9254 |
icons: {
|
|
|
9255 |
primary: 'ui-icon-play'
|
|
|
9256 |
},
|
|
|
9257 |
text: false
|
|
|
9258 |
}).next().button({
|
|
|
9259 |
icons: {
|
|
|
9260 |
primary: 'ui-icon-seek-next'
|
|
|
9261 |
},
|
|
|
9262 |
text: false
|
|
|
9263 |
});
|
|
|
9264 |
IriSP.jQuery(".Ldt-Control2 button:first").button({
|
|
|
9265 |
icons: {
|
|
|
9266 |
primary: 'ui-icon-search'//,
|
|
|
9267 |
//secondary: 'ui-icon-volume-off'
|
|
|
9268 |
},
|
|
|
9269 |
text: false
|
|
|
9270 |
}).next().button({
|
|
|
9271 |
icons: {
|
|
|
9272 |
primary: 'ui-icon-volume-on'
|
|
|
9273 |
},
|
|
|
9274 |
text: false
|
|
|
9275 |
});
|
|
|
9276 |
|
|
|
9277 |
// /!\ PB A MODIFIER
|
|
|
9278 |
//__IriSP.MyTags.draw();
|
|
|
9279 |
IriSP.trace("__IriSP.createInterface","ICI2");
|
|
|
9280 |
IriSP.jQuery( "#ldt-CtrlPlay" ).attr( "style", "background-color:#CD21C24;" );
|
|
|
9281 |
|
|
|
9282 |
IriSP.jQuery( "#Ldt-load-container" ).hide();
|
|
|
9283 |
|
|
|
9284 |
if( IriSP.config.gui.mode=="radio" & IriSP.jQuery.browser.msie != true ) {
|
|
|
9285 |
IriSP.jQuery( "#Ldtplayer1" ).attr( "height", "0" );
|
|
|
9286 |
}
|
|
|
9287 |
IriSP.trace( "__IriSP.createInterface" , "3" );
|
|
|
9288 |
|
|
|
9289 |
IriSP.trace( "__IriSP.createInterface", "END" );
|
|
|
9290 |
|
|
|
9291 |
};
|
|
|
9292 |
/* the widget classes and definitions */
|
|
|
9293 |
|
|
|
9294 |
IriSP.Widget = function(Popcorn, config, Serializer) {
|
|
|
9295 |
|
|
|
9296 |
if (config === undefined || config === null) {
|
|
|
9297 |
config = {}
|
|
|
9298 |
}
|
|
|
9299 |
|
|
|
9300 |
this._Popcorn = Popcorn;
|
|
|
9301 |
this._config = config;
|
|
|
9302 |
this._serializer = Serializer;
|
|
|
9303 |
|
|
|
9304 |
if (config.hasOwnProperty("container")) {
|
|
|
9305 |
this._id = config.container;
|
|
|
9306 |
this.selector = IriSP.jQuery("#" + this._id);
|
|
|
9307 |
}
|
|
|
9308 |
|
|
|
9309 |
if (config.hasOwnProperty("spacer")) {
|
|
|
9310 |
this._spacerId = config.spacer;
|
|
|
9311 |
this.spacer = IriSP.jQuery("#" + this._spacerId);
|
|
|
9312 |
}
|
|
|
9313 |
|
|
|
9314 |
|
|
|
9315 |
if (config.hasOwnProperty("width")) {
|
|
|
9316 |
// this.width and not this._width because we consider it public.
|
|
|
9317 |
this.width = config.width;
|
|
|
9318 |
}
|
|
|
9319 |
|
|
|
9320 |
if (config.hasOwnProperty("height")) {
|
|
|
9321 |
this.height = config.height;
|
|
|
9322 |
}
|
|
|
9323 |
|
|
|
9324 |
if (config.hasOwnProperty("heightmax")) {
|
|
|
9325 |
this.heightmax = config.heightmax;
|
|
|
9326 |
}
|
|
|
9327 |
|
|
|
9328 |
if (config.hasOwnProperty("widthmax")) {
|
|
|
9329 |
this.widthmax = config.widthmax;
|
|
|
9330 |
}
|
|
|
9331 |
|
|
|
9332 |
};
|
|
|
9333 |
|
|
|
9334 |
IriSP.Widget.prototype.draw = function() {
|
|
|
9335 |
/* implemented by "sub-classes" */
|
|
|
9336 |
};
|
|
|
9337 |
|
|
|
9338 |
IriSP.Widget.prototype.redraw = function() {
|
|
|
9339 |
/* implemented by "sub-classes" */
|
|
|
9340 |
};
|
|
|
9341 |
/* modules are non-graphical entities, similar to widgets */
|
|
|
9342 |
|
|
|
9343 |
IriSP.Module = function(Popcorn, config, Serializer) {
|
|
|
9344 |
|
|
|
9345 |
if (config === undefined || config === null) {
|
|
|
9346 |
config = {}
|
|
|
9347 |
}
|
|
|
9348 |
|
|
|
9349 |
this._Popcorn = Popcorn;
|
|
|
9350 |
this._config = config;
|
|
|
9351 |
this._serializer = Serializer;
|
|
|
9352 |
};
|
|
|
9353 |
/* layout.js - very basic layout management */
|
|
|
9354 |
|
|
|
9355 |
/*
|
|
|
9356 |
a layout manager manages a div and the layout of objects
|
|
|
9357 |
inside it.
|
|
|
9358 |
*/
|
|
|
9359 |
|
|
|
9360 |
IriSP.LayoutManager = function(options) {
|
|
|
9361 |
this._Popcorn = null;
|
|
|
9362 |
this._widgets = [];
|
|
|
9363 |
|
|
|
9364 |
this._div = "LdtPlayer";
|
|
|
9365 |
this._width = 640;
|
|
|
9366 |
|
|
|
9367 |
if (options === undefined) {
|
|
|
9368 |
options = {};
|
|
|
9369 |
};
|
|
|
9370 |
|
|
|
9371 |
if (options.hasOwnProperty('container')) {
|
|
|
9372 |
this._div = options.container;
|
|
|
9373 |
}
|
|
|
9374 |
|
|
|
9375 |
if (options.hasOwnProperty('width')) {
|
|
|
9376 |
this._width = options.width;
|
|
|
9377 |
}
|
|
|
9378 |
|
|
|
9379 |
if (options.hasOwnProperty('height')) {
|
|
|
9380 |
this._height = options.height;
|
|
|
9381 |
}
|
|
|
9382 |
|
|
|
9383 |
/* this is a shortcut */
|
|
|
9384 |
this.selector = IriSP.jQuery("#" + this._div);
|
|
|
9385 |
|
|
|
9386 |
this.selector.css("width", this._width);
|
|
|
9387 |
|
|
|
9388 |
if (this._height !== undefined)
|
|
|
9389 |
this.selector.css("height", this._height);
|
|
|
9390 |
};
|
|
|
9391 |
|
|
|
9392 |
/* we need this special setter because of a chicken and egg problem :
|
|
|
9393 |
we want the manager to use popcorn but the popcorn div will be managed
|
|
|
9394 |
by the manager. So we need a way to set the instance the manager uses
|
|
|
9395 |
*/
|
|
|
9396 |
|
|
|
9397 |
IriSP.LayoutManager.prototype.setPopcornInstance = function(popcorn) {
|
|
|
9398 |
this._Popcorn = popcorn;
|
|
|
9399 |
}
|
|
|
9400 |
|
|
|
9401 |
/* stem is a string to append to the id of the widget */
|
|
|
9402 |
IriSP.LayoutManager.prototype.createDiv = function(stem) {
|
|
|
9403 |
if (typeof(stem) === "undefined")
|
|
|
9404 |
stem = "";
|
|
|
9405 |
|
|
|
9406 |
var newDiv = Popcorn.guid(this._div + "_widget_" + stem + "_");
|
|
|
9407 |
var spacerDiv = Popcorn.guid("LdtPlayer_spacer_");
|
|
|
9408 |
this._widgets.push(newDiv);
|
|
|
9409 |
|
|
|
9410 |
var divTempl = "<div id='{{id}}' style='width: {{width}}px; position: relative;'></div";
|
|
|
9411 |
var spacerTempl = "<div id='{{spacer_id}}' style='width: {{width}}px; position: relative; height: {{spacer_div_height}};'></div";
|
|
|
9412 |
|
|
|
9413 |
var divCode = Mustache.to_html(divTempl, {id: newDiv, width: this._width});
|
|
|
9414 |
var spacerCode = Mustache.to_html(spacerTempl, {spacer_id: spacerDiv, width: this._width,
|
|
|
9415 |
spacer_div_height: IriSP.widgetsDefaults.LayoutManager.spacer_div_height });
|
|
|
9416 |
|
|
|
9417 |
this.selector.append(divCode);
|
|
|
9418 |
this.selector.append(spacerCode);
|
|
|
9419 |
|
|
|
9420 |
return [newDiv, spacerDiv];
|
|
|
9421 |
};
|
|
|
9422 |
/* init.js - initialization and configuration of Popcorn and the widgets
|
|
|
9423 |
exemple json configuration:
|
|
|
9424 |
|
|
|
9425 |
*/
|
|
|
9426 |
|
|
|
9427 |
IriSP.setupDataLoader = function() {
|
|
|
9428 |
/* we set it up separately because we need to
|
|
|
9429 |
get data at the very beginning, for instance when
|
|
|
9430 |
setting up the video */
|
|
|
9431 |
IriSP.__dataloader = new IriSP.DataLoader();
|
|
|
9432 |
};
|
|
|
9433 |
|
|
|
9434 |
IriSP.configurePopcorn = function (layoutManager, options) {
|
|
|
9435 |
var pop;
|
|
|
9436 |
var ret = layoutManager.createDiv();
|
|
|
9437 |
var containerDiv = ret[0];
|
|
|
9438 |
|
|
|
9439 |
switch(options.type) {
|
|
|
9440 |
/*
|
|
|
9441 |
todo : dynamically create the div/video tag which
|
|
|
9442 |
will contain the video.
|
|
|
9443 |
*/
|
|
|
9444 |
case "html5":
|
|
|
9445 |
var tmpId = Popcorn.guid("video");
|
|
|
9446 |
IriSP.jQuery("#" + containerDiv).append("<video src='" + options.file + "' id='" + tmpId + "'></video>");
|
|
|
9447 |
|
|
|
9448 |
if (options.hasOwnProperty("width"))
|
|
|
9449 |
IriSP.jQuery("#" + containerDiv).css("width", options.width);
|
|
|
9450 |
|
|
|
9451 |
if (options.hasOwnProperty("height"))
|
|
|
9452 |
IriSP.jQuery("#" + containerDiv).css("height", options.height);
|
|
|
9453 |
|
|
|
9454 |
pop = Popcorn("#" + tmpId).mediafragment({start : 0});
|
|
|
9455 |
break;
|
|
|
9456 |
|
|
|
9457 |
case "jwplayer":
|
|
|
9458 |
var opts = IriSP.jQuery.extend({}, options);
|
|
|
9459 |
delete opts.container;
|
|
|
9460 |
|
|
|
9461 |
if (options.provider === "rtmp") {
|
|
|
9462 |
/* exit if we can't access the metadata */
|
|
|
9463 |
if (typeof(IriSP.__jsonMetadata) === "undefined") {
|
|
|
9464 |
break;
|
|
|
9465 |
};
|
|
|
9466 |
|
|
|
9467 |
|
|
|
9468 |
// the json format is totally illogical
|
|
|
9469 |
opts.streamer = IriSP.__jsonMetadata["medias"][0]["meta"]["item"]["value"];
|
|
|
9470 |
var source = IriSP.__jsonMetadata["medias"][0]["href"];
|
|
|
9471 |
|
|
|
9472 |
// the source if a full url but jwplayer wants an url relative to the
|
|
|
9473 |
// streamer url, so we've got to remove the common part.
|
|
|
9474 |
opts.file = source.slice(opts.streamer.length);
|
|
|
9475 |
} else {
|
|
|
9476 |
/* other providers type, video for instance -
|
|
|
9477 |
pass everything as is */
|
|
|
9478 |
}
|
|
|
9479 |
|
|
|
9480 |
pop = IriSP.PopcornReplacement.jwplayer("#" + containerDiv, opts);
|
|
|
9481 |
break;
|
|
|
9482 |
|
|
|
9483 |
case "youtube":
|
|
|
9484 |
var opts = IriSP.jQuery.extend({}, options);
|
|
|
9485 |
delete opts.container;
|
|
|
9486 |
opts.controls = 0;
|
|
|
9487 |
opts.autostart = false;
|
|
|
9488 |
templ = "width: {{width}}px; height: {{height}}px;";
|
|
|
9489 |
var str = Mustache.to_html(templ, {width: opts.width, height: opts.height});
|
|
|
9490 |
// Popcorn.youtube wants us to specify the size of the player in the style attribute of its container div.
|
|
|
9491 |
IriSP.jQuery("#" + containerDiv).attr("style", str);
|
|
|
9492 |
|
|
|
9493 |
pop = Popcorn.youtube("#" + containerDiv, opts.video, opts).mediafragment({start : 0});
|
|
|
9494 |
break;
|
|
|
9495 |
|
|
|
9496 |
default:
|
|
|
9497 |
pop = undefined;
|
|
|
9498 |
};
|
|
|
9499 |
|
|
|
9500 |
return pop;
|
|
|
9501 |
};
|
|
|
9502 |
|
|
|
9503 |
IriSP.configureWidgets = function (popcornInstance, layoutManager, guiOptions) {
|
|
|
9504 |
|
|
|
9505 |
var serialFactory = new IriSP.SerializerFactory(IriSP.__dataloader);
|
|
|
9506 |
var params = {width: guiOptions.width, height: guiOptions.height};
|
|
|
9507 |
|
|
|
9508 |
var ret_widgets = [];
|
|
|
9509 |
var index;
|
|
|
9510 |
|
|
|
9511 |
for (index = 0; index < guiOptions.widgets.length; index++) {
|
|
|
9512 |
var widgetConfig = guiOptions.widgets[index];
|
|
|
9513 |
var widget = IriSP.instantiateWidget(popcornInstance, serialFactory, layoutManager, widgetConfig);
|
|
|
9514 |
ret_widgets.push(widget);
|
|
|
9515 |
|
|
|
9516 |
};
|
|
|
9517 |
|
|
|
9518 |
return ret_widgets;
|
|
|
9519 |
};
|
|
|
9520 |
|
|
|
9521 |
IriSP.configureModules = function (popcornInstance, modulesList) {
|
|
|
9522 |
|
|
|
9523 |
var serialFactory = new IriSP.SerializerFactory(IriSP.__dataloader);
|
|
|
9524 |
var ret_modules = [];
|
|
|
9525 |
var index;
|
|
|
9526 |
|
|
|
9527 |
for (index = 0; index < modulesList.length; index++) {
|
|
|
9528 |
var moduleConfig = modulesList[index];
|
|
|
9529 |
|
|
|
9530 |
var serializer = serialFactory.getSerializer(moduleConfig.metadata);
|
|
|
9531 |
var module = new IriSP[moduleConfig.type](popcornInstance, moduleConfig, serializer);
|
|
|
9532 |
ret_modules.push(module);
|
|
|
9533 |
};
|
|
|
9534 |
|
|
|
9535 |
return ret_modules;
|
|
|
9536 |
};
|
|
|
9537 |
|
|
|
9538 |
IriSP.instantiateWidget = function(popcornInstance, serialFactory, layoutManager, widgetConfig) {
|
|
|
9539 |
/* create div returns us a container for the widget and a spacer */
|
|
|
9540 |
var ret = layoutManager.createDiv(widgetConfig.type);
|
|
|
9541 |
var container = ret[0];
|
|
|
9542 |
var spacer = ret[1];
|
|
|
9543 |
|
|
|
9544 |
var arr = IriSP.jQuery.extend({}, widgetConfig);
|
|
|
9545 |
arr.container = container;
|
|
|
9546 |
arr.spacer = spacer;
|
|
|
9547 |
|
|
|
9548 |
var serializer = serialFactory.getSerializer(widgetConfig.metadata);
|
|
|
9549 |
|
|
|
9550 |
if (typeof serializer == "undefined")
|
|
|
9551 |
debugger;
|
|
|
9552 |
|
|
|
9553 |
// instantiate the object passed as a string
|
|
|
9554 |
var widget = new IriSP[widgetConfig.type](popcornInstance, arr, serializer);
|
|
|
9555 |
|
|
|
9556 |
if (widgetConfig.hasOwnProperty("requires")) {
|
|
|
9557 |
// also create the widgets this one depends on.
|
|
|
9558 |
// the dependency widget is available in the parent widget context as
|
|
|
9559 |
// this.WidgetName (for instance, this.TipWidget);
|
|
|
9560 |
|
|
|
9561 |
var i = 0;
|
|
|
9562 |
for(i = 0; i < widgetConfig.requires.length; i++) {
|
|
|
9563 |
var widgetName = widgetConfig.requires[i]["type"];
|
|
|
9564 |
widget[widgetName] = IriSP.instantiateWidget(popcornInstance, serialFactory, layoutManager, widgetConfig.requires[i]);
|
|
|
9565 |
}
|
|
|
9566 |
}
|
|
|
9567 |
|
|
|
9568 |
serializer.sync(IriSP.wrap(widget, function() { this.draw(); }));
|
|
|
9569 |
return widget;
|
|
|
9570 |
};
|
|
|
9571 |
/* mediafragment module */
|
|
|
9572 |
|
|
|
9573 |
IriSP.MediaFragment = function(Popcorn, config, Serializer) {
|
|
|
9574 |
IriSP.Module.call(this, Popcorn, config, Serializer);
|
|
|
9575 |
|
|
|
9576 |
this.mutex = false; /* a mutex because we access the url from two different functions */
|
|
|
9577 |
|
|
|
9578 |
this._Popcorn.listen( "loadedmetadata", IriSP.wrap(this, IriSP.MediaFragment.advanceTime));
|
|
|
9579 |
this._Popcorn.listen( "pause", IriSP.wrap(this, IriSP.MediaFragment.updateTime));
|
|
|
9580 |
this._Popcorn.listen( "seeked", IriSP.wrap(this, IriSP.MediaFragment.updateTime));
|
|
|
9581 |
this._Popcorn.listen( "IriSP.PolemicTweet.click", IriSP.wrap(this, IriSP.MediaFragment.updateAnnotation));
|
|
|
9582 |
this._Popcorn.listen( "IriSP.SegmentsWidget.click", IriSP.wrap(this, IriSP.MediaFragment.updateAnnotation));
|
|
|
9583 |
};
|
|
|
9584 |
|
|
|
9585 |
IriSP.MediaFragment.advanceTime = function() {
|
|
|
9586 |
var url = window.location.href;
|
|
|
9587 |
|
|
|
9588 |
if ( url.split( "#" )[ 1 ] != null ) {
|
|
|
9589 |
pageoffset = url.split( "#" )[1];
|
|
|
9590 |
|
|
|
9591 |
if ( pageoffset.substring(0, 2) === "t=") {
|
|
|
9592 |
// timecode
|
|
|
9593 |
if ( pageoffset.substring( 2 ) != null ) {
|
|
|
9594 |
var offsettime = pageoffset.substring( 2 );
|
|
|
9595 |
this._Popcorn.currentTime( parseFloat( offsettime ) );
|
|
|
9596 |
}
|
|
|
9597 |
} else if ( pageoffset.substring(0, 2) === "a=") {
|
|
|
9598 |
// annotation
|
|
|
9599 |
var annotationId = pageoffset.substring( 2 );
|
|
|
9600 |
|
|
|
9601 |
// there's no better way than that because
|
|
|
9602 |
// of possible race conditions
|
|
|
9603 |
this._serializer.sync(IriSP.wrap(this, function() {
|
|
|
9604 |
IriSP.MediaFragment.lookupAnnotation.call(this, annotationId);
|
|
|
9605 |
}));
|
|
|
9606 |
}
|
|
|
9607 |
}
|
|
|
9608 |
};
|
|
|
9609 |
|
|
|
9610 |
IriSP.MediaFragment.updateTime = function() {
|
|
|
9611 |
if (this.mutex === true) {
|
|
|
9612 |
return;
|
|
|
9613 |
}
|
|
|
9614 |
|
|
|
9615 |
var history = window.history;
|
|
|
9616 |
if ( !history.pushState ) {
|
|
|
9617 |
return false;
|
|
|
9618 |
}
|
|
|
9619 |
|
|
|
9620 |
splitArr = window.location.href.split( "#" )
|
|
|
9621 |
history.replaceState( {}, "", splitArr[0] + "#t=" + this._Popcorn.currentTime().toFixed( 2 ) );
|
|
|
9622 |
};
|
|
|
9623 |
|
|
|
9624 |
|
|
|
9625 |
IriSP.MediaFragment.updateAnnotation = function(annotationId) {
|
|
|
9626 |
var _this = this;
|
|
|
9627 |
this.mutex = true;
|
|
|
9628 |
|
|
|
9629 |
var history = window.history;
|
|
|
9630 |
if ( !history.pushState ) {
|
|
|
9631 |
return false;
|
|
|
9632 |
}
|
|
|
9633 |
|
|
|
9634 |
splitArr = window.location.href.split( "#" )
|
|
|
9635 |
history.replaceState( {}, "", splitArr[0] + "#a=" + annotationId);
|
|
|
9636 |
|
|
|
9637 |
window.setTimeout(function() { _this.mutex = false }, 50);
|
|
|
9638 |
};
|
|
|
9639 |
|
|
|
9640 |
// lookup and seek to the beginning of an annotation
|
|
|
9641 |
IriSP.MediaFragment.lookupAnnotation = function(annotationId) {
|
|
|
9642 |
var annotation = undefined;
|
|
|
9643 |
var annotations = this._serializer._data.annotations;
|
|
|
9644 |
|
|
|
9645 |
var i;
|
|
|
9646 |
for (i = 0; i < annotations.length; i++) {
|
|
|
9647 |
if (annotations[i].id === annotationId) {
|
|
|
9648 |
annotation = annotations[i];
|
|
|
9649 |
break;
|
|
|
9650 |
}
|
|
|
9651 |
}
|
|
|
9652 |
|
|
|
9653 |
if (typeof(annotation) !== "undefined") {
|
|
|
9654 |
this._Popcorn.currentTime(annotation.begin / 1000);
|
|
|
9655 |
}
|
|
|
9656 |
};
|
|
|
9657 |
IriSP.AnnotationsWidget = function(Popcorn, config, Serializer) {
|
|
|
9658 |
IriSP.Widget.call(this, Popcorn, config, Serializer);
|
|
|
9659 |
|
|
|
9660 |
};
|
|
|
9661 |
|
|
|
9662 |
|
|
|
9663 |
IriSP.AnnotationsWidget.prototype = new IriSP.Widget();
|
|
|
9664 |
|
|
|
9665 |
IriSP.AnnotationsWidget.prototype.clear = function() {
|
|
|
9666 |
this.selector.find(".Ldt-SaTitle").text("");
|
|
|
9667 |
this.selector.find(".Ldt-SaDescription").text("");
|
|
|
9668 |
this.selector.find(".Ldt-SaKeywordText").text("");
|
|
|
9669 |
};
|
|
|
9670 |
|
|
9
|
9671 |
IriSP.AnnotationsWidget.prototype.displayAnnotation = function(annotation) {
|
|
0
|
9672 |
|
|
|
9673 |
var title = annotation.content.title;
|
|
|
9674 |
var description = annotation.content.description;
|
|
|
9675 |
var keywords = "" // FIXME;
|
|
|
9676 |
var begin = +annotation.begin / 1000;
|
|
|
9677 |
var end = +annotation.end / 1000;
|
|
|
9678 |
var duration = +this._serializer.currentMedia().meta["dc:duration"];
|
|
9
|
9679 |
|
|
0
|
9680 |
var title_templ = "{{title}} - ( {{begin}} - {{end}} )";
|
|
|
9681 |
var endstr = Mustache.to_html(title_templ, {title: title, begin: IriSP.secondsToTime(begin), end: IriSP.secondsToTime(end)});
|
|
|
9682 |
|
|
|
9683 |
this.selector.find(".Ldt-SaTitle").text(endstr);
|
|
|
9684 |
this.selector.find(".Ldt-SaDescription").text(description);
|
|
9
|
9685 |
|
|
|
9686 |
// update sharing buttons
|
|
|
9687 |
var defaults = IriSP.widgetsDefaults.AnnotationsWidget;
|
|
|
9688 |
var text = defaults.share_text;
|
|
|
9689 |
var fb_link = defaults.fb_link;
|
|
|
9690 |
var tw_link = defaults.tw_link;
|
|
|
9691 |
var gplus_link = defaults.gplus_link;
|
|
|
9692 |
var url = document.location.href + "#a=" + annotation.id;
|
|
|
9693 |
this.selector.find(".Ldt-fbShare").attr("href", fb_link + IriSP.encodeURI(text) + IriSP.encodeURI(url));
|
|
|
9694 |
this.selector.find(".Ldt-TwShare").attr("href", tw_link + IriSP.encodeURI(text) + IriSP.encodeURI(url));
|
|
|
9695 |
this.selector.find(".Ldt-GplusShare").attr("href", fb_link + IriSP.encodeURI(text) + IriSP.encodeURI(url));
|
|
0
|
9696 |
};
|
|
|
9697 |
|
|
|
9698 |
IriSP.AnnotationsWidget.prototype.clearWidget = function() {
|
|
|
9699 |
|
|
|
9700 |
|
|
|
9701 |
/* retract the pane between two annotations */
|
|
|
9702 |
this.selector.find(".Ldt-SaTitle").text("");
|
|
|
9703 |
this.selector.find(".Ldt-SaDescription").text("");
|
|
|
9704 |
this.selector.find(".Ldt-SaKeywordText").html("");
|
|
|
9705 |
this.selector.find(".Ldt-ShowAnnotation").slideUp();
|
|
|
9706 |
};
|
|
|
9707 |
|
|
|
9708 |
IriSP.AnnotationsWidget.prototype.draw = function() {
|
|
|
9709 |
var _this = this;
|
|
|
9710 |
|
|
|
9711 |
var annotationMarkup = IriSP.templToHTML(IriSP.annotationWidget_template);
|
|
|
9712 |
this.selector.append(annotationMarkup);
|
|
|
9713 |
var view;
|
|
|
9714 |
|
|
|
9715 |
if (typeof(this._serializer._data.views) !== "undefined" && this._serializer._data.views !== null)
|
|
|
9716 |
view = this._serializer._data.views[0];
|
|
|
9717 |
|
|
|
9718 |
var view_type = "";
|
|
|
9719 |
|
|
|
9720 |
if(typeof(view) !== "undefined" && typeof(view.annotation_types) !== "undefined" && view.annotation_types.length > 1) {
|
|
|
9721 |
view_type = view.annotation_types[0];
|
|
|
9722 |
}
|
|
|
9723 |
|
|
|
9724 |
var annotations = this._serializer._data.annotations;
|
|
|
9725 |
var i;
|
|
|
9726 |
|
|
|
9727 |
for (i in annotations) {
|
|
|
9728 |
var annotation = annotations[i];
|
|
|
9729 |
var begin = Math.round((+ annotation.begin) / 1000);
|
|
|
9730 |
var end = Math.round((+ annotation.end) / 1000);
|
|
|
9731 |
|
|
|
9732 |
if (view_type != "" && typeof(annotation.meta) !== "undefined" && typeof(annotation.meta["id-ref"]) !== "undefined"
|
|
|
9733 |
&& annotation.meta["id-ref"] != view_type) {
|
|
|
9734 |
continue;
|
|
|
9735 |
}
|
|
|
9736 |
|
|
|
9737 |
|
|
|
9738 |
var conf = {start: begin, end: end,
|
|
|
9739 |
onStart:
|
|
|
9740 |
function(annotation) {
|
|
|
9741 |
return function() {
|
|
|
9742 |
_this.displayAnnotation(annotation);
|
|
|
9743 |
|
|
|
9744 |
} }(annotation),
|
|
|
9745 |
onEnd:
|
|
|
9746 |
function() { _this.clearWidget.call(_this); },
|
|
|
9747 |
};
|
|
|
9748 |
this._Popcorn = this._Popcorn.code(conf);
|
|
|
9749 |
}
|
|
|
9750 |
|
|
|
9751 |
};
|
|
|
9752 |
IriSP.ArrowWidget = function(Popcorn, config, Serializer) {
|
|
|
9753 |
IriSP.Widget.call(this, Popcorn, config, Serializer);
|
|
|
9754 |
|
|
|
9755 |
this._oldAnnotation = null;
|
|
|
9756 |
|
|
|
9757 |
};
|
|
|
9758 |
|
|
|
9759 |
|
|
|
9760 |
IriSP.ArrowWidget.prototype = new IriSP.Widget();
|
|
|
9761 |
|
|
|
9762 |
IriSP.ArrowWidget.prototype.clear = function() {
|
|
|
9763 |
|
|
|
9764 |
};
|
|
|
9765 |
|
|
|
9766 |
IriSP.ArrowWidget.prototype.clearWidget = function() {
|
|
|
9767 |
};
|
|
|
9768 |
|
|
|
9769 |
IriSP.ArrowWidget.prototype.draw = function() {
|
|
|
9770 |
var templ = Mustache.to_html(IriSP.arrowWidget_template, {});
|
|
|
9771 |
this.selector.append(templ);
|
|
|
9772 |
this._Popcorn.listen("timeupdate", IriSP.wrap(this, this.timeUpdateHandler));
|
|
|
9773 |
};
|
|
|
9774 |
|
|
|
9775 |
IriSP.ArrowWidget.prototype.timeUpdateHandler = function(percents) {
|
|
|
9776 |
var currentTime = this._Popcorn.currentTime();
|
|
|
9777 |
var currentAnnotation = this._serializer.currentAnnotations(currentTime)[0]; // FIXME : use the others ?
|
|
|
9778 |
|
|
|
9779 |
/* move the arrow only if the current annotation changes */
|
|
|
9780 |
if (currentAnnotation != this._oldAnnotation) {
|
|
|
9781 |
var begin = (+ currentAnnotation.begin) / 1000;
|
|
|
9782 |
var end = (+ currentAnnotation.end) / 1000;
|
|
|
9783 |
|
|
|
9784 |
var duration = +this._serializer.currentMedia().meta["dc:duration"] / 1000;
|
|
|
9785 |
var middle_time = (begin + end) / 2;
|
|
|
9786 |
var percents = Math.floor((middle_time / duration) * 100);
|
|
|
9787 |
|
|
|
9788 |
// we need to apply a fix because the arrow has a certain length
|
|
|
9789 |
// it's half the length of the arrow (27 / 2). We need to convert
|
|
|
9790 |
// it in percents though.
|
|
|
9791 |
var totalWidth = this.selector.width();
|
|
|
9792 |
var correction = ((27 / 2) / totalWidth) * 100;
|
|
|
9793 |
var corrected_percents = percents - correction;
|
|
|
9794 |
|
|
|
9795 |
/* don't move out of the screen */
|
|
|
9796 |
if (corrected_percents <= 0)
|
|
|
9797 |
corrected_percents = 0;
|
|
|
9798 |
|
|
|
9799 |
this.selector.children(".Ldt-arrowWidget").animate({"left" : corrected_percents + "%"});
|
|
|
9800 |
|
|
|
9801 |
this._oldAnnotation = currentAnnotation;
|
|
|
9802 |
}
|
|
|
9803 |
}
|
|
|
9804 |
IriSP.PlayerWidget = function(Popcorn, config, Serializer) {
|
|
|
9805 |
IriSP.Widget.call(this, Popcorn, config, Serializer);
|
|
|
9806 |
|
|
|
9807 |
this._searchBlockOpen = false;
|
|
|
9808 |
this._searchLastValue = "";
|
|
|
9809 |
};
|
|
|
9810 |
|
|
|
9811 |
IriSP.PlayerWidget.prototype = new IriSP.Widget();
|
|
|
9812 |
|
|
|
9813 |
IriSP.PlayerWidget.prototype.draw = function() {
|
|
|
9814 |
var self = this;
|
|
|
9815 |
var width = this.width;
|
|
|
9816 |
var height = this.height;
|
|
|
9817 |
var heightS = this.height-20;
|
|
|
9818 |
|
|
|
9819 |
var Player_templ = Mustache.to_html(IriSP.player_template, {"share_template" : IriSP.share_template});
|
|
|
9820 |
this.selector.append(Player_templ);
|
|
|
9821 |
|
|
|
9822 |
this.selector.children(".Ldt-controler").show();
|
|
|
9823 |
|
|
|
9824 |
// handle clicks by the user on the video.
|
|
|
9825 |
this._Popcorn.listen("play", IriSP.wrap(this, this.playButtonUpdater));
|
|
|
9826 |
this._Popcorn.listen("pause", IriSP.wrap(this, this.playButtonUpdater));
|
|
|
9827 |
|
|
|
9828 |
this._Popcorn.listen("volumechange", IriSP.wrap(this, this.muteButtonUpdater));
|
|
|
9829 |
|
|
|
9830 |
this._Popcorn.listen("timeupdate", IriSP.wrap(this, this.timeDisplayUpdater));
|
|
|
9831 |
this._Popcorn.listen("IriSP.search.matchFound", IriSP.wrap(this, this.searchMatch));
|
|
|
9832 |
this._Popcorn.listen("IriSP.search.noMatchFound", IriSP.wrap(this, this.searchNoMatch));
|
|
|
9833 |
|
|
|
9834 |
|
|
|
9835 |
this.selector.find(".Ldt-CtrlPlay").click(function() { self.playHandler.call(self); });
|
|
|
9836 |
this.selector.find(".Ldt-CtrlNext").click(function() { });
|
|
|
9837 |
this.selector.find(".Ldt-CtrlSearch").click(function() { self.searchButtonHandler.call(self); });
|
|
|
9838 |
|
|
|
9839 |
this.selector.find('.Ldt-CtrlSound').click(function() { self.muteHandler.call(self); } );
|
|
|
9840 |
|
|
|
9841 |
this.selector.find(".Ldt-CtrlPlay").attr( "style", "background-color:#CD21C24;" );
|
|
|
9842 |
|
|
|
9843 |
var searchButtonPos = this.selector.find(".Ldt-CtrlSearch").position();
|
|
|
9844 |
var searchBox = Mustache.to_html(IriSP.search_template, {margin_left : searchButtonPos.left + "px"});
|
|
|
9845 |
this.selector.append(searchBox);
|
|
|
9846 |
|
|
|
9847 |
// trigger an IriSP.PlayerWidget.MouseOver to the widgets that are interested (i.e : sliderWidget)
|
|
|
9848 |
this.selector.hover(function() { self._Popcorn.trigger("IriSP.PlayerWidget.MouseOver"); },
|
|
|
9849 |
function() { self._Popcorn.trigger("IriSP.PlayerWidget.MouseOut"); });
|
|
|
9850 |
|
|
|
9851 |
this.muteButtonUpdater(); /* some player - jwplayer notable - save the state of the mute button between sessions */
|
|
|
9852 |
};
|
|
|
9853 |
|
|
|
9854 |
/* Update the elasped time div */
|
|
|
9855 |
IriSP.PlayerWidget.prototype.timeDisplayUpdater = function() {
|
|
|
9856 |
|
|
|
9857 |
if (this._previousSecond === undefined)
|
|
|
9858 |
this._previousSecond = this._Popcorn.roundTime();
|
|
|
9859 |
|
|
|
9860 |
else {
|
|
|
9861 |
/* we're still in the same second, so it's not necessary to update time */
|
|
|
9862 |
if (this._Popcorn.roundTime() == this._previousSecond)
|
|
|
9863 |
return;
|
|
|
9864 |
|
|
|
9865 |
}
|
|
|
9866 |
|
|
|
9867 |
// we get it at each call because it may change.
|
|
|
9868 |
var duration = +this._serializer.currentMedia().meta["dc:duration"] / 1000;
|
|
|
9869 |
var totalTime = IriSP.secondsToTime(duration);
|
|
|
9870 |
var elapsedTime = IriSP.secondsToTime(this._Popcorn.currentTime());
|
|
|
9871 |
|
|
|
9872 |
this.selector.find(".Ldt-ElapsedTime").html(elapsedTime.toString());
|
|
|
9873 |
this.selector.find(".Ldt-TotalTime").html(totalTime.toString());
|
|
|
9874 |
this._previousSecond = this._Popcorn.roundTime();
|
|
|
9875 |
};
|
|
|
9876 |
|
|
|
9877 |
/* update the icon of the button - separate function from playHandler
|
|
|
9878 |
because in some cases (for instance, when the user directly clicks on
|
|
|
9879 |
the jwplayer window) we have to change the icon without playing/pausing
|
|
|
9880 |
*/
|
|
|
9881 |
IriSP.PlayerWidget.prototype.playButtonUpdater = function() {
|
|
|
9882 |
var status = this._Popcorn.media.paused;
|
|
|
9883 |
|
|
|
9884 |
if ( status == true ){
|
|
|
9885 |
this.selector.find(".Ldt-CtrlPlay").attr("title", "Play");
|
|
|
9886 |
|
|
|
9887 |
// we use templToHTML because it has some predefined
|
|
|
9888 |
// vars like where to get the images
|
|
|
9889 |
var templ = IriSP.templToHTML("url({{img_dir}}/play_sprite.png)");
|
|
|
9890 |
this.selector.find(".Ldt-CtrlPlay").css("background-image", templ);
|
|
|
9891 |
|
|
|
9892 |
} else {
|
|
|
9893 |
this.selector.find(".Ldt-CtrlPlay").attr("title", "Pause");
|
|
|
9894 |
|
|
|
9895 |
// we use templToHTML because it has some predefined
|
|
|
9896 |
// vars like where to get the images
|
|
|
9897 |
var templ = IriSP.templToHTML("url({{img_dir}}/pause_sprite.png)");
|
|
|
9898 |
this.selector.find(".Ldt-CtrlPlay").css("background-image", templ);
|
|
|
9899 |
}
|
|
|
9900 |
|
|
|
9901 |
return;
|
|
|
9902 |
};
|
|
|
9903 |
|
|
|
9904 |
|
|
|
9905 |
IriSP.PlayerWidget.prototype.playHandler = function() {
|
|
|
9906 |
var status = this._Popcorn.media.paused;
|
|
|
9907 |
|
|
|
9908 |
if ( status == true ){
|
|
|
9909 |
this._Popcorn.play();
|
|
|
9910 |
} else {
|
|
|
9911 |
this._Popcorn.pause();
|
|
|
9912 |
}
|
|
|
9913 |
};
|
|
|
9914 |
|
|
|
9915 |
IriSP.PlayerWidget.prototype.muteHandler = function() {
|
|
|
9916 |
if (!this._Popcorn.muted()) {
|
|
|
9917 |
this._Popcorn.mute(true);
|
|
|
9918 |
} else {
|
|
|
9919 |
this._Popcorn.mute(false);
|
|
|
9920 |
}
|
|
|
9921 |
};
|
|
|
9922 |
|
|
|
9923 |
IriSP.PlayerWidget.prototype.muteButtonUpdater = function() {
|
|
|
9924 |
var status = this._Popcorn.media.muted;
|
|
|
9925 |
|
|
|
9926 |
if ( status == true ){
|
|
|
9927 |
this.selector.find(".Ldt-CtrlSound").attr("title", "Unmute");
|
|
|
9928 |
|
|
|
9929 |
// we use templToHTML because it has some predefined
|
|
|
9930 |
// vars like where to get the images
|
|
|
9931 |
var templ = IriSP.templToHTML("url({{img_dir}}/sound_sprite.png)");
|
|
|
9932 |
this.selector.find(".Ldt-CtrlSound").css("background-image", templ);
|
|
|
9933 |
|
|
|
9934 |
} else {
|
|
|
9935 |
this.selector.find(".Ldt-CtrlSound").attr("title", "Mute");
|
|
|
9936 |
|
|
|
9937 |
// we use templToHTML because it has some predefined
|
|
|
9938 |
// vars like where to get the images
|
|
|
9939 |
var templ = IriSP.templToHTML("url({{img_dir}}/mute_sprite.png)");
|
|
|
9940 |
this.selector.find(".Ldt-CtrlSound").css("background-image", templ);
|
|
|
9941 |
}
|
|
|
9942 |
|
|
|
9943 |
return;
|
|
|
9944 |
};
|
|
|
9945 |
|
|
|
9946 |
|
|
|
9947 |
IriSP.PlayerWidget.prototype.searchButtonHandler = function() {
|
|
|
9948 |
var self = this;
|
|
|
9949 |
|
|
|
9950 |
/* show the search field if it is not shown */
|
|
|
9951 |
if ( this._searchBlockOpen == false ) {
|
|
|
9952 |
this.selector.find(".LdtSearch").show(100);
|
|
|
9953 |
|
|
|
9954 |
this.selector.find(".LdtSearchInput").css('background-color','#fff');
|
|
|
9955 |
this.selector.find(".LdtSearchInput").focus();
|
|
|
9956 |
this.selector.find(".LdtSearchInput").attr('value', this._searchLastValue);
|
|
|
9957 |
this._Popcorn.trigger("IriSP.search", this._searchLastValue); // trigger the search to make it more natural.
|
|
|
9958 |
|
|
|
9959 |
this._searchBlockOpen = true;
|
|
|
9960 |
this.selector.find(".LdtSearchInput").bind('keyup', null, function() { self.searchHandler.call(self); } );
|
|
|
9961 |
|
|
|
9962 |
// we need this variable because some widget can find a match in
|
|
|
9963 |
// their data while at the same time other's don't. As we want the
|
|
|
9964 |
// search field to become green when there's a match, we need a
|
|
|
9965 |
// variable to remember that we had one.
|
|
|
9966 |
this._positiveMatch = false;
|
|
|
9967 |
|
|
|
9968 |
// tell the world the field is open
|
|
|
9969 |
this._Popcorn.trigger("IriSP.search.open");
|
|
|
9970 |
|
|
|
9971 |
} else {
|
|
|
9972 |
this._searchLastValue = this.selector.find(".LdtSearchInput").attr('value');
|
|
|
9973 |
this.selector.find(".LdtSearchInput").attr('value','');
|
|
|
9974 |
this.selector.find(".LdtSearch").hide(100);
|
|
|
9975 |
|
|
|
9976 |
// unbind the watcher event.
|
|
|
9977 |
this.selector.find(".LdtSearchInput").unbind('keypress set');
|
|
|
9978 |
this._searchBlockOpen = false;
|
|
|
9979 |
|
|
|
9980 |
this._positiveMatch = false;
|
|
|
9981 |
|
|
|
9982 |
this._Popcorn.trigger("IriSP.search.closed");
|
|
|
9983 |
}
|
|
|
9984 |
};
|
|
|
9985 |
|
|
|
9986 |
/* this handler is called whenever the content of the search
|
|
|
9987 |
field changes */
|
|
|
9988 |
IriSP.PlayerWidget.prototype.searchHandler = function() {
|
|
|
9989 |
this._searchLastValue = this.selector.find(".LdtSearchInput").attr('value');
|
|
|
9990 |
this._positiveMatch = false;
|
|
|
9991 |
|
|
|
9992 |
// do nothing if the search field is empty, instead of highlighting everything.
|
|
|
9993 |
if (this._searchLastValue == "") {
|
|
|
9994 |
this._Popcorn.trigger("IriSP.search.cleared");
|
|
|
9995 |
this.selector.find(".LdtSearchInput").css('background-color','');
|
|
|
9996 |
} else {
|
|
|
9997 |
this._Popcorn.trigger("IriSP.search", this._searchLastValue);
|
|
|
9998 |
}
|
|
|
9999 |
};
|
|
|
10000 |
|
|
|
10001 |
/*
|
|
|
10002 |
handler for the IriSP.search.found message, which is sent by some views when they
|
|
|
10003 |
highlight a match.
|
|
|
10004 |
*/
|
|
|
10005 |
IriSP.PlayerWidget.prototype.searchMatch = function() {
|
|
|
10006 |
this._positiveMatch = true;
|
|
|
10007 |
this.selector.find(".LdtSearchInput").css('background-color','#e1ffe1');
|
|
|
10008 |
}
|
|
|
10009 |
|
|
|
10010 |
/* the same, except that no value could be found */
|
|
|
10011 |
IriSP.PlayerWidget.prototype.searchNoMatch = function() {
|
|
|
10012 |
if (this._positiveMatch !== true)
|
|
|
10013 |
this.selector.find(".LdtSearchInput").css('background-color', "#d62e3a");
|
|
|
10014 |
}
|
|
|
10015 |
|
|
|
10016 |
/*
|
|
|
10017 |
*
|
|
|
10018 |
* Copyright 2010 Institut de recherche et d'innovation
|
|
|
10019 |
* contributor(s) : Samuel Huron
|
|
|
10020 |
*
|
|
|
10021 |
* contact@iri.centrepompidou.fr
|
|
|
10022 |
* http://www.iri.centrepompidou.fr
|
|
|
10023 |
*
|
|
|
10024 |
* This software is a computer program whose purpose is to show and add annotations on a video .
|
|
|
10025 |
* This software is governed by the CeCILL-C license under French law and
|
|
|
10026 |
* abiding by the rules of distribution of free software. You can use,
|
|
|
10027 |
* modify and/ or redistribute the software under the terms of the CeCILL-C
|
|
|
10028 |
* license as circulated by CEA, CNRS and INRIA at the following URL
|
|
|
10029 |
* "http://www.cecill.info".
|
|
|
10030 |
*
|
|
|
10031 |
* The fact that you are presently reading this means that you have had
|
|
|
10032 |
* knowledge of the CeCILL-C license and that you accept its terms.
|
|
|
10033 |
*/
|
|
|
10034 |
// CHART TIMELINE / VERSION PROTOTYPE ::
|
|
|
10035 |
|
|
|
10036 |
IriSP.PolemicWidget = function(Popcorn, config, Serializer) {
|
|
|
10037 |
IriSP.Widget.call(this, Popcorn, config, Serializer);
|
|
|
10038 |
|
|
|
10039 |
this.userPol = new Array();
|
|
|
10040 |
this.userNoPol = new Array();
|
|
|
10041 |
this.userst = new Array();
|
|
|
10042 |
this.numberOfTweet = 0;
|
|
|
10043 |
this.Users;
|
|
|
10044 |
this.TweetPolemic;
|
|
|
10045 |
this.yMax = this.height;
|
|
|
10046 |
this.PaperSlider;
|
|
|
10047 |
this.heightOfChart;
|
|
|
10048 |
this.tweets = new Array();
|
|
|
10049 |
this.svgElements = {};
|
|
|
10050 |
|
|
|
10051 |
// Make and define the Raphael area
|
|
|
10052 |
this.paper = Raphael(document.getElementById(this._id), config.width, config.height);
|
|
|
10053 |
|
|
|
10054 |
this.oldSearchMatches = [];
|
|
|
10055 |
|
|
|
10056 |
// event handlers
|
|
|
10057 |
this._Popcorn.listen("IriSP.search", IriSP.wrap(this, function(searchString) { this.searchHandler(searchString); }));
|
|
|
10058 |
this._Popcorn.listen("IriSP.search.closed", IriSP.wrap(this, this.searchFieldClosedHandler));
|
|
|
10059 |
this._Popcorn.listen("IriSP.search.cleared", IriSP.wrap(this, this.searchFieldClearedHandler));
|
|
|
10060 |
|
|
|
10061 |
};
|
|
|
10062 |
|
|
|
10063 |
IriSP.PolemicWidget.prototype = new IriSP.Widget();
|
|
|
10064 |
|
|
|
10065 |
IriSP.PolemicWidget.prototype.draw = function() {
|
|
|
10066 |
|
|
|
10067 |
// variable
|
|
|
10068 |
// yMax
|
|
|
10069 |
|
|
|
10070 |
var self = this;
|
|
|
10071 |
var yCoef = 2; // coef for height of 1 tweet
|
|
|
10072 |
var frameSize = 5; // frame size
|
|
|
10073 |
var margin = 1; // marge between frame
|
|
|
10074 |
var lineSize = this.width; // timeline pixel width
|
|
|
10075 |
var nbrframes = lineSize/frameSize; // frame numbers
|
|
|
10076 |
var numberOfTweet = 0; // number of tweet overide later
|
|
|
10077 |
var duration = +this._serializer.currentMedia().meta["dc:duration"]; // timescale width
|
|
|
10078 |
var frameLength = lineSize / frameSize; // frame timescale
|
|
|
10079 |
var timeline;
|
|
|
10080 |
var colors = new Array("","#1D973D","#C5A62D","#CE0A15","#036AAE","#585858");
|
|
|
10081 |
|
|
|
10082 |
// array
|
|
|
10083 |
//var tweets = new Array();
|
|
|
10084 |
var element = new Array();
|
|
|
10085 |
var cluster = new Array();
|
|
|
10086 |
var frames = new Array(frameLength);
|
|
|
10087 |
var slices = new Array();
|
|
|
10088 |
|
|
|
10089 |
|
|
|
10090 |
// Classes =======================================================================
|
|
|
10091 |
var Frames = function(){
|
|
|
10092 |
|
|
|
10093 |
var Myclusters;
|
|
|
10094 |
var x;
|
|
|
10095 |
var y;
|
|
|
10096 |
var width;
|
|
|
10097 |
var height;
|
|
|
10098 |
};
|
|
|
10099 |
Frames = function(json){
|
|
|
10100 |
// make my clusters
|
|
|
10101 |
// ou Frame vide
|
|
|
10102 |
};
|
|
|
10103 |
Frames.prototype.draw = function(){
|
|
|
10104 |
};
|
|
|
10105 |
Frames.prototype.zoom = function(){
|
|
|
10106 |
};
|
|
|
10107 |
Frames.prototype.inside = function(){
|
|
|
10108 |
};
|
|
|
10109 |
var Clusters = function(){
|
|
|
10110 |
var Object;
|
|
|
10111 |
var yDist;
|
|
|
10112 |
var x;
|
|
|
10113 |
var y;
|
|
|
10114 |
var width;
|
|
|
10115 |
var height;
|
|
|
10116 |
};
|
|
|
10117 |
Clusters = function(json){
|
|
|
10118 |
// make my object
|
|
|
10119 |
};
|
|
|
10120 |
var Tweet = function(){
|
|
|
10121 |
};
|
|
|
10122 |
// Classes =======================================================================
|
|
|
10123 |
|
|
|
10124 |
// Refactoring (parametere) ************************************************************
|
|
|
10125 |
// color translastion
|
|
|
10126 |
var qTweet_0 =0;
|
|
|
10127 |
var qTweet_Q =0;
|
|
|
10128 |
var qTweet_REF=0;
|
|
|
10129 |
var qTweet_OK =0;
|
|
|
10130 |
var qTweet_KO =0;
|
|
|
10131 |
function colorTranslation(value){
|
|
|
10132 |
if(value == "Q"){
|
|
|
10133 |
qTweet_Q+=1;
|
|
|
10134 |
return 2;
|
|
|
10135 |
}else if(value =="REF"){
|
|
|
10136 |
qTweet_REF+=1;
|
|
|
10137 |
return 4;
|
|
|
10138 |
}else if(value =="OK"){
|
|
|
10139 |
qTweet_OK+=1;
|
|
|
10140 |
return 1;
|
|
|
10141 |
}else if(value =="KO"){
|
|
|
10142 |
qTweet_KO+=1;
|
|
|
10143 |
return 3;
|
|
|
10144 |
}else if(value ==""){
|
|
|
10145 |
qTweet_0+=1;
|
|
|
10146 |
return 5;
|
|
|
10147 |
}
|
|
|
10148 |
}
|
|
|
10149 |
|
|
|
10150 |
|
|
|
10151 |
this._serializer.sync(function(data) { loaded_callback.call(self, data) });
|
|
|
10152 |
|
|
|
10153 |
function loaded_callback (json) {
|
|
|
10154 |
|
|
|
10155 |
// get current view (the first ???)
|
|
|
10156 |
view = json.views[0];
|
|
|
10157 |
|
|
|
10158 |
// the tweets are by definition of the second annotation type FIXME ?
|
|
|
10159 |
tweet_annot_type = null;
|
|
|
10160 |
if(typeof(view.annotation_types) !== "undefined" && view.annotation_types.length > 1) {
|
|
|
10161 |
tweet_annot_type = view.annotation_types[1];
|
|
|
10162 |
}
|
|
|
10163 |
|
|
|
10164 |
for(var i = 0; i < json.annotations.length; i++) {
|
|
|
10165 |
var item = json.annotations[i];
|
|
|
10166 |
var MyTime = Math.floor(item.begin/duration*lineSize);
|
|
|
10167 |
var Myframe = Math.floor(MyTime/lineSize*frameLength);
|
|
|
10168 |
|
|
|
10169 |
if (typeof(item.meta) !== "undefined"
|
|
|
10170 |
&& typeof(item.meta["id-ref"]) !== "undefined"
|
|
|
10171 |
&& item.meta["id-ref"] === tweet_annot_type) {
|
|
|
10172 |
|
|
|
10173 |
var MyTJson = JSON.parse(item.meta['dc:source']['content']);
|
|
|
10174 |
|
|
|
10175 |
if (item.content['polemics'] != undefined
|
|
|
10176 |
&& item.content['polemics'][0] != null) {
|
|
|
10177 |
|
|
|
10178 |
// a tweet can have many polemics at the same time.
|
|
|
10179 |
for(var j=0; j<item.content['polemics'].length; j++){
|
|
|
10180 |
|
|
|
10181 |
this.tweets[numberOfTweet] = {
|
|
|
10182 |
id:i,
|
|
|
10183 |
qualification:colorTranslation(item.content['polemics'][j]),
|
|
|
10184 |
yIndicator:MyTime,
|
|
|
10185 |
yframe:Myframe,
|
|
|
10186 |
title:item.content['title'],
|
|
|
10187 |
timeframe:item.begin,
|
|
|
10188 |
userId: MyTJson.id,
|
|
|
10189 |
userScreenName: MyTJson.screen_name,
|
|
|
10190 |
tsource:MyTJson,
|
|
|
10191 |
cinecast_id: item.id
|
|
|
10192 |
};
|
|
|
10193 |
numberOfTweet+=1;
|
|
|
10194 |
|
|
|
10195 |
}
|
|
|
10196 |
}
|
|
|
10197 |
else {
|
|
|
10198 |
this.tweets[numberOfTweet] = {
|
|
|
10199 |
id:i,
|
|
|
10200 |
qualification:colorTranslation(""),
|
|
|
10201 |
yIndicator:MyTime,
|
|
|
10202 |
yframe:Myframe,
|
|
|
10203 |
title:item.content['title'],
|
|
|
10204 |
timeframe:item.begin,
|
|
|
10205 |
userId: MyTJson.id,
|
|
|
10206 |
userScreenName: MyTJson.screen_name,
|
|
|
10207 |
tsource:MyTJson,
|
|
|
10208 |
cinecast_id: item.id
|
|
|
10209 |
};
|
|
|
10210 |
numberOfTweet+=1;
|
|
|
10211 |
}
|
|
|
10212 |
|
|
|
10213 |
}
|
|
|
10214 |
};
|
|
|
10215 |
|
|
|
10216 |
DrawTweets.call (this); // FIXME: ugly.
|
|
|
10217 |
|
|
|
10218 |
};
|
|
|
10219 |
|
|
|
10220 |
// tweet Drawing (in raphael)
|
|
|
10221 |
function DrawTweets (){
|
|
|
10222 |
// GROUPES TWEET ============================================
|
|
|
10223 |
// Count nbr of cluster and tweet in a frame an save int in "frames"
|
|
|
10224 |
numberOfTweet = this.tweets.length;
|
|
|
10225 |
for(var i=0; i<nbrframes; i++) {
|
|
|
10226 |
for(var j=0; j<numberOfTweet; j++) {
|
|
|
10227 |
|
|
|
10228 |
if (i==this.tweets[j].yframe){
|
|
|
10229 |
|
|
|
10230 |
var k = this.tweets[j].qualification;
|
|
|
10231 |
|
|
|
10232 |
// make array for frame cluster
|
|
|
10233 |
if(frames[i]==undefined){
|
|
|
10234 |
frames[i] = {id:i,
|
|
|
10235 |
qualifVol:new Array(),
|
|
|
10236 |
mytweetsID:new Array()
|
|
|
10237 |
};
|
|
|
10238 |
}
|
|
|
10239 |
// add my tweet to frame
|
|
|
10240 |
frames[i].mytweetsID.push(this.tweets[j]);
|
|
|
10241 |
|
|
|
10242 |
// count opinion by frame
|
|
|
10243 |
if( frames[i].qualifVol[k] == undefined){
|
|
|
10244 |
frames[i].qualifVol[k] = 1;
|
|
|
10245 |
}else{
|
|
|
10246 |
frames[i].qualifVol[k] += 1;
|
|
|
10247 |
}
|
|
|
10248 |
|
|
|
10249 |
}
|
|
|
10250 |
}
|
|
|
10251 |
}
|
|
|
10252 |
|
|
|
10253 |
// GROUPES TWEET ============================================
|
|
|
10254 |
// max of tweet by Frame
|
|
|
10255 |
var max = 0;
|
|
|
10256 |
for(var i = 0; i < nbrframes; i++) {
|
|
|
10257 |
var moy = 0;
|
|
|
10258 |
for (var j = 0; j < 6; j++) {
|
|
|
10259 |
if (frames[i] != undefined) {
|
|
|
10260 |
if (frames[i].qualifVol[j] != undefined) {
|
|
|
10261 |
moy += frames[i].qualifVol[j];
|
|
|
10262 |
}
|
|
|
10263 |
}
|
|
|
10264 |
}
|
|
|
10265 |
|
|
|
10266 |
if (moy > max) {
|
|
|
10267 |
max = moy;
|
|
|
10268 |
}
|
|
|
10269 |
}
|
|
|
10270 |
|
|
|
10271 |
var tweetDrawed = new Array();
|
|
|
10272 |
var TweetHeight = 5;
|
|
|
10273 |
|
|
|
10274 |
// DRAW TWEETS ============================================
|
|
|
10275 |
for(var i = 0; i < nbrframes; i++) {
|
|
|
10276 |
var addEheight = 5;
|
|
|
10277 |
if (frames[i] != undefined){
|
|
|
10278 |
// by type
|
|
|
10279 |
|
|
|
10280 |
for (var j = 6; j > -1; j--) {
|
|
|
10281 |
if (frames[i].qualifVol[j] != undefined) {
|
|
|
10282 |
// show tweet by type
|
|
|
10283 |
for (var k = 0; k < frames[i].mytweetsID.length; k++) {
|
|
|
10284 |
|
|
|
10285 |
if (frames[i].mytweetsID[k].qualification == j) {
|
|
|
10286 |
var x = i * frameSize;
|
|
|
10287 |
var y = this.heightmax - addEheight;
|
|
|
10288 |
|
|
|
10289 |
if (this.yMax > y) {
|
|
|
10290 |
this.yMax = y;
|
|
|
10291 |
}
|
|
|
10292 |
|
|
|
10293 |
var e = this.paper.rect(x, y, frameSize - margin, TweetHeight /* height */)
|
|
|
10294 |
.attr({stroke:"#00","stroke-width":0.1, fill: colors[j]});
|
|
|
10295 |
|
|
|
10296 |
addEheight += TweetHeight;
|
|
|
10297 |
|
|
|
10298 |
e.color = colors[j];
|
|
|
10299 |
e.time = frames[i].mytweetsID[k].timeframe;
|
|
|
10300 |
e.title = frames[i].mytweetsID[k].title;
|
|
|
10301 |
e.id = frames[i].mytweetsID[k].cinecast_id;
|
|
|
10302 |
|
|
|
10303 |
this.svgElements[e.id] = e;
|
|
|
10304 |
|
|
|
10305 |
e.mouseover(function(element) { return function (event) {
|
|
|
10306 |
// event.clientX and event.clientY are to raphael what event.pageX and pageY are to jquery.
|
|
|
10307 |
self.TooltipWidget.show.call(self.TooltipWidget, element.title, element.attr("fill"), event.clientX - 106, event.clientY - 160);
|
|
|
10308 |
element.displayed = true;
|
|
|
10309 |
}}(e)).mouseout(function(element) { return function () {
|
|
|
10310 |
self.TooltipWidget.hide.call(self.TooltipWidget);
|
|
|
10311 |
}}(e)).mousedown(function () {
|
|
|
10312 |
self._Popcorn.currentTime(this.time/1000);
|
|
|
10313 |
self._Popcorn.trigger("IriSP.PolemicTweet.click", this.id);
|
|
|
10314 |
});
|
|
|
10315 |
|
|
|
10316 |
IriSP.jQuery(e.node).attr('id', 't' + k + '');
|
|
|
10317 |
IriSP.jQuery(e.node).attr('title', frames[i].mytweetsID[k].title);
|
|
|
10318 |
IriSP.jQuery(e.node).attr('begin', frames[i].mytweetsID[k].timeframe);
|
|
|
10319 |
}
|
|
|
10320 |
}
|
|
|
10321 |
}
|
|
|
10322 |
}
|
|
|
10323 |
}
|
|
|
10324 |
|
|
|
10325 |
}
|
|
|
10326 |
// DRAW UI :: resize border and bgd
|
|
|
10327 |
this.paperBackground = this.paper.rect(0, 0, this.width, this.heightmax).attr({fill:"#F8F8F8","stroke-width":0.1,opacity: 1});
|
|
|
10328 |
|
|
|
10329 |
// outer borders
|
|
|
10330 |
this.outerBorders = [];
|
|
|
10331 |
this.outerBorders.push(this.paper.rect(0, this.height - 1, this.width, 1).attr({fill:"#ababab",stroke: "none",opacity: 1}));
|
|
|
10332 |
this.outerBorders.push(this.paper.rect(0, 0, this.width, 1).attr({fill:"#ababab",stroke: "none",opacity: 1}));
|
|
|
10333 |
|
|
|
10334 |
// inner borders
|
|
|
10335 |
this.innerBorders = [];
|
|
|
10336 |
this.innerBorders.push(this.paper.rect(1, this.height - 2, this.width, 1).attr({fill:"#efefef",stroke: "none",opacity: 1}));
|
|
|
10337 |
this.innerBorders.push(this.paper.rect(1, 1, this.width, 1).attr({fill:"#efefef",stroke: "none",opacity: 1}));
|
|
|
10338 |
this.innerBorders.push(this.paper.rect(1, 1, 1, this.height - 2).attr({fill:"#d0d1d1",stroke: "none",opacity: 0.8}));
|
|
|
10339 |
this.innerBorders.push(this.paper.rect(this.width - 2, 1, 1, this.height - 2).attr({fill:"#efefef",stroke: "none",opacity: 1}));
|
|
|
10340 |
|
|
|
10341 |
|
|
|
10342 |
|
|
|
10343 |
this.paperSlider = this.paper.rect(0, 0, 0, this.heightmax).attr({fill:"#D4D5D5", stroke: "none", opacity: 1});
|
|
|
10344 |
|
|
|
10345 |
// the small white line displayed over the slider.
|
|
|
10346 |
this.sliderTip = this.paper.rect(0, 0, 1, this.heightmax).attr({fill:"#fc00ff", stroke: "none", opacity: 1});
|
|
|
10347 |
// decalage
|
|
|
10348 |
// tweetSelection = this.paper.rect(-100,-100,5,5).attr({fill:"#fff",stroke: "none",opacity: 1});
|
|
|
10349 |
|
|
|
10350 |
|
|
|
10351 |
this.paperSlider.toBack();
|
|
|
10352 |
this.paperBackground.toBack();
|
|
|
10353 |
this.sliderTip.toFront();
|
|
|
10354 |
}
|
|
|
10355 |
|
|
|
10356 |
this._Popcorn.listen("timeupdate", IriSP.wrap(this, this.sliderUpdater));
|
|
|
10357 |
}
|
|
|
10358 |
|
|
|
10359 |
IriSP.PolemicWidget.prototype.sliderUpdater = function() {
|
|
|
10360 |
|
|
|
10361 |
var time = +this._Popcorn.currentTime();
|
|
|
10362 |
var duration = +this._serializer.currentMedia().meta["dc:duration"];
|
|
|
10363 |
|
|
|
10364 |
this.paperSlider.attr("width", time * (this.width / (duration / 1000)));
|
|
|
10365 |
|
|
|
10366 |
this.sliderTip.attr("x", time * (this.width / (duration / 1000)));
|
|
|
10367 |
};
|
|
|
10368 |
|
|
|
10369 |
IriSP.PolemicWidget.prototype.searchHandler = function(searchString) {
|
|
|
10370 |
if (searchString == "")
|
|
|
10371 |
return;
|
|
|
10372 |
|
|
|
10373 |
var matches = this._serializer.searchTweetsOccurences(searchString);
|
|
|
10374 |
|
|
|
10375 |
if (IriSP.countProperties(matches) > 0) {
|
|
|
10376 |
this._Popcorn.trigger("IriSP.search.matchFound");
|
|
|
10377 |
} else {
|
|
|
10378 |
this._Popcorn.trigger("IriSP.search.noMatchFound");
|
|
|
10379 |
}
|
|
|
10380 |
|
|
|
10381 |
for (var id in matches) {
|
|
|
10382 |
if (this.svgElements.hasOwnProperty(id)) {
|
|
|
10383 |
var e = this.svgElements[id];
|
|
|
10384 |
this.svgElements[id].attr({fill: "#fc00ff"});
|
|
|
10385 |
}
|
|
|
10386 |
}
|
|
|
10387 |
|
|
|
10388 |
// clean up the blocks that were in the previous search
|
|
|
10389 |
// but who aren't in the current one.
|
|
|
10390 |
for (var id in this.oldSearchMatches) {
|
|
|
10391 |
if (!matches.hasOwnProperty(id)) {
|
|
|
10392 |
var e = this.svgElements[id];
|
|
|
10393 |
e.attr({fill: e.color});
|
|
|
10394 |
}
|
|
|
10395 |
}
|
|
|
10396 |
|
|
|
10397 |
this.oldSearchMatches = matches;
|
|
|
10398 |
};
|
|
|
10399 |
|
|
|
10400 |
IriSP.PolemicWidget.prototype.searchFieldClearedHandler = function() {
|
|
|
10401 |
// clean up the blocks that were in the previous search
|
|
|
10402 |
// but who aren't in the current one.
|
|
|
10403 |
for (var id in this.oldSearchMatches) {
|
|
|
10404 |
var e = this.svgElements[id];
|
|
|
10405 |
e.attr({fill: e.color});
|
|
|
10406 |
}
|
|
|
10407 |
|
|
|
10408 |
};
|
|
|
10409 |
|
|
|
10410 |
IriSP.PolemicWidget.prototype.searchFieldClosedHandler = function() {
|
|
|
10411 |
// clean up the blocks that were in the previous search
|
|
|
10412 |
// but who aren't in the current one.
|
|
|
10413 |
for (var id in this.oldSearchMatches) {
|
|
|
10414 |
var e = this.svgElements[id];
|
|
|
10415 |
e.attr({fill: e.color});
|
|
|
10416 |
}
|
|
|
10417 |
|
|
|
10418 |
};
|
|
|
10419 |
|
|
|
10420 |
IriSP.SegmentsWidget = function(Popcorn, config, Serializer) {
|
|
|
10421 |
|
|
|
10422 |
var self = this;
|
|
|
10423 |
IriSP.Widget.call(this, Popcorn, config, Serializer);
|
|
|
10424 |
this.oldSearchMatches = [];
|
|
|
10425 |
|
|
|
10426 |
// event handlers
|
|
|
10427 |
this._Popcorn.listen("IriSP.search", function(searchString) { self.searchHandler.call(self, searchString); });
|
|
|
10428 |
this._Popcorn.listen("IriSP.search.closed", function() { self.searchFieldClosedHandler.call(self); });
|
|
|
10429 |
this._Popcorn.listen("IriSP.search.cleared", function() { self.searchFieldClearedHandler.call(self); });
|
|
|
10430 |
};
|
|
|
10431 |
|
|
|
10432 |
IriSP.SegmentsWidget.prototype = new IriSP.Widget();
|
|
|
10433 |
|
|
|
10434 |
IriSP.SegmentsWidget.prototype.draw = function() {
|
|
|
10435 |
|
|
|
10436 |
var self = this;
|
|
|
10437 |
var annotations = this._serializer._data.annotations;
|
|
|
10438 |
|
|
|
10439 |
this.selector.addClass("Ldt-SegmentsWidget");
|
|
|
10440 |
|
|
|
10441 |
/* in case we have different types of annotations, we want to display only the first type */
|
|
|
10442 |
/* the next two lines are a bit verbose because for some test data, _serializer.data.view is either
|
|
|
10443 |
null or undefined.
|
|
|
10444 |
*/
|
|
|
10445 |
var view;
|
|
|
10446 |
|
|
|
10447 |
if (typeof(this._serializer._data.views) !== "undefined" && this._serializer._data.views !== null)
|
|
|
10448 |
view = this._serializer._data.views[0];
|
|
|
10449 |
|
|
|
10450 |
var view_type = "";
|
|
|
10451 |
|
|
|
10452 |
if(typeof(view) !== "undefined" && typeof(view.annotation_types) !== "undefined" && view.annotation_types.length > 1) {
|
|
|
10453 |
view_type = view.annotation_types[0];
|
|
|
10454 |
}
|
|
|
10455 |
|
|
|
10456 |
this.selector.append(Mustache.to_html(IriSP.overlay_marker_template));
|
|
|
10457 |
|
|
|
10458 |
this.positionMarker = this.selector.children(":first");
|
|
|
10459 |
|
|
|
10460 |
this._Popcorn.listen("timeupdate", IriSP.wrap(this, this.positionUpdater));
|
|
|
10461 |
|
|
|
10462 |
|
|
|
10463 |
var i = 0;
|
|
|
10464 |
var totalWidth = this.selector.width();
|
|
|
10465 |
var onePxPercent = 100 / totalWidth; /* the value of a pixel, in percents */
|
|
|
10466 |
|
|
|
10467 |
for (i = 0; i < annotations.length; i++) {
|
|
|
10468 |
var annotation = annotations[i];
|
|
|
10469 |
|
|
|
10470 |
/* filter the annotations whose type is not the one we want */
|
|
|
10471 |
if (view_type != "" && typeof(annotation.meta) !== "undefined" && typeof(annotation.meta["id-ref"]) !== "undefined"
|
|
|
10472 |
&& annotation.meta["id-ref"] != view_type) {
|
|
|
10473 |
continue;
|
|
|
10474 |
}
|
|
|
10475 |
|
|
|
10476 |
var begin = Math.round((+ annotation.begin) / 1000);
|
|
|
10477 |
var end = Math.round((+ annotation.end) / 1000);
|
|
|
10478 |
var duration = this._serializer.currentMedia().meta["dc:duration"] / 1000;
|
|
|
10479 |
var id = annotation.id;
|
|
|
10480 |
var startPourcent = IriSP.timeToPourcent(begin, duration);
|
|
|
10481 |
|
|
|
10482 |
/* some sort of collapsing occurs, so we only have to substract one pixel to each box instead of
|
|
|
10483 |
two
|
|
|
10484 |
*/
|
|
|
10485 |
var endPourcent = IriSP.timeToPourcent(end, duration) - startPourcent - onePxPercent * 1;
|
|
|
10486 |
|
|
|
10487 |
/* on the other hand, we have to substract one pixel from the first box because it's the only
|
|
|
10488 |
one to have to effective 1px margins */
|
|
|
10489 |
if (i == 0) {
|
|
|
10490 |
|
|
|
10491 |
endPourcent -= onePxPercent;
|
|
|
10492 |
}
|
|
|
10493 |
|
|
|
10494 |
var divTitle = annotation.content.title.substr(0,55);
|
|
12
|
10495 |
|
|
|
10496 |
if (typeof(annotation.content.color) !== "undefined")
|
|
|
10497 |
var color = annotation.content.color;
|
|
|
10498 |
else
|
|
|
10499 |
var color = annotation.color;
|
|
|
10500 |
|
|
|
10501 |
var hexa_color = IriSP.DEC_HEXA_COLOR(color);
|
|
|
10502 |
console.log(hexa_color);
|
|
|
10503 |
if (hexa_color === "FFCC00")
|
|
|
10504 |
hexa_color = "333";
|
|
|
10505 |
|
|
0
|
10506 |
var annotationTemplate = Mustache.to_html(IriSP.annotation_template,
|
|
|
10507 |
{"divTitle" : divTitle, "id" : id, "startPourcent" : startPourcent,
|
|
12
|
10508 |
"endPourcent" : endPourcent, "hexa_color" : hexa_color,
|
|
0
|
10509 |
"seekPlace" : Math.round(begin/1000)});
|
|
|
10510 |
|
|
|
10511 |
|
|
|
10512 |
this.selector.append(annotationTemplate);
|
|
|
10513 |
|
|
|
10514 |
// IriSP.jQuery("#" + id).tooltip({ effect: 'slide'});
|
|
|
10515 |
|
|
|
10516 |
IriSP.jQuery("#" + id).fadeTo(0, 0.3);
|
|
|
10517 |
|
|
|
10518 |
IriSP.jQuery("#" + id).mouseover(
|
|
|
10519 |
/* we wrap the handler in another function because js's scoping
|
|
|
10520 |
rules are function-based - otherwise, the internal vars like
|
|
|
10521 |
divTitle are preserved but they are looked-up from the draw
|
|
|
10522 |
method scope, so after that the loop is run, so they're not
|
|
|
10523 |
preserved */
|
|
|
10524 |
(function(divTitle) {
|
|
|
10525 |
return function(event) {
|
|
|
10526 |
IriSP.jQuery(this).animate({opacity: 0.6}, 5);
|
|
|
10527 |
var offset = IriSP.jQuery(this).offset();
|
|
|
10528 |
var correction = IriSP.jQuery(this).outerWidth() / 2;
|
|
|
10529 |
|
|
|
10530 |
var offset_x = offset.left + correction - 106;
|
|
|
10531 |
if (offset_x < 0)
|
|
|
10532 |
offset_x = 0;
|
|
|
10533 |
|
|
|
10534 |
self.TooltipWidget.show(divTitle, color, offset_x, event.pageY - 160);
|
|
|
10535 |
} })(divTitle)).mouseout(function(){
|
|
|
10536 |
IriSP.jQuery(this).animate({opacity: 0.3}, 5);
|
|
|
10537 |
self.TooltipWidget.hide();
|
|
|
10538 |
});
|
|
|
10539 |
|
|
|
10540 |
IriSP.jQuery("#" + id).click(function(_this, annotation) {
|
|
|
10541 |
return function() { _this.clickHandler(annotation)};
|
|
|
10542 |
}(this, annotation));
|
|
|
10543 |
}
|
|
|
10544 |
};
|
|
|
10545 |
|
|
|
10546 |
/* restores the view after a search */
|
|
|
10547 |
IriSP.SegmentsWidget.prototype.clear = function() {
|
|
12
|
10548 |
//this.selector.children(".Ldt-iri-chapter").css('border','none').animate({opacity:0.3}, 100);
|
|
0
|
10549 |
};
|
|
|
10550 |
|
|
|
10551 |
IriSP.SegmentsWidget.prototype.clickHandler = function(annotation) {
|
|
|
10552 |
this._Popcorn.trigger("IriSP.SegmentsWidget.click", annotation.id);
|
|
|
10553 |
var begin = (+ annotation.begin) / 1000;
|
|
|
10554 |
this._Popcorn.currentTime(Math.round(begin));
|
|
|
10555 |
};
|
|
|
10556 |
|
|
|
10557 |
IriSP.SegmentsWidget.prototype.searchHandler = function(searchString) {
|
|
|
10558 |
|
|
|
10559 |
if (searchString == "")
|
|
|
10560 |
return;
|
|
|
10561 |
|
|
|
10562 |
var matches = this._serializer.searchOccurences(searchString);
|
|
|
10563 |
|
|
|
10564 |
if (IriSP.countProperties(matches) > 0) {
|
|
|
10565 |
this._Popcorn.trigger("IriSP.search.matchFound");
|
|
|
10566 |
} else {
|
|
|
10567 |
this._Popcorn.trigger("IriSP.search.noMatchFound");
|
|
|
10568 |
}
|
|
|
10569 |
|
|
|
10570 |
// un-highlight all the blocks
|
|
|
10571 |
this.selector.children(".Ldt-iri-chapter").css("opacity", 0.1);
|
|
|
10572 |
|
|
|
10573 |
// then highlight the ones with matches.
|
|
|
10574 |
for (var id in matches) {
|
|
|
10575 |
var factor = 0.5 + matches[id] * 0.2;
|
|
|
10576 |
this.selector.find("#"+id).dequeue();
|
|
|
10577 |
this.selector.find("#"+id).css('border','1px red');
|
|
|
10578 |
this.selector.find("#"+id).animate({opacity:factor}, 200);
|
|
|
10579 |
}
|
|
|
10580 |
|
|
|
10581 |
|
|
|
10582 |
this.oldSearchMatches = matches;
|
|
|
10583 |
};
|
|
|
10584 |
|
|
|
10585 |
IriSP.SegmentsWidget.prototype.searchFieldClearedHandler = function() {
|
|
|
10586 |
this.clear();
|
|
|
10587 |
};
|
|
|
10588 |
|
|
|
10589 |
IriSP.SegmentsWidget.prototype.searchFieldClosedHandler = function() {
|
|
|
10590 |
this.clear();
|
|
|
10591 |
};
|
|
|
10592 |
|
|
|
10593 |
IriSP.SegmentsWidget.prototype.positionUpdater = function() {
|
|
|
10594 |
var duration = this._serializer.currentMedia().meta["dc:duration"] / 1000;
|
|
|
10595 |
var time = this._Popcorn.currentTime();
|
|
|
10596 |
var position = ((time / duration) * 100).toFixed(2);
|
|
|
10597 |
|
|
|
10598 |
this.positionMarker.css("left", position + "%");
|
|
|
10599 |
};
|
|
|
10600 |
IriSP.SliderWidget = function(Popcorn, config, Serializer) {
|
|
|
10601 |
IriSP.Widget.call(this, Popcorn, config, Serializer);
|
|
|
10602 |
};
|
|
|
10603 |
|
|
|
10604 |
IriSP.SliderWidget.prototype = new IriSP.Widget();
|
|
|
10605 |
|
|
|
10606 |
IriSP.SliderWidget.prototype.draw = function() {
|
|
|
10607 |
var self = this;
|
|
|
10608 |
|
|
|
10609 |
this.selector.append(Mustache.to_html(IriSP.sliderWidget_template, {}));
|
|
|
10610 |
this.selector.addClass("Ldt-SliderMinimized");
|
|
|
10611 |
|
|
|
10612 |
this.sliderBackground = this.selector.find(".Ldt-sliderBackground");
|
|
|
10613 |
this.sliderForeground = this.selector.find(".Ldt-sliderForeground");
|
|
|
10614 |
this.positionMarker = this.selector.find(".Ldt-sliderPositionMarker");
|
|
|
10615 |
|
|
|
10616 |
|
|
|
10617 |
// a special variable to stop methods from tinkering
|
|
|
10618 |
// with the positionMarker when the user is dragging it
|
|
|
10619 |
this.draggingOngoing = false;
|
|
|
10620 |
|
|
|
10621 |
// another special variable used by the timeout handler to
|
|
|
10622 |
// open or close the slider.
|
|
|
10623 |
this.sliderMaximized = false;
|
|
|
10624 |
this.timeOutId = null;
|
|
|
10625 |
|
|
|
10626 |
this.positionMarker.draggable({axis: "x",
|
|
|
10627 |
start: IriSP.wrap(this, this.positionMarkerDraggingStartedHandler),
|
|
|
10628 |
stop: IriSP.wrap(this, this.positionMarkerDraggedHandler),
|
|
|
10629 |
containment: "parent"
|
|
|
10630 |
});
|
|
|
10631 |
|
|
|
10632 |
this.sliderBackground.click(function(event) { self.backgroundClickHandler.call(self, event); });
|
|
|
10633 |
this.sliderForeground.click(function(event) { self.foregroundClickHandler.call(self, event); });
|
|
|
10634 |
|
|
|
10635 |
this.selector.hover(IriSP.wrap(this, this.mouseOverHandler), IriSP.wrap(this, this.mouseOutHandler));
|
|
|
10636 |
|
|
|
10637 |
// update the positions
|
|
|
10638 |
this._Popcorn.listen("timeupdate", IriSP.wrap(this, this.sliderUpdater));
|
|
|
10639 |
|
|
|
10640 |
// special messages :
|
|
|
10641 |
this._Popcorn.listen("IriSP.PlayerWidget.MouseOver", IriSP.wrap(this, this.mouseOverHandler));
|
|
|
10642 |
this._Popcorn.listen("IriSP.PlayerWidget.MouseOut", IriSP.wrap(this, this.mouseOutHandler));
|
|
|
10643 |
};
|
|
|
10644 |
|
|
|
10645 |
/* update the slider and the position marker as time passes */
|
|
|
10646 |
IriSP.SliderWidget.prototype.sliderUpdater = function() {
|
|
12
|
10647 |
if(this.draggingOngoing || this._disableUpdates)
|
|
0
|
10648 |
return;
|
|
12
|
10649 |
|
|
0
|
10650 |
var time = this._Popcorn.currentTime();
|
|
|
10651 |
|
|
|
10652 |
var duration = this._serializer.currentMedia().meta["dc:duration"] / 1000;
|
|
|
10653 |
var percent = ((time / duration) * 100).toFixed(2);
|
|
10
|
10654 |
|
|
|
10655 |
/* we do these complicated calculations to center exactly
|
|
|
10656 |
the position Marker */
|
|
|
10657 |
var pixels_to_percents = 100 / this.selector.width(); /* how much is a pixel in percents */
|
|
|
10658 |
var positionMarker_width = this.positionMarker.width();
|
|
|
10659 |
var correction = (pixels_to_percents * positionMarker_width) / 2;
|
|
|
10660 |
|
|
|
10661 |
var newPos = percent - correction;
|
|
|
10662 |
if (newPos <= 0)
|
|
|
10663 |
newPos = 0;
|
|
|
10664 |
|
|
0
|
10665 |
this.sliderForeground.css("width", percent + "%");
|
|
10
|
10666 |
this.positionMarker.css("left", newPos + "%");
|
|
0
|
10667 |
|
|
|
10668 |
};
|
|
|
10669 |
|
|
|
10670 |
IriSP.SliderWidget.prototype.backgroundClickHandler = function(event) {
|
|
|
10671 |
/* this piece of code is a little bit convoluted - here's how it works :
|
|
|
10672 |
we want to handle clicks on the progress bar and convert those to seeks in the media.
|
|
|
10673 |
However, jquery only gives us a global position, and we want a number of pixels relative
|
|
|
10674 |
to our container div, so we get the parent position, and compute an offset to this position,
|
|
|
10675 |
and finally compute the progress ratio in the media.
|
|
|
10676 |
Finally we multiply this ratio with the duration to get the correct time
|
|
|
10677 |
*/
|
|
|
10678 |
|
|
|
10679 |
var parentOffset = this.sliderBackground.parent().offset();
|
|
|
10680 |
var width = this.sliderBackground.width();
|
|
|
10681 |
var relX = event.pageX - parentOffset.left;
|
|
|
10682 |
|
|
|
10683 |
var duration = this._serializer.currentMedia().meta["dc:duration"] / 1000;
|
|
|
10684 |
var newTime = ((relX / width) * duration).toFixed(2);
|
|
|
10685 |
|
|
|
10686 |
this._Popcorn.currentTime(newTime);
|
|
|
10687 |
};
|
|
|
10688 |
|
|
|
10689 |
/* same function as the previous one, except that it handles clicks
|
|
|
10690 |
on the foreground element */
|
|
|
10691 |
IriSP.SliderWidget.prototype.foregroundClickHandler = function(event) {
|
|
|
10692 |
var parentOffset = this.sliderForeground.parent().offset();
|
|
|
10693 |
var width = this.sliderBackground.width();
|
|
|
10694 |
var relX = event.pageX - parentOffset.left;
|
|
|
10695 |
|
|
|
10696 |
var duration = this._serializer.currentMedia().meta["dc:duration"] / 1000;
|
|
|
10697 |
var newTime = ((relX / width) * duration).toFixed(2);
|
|
|
10698 |
|
|
|
10699 |
this._Popcorn.currentTime(newTime);
|
|
|
10700 |
};
|
|
|
10701 |
|
|
|
10702 |
/* handles mouse over the slider */
|
|
|
10703 |
IriSP.SliderWidget.prototype.mouseOverHandler = function(event) {
|
|
|
10704 |
|
|
|
10705 |
if (this.timeOutId !== null) {
|
|
|
10706 |
window.clearTimeout(this.timeOutId);
|
|
|
10707 |
}
|
|
|
10708 |
|
|
|
10709 |
this.sliderMaximized = true;
|
|
|
10710 |
|
|
|
10711 |
this.sliderBackground.animate({"height": "9px"}, 100);
|
|
|
10712 |
this.sliderForeground.animate({"height": "9px"}, 100);
|
|
9
|
10713 |
this.positionMarker.animate({"height": "9px", "width": "9px", "margin-top": "-4px"}, 100);
|
|
0
|
10714 |
|
|
|
10715 |
// this.selector.removeClass("Ldt-SliderMinimized");
|
|
|
10716 |
// this.selector.addClass("Ldt-SliderMaximized");
|
|
|
10717 |
};
|
|
|
10718 |
|
|
|
10719 |
/* handles when the mouse leaves the slider */
|
|
|
10720 |
IriSP.SliderWidget.prototype.mouseOutHandler = function(event) {
|
|
|
10721 |
|
|
|
10722 |
this.timeOutId = window.setTimeout(IriSP.wrap(this, this.minimizeOnTimeout),
|
|
|
10723 |
IriSP.widgetsDefaults.SliderWidget.minimize_period);
|
|
|
10724 |
};
|
|
|
10725 |
|
|
|
10726 |
IriSP.SliderWidget.prototype.minimizeOnTimeout = function(event) {
|
|
|
10727 |
this.sliderBackground.animate({"height": "5px"}, 100);
|
|
|
10728 |
this.sliderForeground.animate({"height": "5px"}, 100);
|
|
9
|
10729 |
this.positionMarker.animate({"height": "5px", "width": "5px", "margin-top": "0px"}, 100);
|
|
|
10730 |
|
|
0
|
10731 |
this.sliderMinimized = true;
|
|
|
10732 |
|
|
|
10733 |
// this.selector.removeClass("Ldt-SliderMaximized");
|
|
|
10734 |
// this.selector.addClass("Ldt-SliderMinimized");
|
|
|
10735 |
|
|
|
10736 |
};
|
|
|
10737 |
|
|
|
10738 |
// called when the user starts dragging the position indicator
|
|
12
|
10739 |
IriSP.SliderWidget.prototype.positionMarkerDraggingStartedHandler = function(event, ui) {
|
|
0
|
10740 |
this.draggingOngoing = true;
|
|
|
10741 |
};
|
|
|
10742 |
|
|
|
10743 |
IriSP.SliderWidget.prototype.positionMarkerDraggedHandler = function(event, ui) {
|
|
12
|
10744 |
console.log(ui.offset.left);
|
|
|
10745 |
this._disableUpdate = true; // disable slider position updates while dragging is ongoing.
|
|
|
10746 |
window.setTimeout(IriSP.wrap(this, function() { this._disableUpdate = false; }), 500);
|
|
|
10747 |
|
|
0
|
10748 |
var width = this.sliderBackground.width();
|
|
|
10749 |
var duration = this._serializer.currentMedia().meta["dc:duration"] / 1000;
|
|
|
10750 |
var newTime = ((ui.offset.left / width) * duration).toFixed(2);
|
|
|
10751 |
|
|
|
10752 |
this._Popcorn.currentTime(newTime);
|
|
|
10753 |
|
|
|
10754 |
this.draggingOngoing = false;
|
|
|
10755 |
};
|
|
|
10756 |
|
|
|
10757 |
/* this widget displays a small tooltip */
|
|
|
10758 |
IriSP.TooltipWidget = function(Popcorn, config, Serializer) {
|
|
|
10759 |
IriSP.Widget.call(this, Popcorn, config, Serializer);
|
|
|
10760 |
};
|
|
|
10761 |
|
|
|
10762 |
|
|
|
10763 |
IriSP.TooltipWidget.prototype = new IriSP.Widget();
|
|
|
10764 |
|
|
|
10765 |
IriSP.TooltipWidget.prototype.draw = function() {
|
|
|
10766 |
var templ = Mustache.to_html(IriSP.tooltipWidget_template);
|
|
|
10767 |
|
|
|
10768 |
this.selector.append(templ);
|
|
|
10769 |
this.hide();
|
|
|
10770 |
|
|
|
10771 |
};
|
|
|
10772 |
|
|
|
10773 |
IriSP.TooltipWidget.prototype.clear = function() {
|
|
|
10774 |
this.selector.find(".tiptext").text("");
|
|
|
10775 |
};
|
|
|
10776 |
|
|
|
10777 |
IriSP.TooltipWidget.prototype.show = function(text, color, x, y) {
|
|
|
10778 |
if (this.selector.find(".tiptext").text() == text)
|
|
|
10779 |
return;
|
|
|
10780 |
|
|
|
10781 |
this.selector.find(".tipcolor").css("background-color", color);
|
|
|
10782 |
this.selector.find(".tiptext").text(text);
|
|
|
10783 |
this.selector.find(".tip").css("left", x).css("top", y);
|
|
|
10784 |
};
|
|
|
10785 |
|
|
|
10786 |
IriSP.TooltipWidget.prototype.hide = function() {
|
|
|
10787 |
this.clear();
|
|
|
10788 |
this.selector.find(".tip").css("left", -10000).css("top", -100000);
|
|
|
10789 |
};
|
|
|
10790 |
/* a widget that displays tweet - used in conjunction with the polemicWidget */
|
|
|
10791 |
|
|
|
10792 |
IriSP.TweetsWidget = function(Popcorn, config, Serializer) {
|
|
|
10793 |
IriSP.Widget.call(this, Popcorn, config, Serializer);
|
|
|
10794 |
|
|
|
10795 |
this._displayingTweet = false;
|
|
|
10796 |
this._timeoutId = undefined;
|
|
|
10797 |
};
|
|
|
10798 |
|
|
|
10799 |
|
|
|
10800 |
IriSP.TweetsWidget.prototype = new IriSP.Widget();
|
|
|
10801 |
|
|
|
10802 |
|
|
|
10803 |
IriSP.TweetsWidget.prototype.drawTweet = function(annotation) {
|
|
|
10804 |
|
|
|
10805 |
var title = IriSP.formatTweet(annotation.content.title);
|
|
|
10806 |
var img = annotation.content.img.src;
|
|
|
10807 |
if (typeof(img) === "undefined" || img === "" || img === "None") {
|
|
|
10808 |
img = IriSP.widgetsDefaults.TweetsWidget.default_profile_picture;
|
|
|
10809 |
}
|
|
|
10810 |
|
|
|
10811 |
var imageMarkup = IriSP.templToHTML("<img src='{{src}}' alt='user image'></img>",
|
|
|
10812 |
{src : img});
|
|
|
10813 |
|
|
|
10814 |
if (typeof(annotation.meta["dc:source"].content) !== "undefined") {
|
|
|
10815 |
var tweetContents = JSON.parse(annotation.meta["dc:source"].content);
|
|
|
10816 |
var creator = tweetContents.user.screen_name;
|
|
|
10817 |
var real_name = tweetContents.user.name;
|
|
|
10818 |
|
|
|
10819 |
imageMarkup = IriSP.templToHTML("<a href='http://twitter.com/{{creator}}'><img src='{{src}}' alt='user image'></img></a>",
|
|
|
10820 |
{src : img, creator: creator});
|
|
|
10821 |
|
|
|
10822 |
var formatted_date = new Date(tweetContents.created_at).toLocaleDateString();
|
|
|
10823 |
title = IriSP.templToHTML("<a class='Ldt-tweet_userHandle' href='http://twitter.com/{{creator}}'>@{{creator}}</a> - " +
|
|
|
10824 |
"<div class='Ldt-tweet_realName'>{{real_name}}</div>" +
|
|
|
10825 |
"<div class='Ldt-tweet_tweetContents'>{{{ contents }}}</div>" +
|
|
|
10826 |
"<div class='Ldt-tweet_date'>{{ date }}</div>",
|
|
|
10827 |
{creator: creator, real_name: real_name, contents : title, date : formatted_date});
|
|
|
10828 |
|
|
|
10829 |
this.selector.find(".Ldt-TweetReply").attr("href", "http://twitter.com/home?status=@" + creator + ":%20");
|
|
|
10830 |
|
|
|
10831 |
|
|
|
10832 |
var rtText = Mustache.to_html("http://twitter.com/home?status=RT @{{creator}}: {{text}}",
|
|
|
10833 |
{creator: creator, text: IriSP.encodeURI(annotation.content.title)});
|
|
|
10834 |
this.selector.find(".Ldt-Retweet").attr("href", rtText);
|
|
|
10835 |
}
|
|
|
10836 |
|
|
|
10837 |
this.selector.find(".Ldt-tweetContents").html(title);
|
|
|
10838 |
this.selector.find(".Ldt-tweetAvatar").html(imageMarkup);
|
|
|
10839 |
this.selector.show("blind", 250);
|
|
|
10840 |
};
|
|
|
10841 |
|
|
|
10842 |
IriSP.TweetsWidget.prototype.displayTweet = function(annotation) {
|
|
|
10843 |
if (this._displayingTweet === false) {
|
|
|
10844 |
this._displayingTweet = true;
|
|
|
10845 |
} else {
|
|
|
10846 |
window.clearTimeout(this._timeoutId);
|
|
|
10847 |
}
|
|
|
10848 |
|
|
|
10849 |
this.drawTweet(annotation);
|
|
|
10850 |
|
|
|
10851 |
var time = this._Popcorn.currentTime();
|
|
|
10852 |
this._timeoutId = window.setTimeout(IriSP.wrap(this, this.clearPanel), IriSP.widgetsDefaults.TweetsWidget.tweet_display_period);
|
|
|
10853 |
};
|
|
|
10854 |
|
|
|
10855 |
|
|
|
10856 |
IriSP.TweetsWidget.prototype.clearPanel = function() {
|
|
|
10857 |
this._displayingTweet = false;
|
|
|
10858 |
this._timeoutId = undefined;
|
|
|
10859 |
this.closePanel();
|
|
|
10860 |
|
|
|
10861 |
};
|
|
|
10862 |
|
|
|
10863 |
IriSP.TweetsWidget.prototype.closePanel = function() {
|
|
|
10864 |
if (this._timeoutId != undefined) {
|
|
|
10865 |
/* we're called from the "close window" link */
|
|
|
10866 |
/* cancel the timeout */
|
|
|
10867 |
window.clearTimeout(this._timeoutId);
|
|
|
10868 |
this._timeoutId = null;
|
|
|
10869 |
}
|
|
|
10870 |
|
|
|
10871 |
this.selector.hide("blind", 400);
|
|
|
10872 |
|
|
|
10873 |
};
|
|
|
10874 |
|
|
|
10875 |
/* cancel the timeout if the user clicks on the keep panel open button */
|
|
|
10876 |
IriSP.TweetsWidget.prototype.keepPanel = function() {
|
|
|
10877 |
if (this._timeoutId != undefined) {
|
|
|
10878 |
/* we're called from the "close window" link */
|
|
|
10879 |
/* cancel the timeout */
|
|
|
10880 |
window.clearTimeout(this._timeoutId);
|
|
|
10881 |
this._timeoutId = null;
|
|
|
10882 |
}
|
|
|
10883 |
};
|
|
|
10884 |
|
|
|
10885 |
IriSP.TweetsWidget.prototype.draw = function() {
|
|
|
10886 |
var _this = this;
|
|
|
10887 |
|
|
|
10888 |
var tweetMarkup = IriSP.templToHTML(IriSP.tweetWidget_template, {"share_template" : IriSP.share_template});
|
|
|
10889 |
this.selector.append(tweetMarkup);
|
|
|
10890 |
this.selector.hide();
|
|
|
10891 |
this.selector.find(".Ldt-tweetWidgetMinimize").click(IriSP.wrap(this, this.closePanel));
|
|
|
10892 |
this.selector.find(".Ldt-tweetWidgetKeepOpen").click(IriSP.wrap(this, this.keepPanel));
|
|
|
10893 |
|
|
|
10894 |
this._Popcorn.listen("IriSP.PolemicTweet.click", IriSP.wrap(this, this.PolemicTweetClickHandler));
|
|
|
10895 |
};
|
|
|
10896 |
|
|
|
10897 |
IriSP.TweetsWidget.prototype.PolemicTweetClickHandler = function(tweet_id) {
|
|
|
10898 |
var index, annotation;
|
|
|
10899 |
for (index in this._serializer._data.annotations) {
|
|
|
10900 |
annotation = this._serializer._data.annotations[index];
|
|
|
10901 |
|
|
|
10902 |
if (annotation.id === tweet_id)
|
|
|
10903 |
break;
|
|
|
10904 |
}
|
|
|
10905 |
|
|
|
10906 |
if (annotation.id !== tweet_id)
|
|
|
10907 |
/* we haven't found it */
|
|
|
10908 |
return;
|
|
|
10909 |
|
|
|
10910 |
this.displayTweet(annotation);
|
|
|
10911 |
return;
|
|
|
10912 |
};
|
|
|
10913 |
|
|
|
10914 |
IriSP.JSONSerializer = function(DataLoader, url) {
|
|
|
10915 |
IriSP.Serializer.call(this, DataLoader, url);
|
|
|
10916 |
};
|
|
|
10917 |
|
|
|
10918 |
IriSP.JSONSerializer.prototype = new IriSP.Serializer();
|
|
|
10919 |
|
|
|
10920 |
IriSP.JSONSerializer.prototype.serialize = function(data) {
|
|
|
10921 |
return JSON.stringify(data);
|
|
|
10922 |
};
|
|
|
10923 |
|
|
|
10924 |
IriSP.JSONSerializer.prototype.deserialize = function(data) {
|
|
|
10925 |
return JSON.parse(data);
|
|
|
10926 |
};
|
|
|
10927 |
|
|
|
10928 |
IriSP.JSONSerializer.prototype.sync = function(callback) {
|
|
|
10929 |
/* we don't have to do much because jQuery handles json for us */
|
|
|
10930 |
|
|
|
10931 |
var self = this;
|
|
|
10932 |
|
|
|
10933 |
var fn = function(data) {
|
|
|
10934 |
self._data = data;
|
|
|
10935 |
// sort the data too
|
|
|
10936 |
self._data["annotations"].sort(function(a, b)
|
|
|
10937 |
{ var a_begin = +a.begin;
|
|
|
10938 |
var b_begin = +b.begin;
|
|
|
10939 |
return a_begin - b_begin;
|
|
|
10940 |
});
|
|
|
10941 |
|
|
|
10942 |
callback(data);
|
|
|
10943 |
};
|
|
|
10944 |
|
|
|
10945 |
this._DataLoader.get(this._url, fn);
|
|
|
10946 |
};
|
|
|
10947 |
|
|
|
10948 |
IriSP.JSONSerializer.prototype.currentMedia = function() {
|
|
|
10949 |
return this._data.medias[0]; /* FIXME: don't hardcode it */
|
|
|
10950 |
};
|
|
|
10951 |
|
|
|
10952 |
/* this function searches for an annotation which matches title, description and keyword
|
|
|
10953 |
"" matches any field.
|
|
|
10954 |
Note: it ignores tweets.
|
|
|
10955 |
*/
|
|
|
10956 |
IriSP.JSONSerializer.prototype.searchAnnotations = function(title, description, keyword) {
|
|
|
10957 |
/* we can have many types of annotations. We want search to only look for regular segments */
|
|
|
10958 |
/* the next two lines are a bit verbose because for some test data, _serializer.data.view is either
|
|
|
10959 |
null or undefined.
|
|
|
10960 |
*/
|
|
|
10961 |
var view;
|
|
|
10962 |
|
|
|
10963 |
if (typeof(this._data.views) !== "undefined" && this._data.views !== null)
|
|
|
10964 |
view = this._data.views[0];
|
|
|
10965 |
|
|
|
10966 |
var searchViewType = "";
|
|
|
10967 |
|
|
|
10968 |
if(typeof(view) !== "undefined" && typeof(view.annotation_types) !== "undefined" && view.annotation_types.length > 1) {
|
|
|
10969 |
searchViewType = view.annotation_types[0];
|
|
|
10970 |
}
|
|
|
10971 |
|
|
|
10972 |
var filterfn = function(annotation) {
|
|
|
10973 |
if( searchViewType != "" &&
|
|
|
10974 |
typeof(annotation.meta) !== "undefined" &&
|
|
|
10975 |
typeof(annotation.meta["id-ref"]) !== "undefined" &&
|
|
|
10976 |
annotation.meta["id-ref"] !== searchViewType) {
|
|
|
10977 |
return true; // don't pass
|
|
|
10978 |
} else {
|
|
|
10979 |
return false;
|
|
|
10980 |
}
|
|
|
10981 |
};
|
|
|
10982 |
|
|
|
10983 |
return this.searchAnnotationsFilter(title, description, keyword, filterfn);
|
|
|
10984 |
|
|
|
10985 |
};
|
|
|
10986 |
|
|
|
10987 |
/* only look for tweets */
|
|
|
10988 |
IriSP.JSONSerializer.prototype.searchTweets = function(title, description, keyword) {
|
|
|
10989 |
/* we can have many types of annotations. We want search to only look for regular segments */
|
|
|
10990 |
/* the next two lines are a bit verbose because for some test data, _serializer.data.view is either
|
|
|
10991 |
null or undefined.
|
|
|
10992 |
*/
|
|
|
10993 |
var view;
|
|
|
10994 |
|
|
|
10995 |
if (typeof(this._data.views) !== "undefined" && this._data.views !== null)
|
|
|
10996 |
view = this._data.views[0];
|
|
|
10997 |
|
|
|
10998 |
var searchViewType = "";
|
|
|
10999 |
|
|
|
11000 |
if(typeof(view) !== "undefined" && typeof(view.annotation_types) !== "undefined" && view.annotation_types.length > 1) {
|
|
|
11001 |
searchViewType = view.annotation_types[0];
|
|
|
11002 |
}
|
|
|
11003 |
|
|
|
11004 |
var filterfn = function(annotation) {
|
|
|
11005 |
if( searchViewType != "" &&
|
|
|
11006 |
typeof(annotation.meta) !== "undefined" &&
|
|
|
11007 |
typeof(annotation.meta["id-ref"]) !== "undefined" &&
|
|
|
11008 |
annotation.meta["id-ref"] !== searchViewType) {
|
|
|
11009 |
return false; // pass
|
|
|
11010 |
} else {
|
|
|
11011 |
return true;
|
|
|
11012 |
}
|
|
|
11013 |
};
|
|
|
11014 |
|
|
|
11015 |
return this.searchAnnotationsFilter(title, description, keyword, filterfn);
|
|
|
11016 |
|
|
|
11017 |
};
|
|
|
11018 |
|
|
|
11019 |
/*
|
|
|
11020 |
the previous function call this one, which is more general:
|
|
|
11021 |
*/
|
|
|
11022 |
IriSP.JSONSerializer.prototype.searchAnnotationsFilter = function(title, description, keyword, filter) {
|
|
|
11023 |
|
|
|
11024 |
var rTitle;
|
|
|
11025 |
var rDescription;
|
|
|
11026 |
var rKeyword;
|
|
|
11027 |
/* match anything if given the empty string */
|
|
|
11028 |
if (title == "")
|
|
|
11029 |
title = ".*";
|
|
|
11030 |
if (description == "")
|
|
|
11031 |
description = ".*";
|
|
|
11032 |
if (keyword == "")
|
|
|
11033 |
keyword = ".*";
|
|
|
11034 |
|
|
|
11035 |
rTitle = new RegExp(title, "i");
|
|
|
11036 |
rDescription = new RegExp(description, "i");
|
|
|
11037 |
rKeyword = new RegExp(keyword, "i");
|
|
|
11038 |
|
|
|
11039 |
var ret_array = [];
|
|
|
11040 |
|
|
|
11041 |
var i;
|
|
|
11042 |
for (i in this._data.annotations) {
|
|
|
11043 |
var annotation = this._data.annotations[i];
|
|
|
11044 |
|
|
|
11045 |
/* filter the annotations whose type is not the one we want */
|
|
|
11046 |
if (filter(annotation)) {
|
|
|
11047 |
continue;
|
|
|
11048 |
}
|
|
|
11049 |
|
|
|
11050 |
if (rTitle.test(annotation.content.title) &&
|
|
|
11051 |
rDescription.test(annotation.content.description)) {
|
|
|
11052 |
/* FIXME : implement keyword support */
|
|
|
11053 |
ret_array.push(annotation);
|
|
|
11054 |
}
|
|
|
11055 |
}
|
|
|
11056 |
|
|
|
11057 |
return ret_array;
|
|
|
11058 |
};
|
|
|
11059 |
|
|
|
11060 |
/* breaks a string in words and searches each of these words. Returns an array
|
|
|
11061 |
of objects with the id of the annotation and its number of occurences.
|
|
|
11062 |
|
|
|
11063 |
FIXME: optimize ? seems to be n^2 in the worst case.
|
|
|
11064 |
*/
|
|
|
11065 |
IriSP.JSONSerializer.prototype.searchOccurences = function(searchString) {
|
|
|
11066 |
var ret = { };
|
|
|
11067 |
var keywords = searchString.split(/\s+/);
|
|
|
11068 |
|
|
|
11069 |
for (var i in keywords) {
|
|
|
11070 |
var keyword = keywords[i];
|
|
|
11071 |
|
|
|
11072 |
// search this keyword in descriptions and title
|
|
|
11073 |
var found_annotations = []
|
|
|
11074 |
found_annotations = found_annotations.concat(this.searchAnnotations(keyword, "", ""));
|
|
|
11075 |
found_annotations = found_annotations.concat(this.searchAnnotations("", keyword, ""));
|
|
|
11076 |
|
|
|
11077 |
for (var j in found_annotations) {
|
|
|
11078 |
var current_annotation = found_annotations[j];
|
|
|
11079 |
|
|
|
11080 |
if (!ret.hasOwnProperty(current_annotation.id)) {
|
|
|
11081 |
ret[current_annotation.id] = 1;
|
|
|
11082 |
} else {
|
|
|
11083 |
ret[current_annotation.id] += 1;
|
|
|
11084 |
}
|
|
|
11085 |
|
|
|
11086 |
}
|
|
|
11087 |
|
|
|
11088 |
};
|
|
|
11089 |
|
|
|
11090 |
return ret;
|
|
|
11091 |
};
|
|
|
11092 |
|
|
|
11093 |
/* breaks a string in words and searches each of these words. Returns an array
|
|
|
11094 |
of objects with the id of the annotation and its number of occurences.
|
|
|
11095 |
|
|
|
11096 |
FIXME: optimize ? seems to be n^2 in the worst case.
|
|
|
11097 |
*/
|
|
|
11098 |
IriSP.JSONSerializer.prototype.searchTweetsOccurences = function(searchString) {
|
|
|
11099 |
var ret = { };
|
|
|
11100 |
var keywords = searchString.split(/\s+/);
|
|
|
11101 |
|
|
|
11102 |
for (var i in keywords) {
|
|
|
11103 |
var keyword = keywords[i];
|
|
|
11104 |
|
|
|
11105 |
// search this keyword in descriptions and title
|
|
|
11106 |
var found_annotations = []
|
|
|
11107 |
found_annotations = found_annotations.concat(this.searchTweets(keyword, "", ""));
|
|
|
11108 |
found_annotations = found_annotations.concat(this.searchTweets("", keyword, ""));
|
|
|
11109 |
|
|
|
11110 |
for (var j in found_annotations) {
|
|
|
11111 |
var current_annotation = found_annotations[j];
|
|
|
11112 |
|
|
|
11113 |
if (!ret.hasOwnProperty(current_annotation.id)) {
|
|
|
11114 |
ret[current_annotation.id] = 1;
|
|
|
11115 |
} else {
|
|
|
11116 |
ret[current_annotation.id] += 1;
|
|
|
11117 |
}
|
|
|
11118 |
|
|
|
11119 |
}
|
|
|
11120 |
|
|
|
11121 |
};
|
|
|
11122 |
|
|
|
11123 |
return ret;
|
|
|
11124 |
};
|
|
|
11125 |
|
|
|
11126 |
/* takes the currentTime and returns all the annotations that are displayable at the moment
|
|
|
11127 |
NB: only takes account the first type of annotations - ignores tweets
|
|
|
11128 |
currentTime is in seconds.
|
|
|
11129 |
*/
|
|
|
11130 |
|
|
|
11131 |
IriSP.JSONSerializer.prototype.currentAnnotations = function(currentTime) {
|
|
|
11132 |
var view;
|
|
|
11133 |
var currentTimeMs = 1000 * currentTime;
|
|
|
11134 |
|
|
|
11135 |
if (typeof(this._data.views) !== "undefined" && this._data.views !== null)
|
|
|
11136 |
view = this._data.views[0];
|
|
|
11137 |
|
|
|
11138 |
var view_type = "";
|
|
|
11139 |
|
|
|
11140 |
if(typeof(view) !== "undefined" && typeof(view.annotation_types) !== "undefined" && view.annotation_types.length >= 1) {
|
|
|
11141 |
view_type = view.annotation_types[0];
|
|
|
11142 |
}
|
|
|
11143 |
|
|
|
11144 |
var ret_array = [];
|
|
|
11145 |
|
|
|
11146 |
var i;
|
|
|
11147 |
|
|
|
11148 |
for (i in this._data.annotations) {
|
|
|
11149 |
var annotation = this._data.annotations[i];
|
|
|
11150 |
|
|
|
11151 |
if (annotation.meta["id-ref"] === view_type && annotation.begin <= currentTimeMs && annotation.end >= currentTimeMs)
|
|
|
11152 |
ret_array.push(annotation);
|
|
|
11153 |
}
|
|
|
11154 |
|
|
|
11155 |
return ret_array;
|
|
|
11156 |
};
|