PageSourceSearch

https://frontend.adaptivecurriculum.com/_sources/_js/jquery.nyroModal.custom.js

js adaptivecurriculum.com collected 2026-10-02 04:07:56 UTC 39,195 bytes, 1,339 lines download raw bytes

1/*
2 * nyroModal v2.0.0
3 * Core
4 *
5 * Commit a771d6237dc7c3a278f6 (05/07/2011) * 
6 * 
7 * Included parts:
8 * - anims.fade
9 * - filters.title
10 * - filters.gallery
11 * - filters.link
12 * - filters.dom
13 * - filters.data
14 * - filters.formFile
15 */
16/*
17 * nyroModal v2.0.0
18 * Core
19 *
20 */
21jQuery(function($, undefined) {
22
23	var $w = $(window),
24		$d = $(document),
25		$b = $('body'),
26		baseHref = $('base').attr('href'),
27		// nyroModal Object
28		_nmObj = {
29			filters: [],	// List of filters used
30			callbacks: {},	// Sepcific callbacks
31			loadFilter: undefined,	// Name of the filter used for loading
32
33			modal: false,	// Indicates if it's a modal window or not
34			closeOnEscape: true,	// Indicates if the modal should close on Escape key
35			closeOnClick: true,	// Indicates if a click on the background should close the modal
36			useKeyHandler: false,	// Indicates if the modal has to handle key down event
37
38			showCloseButton: true,	// Indicates if the closeButonn should be added
39			closeButton: '<a href="#" class="nyroModalClose nyroModalCloseButton nmReposition" title="close">Close</a>',	// Close button HTML
40
41			stack: false,	// Indicates if links automatically binded inside the modal should stack or not
42			nonStackable: 'form',	// Filter to not stack DOM element
43
44			header: undefined,	// header include in every modal
45			footer: undefined,	// footer include in every modal
46			
47			// Specific confirguation for gallery filter
48			galleryLoop: true,	// Indicates if the gallery should loop
49			galleryCounts: true,	// Indicates if the gallery counts should be shown
50			ltr: true, // Left to Right by default. Put to false for Hebrew or Right to Left language. Used in gallery filter
51
52			// Specific confirguation for image filter
53			imageRegex: '[^\.]\.(jpg|jpeg|png|tiff|gif|bmp)\s*$',	// Regex used to detect image link
54
55			selIndicator: 'nyroModalSel', // Value added when a form or Ajax is sent with a filter content
56
57			swfObjectId: undefined, // Object id for swf object
58			swf:  {	// Default SWF attributes
59				allowFullScreen: 'true',
60				allowscriptaccess: 'always',
61				wmode: 'transparent'
62			},
63
64			store: {},	// Storage object for filters.
65			errorMsg: 'An error occured',	// Error message
66			elts: {	// HTML elements for the modal
67				all: undefined,
68				bg: undefined,
69				load: undefined,
70				cont: undefined,
71				hidden: undefined
72			},
73			sizes: {	// Size information
74				initW: undefined,	// Initial width
75				initH: undefined,	// Initial height
76				w: undefined,		// width
77				h: undefined,		// height
78				minW: undefined,	// minimum Width
79				minH: undefined,	// minimum height
80				wMargin: undefined,	// Horizontal margin
81				hMargin: undefined	// Vertical margin
82			},
83			anim: {	// Animation names to use
84				def: undefined,			// Default animation set to use if sspecific are not defined or doesn't exist
85				showBg: undefined,		// Set to use for showBg animation
86				hideBg: undefined,		// Set to use for hideBg animation
87				showLoad: undefined,	// Set to use for showLoad animation
88				hideLoad: undefined,	// Set to use for hideLoad animation
89				showCont: undefined,	// Set to use for showCont animation
90				hideCont: undefined,	// Set to use for hideCont animation
91				showTrans: undefined,	// Set to use for showTrans animation
92				hideTrans: undefined,	// Set to use for hideTrans animation
93				resize: undefined		// Set to use for resize animation
94			},
95
96			_open: false,	// Indicates if the modal is open
97			_bgReady: false,	// Indicates if the background is ready
98			_opened: false,	// Indicates if the modal was opened (useful for stacking)
99			_loading: false,	// Indicates if the loading is shown
100			_animated: false,	// Indicates if the modal is currently animated
101			_transition: false,	//Indicates if the modal is in transition
102			_nmOpener: undefined,	// nmObj of the modal that opened the current one in non stacking mode
103			_nbContentLoading: 0,	// Counter for contentLoading call
104			_scripts: '',	// Scripts tags to be included
105			_scriptsShown: '',	//Scripts tags to be included once the modal is swhon
106
107			// save the object in data
108			saveObj: function() {
109				this.opener.data('nmObj', this);
110			},
111			// Open the modal
112			open: function() {
113				if (this._nmOpener)
114					this._nmOpener._close();
115				this.getInternal()._pushStack(this.opener);
116				this._opened = false;
117				this._bgReady = false;
118				this._open = true;
119				this._initElts();
120				this._load();
121				this._nbContentLoading = 0;
122				this._callAnim('showBg', $.proxy(function() {
123					this._bgReady = true;
124					if (this._nmOpener) {
125						// fake closing of the opener nyroModal
126						this._nmOpener._bgReady = false;
127						this._nmOpener._loading = false;
128						this._nmOpener._animated = false;
129						this._nmOpener._opened = false;
130						this._nmOpener._open = false;
131						this._nmOpener.elts.cont = this._nmOpener.elts.hidden = this._nmOpener.elts.load = this._nmOpener.elts.bg = this._nmOpener.elts.all = undefined;
132						this._nmOpener.saveObj();
133						this._nmOpener = undefined;
134					}
135					this._contentLoading();
136				}, this));
137			},
138
139			// Resize the modal according to sizes.initW and sizes.initH
140			// Will call size function
141			// @param recalc boolean: Indicate if the size should be recalaculated (useful when content has changed)
142			resize: function(recalc) {
143				if (recalc) {
144					this.elts.hidden.append(this.elts.cont.children().first().clone());
145					this.sizes.initW = this.sizes.w = this.elts.hidden.width();
146					this.sizes.initH = this.sizes.h = this.elts.hidden.height();
147					this.elts.hidden.empty();
148				} else {
149					this.sizes.w = this.sizes.initW;
150					this.sizes.h = this.sizes.initH;
151				}
152				this._unreposition();
153				this.size();
154				this._callAnim('resize', $.proxy(function() {
155					this._reposition();
156				}, this));
157			},
158
159			// Update sizes element to not go outsize the viewport.
160			// Will call 'size' callback filter
161			size: function() {
162				var maxHeight = this.getInternal().fullSize.viewH - this.sizes.hMargin,
163					maxWidth = this.getInternal().fullSize.viewW - this.sizes.wMargin;
164				if (this.sizes.minW && this.sizes.minW > this.sizes.w)
165					this.sizes.w = this.sizes.minW;
166				if (this.sizes.minH && this.sizes.minH > this.sizes.h)
167					this.sizes.h = this.sizes.minH;
168				if (this.sizes.h > maxHeight || this.sizes.w > maxWidth) {
169					// We're gonna resize the modal as it will goes outside the view port
170					this.sizes.h = Math.min(this.sizes.h, maxHeight);
171					this.sizes.w = Math.min(this.sizes.w, maxWidth);
172				}
173				this._callFilters('size');
174			},
175
176			// Get the nmObject for a new nyroModal
177			getForNewLinks: function(elt) {
178				var ret;
179				if (this.stack && (!elt || this.isStackable(elt))) {
180					ret = $.extend(true, {}, this);
181					ret._nmOpener = undefined;
182					ret.elts.all = undefined;
183				} else {
184					ret = $.extend({}, this);
185					ret._nmOpener = this;
186				}
187				ret.filters = [];
188				ret.opener = undefined;
189				ret._open = false;
190				return ret;
191			},
192			
193			// Indicate if an element can be stackable or not, regarding the nonStackable setting
194			isStackable: function(elt) {
195				return !elt.is(this.nonStackable);
196			},
197
198			// key handle function.
199			// Will call 'keyHandle' callback filter
200			keyHandle: function(e) {
201				this.keyEvent = e;
202				this._callFilters('keyHandle');
203				this.keyEvent = undefined;
204				delete(this.keyEvent);
205			},
206
207			// Get the internal object
208			getInternal: function() {
209				return _internal;
210			},
211
212			// Internal function for closing a nyroModal
213			// Will call 'close' callback filter
214			_close: function() {
215				this.getInternal()._removeStack(this.opener);
216				this._opened = false;
217				this._open = false;
218				this._callFilters('close');
219			},
220			// Public function for closing a nyroModal
221			close: function() {
222				this._close();
223				this._callFilters('beforeClose');
224				var self = this;
225				this._unreposition();
226				self._callAnim('hideCont', function() {
227					self._callAnim('hideLoad', function() {
228						self._callAnim('hideBg', function() {
229							self._callFilters('afterClose');
230							self.elts.cont.remove();
231							self.elts.hidden.remove();
232							self.elts.load.remove();
233							self.elts.bg.remove();
234							self.elts.all.remove();
235							self.elts.cont = self.elts.hidden = self.elts.load = self.elts.bg = self.elts.all = undefined;
236						});
237					});
238				});
239			},
240
241			// Init HTML elements
242			_initElts: function() {
243				if (!this.stack && this.getInternal().stack.length > 1)
244					this.elts = this.getInternal().stack[this.getInternal().stack.length-2]['nmObj'].elts;
245				if (!this.elts.all || this.elts.all.closest('body').length == 0)
246					this.elts.all = this.elts.bg = this.elts.cont = this.elts.hidden = this.elts.load = undefined;
247				if (!this.elts.all)
248					this.elts.all = $('<div />').appendTo(this.getInternal()._container);
249				if (!this.elts.bg)
250					this.elts.bg = $('<div />').hide().appendTo(this.elts.all);
251				if (!this.elts.cont)
252					this.elts.cont = $('<div />').hide().appendTo(this.elts.all);
253				if (!this.elts.hidden)
254					this.elts.hidden = $('<div />').hide().appendTo(this.elts.all);
255				this.elts.hidden.empty();
256				if (!this.elts.load)
257					this.elts.load = $('<div />').hide().appendTo(this.elts.all);
258				this._callFilters('initElts');
259			},
260
261			// Trigger the error
262			// Will call 'error' callback filter
263			_error: function() {
264				this._callFilters('error');
265			},
266
267			// Set the HTML content to show.
268			// - html: HTML content
269			// - selector: selector to filter the content
270			// Will init the size and call the 'size' function.
271			// Will call 'filledContent' callback filter
272			_setCont: function(html, selector) {
273				if (selector) {
274					var tmp = [],
275						i = 0;
276					// Looking for script to store them
277					html = html
278						.replace(/\r\n/gi, 'nyroModalLN')
279						.replace(/<script(.|\s)*?\/script>/gi, function(x) {
280								tmp[i] = x;
281								return '<pre class=nyroModalScript rel="'+(i++)+'"></pre>';
282							});
283					var cur = $('<div>'+html+'</div>').find(selector);
284					if (cur.length) {
285						html = cur.html()
286							.replace(/<pre class="?nyroModalScript"? rel="?(.?)"?><\/pre>/gi, function(x, y, z) { return tmp[y]; })
287							.replace(/nyroModalLN/gi, "\r\n");
288					} else {
289						// selector not found
290						this._error();
291						return;
292					}
293				}
294				this.elts.hidden
295					.append(this._filterScripts(html))
296					.prepend(this.header)
297					.append(this.footer)
298					.wrapInner('<div class="nyroModal'+ucfirst(this.loadFilter)+'" />');
299
300				// Store the size of the element
301				this.sizes.initW = this.sizes.w = this.elts.hidden.width();
302				this.sizes.initH = this.sizes.h = this.elts.hidden.height();
303				var outer = this.getInternal()._getOuter(this.elts.cont);
304				this.sizes.hMargin = outer.h.total;
305				this.sizes.wMargin = outer.w.total;
306
307				this.size();
308
309				this.loading = false;
310				this._callFilters('filledContent');
311				this._contentLoading();
312			},
313
314			// Filter an html content to remove the script[src] and store them appropriately if needed
315			// - data: Data to filter
316			_filterScripts: function(data) {
317				if (typeof data != 'string')
318					return data;
319
320				this._scripts = [];
321				this._scriptsShown = [];
322				var start = 0,
323					stStart = '<script',
324					stEnd = '</script>',
325					endLn = stEnd.length,
326					pos,
327					pos2,
328					tmp;
329				while ((pos = data.indexOf(stStart, start)) > -1) {
330					pos2 = data.indexOf(stEnd)+endLn;
331					tmp = $(data.substring(pos, pos2));
332					if (!tmp.attr('src') || tmp.attr('rel') == 'forceLoad') {
333						if (tmp.attr('rev') == 'shown')
334							this._scriptsShown.push(tmp.get(0));
335						else
336							this._scripts.push(tmp.get(0));
337					}
338					data = data.substring(0, pos)+data.substr(pos2);
339					start = pos;
340				}
341				return data;
342			},
343
344			// Check if the nmObject has a specific filter
345			// - filter: Filter name
346			_hasFilter: function(filter) {
347				var ret = false;
348				$.each(this.filters, function(i, f) {
349					ret = ret || f == filter;
350				});
351				return ret;
352			},
353
354			// Remove a specific filter
355			// - filter: Filter name
356			_delFilter: function(filter) {
357				this.filters = $.map(this.filters, function(v) {
358					if (v != filter)
359						return v;
360				});
361			},
362
363			// Call a function against all active filters
364			// - fct: Function name
365			// return an array of all return of callbacks; keys are filters name
366			_callFilters: function(fct) {
367				this.getInternal()._debug(fct);
368				var ret = [],
369					self = this;
370				$.each(this.filters, function(i, f) {
371					ret[f] = self._callFilter(f, fct);
372				});
373				if (this.callbacks[fct] && $.isFunction(this.callbacks[fct]))
374					this.callbacks[fct](this);
375				return ret;
376			},
377
378			// Call a filter function for a specific filter
379			// - f: Filter name
380			// - fct: Function name
381			// return the return of the callback
382			_callFilter: function(f, fct) {
383				if (_filters[f] && _filters[f][fct] && $.isFunction(_filters[f][fct]))
384					return _filters[f][fct](this);
385				return undefined;
386			},
387
388			// Call animation callback.
389			// Will also call beforeNNN and afterNNN filter callbacks
390			// - fct: Animation function name
391			// - clb: Callback once the animation is done
392			_callAnim: function(fct, clb) {
393				this.getInternal()._debug(fct);
394				this._callFilters('before'+ucfirst(fct));
395				if (!this._animated) {
396					this._animated = true;
397					if (!$.isFunction(clb)) clb = $.noop;
398					var set = this.anim[fct] || this.anim.def || 'basic';
399					if (!_animations[set] || !_animations[set][fct] || !$.isFunction(_animations[set][fct]))
400						set = 'basic';
401					_animations[set][fct](this, $.proxy(function() {
402							this._animated = false;
403							this._callFilters('after'+ucfirst(fct));
404							clb();
405						}, this));
406				}
407			},
408
409			// Load the content
410			// Will call the 'load' function of the filter specified in the loadFilter parameter
411			_load: function() {
412				this.getInternal()._debug('_load');
413				if (!this.loading && this.loadFilter) {
414					this.loading = true;
415					this._callFilter(this.loadFilter, 'load');
416				}
417			},
418
419			// Show the content or the loading according to the current state of the modal
420			_contentLoading: function() {
421				if (!this._animated && this._bgReady) {
422					if (!this._transition && this.elts.cont.html().length > 0)
423						this._transition = true;
424					this._nbContentLoading++;
425					if (!this.loading) {
426						if (!this._opened) {
427							this._opened = true;
428							if (this._transition) {
429								var fct = $.proxy(function() {
430									this._writeContent();
431									this._callFilters('beforeShowCont');
432									this._callAnim('hideTrans', $.proxy(function() {
433										this._transition = false;
434										this._callFilters('afterShowCont');
435										this.elts.cont.append(this._scriptsShown);
436										this._reposition();
437									}, this));
438								}, this);
439								if (this._nbContentLoading == 1) {
440									this._unreposition();
441									this._callAnim('showTrans', fct);
442								} else {
443									fct();
444								}
445							} else {
446								this._callAnim('hideLoad', $.proxy(function() {
447									this._writeContent();
448									this._callAnim('showCont', $.proxy(function() {
449										this.elts.cont.append(this._scriptsShown);
450										this._reposition();
451									}, this));
452								}, this));
453							}
454						}
455					} else if (this._nbContentLoading == 1) {
456						var outer = this.getInternal()._getOuter(this.elts.load);
457						this.elts.load
458							.css({
459								position: 'fixed',
460								top: (this.getInternal().fullSize.viewH - this.elts.load.height() - outer.h.margin)/2,
461								left: (this.getInternal().fullSize.viewW - this.elts.load.width() - outer.w.margin)/2
462							});
463						if (this._transition) {
464							this._unreposition();
465							this._callAnim('showTrans', $.proxy(function() {
466								this._contentLoading();
467							}, this));
468						} else {
469							this._callAnim('showLoad', $.proxy(function() {
470								this._contentLoading();
471							}, this));
472						}
473					}
474				}
475			},
476
477			// Write the content in the modal.
478			// Content comes from the hidden div, scripts and eventually close button.
479			_writeContent: function() {
480				this.elts.cont
481					.empty()
482					.append(this.elts.hidden.contents())
483					.append(this._scripts)
484					.append(this.showCloseButton ? this.closeButton : '')
485					.css({
486						position: 'fixed',
487						width: this.sizes.w,
488						height: this.sizes.h,
489						top: (this.getInternal().fullSize.viewH - this.sizes.h - this.sizes.hMargin)/2,
490						left: (this.getInternal().fullSize.viewW - this.sizes.w - this.sizes.wMargin)/2
491					});
492			},
493
494			// Reposition elements with a class nmReposition
495			_reposition: function() {
496				var elts = this.elts.cont.find('.nmReposition');
497				if (elts.length) {
498					var space = this.getInternal()._getSpaceReposition();
499					elts.each(function() {
500						var me = $(this),
501							offset = me.offset();
502						me.css({
503							position: 'fixed',
504							top: offset.top - space.top,
505							left: offset.left - space.left
506						});
507					});
508					this.elts.cont.after(elts);
509				}
510				this.elts.cont.css('overflow', 'auto');
511				this._callFilters('afterReposition');
512			},
513
514			// Unreposition elements with a class nmReposition
515			// Exaclty the reverse of the _reposition function
516			_unreposition: function() {
517				this.elts.cont.css('overflow', '');
518				var elts = this.elts.all.find('.nmReposition');
519				if (elts.length)
520					this.elts.cont.append(elts.removeAttr('style'));
521				this._callFilters('afterUnreposition');
522			}
523		},
524		_internal = {
525			firstInit: true,
526			debug: false,
527			stack: [],
528			fullSize: {
529				w: 0,
530				h: 0,
531				wW: 0,
532				wH: 0,
533				viewW: 0,
534				viewH: 0
535			},
536			nyroModal: function(opts, fullObj) {
537				if (_internal.firstInit) {
538					_internal._container = $('<div />').appendTo($b);
539					$w.smartresize($.proxy(_internal._resize, _internal));
540					$d.bind('keydown.nyroModal', $.proxy(_internal._keyHandler, _internal));
541					_internal._calculateFullSize();
542					_internal.firstInit = false;
543				}
544				return this.nmInit(opts, fullObj).each(function() {
545					_internal._init($(this).data('nmObj'));
546				});
547			},
548			nmInit: function(opts, fullObj) {
549				return this.each(function() {
550					var me = $(this);
551					if (fullObj)
552						me.data('nmObj', $.extend(true, {opener: me}, opts));
553					else
554						me.data('nmObj',
555							me.data('nmObj')
556								? $.extend(true, me.data('nmObj'), opts)
557								: $.extend(true, {opener: me}, _nmObj, opts));
558				});
559			},
560			nmCall: function() {
561				return this.trigger('nyroModal');
562			},
563
564			nmManual: function(url, opts) {
565				$('<a href="'+url+'"></a>').nyroModal(opts).trigger('nyroModal');
566			},
567			nmData: function(data, opts) {
568				this.nmManual('#', $.extend({data: data}, opts));
569			},
570			nmObj: function(opts) {
571				$.extend(true, _nmObj, opts);
572			},
573			nmInternal: function(opts) {
574				$.extend(true, _internal, opts);
575			},
576			nmAnims: function(opts) {
577				$.extend(true, _animations, opts);
578			},
579			nmFilters: function(opts) {
580				$.extend(true, _filters, opts);
581			},
582			nmTop: function() {
583				if (_internal.stack.length)
584					return _internal.stack[_internal.stack.length-1]['nmObj'];
585				return undefined;
586			},
587
588			_debug: function(msg) {
589				if (this.debug && window.console && window.console.log)
590					window.console.log(msg);
591			},
592
593			_container: undefined,
594
595			_init: function(nm) {
596				nm.filters = [];
597				$.each(_filters, function(f, obj) {
598					if (obj.is && $.isFunction(obj.is) && obj.is(nm)) {
599						nm.filters.push(f);
600					}
601				});
602				nm._callFilters('initFilters');
603				nm._callFilters('init');
604				nm.opener
605					.unbind('nyroModal.nyroModal nmClose.nyroModal nmResize.nyroModal')
606					.bind({
607						'nyroModal.nyroModal': 	function(e) { nm.open(); return false;},
608						'nmClose.nyroModal': 	function() { nm.close(); return false;},
609						'nmResize.nyroModal': 	function() { nm.resize(); return false;}
610					});
611			},
612
613			_scrollWidth: (function() {
614				var scrollbarWidth;
615				if ($.browser.msie) {
616					var $textarea1 = $('<textarea cols="10" rows="2"></textarea>')
617							.css({ position: 'absolute', top: -1000, left: -1000 }).appendTo($b),
618						$textarea2 = $('<textarea cols="10" rows="2" style="overflow: hidden;"></textarea>')
619							.css({ position: 'absolute', top: -1000, left: -1000 }).appendTo($b);
620					scrollbarWidth = $textarea1.width() - $textarea2.width();
621					$textarea1.add($textarea2).remove();
622				} else {
623					var $div = $('<div />')
624						.css({ width: 100, height: 100, overflow: 'auto', position: 'absolute', top: -1000, left: -1000 })
625						.prependTo($b).append('<div />').find('div')
626							.css({ width: '100%', height: 200 });
627					scrollbarWidth = 100 - $div.width();
628					$div.parent().remove();
629				}
630				return scrollbarWidth;
631			})(),
632
633			_selNyroModal: function(obj) {
634				return $(obj).data('nmObj') ? true : false;
635			},
636
637			_selNyroModalOpen: function(obj) {
638				var me = $(obj);
639				return me.data('nmObj') ? me.data('nmObj')._open : false;
640			},
641
642			_keyHandler: function(e) {
643				var nmTop = $.nmTop();
644				if (nmTop && nmTop.useKeyHandler) {
645					return nmTop.keyHandle(e);
646				}
647			},
648			_pushStack: function(obj) {
649				this.stack = $.map(this.stack, function(elA) {
650					if (elA['nmOpener'] != obj.get(0))
651						return elA;
652				});
653				this.stack.push({
654					nmOpener: obj.get(0),
655					nmObj: $(obj).data('nmObj')
656				});
657			},
658			_removeStack: function(obj) {
659				this.stack = $.map(this.stack, function(elA) {
660					if (elA['nmOpener'] != obj.get(0))
661						return elA;
662				});
663			},
664			_resize: function() {
665				var opens = $(':nmOpen').each(function() {
666					$(this).data('nmObj')._unreposition();
667				});
668				this._calculateFullSize();
669				opens.trigger('nmResize');
670			},
671			_calculateFullSize: function() {
672				this.fullSize = {
673					w: $d.width(),
674					h: $d.height(),
675					wW: $w.width(),
676					wH: $w.height()
677				};
678				this.fullSize.viewW = Math.min(this.fullSize.w, this.fullSize.wW);
679				this.fullSize.viewH = Math.min(this.fullSize.h, this.fullSize.wH);
680			},
681			_getCurCSS: function(elm, name) {
682				var ret = parseInt($.curCSS(elm, name, true));
683				return isNaN(ret) ? 0 : ret;
684			},
685			_getOuter: function(elm) {
686				elm = elm.get(0);
687				var ret = {
688					h: {
689						margin: this._getCurCSS(elm, 'marginTop') + this._getCurCSS(elm, 'marginBottom'),
690						border: this._getCurCSS(elm, 'borderTopWidth') + this._getCurCSS(elm, 'borderBottomWidth'),
691						padding: this._getCurCSS(elm, 'paddingTop') + this._getCurCSS(elm, 'paddingBottom')
692					},
693					w: {
694						margin: this._getCurCSS(elm, 'marginLeft') + this._getCurCSS(elm, 'marginRight'),
695						border: this._getCurCSS(elm, 'borderLeftWidth') + this._getCurCSS(elm, 'borderRightWidth'),
696						padding: this._getCurCSS(elm, 'paddingLeft') + this._getCurCSS(elm, 'paddingRight')
697					}
698				};
699
700				ret.h.outer = ret.h.margin + ret.h.border;
701				ret.w.outer = ret.w.margin + ret.w.border;
702
703				ret.h.inner = ret.h.padding + ret.h.border;
704				ret.w.inner = ret.w.padding + ret.w.border;
705
706				ret.h.total = ret.h.outer + ret.h.padding;
707				ret.w.total = ret.w.outer + ret.w.padding;
708
709				return ret;
710			},
711			_getSpaceReposition: function() {
712				var	outer = this._getOuter($b),
713					ie7 = $.browser.msie && $.browser.version < 8 && !(screen.height <= $
713w.height()+23);
714				return {
715					top: $w.scrollTop() - (!ie7 ? outer.h.border / 2 : 0),
716					left: $w.scrollLeft() - (!ie7 ? outer.w.border / 2 : 0)
717				};
718			},
719
720			_getHash: function(url) {
721				if (typeof url == 'string') {
722					var hashPos = url.indexOf('#');
723					if (hashPos > -1)
724						return url.substring(hashPos);
725				}
726				return '';
727			},
728			_extractUrl: function(url) {
729				var ret = {
730					url: undefined,
731					sel: undefined
732				};
733
734				if (url) {
735					var hash = this._getHash(url),
736						hashLoc = this._getHash(window.location.href),
737						curLoc = window.location.href.substring(0, window.location.href.length - hashLoc.length),
738						req = url.substring(0, url.length - hash.length);
739					ret.sel = hash;
740					if (req != curLoc && req != baseHref)
741						ret.url = req;
742				}
743				return ret;
744			}
745		},
746		_animations = {
747			basic: {
748				showBg: function(nm, clb) {
749					nm.elts.bg.css({opacity: 0.7}).show();
750					clb();
751				},
752				hideBg: function(nm, clb) {
753					nm.elts.bg.hide();
754					clb();
755				},
756				showLoad: function(nm, clb) {
757					nm.elts.load.show();
758					clb();
759				},
760				hideLoad: function(nm, clb) {
761					nm.elts.load.hide();
762					clb();
763				},
764				showCont: function(nm, clb) {
765					nm.elts.cont.show();
766					clb();
767				},
768				hideCont: function(nm, clb) {
769					nm.elts.cont.hide();
770					clb();
771				},
772				showTrans: function(nm, clb) {
773					nm.elts.cont.hide();
774					nm.elts.load.show();
775					clb();
776				},
777				hideTrans: function(nm, clb) {
778					nm.elts.cont.show();
779					nm.elts.load.hide();
780					clb();
781				},
782				resize: function(nm, clb) {
783					nm.elts.cont.css({
784						width: nm.sizes.w,
785						height: nm.sizes.h,
786						top: (nm.getInternal().fullSize.viewH - nm.sizes.h - nm.sizes.hMargin)/2,
787						left: (nm.getInternal().fullSize.viewW - nm.sizes.w - nm.sizes.wMargin)/2
788					});
789					clb();
790				}
791			}
792		},
793		_filters = {
794			basic: {
795				is: function(nm) {
796					return true;
797				},
798				init: function(nm) {
799					if (nm.opener.attr('rev') == 'modal')
800						nm.modal = true;
801					if (nm.modal)
802						nm.closeOnEscape = nm.closeOnClick = nm.showCloseButton = false;
803					if (nm.closeOnEscape)
804						nm.useKeyHandler = true;
805				},
806				initElts: function(nm) {
807					nm.elts.bg.addClass('nyroModalBg');
808					if (nm.closeOnClick)
809						nm.elts.bg.unbind('click.nyroModal').bind('click.nyroModal', function(e) {
810							e.preventDefault();
811							nm.close();
812						});
813					nm.elts.cont.addClass('nyroModalCont');
814					nm.elts.hidden.addClass('nyroModalCont nyroModalHidden');
815					nm.elts.load.addClass('nyroModalCont nyroModalLoad');
816				},
817				error: function(nm) {
818					nm.elts.hidden.addClass('nyroModalError');
819					nm.elts.cont.addClass('nyroModalError');
820					nm._setCont(nm.errorMsg);
821				},
822				beforeShowCont: function(nm) {
823					nm.elts.cont
824						.find('.nyroModal').each(function() {
825							var cur = $(this);
826							cur.nyroModal(nm.getForNewLinks(cur), true);
827						}).end()
828						.find('.nyroModalClose').bind('click.nyroModal', function(e) {
829							e.preventDefault();
830							nm.close();
831						});
832				},
833				keyHandle: function(nm) {
834					// used for escape key
835					if (nm.keyEvent.keyCode == 27 && nm.closeOnEscape) {
836						nm.keyEvent.preventDefault();
837						nm.close();
838					}
839				}
840			},
841
842			custom: {
843				is: function(nm) {
844					return true;
845				}
846			}
847		};
848
849	// Add jQuery call fucntions
850	$.fn.extend({
851		nm: _internal.nyroModal,
852		nyroModal: _internal.nyroModal,
853		nmInit: _internal.nmInit,
854		nmCall: _internal.nmCall
855	});
856
857	// Add global jQuery functions
858	$.extend({
859		nmManual: _internal.nmManual,
860		nmData: _internal.nmData,
861		nmObj: _internal.nmObj,
862		nmInternal: _internal.nmInternal,
863		nmAnims: _internal.nmAnims,
864		nmFilters: _internal.nmFilters,
865		nmTop: _internal.nmTop
866	});
867
868	// Add jQuery selectors
869	$.expr[':'].nyroModal = $.expr[':'].nm = _internal._selNyroModal;
870	$.expr[':'].nmOpen = _internal._selNyroModalOpen;
871});
872
873// Smartresize plugin
874(function($,sr){
875
876  // debouncing function from John Hann
877  // http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
878  var debounce = function (func, threshold, execAsap) {
879      var timeout;
880
881      return function debounced () {
882          var obj = this, args = arguments;
883          function delayed () {
884              if (!execAsap)
885                  func.apply(obj, args);
886              timeout = null;
887          };
888
889          if (timeout)
890              clearTimeout(timeout);
891          else if (execAsap)
892              func.apply(obj, args);
893
894          timeout = setTimeout(delayed, threshold || 100);
895      };
896  };
897	// smartresize
898	jQuery.fn[sr] = function(fn){  return fn ? this.bind('resize', debounce(fn)) : this.trigger(sr); };
899
900})(jQuery,'smartresize');
901// ucFirst
902function ucfirst(str) {
903    // http://kevin.vanzonneveld.net
904    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
905    // +   bugfixed by: Onno Marsman
906    // +   improved by: Brett Zamir (http://brett-zamir.me)
907    // *     example 1: ucfirst('kevin van zonneveld');
908    // *     returns 1: 'Kevin van zonneveld'
909    str += '';
910    var f = str.charAt(0).toUpperCase();
911    return f + str.substr(1);
912}
913/*
914 * nyroModal v2.0.0
915 * 
916 * Fade animations
917 * 
918 * Depends:
919 * 
920 */
921jQuery(function($, undefined) {
922	$.nmAnims({
923		fade: {
924			showBg: function(nm, clb) {
925				nm.elts.bg.fadeTo(250, 0.7, clb);
926			},
927			hideBg: function(nm, clb) {
928				nm.elts.bg.fadeOut(clb);
929			},
930			showLoad: function(nm, clb) {
931				nm.elts.load.fadeIn(clb);
932			},
933			hideLoad: function(nm, clb) {
934				nm.elts.load.fadeOut(clb);
935			},
936			showCont: function(nm, clb) {
937				nm.elts.cont.fadeIn(clb);
938			},
939			hideCont: function(nm, clb) {
940				nm.elts.cont.css('overflow', 'hidden').fadeOut(clb);
941			},
942			showTrans: function(nm, clb) {
943				nm.elts.load
944					.css({
945						position: nm.elts.cont.css('position'),
946						top: nm.elts.cont.css('top'),
947						left: nm.elts.cont.css('left'),
948						width: nm.elts.cont.css('width'),
949						height: nm.elts.cont.css('height'),
950						marginTop: nm.elts.cont.css('marginTop'),
951						marginLeft: nm.elts.cont.css('marginLeft')
952					})
953					.fadeIn(function() {
954						nm.elts.cont.hide();
955						clb();
956					});
957			},
958			hideTrans: function(nm, clb) {
959				nm.elts.cont.css('visibility', 'hidden').show();
960				nm.elts.load
961					.css('position', nm.elts.cont.css('position'))
962					.animate({
963						top: nm.elts.cont.css('top'),
964						left: nm.elts.cont.css('left'),
965						width: nm.elts.cont.css('width'),
966						height: nm.elts.cont.css('height'),
967						marginTop: nm.elts.cont.css('marginTop'),
968						marginLeft: nm.elts.cont.css('marginLeft')
969					}, function() {
970						nm.elts.cont.css('visibility', '');
971						nm.elts.load.fadeOut(clb);
972					});
973			},
974			resize: function(nm, clb) {
975				nm.elts.cont.animate({
976					width: nm.sizes.w,
977					height: nm.sizes.h,
978					top: (nm.getInternal().fullSize.viewH - nm.sizes.h - nm.sizes.hMargin)/2,
979					left: (nm.getInternal().fullSize.viewW - nm.sizes.w - nm.sizes.wMargin)/2
980				}, clb);
981			}
982		}
983	});
984	// Define fade aniamtions as default
985	$.nmObj({anim: {def: 'fade'}});
986});
987/*
988 * nyroModal v2.0.0
989 * 
990 * Title filter
991 * 
992 * Depends:
993 * 
994 * Before:
995 */
996jQuery(function($, undefined) {
997	$.nmFilters({
998		title: {
999			is: function(nm) {
1000				return nm.opener.is('[title]');
1001			},
1002			beforeShowCont: function(nm) {
1003				var offset = nm.elts.cont.offset();
1004				nm.store.title = $('<h1 />', {
1005					text: nm.opener.attr('title')
1006				}).addClass('nyroModalTitle nmReposition');
1007				nm.elts.cont.prepend(nm.store.title);
1008			},
1009			close: function(nm) {
1010				if (nm.store.title) {
1011					nm.store.title.remove();
1012					nm.store.title = undefined;
1013					delete(nm.store.title);
1014				}
1015			}
1016		}
1017	});
1018});
1019/*
1020 * nyroModal v2.0.0
1021 * 
1022 * Gallery filter
1023 * 
1024 * Depends:
1025 * - filters.title
1026 * 
1027 * Before: filters.title
1028 */
1029jQuery(function($, undefined) {
1030	$.nmFilters({
1031		gallery: {
1032			is: function(nm) {
1033				var ret = nm.opener.is('[rel]:not([rel=external], [rel=nofollow])');
1034				if (ret) {
1035					var rel = nm.opener.attr('rel'),
1036						indexSpace = rel.indexOf(' '),
1037						gal = indexSpace > 0 ? rel.substr(0, indexSpace) : rel,
1038						links = $('[href][rel="'+gal+'"], [href][rel^="'+gal+' "]');
1039					if (links.length < 2)
1040						ret = false;
1041					if (ret && nm.galleryCounts && !nm._hasFilter('title'))
1042						nm.filters.push('title');
1043				}
1044				return ret;
1045			},
1046			init: function(nm) {
1047				nm.useKeyHandler = true;
1048			},
1049			keyHandle: function(nm) {
1050				// used for arrows key
1051				if (!nm._animated && nm._opened) {
1052					if (nm.keyEvent.keyCode == 39 || nm.keyEvent.keyCode == 40) {
1053						nm.keyEvent.preventDefault();
1054						nm._callFilters('galleryNext');
1055					} else if (nm.keyEvent.keyCode == 37 || nm.keyEvent.keyCode == 38) {
1056						nm.keyEvent.preventDefault();
1057						nm._callFilters('galleryPrev');
1058					}
1059				}
1060			},
1061			initElts: function(nm) {
1062				var rel = nm.opener.attr('rel'),
1063					indexSpace = rel.indexOf(' ');
1064				nm.store.gallery = indexSpace > 0 ? rel.substr(0, indexSpace) : rel;
1065				nm.store.galleryLinks = $('[href][rel="'+nm.store.gallery+'"], [href][rel^="'+nm.store.gallery+' "]');
1066				nm.store.galleryIndex = nm.store.galleryLinks.index(nm.opener);
1067			},
1068			beforeShowCont: function(nm) {
1069				if (nm.galleryCounts && nm.store.title && nm.store.galleryLinks && nm.store.galleryLinks.length > 1) {
1070					var curTitle = nm.store.title.html();
1071					nm.store.title.html((curTitle.length ? curTitle+' - ' : '')+(nm.store.galleryIndex+1)+'/'+nm.store.galleryLinks.length);
1072				}
1073			},
1074			filledContent: function(nm) {
1075				var link = this._getGalleryLink(nm, -1),
1076					append = nm.elts.hidden.find(' > div');
1077				if (link) {
1078					$('<a />', {
1079							text: 'previous',
1080							href: '#'
1081						})
1082						.addClass('nyroModalPrev')
1083						.bind('click', function(e) {
1084							e.preventDefault();
1085							nm._callFilters('galleryPrev');
1086						})
1087						.appendTo(append);
1088				}
1089				link = this._getGalleryLink(nm, 1);
1090				if (link) {
1091					$('<a />', {
1092							text: 'next',
1093							href: '#'
1094						})
1095						.addClass('nyroModalNext')
1096						.bind('click', function(e) {
1097							e.preventDefault();
1098							nm._callFilters('galleryNext');
1099						})
1100						.appendTo(append);
1101				}
1102			},
1103			close: function(nm) {
1104				nm.store.gallery = undefined;
1105				nm.store.galleryLinks = undefined;
1106				nm.store.galleryIndex = undefined;
1107				delete(nm.store.gallery);
1108				delete(nm.store.galleryLinks);
1109				delete(nm.store.galleryIndex);
1110				if (nm.elts.cont)
1111					nm.elts.cont.find('.nyroModalNext, .nyroModalPrev').remove();
1112			},
1113			galleryNext: function(nm) {
1114				this._getGalleryLink(nm, 1).nyroModal(nm.getForNewLinks(), true).click();
1115			},
1116			galleryPrev: function(nm) {
1117				this._getGalleryLink(nm, -1).nyroModal(nm.getForNewLinks(), true).click();
1118			},
1119			_getGalleryLink: function(nm, dir) {
1120				if (nm.store.gallery) {
1121					if (!nm.ltr)
1122						dir *= -1;
1123					var index = nm.store.galleryIndex + dir;
1124					if (nm.store.galleryLinks && index >= 0 && index < nm.store.galleryLinks.length)
1125						return nm.store.galleryLinks.eq(index);
1126					else if (nm.galleryLoop && nm.store.galleryLinks)
1127						return nm.store.galleryLinks.eq(index<0 ? nm.store.galleryLinks.length-1 : 0);
1128				}
1129				return undefined;
1130			}
1131		}
1132	});
1133});
1134/*
1135 * nyroModal v2.0.0
1136 * 
1137 * Link filter
1138 * 
1139 * Depends:
1140 * 
1141 * Before: filters.gallery
1142 */
1143jQuery(function($, undefined) {
1144	$.nmFilters({
1145		link: {
1146			is: function(nm) {
1147				var ret = nm.opener.is('[href]');
1148				if (ret)
1149					nm.store.link = nm.getInternal()._extractUrl(nm.opener.attr('href'));
1150				return ret;
1151			},
1152			init: function(nm) {
1153				nm.loadFilter = 'link';
1154				nm.opener.unbind('click.nyroModal').bind('click.nyroModal', function(e) {
1155					e.preventDefault();
1156					nm.opener.trigger('nyroModal');
1157				});
1158			},
1159			load: function(nm) {
1160				$.ajax({
1161					url: nm.store.link.url,
1162					data: nm.store.link.sel ? [{name: nm.selIndicator, value: nm.store.link.sel.substring(1)}] : undefined,
1163					success: function(data) {
1164						nm._setCont(data, nm.store.link.sel);
1165					},
1166					error: function() {
1167						nm._error();
1168					}
1169				});
1170			}
1171		}
1172	});
1173});
1174/*
1175 * nyroModal v2.0.0
1176 * 
1177 * Dom filter
1178 * 
1179 * Depends:
1180 * - filters.link
1181 * 
1182 * Before: filters.link
1183 */
1184jQuery(function($, undefined) {
1185	$.nmFilters({
1186		dom: {
1187			is: function(nm) {
1188				return nm._hasFilter('link') && !nm.store.link.url && nm.store.link.sel;
1189			},
1190			init: function(nm) {
1191				nm.loadFilter = 'dom';
1192			},
1193			load: function(nm) {
1194				nm.store.domEl = $(nm.store.link.sel);
1195				if (nm.store.domEl.length)
1196					nm._setCont(nm.store.domEl.contents());
1197				else
1198					nm._error();
1199			},
1200			close: function(nm) {
1201				if (nm.store.domEl && nm.elts.cont)
1202					nm.store.domEl.append(nm.elts.cont.find('.nyroModalDom').contents());
1203			}
1204		}
1205	});
1206});
1207/*
1208 * nyroModal v2.0.0
1209 * 
1210 * Data filter
1211 * 
1212 * Depends:
1213 * - filters.link
1214 * 
1215 * Before: filters.dom
1216 */
1217jQuery(function($, undefined) {
1218	$.nmFilters({
1219		data: {
1220			is: function(nm) {
1221				var ret = nm.data ? true : false;
1222				if (ret) {
1223					nm._delFilter('dom');
1224				}
1225				return ret;
1226			},
1227			init: function(nm) {
1228				nm.loadFilter = 'data';
1229			},
1230			load: function(nm) {
1231				nm._setCont(nm.data);
1232			}
1233		}
1234	});
1235});
1236/*
1237 * nyroModal v2.0.0
1238 * 
1239 * Form file filter
1240 * 
1241 * Depends:
1242 * 
1243 * Before: filters.form
1244 */
1245jQuery(function($, undefined) {
1246	$.nmFilters({
1247		formFile: {
1248			is: function(nm) {
1249				var ret = nm.opener.is('form[enctype="multipart/form-data"]');
1250				if (ret) {
1251					nm._delFilter('form');
1252					if (!nm.store.form)
1253						nm.store.form = nm.getInternal()._extractUrl(nm.opener.attr('action'));
1254				}
1255				return ret;
1256			},
1257			init: function(nm) {
1258				nm.loadFilter = 'formFile';
1259				nm.store.formFileLoading = false;
1260				nm.opener.unbind('submit.nyroModal').bind('submit.nyroModal', function(e) {
1261					if (!nm.store.formFileIframe) {
1262						e.preventDefault();
1263						nm.opener.trigger('nyroModal');
1264					} else {
1265						nm.store.formFileLoading = true;
1266					}
1267				});
1268			},
1269			initElts: function(nm) {
1270				var inputSel;
1271				if (nm.store.form.sel)
1272					inputSel = $('<input />', {
1273						'type': 'hidden',
1274						name: nm.selIndicator,
1275						value: nm.store.form.sel.substring(1)
1276					}).appendTo(nm.opener);
1277				function rmFormFileElts() {
1278					if (inputSel) {
1279						inputSel.remove();
1280						inputSel = undefined;
1281						delete(inputSel);
1282					}
1283					nm.store.formFileIframe.attr('src', 'about:blank').remove();
1284					nm.store.formFileIframe = undefined;
1285					delete(nm.store.formFileIframe);
1286				}
1287				nm.store.formFileIframe = $('<iframe name="nyroModalFormFile" src="javascript:\'\';" id="nyromodal-iframe-'+(new Date().getTime())+'"></iframe>')
1288					.hide()
1289					.load(function() {
1290						if (nm.store.formFileLoading) {
1291							nm.store.formFileLoading = false;
1292							var content = nm.store.formFileIframe
1293									.unbind('load error')
1294									.contents().find('body').not('script[src]');
1295							if (content && content.html() && content.html().length) {
1296								rmFormFileElts();
1297								nm._setCont(content.html(), nm.store.form.sel);
1298							} else {
1299								// Not totally ready, try it in a few secs
1300								var nbTry = 0;
1301									fct = function() {
1302										nbTry++;
1303										var content = nm.store.formFileIframe
1304												.unbind('load error')
1305												.contents().find('body').not('script[src]');
1306										if (content && content.html() && content.html().length) {
1307											nm._setCont(content.html(), nm.store.form.sel);
1308											rmFormFileElts();
1309										} else if (nbTry < 5) {
1310											setTimeout(fct, 25);
1311										} else {
1312											rmFormFileElts();
1313											nm._error();
1314										}
1315									};
1316								setTimeout(fct, 25);
1317							}
1318						}
1319					})
1320					.error(function() {
1321						rmFormFileElts();
1322						nm._error();
1323					});
1324				nm.elts.all.append(nm.store.formFileIframe);
1325				nm.opener
1326					.attr('target', 'nyroModalFormFile')
1327					.submit();
1328			},
1329			close: function(nm) {
1330				nm.store.formFileLoading = false;
1331				if (nm.store.formFileIframe) {
1332					nm.store.formFileIframe.remove();
1333					nm.store.formFileIframe = undefined;
1334					delete(nm.store.formFileIframe);
1335				}
1336			}
1337		}
1338	});
1339});

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