Index: /sandbox/2.4.1-3/services/class.db.php
===================================================================
--- /sandbox/2.4.1-3/services/class.db.php	(revision 5842)
+++ /sandbox/2.4.1-3/services/class.db.php	(revision 6512)
@@ -263,4 +263,5 @@
 		$query = 'select'
 						. ' G.oid,'
+						. ' G.id_group,'
 						. ' G.title,'
 						. ' G.short_name';
@@ -288,4 +289,5 @@
 				$all_contacts[ $object[ 'oid' ] ]['title'] = $object['title'];
 				$all_contacts[ $object[ 'oid' ] ]['short_name'] = $object['short_name'];
+				$all_contacts[ $object[ 'oid' ] ]['id'] = $object[ 'id_group' ];
 		}
 		return array_values($all_contacts);
Index: /sandbox/2.4.1-3/prototype/plugins/jq-raty/test/runner.htm
===================================================================
--- /sandbox/2.4.1-3/prototype/plugins/jq-raty/test/runner.htm	(revision 6512)
+++ /sandbox/2.4.1-3/prototype/plugins/jq-raty/test/runner.htm	(revision 6512)
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+
+<html>
+	<head>
+		<title>jQuery Test Runner</title>
+
+		<link rel="stylesheet" type="text/css" href="lib/jasmine.css">
+		
+		<script type="text/javascript" charset="utf-8" src="../js/jquery.min.js"></script>
+		<script type="text/javascript" charset="utf-8" src="../js/jquery.raty.js"></script>
+
+		<script type="text/javascript" charset="utf-8" src="lib/jasmine.js"></script>
+		<script type="text/javascript" charset="utf-8" src="lib/jasmine-html.js"></script>
+		<script type="text/javascript" charset="utf-8" src="lib/jasmine-jquery.js"></script>
+	</head>
+	<body>
+		<script type="text/javascript">
+		describe('', function() {
+
+			beforeEach(function() {
+			    $('body').append('<div id="star"></div><div class="star">1</div><div class="star">2</div><div class="star">3</div>');
+			});
+
+			it ('[score / readOnly] should not set score when it is read-only', function() {
+				// given
+				var star = $('#star').raty({ readOnly: true });
+
+				// when
+				star.raty('score', 1);
+
+				// then
+				var imgs = star.children('img');
+
+				expect(imgs.eq(0)).toHaveAttr('src', 'img/star-off.png');
+				expect(imgs.eq(1)).toHaveAttr('src', 'img/star-off.png');
+				expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+				expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+				expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+			});
+
+		});
+
+			jasmine.getEnv().addReporter(new jasmine.TrivialReporter());
+			jasmine.getEnv().execute();
+		</script>
+	</body>
+</html>
Index: /sandbox/2.4.1-3/prototype/plugins/jq-raty/test/spec.js
===================================================================
--- /sandbox/2.4.1-3/prototype/plugins/jq-raty/test/spec.js	(revision 6512)
+++ /sandbox/2.4.1-3/prototype/plugins/jq-raty/test/spec.js	(revision 6512)
@@ -0,0 +1,2993 @@
+describe('Using ID', function() {
+
+	beforeEach(function() {
+		$('body').append('<div id="star"></div>');
+	});
+
+	afterEach(function() {
+		$('#star').remove();
+	});
+
+	it ('should chainable', function() {
+		// given
+		var star		= $('#star'),
+			className	= 'my-class';
+
+		// when
+		star.raty().addClass(className);
+
+		// then
+	    expect(star).toHaveClass(className);
+	});
+
+	it ('should change the path', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ path: '../img' });
+
+		var imgs = star.children('img');
+
+		// then
+	    expect(imgs.eq(0)).toHaveAttr('src', '../img/star-off.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', '../img/star-off.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', '../img/star-off.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', '../img/star-off.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', '../img/star-off.png');
+	});
+
+	it ('should create the default stars', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty();
+
+		var imgs = star.children('img');
+
+		// then
+	    expect(imgs.eq(0)).toHaveAttr('title', 'bad');
+	    expect(imgs.eq(1)).toHaveAttr('title', 'poor');
+	    expect(imgs.eq(2)).toHaveAttr('title', 'regular');
+	    expect(imgs.eq(3)).toHaveAttr('title', 'good');
+	    expect(imgs.eq(4)).toHaveAttr('title', 'gorgeous');
+
+	    expect(imgs.eq(0)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+	    expect(star.children('input').val()).toEqual('');
+	});
+
+	it ('should create 7 stars', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ number: 7 });
+
+		var imgs = star.children('img');
+
+		// then
+	    expect(imgs.eq(0)).toHaveAttr('title', 'bad');
+	    expect(imgs.eq(1)).toHaveAttr('title', 'poor');
+	    expect(imgs.eq(2)).toHaveAttr('title', 'regular');
+	    expect(imgs.eq(3)).toHaveAttr('title', 'good');
+	    expect(imgs.eq(4)).toHaveAttr('title', 'gorgeous');
+	    expect(imgs.eq(5)).toHaveAttr('title', '6');
+	    expect(imgs.eq(6)).toHaveAttr('title', '7');
+
+	    expect(imgs.eq(0)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(5)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(6)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should create the score field', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty();
+
+		var $score = star.children('input');
+
+		// then
+	    expect($score).toHaveAttr('type', 'hidden');
+	    expect($score).toHaveAttr('name', 'score');
+	    expect($score).toHaveValue(0);
+	});
+
+	it ('should create a custom score name field', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ scoreName: 'entity.score' });
+
+		var $score = star.children('input');
+
+		// then
+		expect($score).toHaveAttr('type', 'hidden');
+		expect($score).toHaveAttr('name', 'entity.score');
+		expect($score).toHaveValue(0);
+	});
+
+	it ('should start readOnly with not rated yet message', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ readOnly: true });
+
+		var imgs = star.children('img');
+
+		// then
+	    expect(imgs.eq(0)).toHaveAttr('title', 'not rated yet');
+	    expect(imgs.eq(1)).toHaveAttr('title', 'not rated yet');
+	    expect(imgs.eq(2)).toHaveAttr('title', 'not rated yet');
+	    expect(imgs.eq(3)).toHaveAttr('title', 'not rated yet');
+	    expect(imgs.eq(4)).toHaveAttr('title', 'not rated yet');
+	});
+
+	it ('should be started with 3 stars', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ score: 3 });
+
+		var imgs = star.children('img');
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should be started with 3 stars and readOnly', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ readOnly: true, score: 3});
+
+		var imgs = star.children('img');
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('title', 'regular');
+	    expect(imgs.eq(1)).toHaveAttr('title', 'regular');
+	    expect(imgs.eq(2)).toHaveAttr('title', 'regular');
+	    expect(imgs.eq(3)).toHaveAttr('title', 'regular');
+	    expect(imgs.eq(4)).toHaveAttr('title', 'regular');
+
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should be hovered 2 stars', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty();
+
+		var imgs = star.children('img');
+
+		imgs.eq(1).mouseover();
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should be clicked 2 stars', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty();
+
+		var imgs = star.children('img');
+
+		imgs.eq(1).mouseover().click().mouseleave();
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+		expect(star.children('input')).toHaveValue(2);
+	});
+
+	it ('should not be hovered with readOnly', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ readOnly: true });
+
+		var imgs = star.children('img');
+
+		imgs.eq(1).mouseover();
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should not be clicked with readOnly', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ readOnly: true });
+
+		var imgs = star.children('img');
+
+		imgs.eq(1).mouseover().click().mouseleave();
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+		expect(star.children('input').val()).toEqual('');
+	});
+
+	it ('should execute click callback', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({
+			click: function(score, evt) {
+				$(this).attr('title', score);
+			}
+		});
+
+		star.children('img').eq(3).mouseover().click().mouseleave();
+
+		// then
+		expect(star).toHaveAttr('title', 4);
+	});
+
+	it ('should have this as self element', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({
+			click: function(score, evt) {
+				$(this).attr('title', score);
+			}
+		});
+
+		star.children('img').eq(3).mouseover().click().mouseleave();
+
+		// then
+		expect(star).toHaveAttr('title', 4);
+	});
+
+	it ('should create default cancel button', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ cancel: true });
+
+		var cancel = star.children('img:first');
+		
+		// then
+		expect(cancel).toHaveClass('raty-cancel');
+		expect(cancel).toHaveAttr('title', 'cancel this rating!');
+		expect(cancel).toHaveAttr('alt', 'x');
+		expect(cancel).toHaveAttr('src', 'img/cancel-off.png');
+	});
+
+	it ('should change cancel off button', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ cancel: true, cancelOff: 'new-cancel-off.png' });
+
+		var cancel = star.children('img:first');
+
+		// then
+		expect(cancel).toHaveClass('raty-cancel');
+		expect(cancel).toHaveAttr('title', 'cancel this rating!');
+		expect(cancel).toHaveAttr('alt', 'x');
+		expect(cancel).toHaveAttr('src', 'img/new-cancel-off.png');
+	});
+
+	it ('should change cancel on button', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ cancel: true, cancelOn: 'new-cancel-on.png' });
+
+		var cancel = star.children('img:first').mouseenter();
+
+		// then
+		expect(cancel).toHaveClass('raty-cancel');
+		expect(cancel).toHaveAttr('title', 'cancel this rating!');
+		expect(cancel).toHaveAttr('alt', 'x');
+		expect(cancel).toHaveAttr('src', 'img/new-cancel-on.png');
+	});
+
+	it ('should change cancel hint', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ cancel: true, cancelHint: 'my-hint' });
+
+		var cancel = star.children('img:first').mouseenter();
+
+		// then
+		expect(cancel).toHaveAttr('title', 'my-hint');
+	});
+
+	it ('should turn off the stars on mouseover on cancel button', function() {
+		// given
+		var star	= $('#star').raty({ score: 3, cancel: true }),
+			imgs	= star.children('img');
+		
+		// when
+		star.children('img:first').mouseenter();
+
+		// then
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(5)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should display noRatedMsg when readOnly', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ readOnly: true });
+
+		// then
+		var imgs = star.children('img');
+
+		expect(imgs.eq(0)).toHaveAttr('title', 'not rated yet');
+		expect(imgs.eq(1)).toHaveAttr('title', 'not rated yet');
+		expect(imgs.eq(2)).toHaveAttr('title', 'not rated yet');
+		expect(imgs.eq(3)).toHaveAttr('title', 'not rated yet');
+		expect(imgs.eq(4)).toHaveAttr('title', 'not rated yet');
+	});
+
+	it ('should cancel the rating', function() {
+		// given
+		var star	= $('#star').raty({ score: 5, cancel: true }),
+			imgs	= star.children('img');
+
+		// when
+		star.children('img:first').mouseover().click().mouseleave();
+
+		// then
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(5)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should create right cancel button', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ cancel: true, cancelPlace: 'right' });
+
+		var cancel = star.children('img:last');
+
+		// then
+		expect(cancel).toHaveClass('raty-cancel');
+		expect(cancel).toHaveAttr('title', 'cancel this rating!');
+		expect(cancel).toHaveAttr('alt', 'x');
+		expect(cancel).toHaveAttr('src', 'img/cancel-off.png');
+	});
+
+	it ('should set hint for cancel button', function() {
+		// given
+		var star	= $('#star'),
+			hint	= 'remove my rating!';
+
+		// when
+		star.raty({ cancel: true, cancelHint: hint });
+
+		var cancel = star.children('img:first');
+
+		// then
+		expect(cancel).toHaveClass('raty-cancel');
+		expect(cancel).toHaveAttr('title', hint);
+		expect(cancel).toHaveAttr('alt', 'x');
+		expect(cancel).toHaveAttr('src', 'img/cancel-off.png');
+	});
+
+	it ('should execute cancel click callback', function() {
+		// given
+		var star = $('#star').raty({ cancel: true, click: function(score, evt) { $(this).attr('title', (score === null)); } });
+
+		// when
+		star.children('img:first').mouseover().click().mouseleave();
+
+		// then
+		expect(star).toHaveAttr('title', 'true');
+		expect(star.children('input').val()).toEqual('');
+	});
+
+	it ('should round down on max limit down with no half and halfShow', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ half: false, halfShow: false, score: 1.5 });
+
+		var imgs = star.children('img');
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should round up on min limit up with no half and halfShow', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ half: false, halfShow: false, score: 1.6 });
+
+		var imgs = star.children('img');
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should round down on max limit down with half and halfShow', function() {
+		// given
+		var star = $('#star');
+		
+		// when
+		star.raty({ half: true, halfShow: true, score: 1.25 });
+		
+		var imgs = star.children('img');
+		
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should show half on min limit half with half and halfShow', function() {
+		// given
+		var star = $('#star');
+		
+		// when
+		star.raty({ half: true, halfShow: true, score: 1.26 });
+		
+		var imgs = star.children('img');
+		
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/star-half.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should show half on max limit half with half and halfShow', function() {
+		// given
+		var star = $('#star');
+		
+		// when
+		star.raty({ half: true, halfShow: true, score: 1.75 });
+		
+		var imgs = star.children('img');
+		
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/star-half.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should show round up on min limit up with half and halfShow', function() {
+		// given
+		var star = $('#star');
+		
+		// when
+		star.raty({ half: true, halfShow: true, score: 1.76 });
+		
+		var imgs = star.children('img');
+		
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should round down on max limit down with half and no halfShow', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ half: true, halfShow: false, score: 1.25 });
+
+		var imgs = star.children('img');
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should round down on min limit half with half and no halfShow', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ half: true, halfShow: false, score: 1.26 });
+
+		var imgs = star.children('img');
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should round up on max limit half with half and no halfShow', function() {
+		// given
+		var star = $('#star');
+		
+		// when
+		star.raty({ half: true, halfShow: false, score: 1.75 });
+		
+		var imgs = star.children('img');
+		
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should round up on min limit up with half and no halfShow', function() {
+		// given
+		var star = $('#star');
+		
+		// when
+		star.raty({ half: true, halfShow: false, score: 1.76 });
+		
+		var imgs = star.children('img');
+		
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should round down on max limit down with no half and halfShow', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ half: false, halfShow: true, score: 1.25 });
+
+		var imgs = star.children('img');
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should show half on min limit half with no half and halfShow', function() {
+		// given
+		var star = $('#star');
+		
+		// when
+		star.raty({ half: false, halfShow: true, score: 1.26 });
+		
+		var imgs = star.children('img');
+		
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/star-half.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should show half on max limit half with no half and halfShow', function() {
+		// given
+		var star = $('#star');
+		
+		// when
+		star.raty({ half: false, halfShow: true, score: 1.75 });
+		
+		var imgs = star.children('img');
+		
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/star-half.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should show round up on min limit up with no half and halfShow', function() {
+		// given
+		var star = $('#star');
+		
+		// when
+		star.raty({ half: false, halfShow: true, score: 1.76 });
+		
+		var imgs = star.children('img');
+		
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should set custom hints', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ hints: ['a', '', null, 'd', '5'] });
+
+		var imgs = star.children('img');
+
+		// then
+	    expect(imgs.eq(0)).toHaveAttr('title', 'a');
+	    expect(imgs.eq(1)).toHaveAttr('title', '');
+	    expect(imgs.eq(2)).toHaveAttr('title', 3);
+	    expect(imgs.eq(3)).toHaveAttr('title', 'd');
+	    expect(imgs.eq(4)).toHaveAttr('title', '5');
+	});
+
+	it ('should change the star off', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ starOff: 'medal-off.png' });
+
+		var imgs = star.children('img');
+
+		// then
+	    expect(imgs.eq(0)).toHaveAttr('src', 'img/medal-off.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/medal-off.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/medal-off.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/medal-off.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/medal-off.png');
+	});
+
+	it ('should change the star on', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ starOn: 'medal-on.png' });
+
+		var imgs = star.children('img');
+
+		imgs.eq(3).mouseover();
+
+		// then
+	    expect(imgs.eq(0)).toHaveAttr('src', 'img/medal-on.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/medal-on.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/medal-on.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/medal-on.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should use range icons', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({
+			iconRange: [
+	            { range: 2, on: 'face-a.png', off: 'face-a-off.png' },
+	            { range: 3, on: 'face-b.png', off: 'face-b-off.png' },
+	            { range: 4, on: 'face-c.png', off: 'face-c-off.png' },
+	            { range: 5, on: 'face-d.png', off: 'face-d-off.png' }
+			]
+		});
+
+		var imgs = star.children('img');
+
+		// then
+	    expect(imgs.eq(0)).toHaveAttr('src', 'img/face-a-off.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/face-a-off.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/face-b-off.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/face-c-off.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/face-d-off.png');
+	});
+
+	it ('should use range icons and apply not found icons default', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({
+			iconRange: [
+	            { range: 2, off: 'face-a-off.png' },
+	            { range: 3, off: 'face-b-off.png' },
+	            { range: 4, on: 'face-c.png', off: 'face-c-off.png' },
+	            { range: 5 }
+			]
+		});
+
+		var imgs = star.children('img');
+
+		imgs.eq(3).mouseover();
+
+		// then
+	    expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/face-c.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should hover range icons', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({
+			iconRange: [
+				{ range: 2, on: 'face-a.png', off: 'face-a-off.png' },
+				{ range: 3, on: 'face-b.png', off: 'face-b-off.png' },
+				{ range: 4, on: 'face-c.png', off: 'face-c-off.png' },
+				{ range: 5, on: 'face-d.png', off: 'face-d-off.png' }
+			],
+            starOff: 'face-off.png'
+		});
+
+		var imgs = star.children('img');
+
+		imgs.eq(4).mouseover();
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/face-a.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/face-a.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/face-b.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/face-c.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/face-d.png');
+	});
+
+	it ('should set off range icons on mouseleave', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({
+			iconRange: [
+				{ range: 2, on: 'face-a.png', off: 'face-a-off.png' },
+				{ range: 3, on: 'face-b.png', off: 'face-b-off.png' },
+				{ range: 4, on: 'face-c.png', off: 'face-c-off.png' },
+				{ range: 5, on: 'face-d.png', off: 'face-d-off.png' },
+			],
+            starOff: 'face-off.png'
+		});
+
+		var imgs = star.children('img');
+
+		imgs.eq(4).mouseover();
+		star.mouseleave();
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/face-a-off.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/face-a-off.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/face-b-off.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/face-c-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/face-d-off.png');
+	});
+
+	it ('should keep the score value range icons on mouseleave', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({
+			iconRange: [
+				{ range: 2, on: 'face-a.png', off: 'face-a-off.png' },
+				{ range: 3, on: 'face-b.png', off: 'face-b-off.png' },
+				{ range: 4, on: 'face-c.png', off: 'face-c-off.png' },
+				{ range: 5, on: 'face-d.png', off: 'face-d-off.png' }
+			],
+            starOff: 'face-off.png',
+            score: 1
+		});
+
+		var imgs = star.children('img');
+
+		imgs.eq(4).mouseover();
+		star.mouseleave();
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/face-a.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/face-a-off.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/face-b-off.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/face-c-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/face-d-off.png');
+	});
+
+	it ('should calculate the right icon size', function() {
+		// given
+		var star	= $('#star'),
+			size	= 24,
+			number	= 5;
+
+		// when
+		star.raty({ size: size });
+
+		// then
+		expect(star.width()).toEqual(number * size + number * 4);
+	});
+
+	it ('should set custom width', function() {
+		// given
+		var star	= $('#star'),
+			size	= 24;
+
+		// when
+		star.raty({ size: size, width: 200 });
+
+		// then
+		expect(star.width()).toEqual(200);
+	});
+
+	it ('should set custom width when readOnly', function() {
+		// given
+		var star	= $('#star'),
+			size	= 24;
+
+		// when
+		star.raty({ readOnly: true, size: size, width: 200 });
+
+		// then
+		expect(star.width()).toEqual(200);
+	});
+
+	it ('should calculate the right icon size with cancel button', function() {
+		// given
+		var star	= $('#star'),
+			size	= 24,
+			number	= 5;
+
+		// when
+		star.raty({ cancel: true, size: size });
+
+		// then
+		expect(star.width()).toEqual(number * size + number * 4 + (size + 4));
+	});
+
+	it ('should set a target on div with mouseover', function() {
+		$('body').append('<div id="hint"></div>');
+
+		// given
+		var hint = $('#hint'),
+			star = $('#star').raty({ target: '#hint' });
+
+		// when
+		star.children('img').eq(3).mouseover();
+
+		// then
+		expect(hint).toHaveHtml('good');
+
+		hint.remove();
+	});
+
+	it ('should set a target on div with mouseover but take off when mouseleave', function() {
+		$('body').append('<div id="hint"></div>');
+
+		// given
+		var hint = $('#hint'),
+			star = $('#star').raty({ target: '#hint' });
+
+		// when
+		star.children('img').eq(3).mouseover().mouseleave();
+
+		// then
+		expect(hint).toBeEmpty();
+
+		hint.remove();
+	});
+
+	it ('should change the cancel hint using target', function() {
+		$('body').append('<div id="hint"></div>');
+
+		// given
+		var hint = $('#hint'),
+			star = $('#star').raty({
+			cancel:     true,
+			cancelHint: 'none',
+			target:     '#hint',
+		});
+
+		// when
+		star.children('img:first').mouseenter();
+
+		// then
+		expect(hint).toHaveHtml('none');
+
+		hint.remove();
+	});
+
+	it ('should set hint on a combobox element', function() {
+		$('body').append('<select id="hint"><option value="">--</option><option value="good">good</option></select>');
+
+		// given
+		var hint = $('#hint'),
+			star = $('#star').raty({ target: '#hint' });
+
+		// when
+		star.children('img').eq(3).mouseover();
+
+		// then
+		expect(hint.val()).toEqual('good');
+
+		hint.remove();
+	});
+
+	it ('should set hint on a text element', function() {
+		$('body').append('<input id="hint" type="text" />');
+
+		// given
+		var hint = $('#hint'),
+			star = $('#star').raty({ target: '#hint' });
+
+		// when
+		star.children('img').eq(3).mouseover();
+
+		// then
+		expect(hint.val()).toEqual('good');
+
+		hint.remove();
+	});
+
+	it ('should set hint on a textarea element', function() {
+		$('body').append('<textarea id="hint"></textarea>');
+
+		// given
+		var hint = $('#hint'),
+			star = $('#star').raty({ target: '#hint' });
+
+		// when
+		star.children('img').eq(3).mouseover();
+
+		// then
+		expect(hint.val()).toEqual('good');
+
+		hint.remove();
+	});
+
+	it ('should set number hint on a combobox element', function() {
+		$('body').append('<select id="hint"><option value="">--</option><option value="4">4</option></select>');
+
+		// given
+		var hint = $('#hint'),
+			star = $('#star').raty({ target: '#hint', targetType: 'number' });
+
+		// when
+		star.children('img').eq(3).mouseover();
+
+		// then
+		expect(hint.val()).toEqual('4');
+
+		hint.remove();
+	});
+
+	it ('should set number hint and keep it on mouseleave', function() {
+		$('body').append('<select id="hint"><option value="">--</option><option value="4">4</option></select>');
+
+		// given
+		var hint = $('#hint'),
+			star = $('#star').raty({ target: '#hint', targetType: 'number', targetKeep: true });
+
+		// when
+		star.children('img').eq(3).mouseover().click().mouseleave();
+
+		// then
+		expect(hint.val()).toEqual('4');
+
+		hint.remove();
+	});
+
+	it ('should create stars without space', function() {
+		// given
+		var star	= $('#star');
+			size	= 16,
+			number	= 5;
+
+		// when
+		star.raty({ space: false });
+
+		// then
+		expect(star.width()).toEqual(number * size + number * (4 * 0));
+	});
+
+	it ('should create stars with cancel without space', function() {
+		// given
+		var star	= $('#star');
+			size	= 16,
+			number	= 5;
+
+		// when
+		star.raty({ cancel: true, space: false });
+
+		// then
+		expect(star.width()).toEqual(number * size + number * (4 * 0) + 16 + (4 * 0));
+	});
+
+	it ('should not set target with targetText when has started score and targetKeep is true with mouseout', function() {
+		$('body').append('<div id="hint"></div>');
+
+		// given
+		var hint	= $('#hint'),
+			star	= $('#star').raty({ score: 3, target: '#hint', targetKeep: true, targetText: 'my-hint-message' });
+
+		// when
+		star.children('img').eq(3).mouseover().mouseleave();
+
+		// then
+		expect(hint).toHaveHtml('regular');
+
+		hint.remove();
+	});
+
+	it ('should not set target with targetText when has clicked score and targetKeep is true with mouseout', function() {
+		$('body').append('<div id="hint"></div>');
+
+		// given
+		var hint	= $('#hint'),
+			star	= $('#star').raty({ target: '#hint', targetKeep: true, targetText: 'my-hint-message' });
+
+		// when
+		star.children('img').eq(3).mouseover().click().mouseleave();
+
+		// then
+		expect(hint).toHaveHtml('good');
+
+		hint.remove();
+	});
+
+	it ('should set target with targetText when has scoreed score and targetKeep is false with mouseout', function() {
+		$('body').append('<div id="hint"></div>');
+
+		// given
+		var message	= 'my-hint-message',
+			hint	= $('#hint'),
+			star	= $('#star').raty({ score: 3, target: '#hint', targetKeep: false, targetText: message });
+
+		// when
+		star.children('img').eq(3).mouseover().mouseleave();
+
+		// then
+		expect(hint).toHaveHtml(message);
+
+		hint.remove();
+	});
+
+	it ('should set target with targetText when has clicked score and targetKeep false with mouseout', function() {
+		$('body').append('<div id="hint"></div>');
+
+		// given
+		var message	= 'my-hint-message',
+			hint	= $('#hint'),
+			star	= $('#star').raty({ target: '#hint', targetKeep: false, targetText: message });
+
+		// when
+		star.children('img').eq(3).mouseover().click().mouseleave();
+
+		// then
+		expect(hint).toHaveHtml(message);
+
+		hint.remove();
+	});
+
+	it ('should set target with targetText when has started score and targetKeep is false without mouseout', function() {
+		$('body').append('<div id="hint"></div>');
+
+		// given
+		var message	= 'my-hint-message',
+			hint	= $('#hint'),
+			star	= $('#star');
+
+		// when
+		star.raty({ score: 3, target: '#hint', targetKeep: false, targetText: message });
+
+		// then
+		expect(hint).toHaveHtml(message);
+
+		hint.remove();
+	});
+
+	it ('should set score as readonly when start with readOnly', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ readOnly: true });
+
+		// then
+		expect(star.children('input')).toHaveAttr('readonly', 'readonly');
+	});
+
+	it ('should be down with round option', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ halfShow: true, score: 1.9, round: { down: .9, full: .98, up: .99 } });
+
+		var imgs = star.children('img');
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should be half with round option', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ halfShow: true, score: 1.91, round: { down: .9, full: .98, up: .99 } });
+
+		var imgs = star.children('img');
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/star-half.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should be up with round option', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ halfShow: true, score: 1.99, round: { down: .9, full: .98, up: .99 } });
+
+		var imgs = star.children('img');
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should be full with round option and halfShow off', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ halfShow: false, score: 1.98, round: { down: .9, full: .98, up: .99 } });
+
+		var imgs = star.children('img');
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should be down with round option and others options default', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ halfShow: true, score: 1.9, round: { down: .9 } });
+
+		var imgs = star.children('img');
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should be half with round option and others options default', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ halfShow: true, score: 1.26, round: { } });
+
+		var imgs = star.children('img');
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/star-half.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should be up with round option and others options default', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ halfShow: true, score: 1.99, round: { up: .99 } });
+
+		var imgs = star.children('img');
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should be full with round option and halfShow off and others options default', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ halfShow: false, score: 1.98, round: { full: .98 } });
+
+		var imgs = star.children('img');
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should set hint target with start option and targetKeep true', function() {
+		$('body').append('<div id="hint"></div>');
+
+		// given
+		var hint	= $('#hint'),
+			star	= $('#star');
+
+		// when
+		star.raty({ target: '#hint', precision: true, score: 3, targetKeep: true });
+
+		// then
+		expect(hint).toHaveHtml('regular');
+
+		hint.remove();
+	});
+
+	it ('should set precision number target with just one fractional number', function() {
+		$('body').append('<div id="hint"></div>');
+
+		// given
+		var hint	= $('#hint'),
+			star	= $('#star');
+
+		// when
+		star.raty({ target: '#hint', precision: true, targetType: 'number', score: 1.2333, targetKeep: true });
+
+		// then
+		expect(hint).toHaveHtml('1.2');
+
+		hint.remove();
+	});
+
+	it ('should set precision number target with start options and targetKeep true', function() {
+		$('body').append('<div id="hint"></div>');
+
+		// given
+		var hint	= $('#hint'),
+			star	= $('#star');
+
+		// when
+		star.raty({ target: '#hint', precision: true, targetType: 'number', score: 1.2, targetKeep: true });
+
+		// then
+		expect(hint).toHaveHtml('1.2');
+
+		hint.remove();
+	});
+
+	it ('should set target with format on mouseover', function() {
+		$('body').append('<div id="hint"></div>');
+
+		// given
+		var hint	= $('#hint'),
+			star	= $('#star').raty({ target: '#hint', targetFormat: 'score: {score}', precision: true });
+
+		// when
+		star.children('img:first').mouseover();
+
+		// then
+		expect(hint).toHaveHtml('score: bad');
+
+		hint.remove();
+	});
+
+	it ('should set score with precision and half disabled', function() {
+		$('body').append('<div id="hint"></div>');
+
+		// given
+		var hint	= $('#hint'),
+			star	= $('#star').raty({ target: '#hint', targetKeep: true, precision: true });
+
+		// when
+		star.children('img:first').mouseover().click().mouseleave();
+
+		// then
+		expect(hint).toHaveHtml('bad');
+
+		hint.remove();
+	});
+
+	it ('should set and keep target with format on click and mouseleave', function() {
+		$('body').append('<div id="hint"></div>');
+
+		// given
+		var hint	= $('#hint'),
+			star	= $('#star').raty({ target: '#hint', targetFormat: 'score: {score}', targetKeep: true });
+
+		// when
+		star.children('img:first').mouseover().click().mouseleave();
+
+		// then
+		expect(hint).toHaveHtml('score: bad');
+
+		hint.remove();
+	});
+
+	it ('should set target with format and precision', function() {
+		$('body').append('<div id="hint"></div>');
+
+		// given
+		var hint	= $('#hint'),
+			star	= $('#star');
+
+		// when
+		star.raty({ target: '#hint', targetFormat: 'score: {score}', targetKeep: true, targetType: 'number', precision: true, score: 1.2 });
+
+		// then
+		expect(hint).toHaveHtml('score: 1.2');
+
+		hint.remove();
+	});
+
+	it ('should set target with none value', function() {
+		$('body').append('<div id="hint"></div>');
+
+		// given
+		var hint	= $('#hint'),
+			star	= $('#star');
+
+		// when
+		star.raty({ target: '#hint', targetFormat: 'score: {score}', targetKeep: true, targetType: 'number', targetText: 'none' });
+
+		// then
+		expect(hint).toHaveHtml('score: none');
+
+		hint.remove();
+	});
+
+	it ('should not to use format template on cancel mouseover', function() {
+		$('body').append('<div id="hint"></div>');
+
+		// given
+		var hint	= $('#hint'),
+			star	= $('#star').raty({ cancel: true, target: '#hint', targetFormat: 'score: {score}', targetKeep: true });
+
+		// when
+		star.children('img:first').mouseenter();
+
+		// then
+		expect(hint).toHaveHtml('cancel this rating!');
+
+		hint.remove();
+	});
+
+	it ('should show single icon selection on mouseover', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ single: true });
+
+		var imgs = star.children('img');
+
+		imgs.eq(2).mouseover();
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should show single icon selection on click', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ single: true });
+
+		var imgs = star.children('img');
+
+		imgs.eq(2).mouseover().click().mouseleave();
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should show single icon selection with iconRange enabled on mouseover', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({
+			iconRange: [
+				{ range: 2, on: 'face-a.png', off: 'face-a-off.png' },
+				{ range: 3, on: 'face-b.png', off: 'face-b-off.png' },
+				{ range: 4, on: 'face-c.png', off: 'face-c-off.png' },
+				{ range: 5, on: 'face-d.png', off: 'face-d-off.png' }
+			],
+			single: true
+		});
+
+		var imgs = star.children('img');
+
+		imgs.eq(3).mouseover();
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/face-a-off.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/face-a-off.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/face-b-off.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/face-c.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/face-d-off.png');
+	});
+
+	it ('should show single icon selection with iconRange enabled on click', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({
+			iconRange: [
+				{ range: 2, on: 'face-a.png', off: 'face-a-off.png' },
+				{ range: 3, on: 'face-b.png', off: 'face-b-off.png' },
+				{ range: 4, on: 'face-c.png', off: 'face-c-off.png' },
+				{ range: 5, on: 'face-d.png', off: 'face-d-off.png' }
+			],
+			single: true
+		});
+
+		var imgs = star.children('img');
+
+		imgs.eq(3).mouseover().click().mouseleave();
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/face-a-off.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/face-a-off.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/face-b-off.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/face-c.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/face-d-off.png');
+	});
+
+	it ('score should get it as int', function() {
+		// given
+		var star = $('#star').raty({ score: 1 });
+
+		// when
+		var score = star.raty('score');
+
+		// then
+		expect(score).toEqual(1);
+	});
+
+	it ('score should get it as float', function() {
+		// given
+		var star = $('#star').raty({ score: 1.5 });
+
+		// when
+		var score = star.raty('score');
+
+		// then
+		expect(score).toEqual(1.5);
+	});
+
+	it ('[score] should not have score when it is setted to 0', function() {
+		// given
+		var star = $('#star').raty({ score: 0 });
+
+		// when
+		var score = star.raty('score');
+
+		// then
+		expect(score).toEqual(null);
+	});
+
+	it ('[score] should have 20 as max', function() {
+		// given
+		var star = $('#star').raty({ number: 30, score: 30 });
+
+		// when
+		var score = star.raty('score');
+
+		// then
+		expect(score).toEqual(20);
+	});
+
+	it ('[score] should have 0 as min', function() {
+		// given
+		var star = $('#star').raty({ score: -30 });
+
+		// when
+		var score = star.raty('score');
+
+		// then
+		expect(score).toEqual(null);
+	});
+
+	it ('[set] should be chainable', function() {
+		// given
+		var star	= $('#star').raty(),
+			clazz	= 'some-class';
+
+		// when
+		var clone = star.raty('set', { readOnly: true }).addClass(clazz);
+
+		// then
+		expect(clone).toHaveClass(clazz);
+	});
+
+	it ('[set] should change just the passed parameters', function() {
+		// given
+		var star = $('#star').raty({ number: 6 });
+
+		// when
+		star.raty('set', { scoreName: 'changed' });
+
+		// then
+		var clone = $('#star');
+
+		expect(clone.children('input')).toHaveAttr('name', 'changed');
+		expect(clone.children('img').length).toEqual(6);
+	});
+
+	it ('[reload] should be chainable', function() {
+		// given
+		var star	= $('#star').raty(),
+			clazz	= 'some-class';
+
+		// when
+		var clone = star.raty('reload').addClass(clazz);
+
+		// then
+		expect(clone).toHaveClass(clazz);
+	});
+
+	it ('[reload] should reload with same configuration', function() {
+		// given
+		var star = $('#star').raty({ number: 6 });
+
+		// when
+		star.raty('reload');
+
+		// then
+		expect($('#star').children('img').length).toEqual(6);
+	});
+
+	it ('[mouseover] should display the value', function() {
+		$('body').append('<div id="hint"></div>');
+
+		// given
+		var hint	= $('#hint'),
+			star	= $('#star').raty({
+				mouseover: function(score, evt) {
+					hint.html(score);
+				}
+			});
+
+		// when
+		star.children('img:eq(1)').mouseover();
+
+		// then
+		expect(hint).toHaveHtml(2);
+
+		hint.remove();
+	});
+
+	it ('[mouseover] should display the cancel value', function() {
+		$('body').append('<div id="hint"></div>');
+
+		// given
+		var hint	= $('#hint'),
+			star	= $('#star').raty({
+				cancel		: true,
+				mouseover	: function(score, evt) {
+					hint.html(score === null ? 'null' : score);
+				}
+			});
+
+		// when
+		star.children('.raty-cancel').mouseover();
+
+		// then
+		expect(hint).toHaveHtml('null');
+
+		hint.remove();
+	});
+
+	it ('[mouseover] should pass the original value on cancel mouseout', function() {
+		$('body').append('<div id="hint"></div>');
+
+		// given
+		var hint	= $('#hint'),
+			star	= $('#star').raty({
+				cancel		: true,
+				score		: 1,
+				mouseover	: function(score, evt) {
+					hint.html(score === null ? 'null' : score);
+				}
+			});
+
+		// when
+		star.children('.raty-cancel').mouseenter().mouseleave();
+
+		// then
+		expect(hint).toHaveHtml(1);
+
+		hint.remove();
+	});
+
+	it ('[mouseover] should pass the original value on star mouseout', function() {
+		$('body').append('<div id="hint"></div>');
+
+		// given
+		var hint	= $('#hint'),
+			star	= $('#star').raty({
+				score		: 1,
+				cancel		: true,
+				mouseover	: function(score, evt) {
+					hint.html(score);
+				}
+			});
+
+		// when
+		star.children('img:eq(4)').mouseover().mouseleave();
+
+		// then
+		expect(hint).toHaveHtml(1);
+
+		hint.remove();
+	});
+
+	it ('[score] should accept int string', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ number: 10, score: '10' });
+
+		// then
+		expect(star.children('input')).toHaveValue(10);
+	});
+
+	it ('[score] should accept float string', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ number: 11, score: '10.5' });
+
+		// then
+		expect(star.children('input')).toHaveValue(10.5);
+	});
+
+	it ('[number] should accept string', function() {
+		// given
+		var star = $('#star');
+
+		// when
+		star.raty({ number: '10' });
+
+		// then
+		expect(star.children('img').length).toEqual(10);
+	});
+
+	it ('[mouseover] handle null on cancel over', function() {
+		var isOver = true;
+
+		// given
+		var star = $('#star').raty({
+			cancel		: true,
+			mouseover	: function(score, evt) {
+				if (isOver) {
+					// then
+					expect(score === null).toBeTruthy();
+
+					isOver = false;
+				}
+			}
+		});
+
+		// when
+		star.children('.raty-cancel').mouseover();
+	});
+
+	it ('[mouseover] handle undefined on mouse out of cancel', function() {
+		var nextOut = false;
+
+		// given
+		var star = $('#star').raty({
+			cancel		: true,
+			mouseover	: function(score, evt) {
+				if (nextOut) {
+					// then
+					expect(score === undefined).toBeTruthy();
+				}
+
+				nextOut = true;
+			}
+		});
+
+		// when
+		star.children('.raty-cancel').mouseleave();
+	});
+
+	it ('[mouseover] handle undefined on star out', function() {
+		var nextOut = false;
+
+		// given
+		var star = $('#star').raty({
+			mouseover	: function(score, evt) {
+				if (nextOut) {
+					// then
+					expect(score === undefined).toBeTruthy();
+				}
+
+				nextOut = true;
+			}
+		});
+
+		// when
+		star.children('img:first').mouseleave();
+	});
+
+	it ('[mouseover] handle 1 on star out', function() {
+		var nextOut = false;
+
+		// given
+		var star = $('#star').raty({
+			score		: 1,
+			mouseover	: function(score, evt) {
+				if (nextOut) {
+					// then
+					expect(score).toEqual(1);
+				}
+
+				nextOut = true;
+			}
+		});
+
+		// when
+		star.children('img:first').mouseleave();
+	});
+
+	it ('[mouseover] handle 1 on cancel out', function() {
+		var nextOut = false;
+
+		// given
+		var star = $('#star').raty({
+			cancel		: true,
+			score		: 1,
+			mouseover	: function(score, evt) {
+				if (nextOut) {
+					// then
+					expect(parseInt(score)).toEqual(1);
+				}
+
+				nextOut = true;
+			}
+		});
+
+		// when
+		star.children('.raty-cancel').mouseleave();
+	});
+
+});
+
+describe('Using class', function() {
+
+	beforeEach(function() {
+		$('body').append('<div class="star"></div><div class="star"></div><div class="star"></div>');
+	});
+
+	afterEach(function() {
+		$('.star').remove();
+	});
+
+	it ('should create the default stars', function() {
+		// given
+		var stars = $('.star');
+
+		// when
+		stars.raty();
+
+		// then
+		var imgs1 = stars.eq(0).children('img'),
+			imgs2 = stars.eq(1).children('img'),
+			imgs3 = stars.eq(2).children('img');
+
+	    expect(imgs1.eq(0)).toHaveAttr('title', 'bad');
+	    expect(imgs1.eq(1)).toHaveAttr('title', 'poor');
+	    expect(imgs1.eq(2)).toHaveAttr('title', 'regular');
+	    expect(imgs1.eq(3)).toHaveAttr('title', 'good');
+	    expect(imgs1.eq(4)).toHaveAttr('title', 'gorgeous');
+
+	    expect(imgs1.eq(0)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs1.eq(1)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs1.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs1.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs1.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+	    expect(imgs2.eq(0)).toHaveAttr('title', 'bad');
+	    expect(imgs2.eq(1)).toHaveAttr('title', 'poor');
+	    expect(imgs2.eq(2)).toHaveAttr('title', 'regular');
+	    expect(imgs2.eq(3)).toHaveAttr('title', 'good');
+	    expect(imgs2.eq(4)).toHaveAttr('title', 'gorgeous');
+
+	    expect(imgs2.eq(0)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs2.eq(1)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs2.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs2.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs2.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+	    expect(imgs3.eq(0)).toHaveAttr('title', 'bad');
+	    expect(imgs3.eq(1)).toHaveAttr('title', 'poor');
+	    expect(imgs3.eq(2)).toHaveAttr('title', 'regular');
+	    expect(imgs3.eq(3)).toHaveAttr('title', 'good');
+	    expect(imgs3.eq(4)).toHaveAttr('title', 'gorgeous');
+
+	    expect(imgs3.eq(0)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs3.eq(1)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs3.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs3.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs3.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should select first raty', function() {
+		// given
+		var stars = $('.star').raty(),
+			imgs1 = stars.eq(0).children('img'),
+			imgs2 = stars.eq(1).children('img'),
+			imgs3 = stars.eq(2).children('img');
+
+		// when
+		imgs1.eq(3).mouseover();
+
+		// then
+	    expect(imgs1.eq(0)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs1.eq(1)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs1.eq(2)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs1.eq(3)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs1.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+	    expect(imgs2.eq(0)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs2.eq(1)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs2.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs2.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs2.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+	    expect(imgs3.eq(0)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs3.eq(1)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs3.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs3.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs3.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should click second raty', function() {
+		// given
+		var stars = $('.star').raty(),
+			imgs1 = stars.eq(0).children('img'),
+			imgs2 = stars.eq(1).children('img'),
+			imgs3 = stars.eq(2).children('img');
+
+		// when
+
+		imgs2.eq(3).mouseover().click().mouseleave();
+
+		// then
+	    expect(imgs1.eq(0)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs1.eq(1)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs1.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs1.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs1.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+	    expect(imgs2.eq(0)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs2.eq(1)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs2.eq(2)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs2.eq(3)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs2.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+	    expect(imgs3.eq(0)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs3.eq(1)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs3.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs3.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs3.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should click on first and third raty', function() {
+		// given
+		var stars = $('.star').raty(),
+			imgs1 = stars.eq(0).children('img'),
+			imgs2 = stars.eq(1).children('img'),
+			imgs3 = stars.eq(2).children('img');
+
+		// when
+		imgs1.eq(3).mouseover().click().mouseleave();
+		imgs3.eq(3).mouseover().click().mouseleave();
+
+		// then
+		expect(imgs1.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs1.eq(1)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs1.eq(2)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs1.eq(3)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs1.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+	    expect(imgs2.eq(0)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs2.eq(1)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs2.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs2.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs2.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+		expect(imgs3.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs3.eq(1)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs3.eq(2)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs3.eq(3)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs3.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should hover all and out', function() {
+		// given
+		var stars = $('.star').raty(),
+			imgs1 = stars.eq(0).children('img'),
+			imgs2 = stars.eq(1).children('img'),
+			imgs3 = stars.eq(2).children('img');
+
+		// when
+		imgs1.eq(1).mouseover().mouseleave();
+		imgs2.eq(2).mouseover().mouseleave();
+		imgs3.eq(3).mouseover().mouseleave();
+
+		// then
+		expect(imgs1.eq(0)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+	    expect(imgs2.eq(0)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs2.eq(1)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs2.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs2.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs2.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+		expect(imgs3.eq(0)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should set score as readonly when start with readOnly', function() {
+		// given
+		var stars = $('.star');
+
+		// when
+		stars.eq(0).raty({ readOnly: true });
+		stars.eq(1).raty({ readOnly: true });
+		stars.eq(2).raty({ readOnly: true });
+
+		// then
+		expect(stars.eq(0).children('input')).toHaveAttr('readonly', 'readonly');
+		expect(stars.eq(1).children('input')).toHaveAttr('readonly', 'readonly');
+		expect(stars.eq(2).children('input')).toHaveAttr('readonly', 'readonly');
+	});
+
+	it ('score should get it as int', function() {
+		// given
+		var stars = $('.star');;
+
+		stars.eq(0).raty({ score: 1 });
+		stars.eq(1).raty({ score: 2 });
+		stars.eq(2).raty({ score: 3 });
+
+		// when
+		var score1 = stars.eq(0).raty('score'),
+			score2 = stars.eq(1).raty('score'),
+			score3 = stars.eq(2).raty('score');
+
+		// then
+		expect(score1).toEqual(1);
+		expect(score2).toEqual(2);
+		expect(score3).toEqual(3);
+	});
+
+	it ('score should get it as float', function() {
+		// given
+		var stars = $('.star');;
+
+		stars.eq(0).raty({ score: 1.1 });
+		stars.eq(1).raty({ score: 2.2 });
+		stars.eq(2).raty({ score: 3.3 });
+
+		// when
+		var score1 = stars.eq(0).raty('score'),
+			score2 = stars.eq(1).raty('score'),
+			score3 = stars.eq(2).raty('score');
+
+		// then
+		expect(score1).toEqual(1.1);
+		expect(score2).toEqual(2.2);
+		expect(score3).toEqual(3.3);
+	});
+
+});
+
+describe('Using function with id', function() {
+
+	beforeEach(function() {
+		$('body').append('<div id="star"></div>');
+	});
+
+	afterEach(function() {
+		$('#star').remove();
+	});
+
+	it ('should start the start with 3 stars', function() {
+		// given
+		var star = $('#star').raty();
+
+		// when
+		star.raty('score', 3);
+
+		// then
+		var imgs = star.children('img');
+
+	    expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should not call click callback when start function run without true option', function() {
+		// given
+		var star = $('#star').raty({ click: function(score, evt) { $(this).attr('title', score); }});
+
+		// when
+		star.raty('score', 3);
+
+		// then
+		var imgs = star.children('img');
+
+	    expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+	    expect(star.attr('title')).toEqual(undefined);
+	});
+
+	it ('should set readOnly and fix the hints', function() {
+		// given
+		var star = $('#star').raty({ score: 1 });
+
+		// when
+		star.raty('readOnly', true);
+
+		var imgs = star.children('img');
+
+		imgs.eq(3).mouseover().click();
+
+		// then
+	    expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+	    expect(imgs.eq(0)).toHaveAttr('title', 'bad');
+	    expect(imgs.eq(1)).toHaveAttr('title', 'bad');
+	    expect(imgs.eq(2)).toHaveAttr('title', 'bad');
+	    expect(imgs.eq(3)).toHaveAttr('title', 'bad');
+	    expect(imgs.eq(4)).toHaveAttr('title', 'bad');
+	});
+
+	it ('should set readOnly and hide cancel button', function() {
+		// given
+		var star = $('#star').raty({ cancel: true, path: '../img' });
+
+		// when
+		star.raty('readOnly', true);
+
+		// then
+	    expect(star.children('.raty-cancel')).not.toBeVisible();
+	});
+
+	it ('should unset readOnly and show cancel button', function() {
+		// given
+		var star = $('#star').raty({ cancel: true, readOnly: true, path: '../img' });
+
+		// when
+		star.raty('readOnly', false);
+
+		// then
+	    expect(star.children('.raty-cancel')).toBeVisible();
+	});
+
+	it ('should unset readOnly and put back the titles', function() {
+		// given
+		var star = $('#star').raty();
+
+		// when
+		star.raty('readOnly', true).raty('readOnly', false);
+
+		var imgs = star.children('img');
+
+		imgs.eq(1).mouseover().click();
+
+		// then
+	    expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/star-on.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+	    expect(imgs.eq(0)).toHaveAttr('title', 'bad');
+	    expect(imgs.eq(1)).toHaveAttr('title', 'poor');
+	    expect(imgs.eq(2)).toHaveAttr('title', 'regular');
+	    expect(imgs.eq(3)).toHaveAttr('title', 'good');
+	    expect(imgs.eq(4)).toHaveAttr('title', 'gorgeous');
+	});
+
+	it ('should cancel without click', function() {
+		// given
+		var star = $('#star').raty({ score: 1 });
+
+		// when
+		star.raty('cancel');
+
+		var imgs = star.children('img');
+
+		// then
+	    expect(imgs.eq(0)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+	    expect(star.children('input').val()).toEqual('');
+	});
+
+	it ('should cancel with click', function() {
+		// given
+		var star = $('#star').raty({
+			click: function(score, evt) {
+				$(this).attr('title', (score === null) ? 'null' : score);
+			},
+			score: 1
+		});
+
+		// when
+		star.raty('cancel', true);
+
+		var imgs = star.children('img');
+
+		// then
+	    expect(imgs.eq(0)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+	    expect(star).toHaveAttr('title', 'null');
+	    expect(star.children('input').val()).toEqual('');
+	});
+
+	it ('should click the star 3', function() {
+		// given
+		var star = $('#star').raty({
+			click: function(score, evt) {
+				$(this).attr('title', score);
+			}
+		});
+
+		// when
+		star.raty('click', 3);
+
+		// then
+		var imgs = star.children('img');
+
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+		expect(star).toHaveAttr('title', 3);
+	});
+
+	it ('should set a target on div with mouseover', function() {
+		$('body').append('<div id="hint"></div>');
+
+		// given
+		var hint = $('#hint'),
+			star = $('#star').raty({ target: '#hint', targetKeep: true, click: function(score, evt) { } });
+
+		// when
+		star.raty('click', 4);
+
+		// then
+		expect(hint).toHaveHtml('good');
+
+		hint.remove();
+	});
+
+	it ('should set a target on div with mouseover', function() {
+		$('body').append('<div id="hint"></div>');
+
+		// given
+		var hint = $('#hint'),
+			star = $('#star').raty({ target: '#hint', targetKeep: true });
+
+		// when
+		star.raty('score', 4);
+
+		// then
+		expect(hint).toHaveHtml('good');
+
+		hint.remove();
+	});
+
+	it ('should set a target on div with cancel', function() {
+		$('body').append('<div id="hint"></div>');
+
+		// given
+		var hint = $('#hint'),
+			star = $('#star').raty({ cancel: true, target: '#hint', targetKeep: true });
+
+		// when
+		star.raty('cancel').mouseout();
+
+		// then
+		expect(hint).toBeEmpty();
+
+		hint.remove();
+	});
+
+	it ('[score / readOnly] should not set score when it is read-only', function() {
+		// given
+		var star = $('#star').raty({ readOnly: true });
+
+		// when
+		star.raty('score', 1);
+
+		// then
+		var imgs = star.children('img');
+
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should not click when it is readOnly', function() {
+		// given
+		var star = $('#star').raty({ readOnly: true, click: function(score, evt) { } });
+
+		// when
+		star.raty('click', 1);
+
+		// then
+		var imgs = star.children('img');
+
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should not cancel when it is readOnly', function() {
+		// given
+		var star = $('#star').raty({ readOnly: true, score: 1 });
+
+		// when
+		star.raty('cancel');
+
+		// then
+		var imgs = star.children('img');
+
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+		expect(star.children('input').val()).toEqual('1');
+	});
+
+	it ('should set score as readonly when start with readOnly', function() {
+		// given
+		var star = $('#star').raty();
+
+		// when
+		star.raty('readOnly', true);
+
+		// then
+		expect(star.children('input')).toHaveAttr('readonly', 'readonly');
+	});
+
+	it ('should set the cancel hint on target', function() {
+		$('body').append('<div id="hint"></div>');
+
+		// given
+		var hint	= $('#hint'),
+			star	= $('#star').raty({ cancel: true, target: '#hint', targetFormat: 'score: {score}', targetKeep: true });
+
+		// when
+		star.raty('cancel').mouseleave();
+
+		// then
+		expect(hint).toHaveHtml('score: ');
+
+		hint.remove();
+	});
+
+	it ('should rebind the cancel button after readOnly be enabled', function() {
+		// given
+		var star = $('#star').raty({ cancel: true });
+
+		// when
+		star.raty('readOnly', true).raty('readOnly', false).children('.raty-cancel').mouseenter();
+
+		var imgs = star.children('img').not('.raty-cancel');
+
+		// then
+		expect(imgs.eq(0)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('[cancel] should cancel after a read-only false', function() {
+		// given
+		var star = $('#star').raty({ score: 1 }).raty('readOnly', true).raty('readOnly', false);
+
+		// when
+		star.raty('cancel');
+
+		var imgs = star.children('img');
+
+		// then
+	    expect(imgs.eq(0)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(1)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(2)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(3)).toHaveAttr('src', 'img/star-off.png');
+	    expect(imgs.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+	    expect(star.children('input').val()).toEqual('');
+	});
+
+});
+
+describe('Using function with class', function() {
+	
+	beforeEach(function() {
+		$('body').append('<div class="star"></div><div class="star"></div><div class="star"></div>');
+	});
+
+	afterEach(function() {
+		$('.star').remove();
+	});
+
+	it ('should start the starts with 3 stars', function() {
+		// given
+		var stars = $('.star').raty();
+
+		// when
+		stars.raty('score', 3);
+
+		// then
+		var imgs1 = stars.eq(0).children('img'),
+			imgs2 = stars.eq(1).children('img'),
+			imgs3 = stars.eq(2).children('img');
+
+		expect(imgs1.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs1.eq(1)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs1.eq(2)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs1.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+		expect(imgs2.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs2.eq(1)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs2.eq(2)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs2.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+		expect(imgs3.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs3.eq(1)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs3.eq(2)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs3.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+	
+	it ('should set readOnly and fix the hint', function() {
+		// given
+		var stars = $('.star').raty();
+
+		// when
+		stars.raty('readOnly', true);
+
+		var imgs1 = stars.eq(0).children('img'),
+			imgs2 = stars.eq(1).children('img'),
+			imgs3 = stars.eq(2).children('img');
+	
+		imgs1.eq(3).mouseover().click();
+		imgs2.eq(3).mouseover().click();
+		imgs3.eq(3).mouseover().click();
+
+		// then
+		expect(imgs1.eq(0)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+		expect(imgs1.eq(0)).toHaveAttr('title', 'not rated yet');
+	    expect(imgs1.eq(1)).toHaveAttr('title', 'not rated yet');
+	    expect(imgs1.eq(2)).toHaveAttr('title', 'not rated yet');
+	    expect(imgs1.eq(3)).toHaveAttr('title', 'not rated yet');
+	    expect(imgs1.eq(4)).toHaveAttr('title', 'not rated yet');
+
+		expect(imgs2.eq(0)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+		expect(imgs2.eq(0)).toHaveAttr('title', 'not rated yet');
+	    expect(imgs2.eq(1)).toHaveAttr('title', 'not rated yet');
+	    expect(imgs2.eq(2)).toHaveAttr('title', 'not rated yet');
+	    expect(imgs2.eq(3)).toHaveAttr('title', 'not rated yet');
+	    expect(imgs2.eq(4)).toHaveAttr('title', 'not rated yet');
+
+		expect(imgs3.eq(0)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+		expect(imgs3.eq(0)).toHaveAttr('title', 'not rated yet');
+	    expect(imgs3.eq(1)).toHaveAttr('title', 'not rated yet');
+	    expect(imgs3.eq(2)).toHaveAttr('title', 'not rated yet');
+	    expect(imgs3.eq(3)).toHaveAttr('title', 'not rated yet');
+	    expect(imgs3.eq(4)).toHaveAttr('title', 'not rated yet');
+	});
+
+	it ('should unset readOnly and put back the titles', function() {
+		// given
+		var stars = $('.star').raty();
+
+		// when
+		stars.raty('readOnly', true).raty('readOnly', false);
+
+		var imgs1 = stars.eq(0).children('img'),
+			imgs2 = stars.eq(1).children('img'),
+			imgs3 = stars.eq(2).children('img');
+
+		imgs1.eq(3).mouseover().click();
+		imgs2.eq(3).mouseover().click();
+		imgs3.eq(3).mouseover().click();
+
+		// then
+		expect(imgs1.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs1.eq(1)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs1.eq(2)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs1.eq(3)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs1.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+		expect(imgs1.eq(0)).toHaveAttr('title', 'bad');
+	    expect(imgs1.eq(1)).toHaveAttr('title', 'poor');
+	    expect(imgs1.eq(2)).toHaveAttr('title', 'regular');
+	    expect(imgs1.eq(3)).toHaveAttr('title', 'good');
+	    expect(imgs1.eq(4)).toHaveAttr('title', 'gorgeous');
+
+		expect(imgs2.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs2.eq(1)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs2.eq(2)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs2.eq(3)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs2.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+		expect(imgs2.eq(0)).toHaveAttr('title', 'bad');
+	    expect(imgs2.eq(1)).toHaveAttr('title', 'poor');
+	    expect(imgs2.eq(2)).toHaveAttr('title', 'regular');
+	    expect(imgs2.eq(3)).toHaveAttr('title', 'good');
+	    expect(imgs2.eq(4)).toHaveAttr('title', 'gorgeous');
+
+		expect(imgs3.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs3.eq(1)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs3.eq(2)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs3.eq(3)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs3.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+		expect(imgs3.eq(0)).toHaveAttr('title', 'bad');
+	    expect(imgs3.eq(1)).toHaveAttr('title', 'poor');
+	    expect(imgs3.eq(2)).toHaveAttr('title', 'regular');
+	    expect(imgs3.eq(3)).toHaveAttr('title', 'good');
+	    expect(imgs3.eq(4)).toHaveAttr('title', 'gorgeous');
+	});
+	
+	it ('should cancel without click', function() {
+		// given
+		var stars = $('.star').raty({ score: 1 });
+
+		// when
+		stars.raty('cancel');
+
+		// then
+		var imgs1 = stars.eq(0).children('img'),
+			imgs2 = stars.eq(1).children('img'),
+			imgs3 = stars.eq(2).children('img');
+
+		expect(imgs1.eq(0)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(4)).toHaveAttr('src', 'img/star-off.png');
+		expect(stars.eq(0).children('input').val()).toEqual('');
+
+		expect(imgs2.eq(0)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(4)).toHaveAttr('src', 'img/star-off.png');
+		expect(stars.eq(1).children('input').val()).toEqual('');
+
+		expect(imgs3.eq(0)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(4)).toHaveAttr('src', 'img/star-off.png');
+		expect(stars.eq(2).children('input').val()).toEqual('');
+	});
+	
+	it ('should cancel with click', function() {
+		// given
+		var stars = $('.star').raty({
+			click: function(score, evt) {
+				$(this).attr('title', (score === null) ? 'null' : score);
+			},
+			score: 1
+		});
+
+		// when
+		stars.raty('cancel', true);
+
+		// then
+		var imgs1 = stars.eq(0).children('img'),
+			imgs2 = stars.eq(1).children('img'),
+			imgs3 = stars.eq(2).children('img');
+	
+		expect(imgs1.eq(0)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(4)).toHaveAttr('src', 'img/star-off.png');
+		expect(stars.eq(0)).toHaveAttr('title', 'null');
+		expect(stars.eq(0).children('input').val()).toEqual('');
+
+		expect(imgs2.eq(0)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(4)).toHaveAttr('src', 'img/star-off.png');
+		expect(stars.eq(1)).toHaveAttr('title', 'null');
+		expect(stars.eq(1).children('input').val()).toEqual('');
+
+		expect(imgs3.eq(0)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(4)).toHaveAttr('src', 'img/star-off.png');
+		expect(stars.eq(1)).toHaveAttr('title', 'null');
+		expect(stars.eq(2).children('input').val()).toEqual('');
+	});
+
+	it ('should click the star 3', function() {
+		// given
+		var stars = $('.star').raty({
+			click: function(score, evt) {
+				$(this).attr('title', score);
+			}
+		});
+
+		// when
+		stars.raty('click', 3);
+
+		// then
+		var imgs1 = stars.eq(0).children('img'),
+			imgs2 = stars.eq(1).children('img'),
+			imgs3 = stars.eq(2).children('img');
+	
+		expect(imgs1.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs1.eq(1)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs1.eq(2)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs1.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(4)).toHaveAttr('src', 'img/star-off.png');
+		expect(stars.eq(0)).toHaveAttr('title', 3);
+
+		expect(imgs2.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs2.eq(1)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs2.eq(2)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs2.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(4)).toHaveAttr('src', 'img/star-off.png');
+		expect(stars.eq(1)).toHaveAttr('title', 3);
+
+		expect(imgs3.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs3.eq(1)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs3.eq(2)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs3.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(4)).toHaveAttr('src', 'img/star-off.png');
+		expect(stars.eq(2)).toHaveAttr('title', 3);
+	});
+	
+	it ('should set a target on div with click', function() {
+		$('body').append('<div id="hint1"></div><div id="hint2"></div><div id="hint3"></div>');
+
+		// given
+		var hint1	= $('#hint1'),
+			hint2	= $('#hint2'),
+			hint3	= $('#hint3'),
+			stars	= $('.star');
+
+		stars.eq(0).raty({ target: '#hint1', targetKeep: true, click: function(score, evt) { } });
+		stars.eq(1).raty({ target: '#hint2', targetKeep: true, click: function(score, evt) { } });
+		stars.eq(2).raty({ target: '#hint3', targetKeep: true, click: function(score, evt) { } });
+
+		// when
+		stars.raty('click', 4);
+
+		// then
+		expect(hint1).toHaveHtml('good');
+		expect(hint2).toHaveHtml('good');
+		expect(hint3).toHaveHtml('good');
+
+		hint1.remove();
+		hint2.remove();
+		hint3.remove();
+	});
+	
+	it ('should set a target on div with start', function() {
+		$('body').append('<div id="hint1"></div><div id="hint2"></div><div id="hint3"></div>');
+
+		// given
+		var hint1	= $('#hint1'),
+			hint2	= $('#hint2'),
+			hint3	= $('#hint3'),
+			stars	= $('.star');
+	
+		stars.eq(0).raty({ target: '#hint1', targetKeep: true, click: function(score, evt) { } });
+		stars.eq(1).raty({ target: '#hint2', targetKeep: true, click: function(score, evt) { } });
+		stars.eq(2).raty({ target: '#hint3', targetKeep: true, click: function(score, evt) { } });
+
+		// when
+		stars.raty('score', 4);
+
+		// then
+		expect(hint1).toHaveHtml('good');
+		expect(hint2).toHaveHtml('good');
+		expect(hint3).toHaveHtml('good');
+
+		hint1.remove();
+		hint2.remove();
+		hint3.remove();
+	});
+
+	it ('should set a target on div with cancel', function() {
+		$('body').append('<div id="hint1"></div><div id="hint2"></div><div id="hint3"></div>');
+
+		// given
+		var hint1	= $('#hint1'),
+			hint2	= $('#hint2'),
+			hint3	= $('#hint3'),
+			stars	= $('.star');
+	
+		stars.eq(0).raty({ cancel: true, target: '#hint1', targetKeep: true, click: function(score, evt) { } });
+		stars.eq(1).raty({ cancel: true, target: '#hint2', targetKeep: true, click: function(score, evt) { } });
+		stars.eq(2).raty({ cancel: true, target: '#hint3', targetKeep: true, click: function(score, evt) { } });
+
+		// when
+		stars.raty('cancel').mouseout();
+
+		// then
+		expect(hint1).toBeEmpty();
+		expect(hint2).toBeEmpty();
+		expect(hint3).toBeEmpty();
+
+		hint1.remove();
+		hint2.remove();
+		hint3.remove();
+	});
+
+	it ('should not start when it is readOnly', function() {
+		// given
+		var stars = $('.star').raty({ readOnly: true });
+
+		// when
+		stars.eq(0).raty('score', 1);
+		stars.eq(1).raty('score', 1);
+		stars.eq(2).raty('score', 1);
+
+		// then
+		var imgs1 = stars.eq(0).children('img'),
+			imgs2 = stars.eq(1).children('img'),
+			imgs3 = stars.eq(2).children('img');
+
+		expect(imgs1.eq(0)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+		expect(imgs2.eq(0)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+		expect(imgs3.eq(0)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should not click when it is readOnly', function() {
+		// given
+		var stars = $('.star').raty({ readOnly: true, click: function(score, evt) { } });
+
+		// when
+		stars.eq(0).raty('click', 1);
+		stars.eq(1).raty('click', 1);
+		stars.eq(2).raty('click', 1);
+
+		// then
+		var imgs1 = stars.eq(0).children('img'),
+			imgs2 = stars.eq(1).children('img'),
+			imgs3 = stars.eq(2).children('img');
+
+		expect(imgs1.eq(0)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+		expect(imgs2.eq(0)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(4)).toHaveAttr('src', 'img/star-off.png');
+
+		expect(imgs3.eq(0)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('should not cancel when it is readOnly', function() {
+		// given
+		var stars = $('.star').raty({ readOnly: true, score: 1 });
+
+		// when
+		stars.eq(0).raty('cancel');
+		stars.eq(1).raty('cancel');
+		stars.eq(2).raty('cancel');
+
+		// then
+		var imgs1 = stars.eq(0).children('img'),
+			imgs2 = stars.eq(1).children('img'),
+			imgs3 = stars.eq(2).children('img');
+
+		expect(imgs1.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs1.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(4)).toHaveAttr('src', 'img/star-off.png');
+		expect(stars.eq(0).children('input').val()).toEqual('1');
+
+		expect(imgs2.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs2.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(4)).toHaveAttr('src', 'img/star-off.png');
+		expect(stars.eq(1).children('input').val()).toEqual('1');
+
+		expect(imgs3.eq(0)).toHaveAttr('src', 'img/star-on.png');
+		expect(imgs3.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(4)).toHaveAttr('src', 'img/star-off.png');
+		expect(stars.eq(2).children('input').val()).toEqual('1');
+	});
+
+	it ('should set score as readonly when start with readOnly', function() {
+		// given
+		var stars = $('.star').raty();
+
+		// when
+		stars.eq(0).raty('readOnly', true);
+		stars.eq(1).raty('readOnly', true);
+		stars.eq(2).raty('readOnly', true);
+
+		// then
+		expect(stars.eq(0).children('input')).toHaveAttr('readonly', 'readonly');
+		expect(stars.eq(1).children('input')).toHaveAttr('readonly', 'readonly');
+		expect(stars.eq(2).children('input')).toHaveAttr('readonly', 'readonly');
+	});
+
+	it ('should rebind the cancel button after readOnly be enabled', function() {
+		// given
+		var stars = $('.star').raty({ cancel: true });
+
+		// when
+		stars.raty('readOnly', true).raty('readOnly', false).children('.raty-cancel').mouseenter();
+
+		// then
+		var imgs1 = stars.eq(0).children('img').not('.raty-cancel'),
+			imgs2 = stars.eq(1).children('img').not('.raty-cancel'),
+			imgs3 = stars.eq(2).children('img').not('.raty-cancel');
+
+		expect(imgs1.eq(0)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs1.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	
+		expect(imgs2.eq(0)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs2.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	
+		expect(imgs3.eq(0)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(1)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(2)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(3)).toHaveAttr('src', 'img/star-off.png');
+		expect(imgs3.eq(4)).toHaveAttr('src', 'img/star-off.png');
+	});
+
+	it ('[score] should set score on rating that is not read-only', function() {
+		// given
+		var stars = $('.star');
+
+		stars.raty();
+		stars.eq(1).raty('readOnly', true);
+
+		// when
+		stars.raty('score', 2);
+
+		// then
+		expect(stars.eq(0).children('input')).toHaveValue('2');
+	    expect(stars.eq(1).children('input').val()).toEqual('');
+	    expect(stars.eq(2).children('input')).toHaveValue('2');
+	});
+
+	it ('[click] should click on rating that is not read-only', function() {
+		// given
+		var stars = $('.star');
+
+		stars.raty({ click: function() { } });
+		stars.eq(1).raty('readOnly', true);
+
+		// when
+		stars.raty('click', 2);
+
+		// then
+		expect(stars.eq(0).children('input')).toHaveValue('2');
+	    expect(stars.eq(1).children('input').val()).toEqual('');
+	    expect(stars.eq(2).children('input')).toHaveValue('2');
+	});
+
+	it ('[cancel] should cancel all rating that is not read-only', function() {
+		// given
+		var stars = $('.star');
+
+		stars.raty({ score: 2 });
+		stars.eq(1).raty('readOnly', true);
+
+		// when
+		stars.raty('cancel');
+
+		// then
+		expect(stars.eq(0).children('input').val()).toEqual('');
+	    expect(stars.eq(1).children('input')).toHaveValue('2');
+	    expect(stars.eq(2).children('input').val()).toEqual('');
+	});
+
+});
Index: /sandbox/2.4.1-3/prototype/plugins/jq-raty/test/lib/jasmine.js
===================================================================
--- /sandbox/2.4.1-3/prototype/plugins/jq-raty/test/lib/jasmine.js	(revision 6512)
+++ /sandbox/2.4.1-3/prototype/plugins/jq-raty/test/lib/jasmine.js	(revision 6512)
@@ -0,0 +1,2476 @@
+var isCommonJS = typeof window == "undefined";
+
+/**
+ * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework.
+ *
+ * @namespace
+ */
+var jasmine = {};
+if (isCommonJS) exports.jasmine = jasmine;
+/**
+ * @private
+ */
+jasmine.unimplementedMethod_ = function() {
+  throw new Error("unimplemented method");
+};
+
+/**
+ * Use <code>jasmine.undefined</code> instead of <code>undefined</code>, since <code>undefined</code> is just
+ * a plain old variable and may be redefined by somebody else.
+ *
+ * @private
+ */
+jasmine.undefined = jasmine.___undefined___;
+
+/**
+ * Show diagnostic messages in the console if set to true
+ *
+ */
+jasmine.VERBOSE = false;
+
+/**
+ * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed.
+ *
+ */
+jasmine.DEFAULT_UPDATE_INTERVAL = 250;
+
+/**
+ * Default timeout interval in milliseconds for waitsFor() blocks.
+ */
+jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
+
+jasmine.getGlobal = function() {
+  function getGlobal() {
+    return this;
+  }
+
+  return getGlobal();
+};
+
+/**
+ * Allows for bound functions to be compared.  Internal use only.
+ *
+ * @ignore
+ * @private
+ * @param base {Object} bound 'this' for the function
+ * @param name {Function} function to find
+ */
+jasmine.bindOriginal_ = function(base, name) {
+  var original = base[name];
+  if (original.apply) {
+    return function() {
+      return original.apply(base, arguments);
+    };
+  } else {
+    // IE support
+    return jasmine.getGlobal()[name];
+  }
+};
+
+jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout');
+jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout');
+jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval');
+jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval');
+
+jasmine.MessageResult = function(values) {
+  this.type = 'log';
+  this.values = values;
+  this.trace = new Error(); // todo: test better
+};
+
+jasmine.MessageResult.prototype.toString = function() {
+  var text = "";
+  for (var i = 0; i < this.values.length; i++) {
+    if (i > 0) text += " ";
+    if (jasmine.isString_(this.values[i])) {
+      text += this.values[i];
+    } else {
+      text += jasmine.pp(this.values[i]);
+    }
+  }
+  return text;
+};
+
+jasmine.ExpectationResult = function(params) {
+  this.type = 'expect';
+  this.matcherName = params.matcherName;
+  this.passed_ = params.passed;
+  this.expected = params.expected;
+  this.actual = params.actual;
+  this.message = this.passed_ ? 'Passed.' : params.message;
+
+  var trace = (params.trace || new Error(this.message));
+  this.trace = this.passed_ ? '' : trace;
+};
+
+jasmine.ExpectationResult.prototype.toString = function () {
+  return this.message;
+};
+
+jasmine.ExpectationResult.prototype.passed = function () {
+  return this.passed_;
+};
+
+/**
+ * Getter for the Jasmine environment. Ensures one gets created
+ */
+jasmine.getEnv = function() {
+  var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();
+  return env;
+};
+
+/**
+ * @ignore
+ * @private
+ * @param value
+ * @returns {Boolean}
+ */
+jasmine.isArray_ = function(value) {
+  return jasmine.isA_("Array", value);
+};
+
+/**
+ * @ignore
+ * @private
+ * @param value
+ * @returns {Boolean}
+ */
+jasmine.isString_ = function(value) {
+  return jasmine.isA_("String", value);
+};
+
+/**
+ * @ignore
+ * @private
+ * @param value
+ * @returns {Boolean}
+ */
+jasmine.isNumber_ = function(value) {
+  return jasmine.isA_("Number", value);
+};
+
+/**
+ * @ignore
+ * @private
+ * @param {String} typeName
+ * @param value
+ * @returns {Boolean}
+ */
+jasmine.isA_ = function(typeName, value) {
+  return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';
+};
+
+/**
+ * Pretty printer for expecations.  Takes any object and turns it into a human-readable string.
+ *
+ * @param value {Object} an object to be outputted
+ * @returns {String}
+ */
+jasmine.pp = function(value) {
+  var stringPrettyPrinter = new jasmine.StringPrettyPrinter();
+  stringPrettyPrinter.format(value);
+  return stringPrettyPrinter.string;
+};
+
+/**
+ * Returns true if the object is a DOM Node.
+ *
+ * @param {Object} obj object to check
+ * @returns {Boolean}
+ */
+jasmine.isDomNode = function(obj) {
+  return obj.nodeType > 0;
+};
+
+/**
+ * Returns a matchable 'generic' object of the class type.  For use in expecations of type when values don't matter.
+ *
+ * @example
+ * // don't care about which function is passed in, as long as it's a function
+ * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function));
+ *
+ * @param {Class} clazz
+ * @returns matchable object of the type clazz
+ */
+jasmine.any = function(clazz) {
+  return new jasmine.Matchers.Any(clazz);
+};
+
+/**
+ * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks.
+ *
+ * Spies should be created in test setup, before expectations.  They can then be checked, using the standard Jasmine
+ * expectation syntax. Spies can be checked if they were called or not and what the calling params were.
+ *
+ * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs).
+ *
+ * Spies are torn down at the end of every spec.
+ *
+ * Note: Do <b>not</b> call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj.
+ *
+ * @example
+ * // a stub
+ * var myStub = jasmine.createSpy('myStub');  // can be used anywhere
+ *
+ * // spy example
+ * var foo = {
+ *   not: function(bool) { return !bool; }
+ * }
+ *
+ * // actual foo.not will not be called, execution stops
+ * spyOn(foo, 'not');
+
+ // foo.not spied upon, execution will continue to implementation
+ * spyOn(foo, 'not').andCallThrough();
+ *
+ * // fake example
+ * var foo = {
+ *   not: function(bool) { return !bool; }
+ * }
+ *
+ * // foo.not(val) will return val
+ * spyOn(foo, 'not').andCallFake(function(value) {return value;});
+ *
+ * // mock example
+ * foo.not(7 == 7);
+ * expect(foo.not).toHaveBeenCalled();
+ * expect(foo.not).toHaveBeenCalledWith(true);
+ *
+ * @constructor
+ * @see spyOn, jasmine.createSpy, jasmine.createSpyObj
+ * @param {String} name
+ */
+jasmine.Spy = function(name) {
+  /**
+   * The name of the spy, if provided.
+   */
+  this.identity = name || 'unknown';
+  /**
+   *  Is this Object a spy?
+   */
+  this.isSpy = true;
+  /**
+   * The actual function this spy stubs.
+   */
+  this.plan = function() {
+  };
+  /**
+   * Tracking of the most recent call to the spy.
+   * @example
+   * var mySpy = jasmine.createSpy('foo');
+   * mySpy(1, 2);
+   * mySpy.mostRecentCall.args = [1, 2];
+   */
+  this.mostRecentCall = {};
+
+  /**
+   * Holds arguments for each call to the spy, indexed by call count
+   * @example
+   * var mySpy = jasmine.createSpy('foo');
+   * mySpy(1, 2);
+   * mySpy(7, 8);
+   * mySpy.mostRecentCall.args = [7, 8];
+   * mySpy.argsForCall[0] = [1, 2];
+   * mySpy.argsForCall[1] = [7, 8];
+   */
+  this.argsForCall = [];
+  this.calls = [];
+};
+
+/**
+ * Tells a spy to call through to the actual implemenatation.
+ *
+ * @example
+ * var foo = {
+ *   bar: function() { // do some stuff }
+ * }
+ *
+ * // defining a spy on an existing property: foo.bar
+ * spyOn(foo, 'bar').andCallThrough();
+ */
+jasmine.Spy.prototype.andCallThrough = function() {
+  this.plan = this.originalValue;
+  return this;
+};
+
+/**
+ * For setting the return value of a spy.
+ *
+ * @example
+ * // defining a spy from scratch: foo() returns 'baz'
+ * var foo = jasmine.createSpy('spy on foo').andReturn('baz');
+ *
+ * // defining a spy on an existing property: foo.bar() returns 'baz'
+ * spyOn(foo, 'bar').andReturn('baz');
+ *
+ * @param {Object} value
+ */
+jasmine.Spy.prototype.andReturn = function(value) {
+  this.plan = function() {
+    return value;
+  };
+  return this;
+};
+
+/**
+ * For throwing an exception when a spy is called.
+ *
+ * @example
+ * // defining a spy from scratch: foo() throws an exception w/ message 'ouch'
+ * var foo = jasmine.createSpy('spy on foo').andThrow('baz');
+ *
+ * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch'
+ * spyOn(foo, 'bar').andThrow('baz');
+ *
+ * @param {String} exceptionMsg
+ */
+jasmine.Spy.prototype.andThrow = function(exceptionMsg) {
+  this.plan = function() {
+    throw exceptionMsg;
+  };
+  return this;
+};
+
+/**
+ * Calls an alternate implementation when a spy is called.
+ *
+ * @example
+ * var baz = function() {
+ *   // do some stuff, return something
+ * }
+ * // defining a spy from scratch: foo() calls the function baz
+ * var foo = jasmine.createSpy('spy on foo').andCall(baz);
+ *
+ * // defining a spy on an existing property: foo.bar() calls an anonymnous function
+ * spyOn(foo, 'bar').andCall(function() { return 'baz';} );
+ *
+ * @param {Function} fakeFunc
+ */
+jasmine.Spy.prototype.andCallFake = function(fakeFunc) {
+  this.plan = fakeFunc;
+  return this;
+};
+
+/**
+ * Resets all of a spy's the tracking variables so that it can be used again.
+ *
+ * @example
+ * spyOn(foo, 'bar');
+ *
+ * foo.bar();
+ *
+ * expect(foo.bar.callCount).toEqual(1);
+ *
+ * foo.bar.reset();
+ *
+ * expect(foo.bar.callCount).toEqual(0);
+ */
+jasmine.Spy.prototype.reset = function() {
+  this.wasCalled = false;
+  this.callCount = 0;
+  this.argsForCall = [];
+  this.calls = [];
+  this.mostRecentCall = {};
+};
+
+jasmine.createSpy = function(name) {
+
+  var spyObj = function() {
+    spyObj.wasCalled = true;
+    spyObj.callCount++;
+    var args = jasmine.util.argsToArray(arguments);
+    spyObj.mostRecentCall.object = this;
+    spyObj.mostRecentCall.args = args;
+    spyObj.argsForCall.push(args);
+    spyObj.calls.push({object: this, args: args});
+    return spyObj.plan.apply(this, arguments);
+  };
+
+  var spy = new jasmine.Spy(name);
+
+  for (var prop in spy) {
+    spyObj[prop] = spy[prop];
+  }
+
+  spyObj.reset();
+
+  return spyObj;
+};
+
+/**
+ * Determines whether an object is a spy.
+ *
+ * @param {jasmine.Spy|Object} putativeSpy
+ * @returns {Boolean}
+ */
+jasmine.isSpy = function(putativeSpy) {
+  return putativeSpy && putativeSpy.isSpy;
+};
+
+/**
+ * Creates a more complicated spy: an Object that has every property a function that is a spy.  Used for stubbing something
+ * large in one call.
+ *
+ * @param {String} baseName name of spy class
+ * @param {Array} methodNames array of names of methods to make spies
+ */
+jasmine.createSpyObj = function(baseName, methodNames) {
+  if (!jasmine.isArray_(methodNames) || methodNames.length === 0) {
+    throw new Error('createSpyObj requires a non-empty array of method names to create spies for');
+  }
+  var obj = {};
+  for (var i = 0; i < methodNames.length; i++) {
+    obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]);
+  }
+  return obj;
+};
+
+/**
+ * All parameters are pretty-printed and concatenated together, then written to the current spec's output.
+ *
+ * Be careful not to leave calls to <code>jasmine.log</code> in production code.
+ */
+jasmine.log = function() {
+  var spec = jasmine.getEnv().currentSpec;
+  spec.log.apply(spec, arguments);
+};
+
+/**
+ * Function that installs a spy on an existing object's method name.  Used within a Spec to create a spy.
+ *
+ * @example
+ * // spy example
+ * var foo = {
+ *   not: function(bool) { return !bool; }
+ * }
+ * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops
+ *
+ * @see jasmine.createSpy
+ * @param obj
+ * @param methodName
+ * @returns a Jasmine spy that can be chained with all spy methods
+ */
+var spyOn = function(obj, methodName) {
+  return jasmine.getEnv().currentSpec.spyOn(obj, methodName);
+};
+if (isCommonJS) exports.spyOn = spyOn;
+
+/**
+ * Creates a Jasmine spec that will be added to the current suite.
+ *
+ * // TODO: pending tests
+ *
+ * @example
+ * it('should be true', function() {
+ *   expect(true).toEqual(true);
+ * });
+ *
+ * @param {String} desc description of this specification
+ * @param {Function} func defines the preconditions and expectations of the spec
+ */
+var it = function(desc, func) {
+  return jasmine.getEnv().it(desc, func);
+};
+if (isCommonJS) exports.it = it;
+
+/**
+ * Creates a <em>disabled</em> Jasmine spec.
+ *
+ * A convenience method that allows existing specs to be disabled temporarily during development.
+ *
+ * @param {String} desc description of this specification
+ * @param {Function} func defines the preconditions and expectations of the spec
+ */
+var xit = function(desc, func) {
+  return jasmine.getEnv().xit(desc, func);
+};
+if (isCommonJS) exports.xit = xit;
+
+/**
+ * Starts a chain for a Jasmine expectation.
+ *
+ * It is passed an Object that is the actual value and should chain to one of the many
+ * jasmine.Matchers functions.
+ *
+ * @param {Object} actual Actual value to test against and expected value
+ */
+var expect = function(actual) {
+  return jasmine.getEnv().currentSpec.expect(actual);
+};
+if (isCommonJS) exports.expect = expect;
+
+/**
+ * Defines part of a jasmine spec.  Used in cominbination with waits or waitsFor in asynchrnous specs.
+ *
+ * @param {Function} func Function that defines part of a jasmine spec.
+ */
+var runs = function(func) {
+  jasmine.getEnv().currentSpec.runs(func);
+};
+if (isCommonJS) exports.runs = runs;
+
+/**
+ * Waits a fixed time period before moving to the next block.
+ *
+ * @deprecated Use waitsFor() instead
+ * @param {Number} timeout milliseconds to wait
+ */
+var waits = function(timeout) {
+  jasmine.getEnv().currentSpec.waits(timeout);
+};
+if (isCommonJS) exports.waits = waits;
+
+/**
+ * Waits for the latchFunction to return true before proceeding to the next block.
+ *
+ * @param {Function} latchFunction
+ * @param {String} optional_timeoutMessage
+ * @param {Number} optional_timeout
+ */
+var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
+  jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments);
+};
+if (isCommonJS) exports.waitsFor = waitsFor;
+
+/**
+ * A function that is called before each spec in a suite.
+ *
+ * Used for spec setup, including validating assumptions.
+ *
+ * @param {Function} beforeEachFunction
+ */
+var beforeEach = function(beforeEachFunction) {
+  jasmine.getEnv().beforeEach(beforeEachFunction);
+};
+if (isCommonJS) exports.beforeEach = beforeEach;
+
+/**
+ * A function that is called after each spec in a suite.
+ *
+ * Used for restoring any state that is hijacked during spec execution.
+ *
+ * @param {Function} afterEachFunction
+ */
+var afterEach = function(afterEachFunction) {
+  jasmine.getEnv().afterEach(afterEachFunction);
+};
+if (isCommonJS) exports.afterEach = afterEach;
+
+/**
+ * Defines a suite of specifications.
+ *
+ * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared
+ * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization
+ * of setup in some tests.
+ *
+ * @example
+ * // TODO: a simple suite
+ *
+ * // TODO: a simple suite with a nested describe block
+ *
+ * @param {String} description A string, usually the class under test.
+ * @param {Function} specDefinitions function that defines several specs.
+ */
+var describe = function(description, specDefinitions) {
+  return jasmine.getEnv().describe(description, specDefinitions);
+};
+if (isCommonJS) exports.describe = describe;
+
+/**
+ * Disables a suite of specifications.  Used to disable some suites in a file, or files, temporarily during development.
+ *
+ * @param {String} description A string, usually the class under test.
+ * @param {Function} specDefinitions function that defines several specs.
+ */
+var xdescribe = function(description, specDefinitions) {
+  return jasmine.getEnv().xdescribe(description, specDefinitions);
+};
+if (isCommonJS) exports.xdescribe = xdescribe;
+
+
+// Provide the XMLHttpRequest class for IE 5.x-6.x:
+jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() {
+  function tryIt(f) {
+    try {
+      return f();
+    } catch(e) {
+    }
+    return null;
+  }
+
+  var xhr = tryIt(function() {
+    return new ActiveXObject("Msxml2.XMLHTTP.6.0");
+  }) ||
+    tryIt(function() {
+      return new ActiveXObject("Msxml2.XMLHTTP.3.0");
+    }) ||
+    tryIt(function() {
+      return new ActiveXObject("Msxml2.XMLHTTP");
+    }) ||
+    tryIt(function() {
+      return new ActiveXObject("Microsoft.XMLHTTP");
+    });
+
+  if (!xhr) throw new Error("This browser does not support XMLHttpRequest.");
+
+  return xhr;
+} : XMLHttpRequest;
+/**
+ * @namespace
+ */
+jasmine.util = {};
+
+/**
+ * Declare that a child class inherit it's prototype from the parent class.
+ *
+ * @private
+ * @param {Function} childClass
+ * @param {Function} parentClass
+ */
+jasmine.util.inherit = function(childClass, parentClass) {
+  /**
+   * @private
+   */
+  var subclass = function() {
+  };
+  subclass.prototype = parentClass.prototype;
+  childClass.prototype = new subclass();
+};
+
+jasmine.util.formatException = function(e) {
+  var lineNumber;
+  if (e.line) {
+    lineNumber = e.line;
+  }
+  else if (e.lineNumber) {
+    lineNumber = e.lineNumber;
+  }
+
+  var file;
+
+  if (e.sourceURL) {
+    file = e.sourceURL;
+  }
+  else if (e.fileName) {
+    file = e.fileName;
+  }
+
+  var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString();
+
+  if (file && lineNumber) {
+    message += ' in ' + file + ' (line ' + lineNumber + ')';
+  }
+
+  return message;
+};
+
+jasmine.util.htmlEscape = function(str) {
+  if (!str) return str;
+  return str.replace(/&/g, '&amp;')
+    .replace(/</g, '&lt;')
+    .replace(/>/g, '&gt;');
+};
+
+jasmine.util.argsToArray = function(args) {
+  var arrayOfArgs = [];
+  for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]);
+  return arrayOfArgs;
+};
+
+jasmine.util.extend = function(destination, source) {
+  for (var property in source) destination[property] = source[property];
+  return destination;
+};
+
+/**
+ * Environment for Jasmine
+ *
+ * @constructor
+ */
+jasmine.Env = function() {
+  this.currentSpec = null;
+  this.currentSuite = null;
+  this.currentRunner_ = new jasmine.Runner(this);
+
+  this.reporter = new jasmine.MultiReporter();
+
+  this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL;
+  this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL;
+  this.lastUpdate = 0;
+  this.specFilter = function() {
+    return true;
+  };
+
+  this.nextSpecId_ = 0;
+  this.nextSuiteId_ = 0;
+  this.equalityTesters_ = [];
+
+  // wrap matchers
+  this.matchersClass = function() {
+    jasmine.Matchers.apply(this, arguments);
+  };
+  jasmine.util.inherit(this.matchersClass, jasmine.Matchers);
+
+  jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass);
+};
+
+
+jasmine.Env.prototype.setTimeout = jasmine.setTimeout;
+jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout;
+jasmine.Env.prototype.setInterval = jasmine.setInterval;
+jasmine.Env.prototype.clearInterval = jasmine.clearInterval;
+
+/**
+ * @returns an object containing jasmine version build info, if set.
+ */
+jasmine.Env.prototype.version = function () {
+  if (jasmine.version_) {
+    return jasmine.version_;
+  } else {
+    throw new Error('Version not set');
+  }
+};
+
+/**
+ * @returns string containing jasmine version build info, if set.
+ */
+jasmine.Env.prototype.versionString = function() {
+  if (!jasmine.version_) {
+    return "version unknown";
+  }
+
+  var version = this.version();
+  var versionString = version.major + "." + version.minor + "." + version.build;
+  if (version.release_candidate) {
+    versionString += ".rc" + version.release_candidate;
+  }
+  versionString += " revision " + version.revision;
+  return versionString;
+};
+
+/**
+ * @returns a sequential integer starting at 0
+ */
+jasmine.Env.prototype.nextSpecId = function () {
+  return this.nextSpecId_++;
+};
+
+/**
+ * @returns a sequential integer starting at 0
+ */
+jasmine.Env.prototype.nextSuiteId = function () {
+  return this.nextSuiteId_++;
+};
+
+/**
+ * Register a reporter to receive status updates from Jasmine.
+ * @param {jasmine.Reporter} reporter An object which will receive status updates.
+ */
+jasmine.Env.prototype.addReporter = function(reporter) {
+  this.reporter.addReporter(reporter);
+};
+
+jasmine.Env.prototype.execute = function() {
+  this.currentRunner_.execute();
+};
+
+jasmine.Env.prototype.describe = function(description, specDefinitions) {
+  var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite);
+
+  var parentSuite = this.currentSuite;
+  if (parentSuite) {
+    parentSuite.add(suite);
+  } else {
+    this.currentRunner_.add(suite);
+  }
+
+  this.currentSuite = suite;
+
+  var declarationError = null;
+  try {
+    specDefinitions.call(suite);
+  } catch(e) {
+    declarationError = e;
+  }
+
+  if (declarationError) {
+    this.it("encountered a declaration exception", function() {
+      throw declarationError;
+    });
+  }
+
+  this.currentSuite = parentSuite;
+
+  return suite;
+};
+
+jasmine.Env.prototype.beforeEach = function(beforeEachFunction) {
+  if (this.currentSuite) {
+    this.currentSuite.beforeEach(beforeEachFunction);
+  } else {
+    this.currentRunner_.beforeEach(beforeEachFunction);
+  }
+};
+
+jasmine.Env.prototype.currentRunner = function () {
+  return this.currentRunner_;
+};
+
+jasmine.Env.prototype.afterEach = function(afterEachFunction) {
+  if (this.currentSuite) {
+    this.currentSuite.afterEach(afterEachFunction);
+  } else {
+    this.currentRunner_.afterEach(afterEachFunction);
+  }
+
+};
+
+jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) {
+  return {
+    execute: function() {
+    }
+  };
+};
+
+jasmine.Env.prototype.it = function(description, func) {
+  var spec = new jasmine.Spec(this, this.currentSuite, description);
+  this.currentSuite.add(spec);
+  this.currentSpec = spec;
+
+  if (func) {
+    spec.runs(func);
+  }
+
+  return spec;
+};
+
+jasmine.Env.prototype.xit = function(desc, func) {
+  return {
+    id: this.nextSpecId(),
+    runs: function() {
+    }
+  };
+};
+
+jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) {
+  if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) {
+    return true;
+  }
+
+  a.__Jasmine_been_here_before__ = b;
+  b.__Jasmine_been_here_before__ = a;
+
+  var hasKey = function(obj, keyName) {
+    return obj !== null && obj[keyName] !== jasmine.undefined;
+  };
+
+  for (var property in b) {
+    if (!hasKey(a, property) && hasKey(b, property)) {
+      mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
+    }
+  }
+  for (property in a) {
+    if (!hasKey(b, property) && hasKey(a, property)) {
+      mismatchKeys.push("expected missing key '" + property + "', but present in actual.");
+    }
+  }
+  for (property in b) {
+    if (property == '__Jasmine_been_here_before__') continue;
+    if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) {
+      mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual.");
+    }
+  }
+
+  if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) {
+    mismatchValues.push("arrays were not the same length");
+  }
+
+  delete a.__Jasmine_been_here_before__;
+  delete b.__Jasmine_been_here_before__;
+  return (mismatchKeys.length === 0 && mismatchValues.length === 0);
+};
+
+jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
+  mismatchKeys = mismatchKeys || [];
+  mismatchValues = mismatchValues || [];
+
+  for (var i = 0; i < this.equalityTesters_.length; i++) {
+    var equalityTester = this.equalityTesters_[i];
+    var result = equalityTester(a, b, this, mismatchKeys, mismatchValues);
+    if (result !== jasmine.undefined) return result;
+  }
+
+  if (a === b) return true;
+
+  if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) {
+    return (a == jasmine.undefined && b == jasmine.undefined);
+  }
+
+  if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) {
+    return a === b;
+  }
+
+  if (a instanceof Date && b instanceof Date) {
+    return a.getTime() == b.getTime();
+  }
+
+  if (a instanceof jasmine.Matchers.Any) {
+    return a.matches(b);
+  }
+
+  if (b instanceof jasmine.Matchers.Any) {
+    return b.matches(a);
+  }
+
+  if (jasmine.isString_(a) && jasmine.isString_(b)) {
+    return (a == b);
+  }
+
+  if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) {
+    return (a == b);
+  }
+
+  if (typeof a === "object" && typeof b === "object") {
+    return this.compareObjects_(a, b, mismatchKeys, mismatchValues);
+  }
+
+  //Straight check
+  return (a === b);
+};
+
+jasmine.Env.prototype.contains_ = function(haystack, needle) {
+  if (jasmine.isArray_(haystack)) {
+    for (var i = 0; i < haystack.length; i++) {
+      if (this.equals_(haystack[i], needle)) return true;
+    }
+    return false;
+  }
+  return haystack.indexOf(needle) >= 0;
+};
+
+jasmine.Env.prototype.addEqualityTester = function(equalityTester) {
+  this.equalityTesters_.push(equalityTester);
+};
+/** No-op base class for Jasmine reporters.
+ *
+ * @constructor
+ */
+jasmine.Reporter = function() {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.Reporter.prototype.reportRunnerStarting = function(runner) {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.Reporter.prototype.reportRunnerResults = function(runner) {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.Reporter.prototype.reportSuiteResults = function(suite) {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.Reporter.prototype.reportSpecStarting = function(spec) {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.Reporter.prototype.reportSpecResults = function(spec) {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.Reporter.prototype.log = function(str) {
+};
+
+/**
+ * Blocks are functions with executable code that make up a spec.
+ *
+ * @constructor
+ * @param {jasmine.Env} env
+ * @param {Function} func
+ * @param {jasmine.Spec} spec
+ */
+jasmine.Block = function(env, func, spec) {
+  this.env = env;
+  this.func = func;
+  this.spec = spec;
+};
+
+jasmine.Block.prototype.execute = function(onComplete) {  
+  try {
+    this.func.apply(this.spec);
+  } catch (e) {
+    this.spec.fail(e);
+  }
+  onComplete();
+};
+/** JavaScript API reporter.
+ *
+ * @constructor
+ */
+jasmine.JsApiReporter = function() {
+  this.started = false;
+  this.finished = false;
+  this.suites_ = [];
+  this.results_ = {};
+};
+
+jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) {
+  this.started = true;
+  var suites = runner.topLevelSuites();
+  for (var i = 0; i < suites.length; i++) {
+    var suite = suites[i];
+    this.suites_.push(this.summarize_(suite));
+  }
+};
+
+jasmine.JsApiReporter.prototype.suites = function() {
+  return this.suites_;
+};
+
+jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) {
+  var isSuite = suiteOrSpec instanceof jasmine.Suite;
+  var summary = {
+    id: suiteOrSpec.id,
+    name: suiteOrSpec.description,
+    type: isSuite ? 'suite' : 'spec',
+    children: []
+  };
+  
+  if (isSuite) {
+    var children = suiteOrSpec.children();
+    for (var i = 0; i < children.length; i++) {
+      summary.children.push(this.summarize_(children[i]));
+    }
+  }
+  return summary;
+};
+
+jasmine.JsApiReporter.prototype.results = function() {
+  return this.results_;
+};
+
+jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) {
+  return this.results_[specId];
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) {
+  this.finished = true;
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) {
+  this.results_[spec.id] = {
+    messages: spec.results().getItems(),
+    result: spec.results().failedCount > 0 ? "failed" : "passed"
+  };
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.JsApiReporter.prototype.log = function(str) {
+};
+
+jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){
+  var results = {};
+  for (var i = 0; i < specIds.length; i++) {
+    var specId = specIds[i];
+    results[specId] = this.summarizeResult_(this.results_[specId]);
+  }
+  return results;
+};
+
+jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){
+  var summaryMessages = [];
+  var messagesLength = result.messages.length;
+  for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) {
+    var resultMessage = result.messages[messageIndex];
+    summaryMessages.push({
+      text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined,
+      passed: resultMessage.passed ? resultMessage.passed() : true,
+      type: resultMessage.type,
+      message: resultMessage.message,
+      trace: {
+        stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined
+      }
+    });
+  }
+
+  return {
+    result : result.result,
+    messages : summaryMessages
+  };
+};
+
+/**
+ * @constructor
+ * @param {jasmine.Env} env
+ * @param actual
+ * @param {jasmine.Spec} spec
+ */
+jasmine.Matchers = function(env, actual, spec, opt_isNot) {
+  this.env = env;
+  this.actual = actual;
+  this.spec = spec;
+  this.isNot = opt_isNot || false;
+  this.reportWasCalled_ = false;
+};
+
+// todo: @deprecated as of Jasmine 0.11, remove soon [xw]
+jasmine.Matchers.pp = function(str) {
+  throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!");
+};
+
+// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw]
+jasmine.Matchers.prototype.report = function(result, failing_message, details) {
+  throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs");
+};
+
+jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) {
+  for (var methodName in prototype) {
+    if (methodName == 'report') continue;
+    var orig = prototype[methodName];
+    matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig);
+  }
+};
+
+jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) {
+  return function() {
+    var matcherArgs = jasmine.util.argsToArray(arguments);
+    var result = matcherFunction.apply(this, arguments);
+
+    if (this.isNot) {
+      result = !result;
+    }
+
+    if (this.reportWasCalled_) return result;
+
+    var message;
+    if (!result) {
+      if (this.message) {
+        message = this.message.apply(this, arguments);
+        if (jasmine.isArray_(message)) {
+          message = message[this.isNot ? 1 : 0];
+        }
+      } else {
+        var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); });
+        message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate;
+        if (matcherArgs.length > 0) {
+          for (var i = 0; i < matcherArgs.length; i++) {
+            if (i > 0) message += ",";
+            message += " " + jasmine.pp(matcherArgs[i]);
+          }
+        }
+        message += ".";
+      }
+    }
+    var expectationResult = new jasmine.ExpectationResult({
+      matcherName: matcherName,
+      passed: result,
+      expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0],
+      actual: this.actual,
+      message: message
+    });
+    this.spec.addMatcherResult(expectationResult);
+    return jasmine.undefined;
+  };
+};
+
+
+
+
+/**
+ * toBe: compares the actual to the expected using ===
+ * @param expected
+ */
+jasmine.Matchers.prototype.toBe = function(expected) {
+  return this.actual === expected;
+};
+
+/**
+ * toNotBe: compares the actual to the expected using !==
+ * @param expected
+ * @deprecated as of 1.0. Use not.toBe() instead.
+ */
+jasmine.Matchers.prototype.toNotBe = function(expected) {
+  return this.actual !== expected;
+};
+
+/**
+ * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc.
+ *
+ * @param expected
+ */
+jasmine.Matchers.prototype.toEqual = function(expected) {
+  return this.env.equals_(this.actual, expected);
+};
+
+/**
+ * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual
+ * @param expected
+ * @deprecated as of 1.0. Use not.toNotEqual() instead.
+ */
+jasmine.Matchers.prototype.toNotEqual = function(expected) {
+  return !this.env.equals_(this.actual, expected);
+};
+
+/**
+ * Matcher that compares the actual to the expected using a regular expression.  Constructs a RegExp, so takes
+ * a pattern or a String.
+ *
+ * @param expected
+ */
+jasmine.Matchers.prototype.toMatch = function(expected) {
+  return new RegExp(expected).test(this.actual);
+};
+
+/**
+ * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch
+ * @param expected
+ * @deprecated as of 1.0. Use not.toMatch() instead.
+ */
+jasmine.Matchers.prototype.toNotMatch = function(expected) {
+  return !(new RegExp(expected).test(this.actual));
+};
+
+/**
+ * Matcher that compares the actual to jasmine.undefined.
+ */
+jasmine.Matchers.prototype.toBeDefined = function() {
+  return (this.actual !== jasmine.undefined);
+};
+
+/**
+ * Matcher that compares the actual to jasmine.undefined.
+ */
+jasmine.Matchers.prototype.toBeUndefined = function() {
+  return (this.actual === jasmine.undefined);
+};
+
+/**
+ * Matcher that compares the actual to null.
+ */
+jasmine.Matchers.prototype.toBeNull = function() {
+  return (this.actual === null);
+};
+
+/**
+ * Matcher that boolean not-nots the actual.
+ */
+jasmine.Matchers.prototype.toBeTruthy = function() {
+  return !!this.actual;
+};
+
+
+/**
+ * Matcher that boolean nots the actual.
+ */
+jasmine.Matchers.prototype.toBeFalsy = function() {
+  return !this.actual;
+};
+
+
+/**
+ * Matcher that checks to see if the actual, a Jasmine spy, was called.
+ */
+jasmine.Matchers.prototype.toHaveBeenCalled = function() {
+  if (arguments.length > 0) {
+    throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');
+  }
+
+  if (!jasmine.isSpy(this.actual)) {
+    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
+  }
+
+  this.message = function() {
+    return [
+      "Expected spy " + this.actual.identity + " to have been called.",
+      "Expected spy " + this.actual.identity + " not to have been called."
+    ];
+  };
+
+  return this.actual.wasCalled;
+};
+
+/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */
+jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled;
+
+/**
+ * Matcher that checks to see if the actual, a Jasmine spy, was not called.
+ *
+ * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead
+ */
+jasmine.Matchers.prototype.wasNotCalled = function() {
+  if (arguments.length > 0) {
+    throw new Error('wasNotCalled does not take arguments');
+  }
+
+  if (!jasmine.isSpy(this.actual)) {
+    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
+  }
+
+  this.message = function() {
+    return [
+      "Expected spy " + this.actual.identity + " to not have been called.",
+      "Expected spy " + this.actual.identity + " to have been called."
+    ];
+  };
+
+  return !this.actual.wasCalled;
+};
+
+/**
+ * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters.
+ *
+ * @example
+ *
+ */
+jasmine.Matchers.prototype.toHaveBeenCalledWith = function() {
+  var expectedArgs = jasmine.util.argsToArray(arguments);
+  if (!jasmine.isSpy(this.actual)) {
+    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
+  }
+  this.message = function() {
+    if (this.actual.callCount === 0) {
+      // todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw]
+      return [
+        "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.",
+        "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was."
+      ];
+    } else {
+      return [
+        "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall),
+        "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall)
+      ];
+    }
+  };
+
+  return this.env.contains_(this.actual.argsForCall, expectedArgs);
+};
+
+/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */
+jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith;
+
+/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */
+jasmine.Matchers.prototype.wasNotCalledWith = function() {
+  var expectedArgs = jasmine.util.argsToArray(arguments);
+  if (!jasmine.isSpy(this.actual)) {
+    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
+  }
+
+  this.message = function() {
+    return [
+      "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was",
+      "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was"
+    ];
+  };
+
+  return !this.env.contains_(this.actual.argsForCall, expectedArgs);
+};
+
+/**
+ * Matcher that checks that the expected item is an element in the actual Array.
+ *
+ * @param {Object} expected
+ */
+jasmine.Matchers.prototype.toContain = function(expected) {
+  return this.env.contains_(this.actual, expected);
+};
+
+/**
+ * Matcher that checks that the expected item is NOT an element in the actual Array.
+ *
+ * @param {Object} expected
+ * @deprecated as of 1.0. Use not.toNotContain() instead.
+ */
+jasmine.Matchers.prototype.toNotContain = function(expected) {
+  return !this.env.contains_(this.actual, expected);
+};
+
+jasmine.Matchers.prototype.toBeLessThan = function(expected) {
+  return this.actual < expected;
+};
+
+jasmine.Matchers.prototype.toBeGreaterThan = function(expected) {
+  return this.actual > expected;
+};
+
+/**
+ * Matcher that checks that the expected item is equal to the actual item
+ * up to a given level of decimal precision (default 2).
+ *
+ * @param {Number} expected
+ * @param {Number} precision
+ */
+jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) {
+  if (!(precision === 0)) {
+    precision = precision || 2;
+  }
+  var multiplier = Math.pow(10, precision);
+  var actual = Math.round(this.actual * multiplier);
+  expected = Math.round(expected * multiplier);
+  return expected == actual;
+};
+
+/**
+ * Matcher that checks that the expected exception was thrown by the actual.
+ *
+ * @param {String} expected
+ */
+jasmine.Matchers.prototype.toThrow = function(expected) {
+  var result = false;
+  var exception;
+  if (typeof this.actual != 'function') {
+    throw new Error('Actual is not a function');
+  }
+  try {
+    this.actual();
+  } catch (e) {
+    exception = e;
+  }
+  if (exception) {
+    result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected));
+  }
+
+  var not = this.isNot ? "not " : "";
+
+  this.message = function() {
+    if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {
+      return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' ');
+    } else {
+      return "Expected function to throw an exception.";
+    }
+  };
+
+  return result;
+};
+
+jasmine.Matchers.Any = function(expectedClass) {
+  this.expectedClass = expectedClass;
+};
+
+jasmine.Matchers.Any.prototype.matches = function(other) {
+  if (this.expectedClass == String) {
+    return typeof other == 'string' || other instanceof String;
+  }
+
+  if (this.expectedClass == Number) {
+    return typeof other == 'number' || other instanceof Number;
+  }
+
+  if (this.expectedClass == Function) {
+    return typeof other == 'function' || other instanceof Function;
+  }
+
+  if (this.expectedClass == Object) {
+    return typeof other == 'object';
+  }
+
+  return other instanceof this.expectedClass;
+};
+
+jasmine.Matchers.Any.prototype.toString = function() {
+  return '<jasmine.any(' + this.expectedClass + ')>';
+};
+
+/**
+ * @constructor
+ */
+jasmine.MultiReporter = function() {
+  this.subReporters_ = [];
+};
+jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter);
+
+jasmine.MultiReporter.prototype.addReporter = function(reporter) {
+  this.subReporters_.push(reporter);
+};
+
+(function() {
+  var functionNames = [
+    "reportRunnerStarting",
+    "reportRunnerResults",
+    "reportSuiteResults",
+    "reportSpecStarting",
+    "reportSpecResults",
+    "log"
+  ];
+  for (var i = 0; i < functionNames.length; i++) {
+    var functionName = functionNames[i];
+    jasmine.MultiReporter.prototype[functionName] = (function(functionName) {
+      return function() {
+        for (var j = 0; j < this.subReporters_.length; j++) {
+          var subReporter = this.subReporters_[j];
+          if (subReporter[functionName]) {
+            subReporter[functionName].apply(subReporter, arguments);
+          }
+        }
+      };
+    })(functionName);
+  }
+})();
+/**
+ * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults
+ *
+ * @constructor
+ */
+jasmine.NestedResults = function() {
+  /**
+   * The total count of results
+   */
+  this.totalCount = 0;
+  /**
+   * Number of passed results
+   */
+  this.passedCount = 0;
+  /**
+   * Number of failed results
+   */
+  this.failedCount = 0;
+  /**
+   * Was this suite/spec skipped?
+   */
+  this.skipped = false;
+  /**
+   * @ignore
+   */
+  this.items_ = [];
+};
+
+/**
+ * Roll up the result counts.
+ *
+ * @param result
+ */
+jasmine.NestedResults.prototype.rollupCounts = function(result) {
+  this.totalCount += result.totalCount;
+  this.passedCount += result.passedCount;
+  this.failedCount += result.failedCount;
+};
+
+/**
+ * Adds a log message.
+ * @param values Array of message parts which will be concatenated later.
+ */
+jasmine.NestedResults.prototype.log = function(values) {
+  this.items_.push(new jasmine.MessageResult(values));
+};
+
+/**
+ * Getter for the results: message & results.
+ */
+jasmine.NestedResults.prototype.getItems = function() {
+  return this.items_;
+};
+
+/**
+ * Adds a result, tracking counts (total, passed, & failed)
+ * @param {jasmine.ExpectationResult|jasmine.NestedResults} result
+ */
+jasmine.NestedResults.prototype.addResult = function(result) {
+  if (result.type != 'log') {
+    if (result.items_) {
+      this.rollupCounts(result);
+    } else {
+      this.totalCount++;
+      if (result.passed()) {
+        this.passedCount++;
+      } else {
+        this.failedCount++;
+      }
+    }
+  }
+  this.items_.push(result);
+};
+
+/**
+ * @returns {Boolean} True if <b>everything</b> below passed
+ */
+jasmine.NestedResults.prototype.passed = function() {
+  return this.passedCount === this.totalCount;
+};
+/**
+ * Base class for pretty printing for expectation results.
+ */
+jasmine.PrettyPrinter = function() {
+  this.ppNestLevel_ = 0;
+};
+
+/**
+ * Formats a value in a nice, human-readable string.
+ *
+ * @param value
+ */
+jasmine.PrettyPrinter.prototype.format = function(value) {
+  if (this.ppNestLevel_ > 40) {
+    throw new Error('jasmine.PrettyPrinter: format() nested too deeply!');
+  }
+
+  this.ppNestLevel_++;
+  try {
+    if (value === jasmine.undefined) {
+      this.emitScalar('undefined');
+    } else if (value === null) {
+      this.emitScalar('null');
+    } else if (value === jasmine.getGlobal()) {
+      this.emitScalar('<global>');
+    } else if (value instanceof jasmine.Matchers.Any) {
+      this.emitScalar(value.toString());
+    } else if (typeof value === 'string') {
+      this.emitString(value);
+    } else if (jasmine.isSpy(value)) {
+      this.emitScalar("spy on " + value.identity);
+    } else if (value instanceof RegExp) {
+      this.emitScalar(value.toString());
+    } else if (typeof value === 'function') {
+      this.emitScalar('Function');
+    } else if (typeof value.nodeType === 'number') {
+      this.emitScalar('HTMLNode');
+    } else if (value instanceof Date) {
+      this.emitScalar('Date(' + value + ')');
+    } else if (value.__Jasmine_been_here_before__) {
+      this.emitScalar('<circular reference: ' + (jasmine.isArray_(value) ? 'Array' : 'Object') + '>');
+    } else if (jasmine.isArray_(value) || typeof value == 'object') {
+      value.__Jasmine_been_here_before__ = true;
+      if (jasmine.isArray_(value)) {
+        this.emitArray(value);
+      } else {
+        this.emitObject(value);
+      }
+      delete value.__Jasmine_been_here_before__;
+    } else {
+      this.emitScalar(value.toString());
+    }
+  } finally {
+    this.ppNestLevel_--;
+  }
+};
+
+jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {
+  for (var property in obj) {
+    if (property == '__Jasmine_been_here_before__') continue;
+    fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined && 
+                                         obj.__lookupGetter__(property) !== null) : false);
+  }
+};
+
+jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_;
+jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_;
+jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_;
+jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_;
+
+jasmine.StringPrettyPrinter = function() {
+  jasmine.PrettyPrinter.call(this);
+
+  this.string = '';
+};
+jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter);
+
+jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) {
+  this.append(value);
+};
+
+jasmine.StringPrettyPrinter.prototype.emitString = function(value) {
+  this.append("'" + value + "'");
+};
+
+jasmine.StringPrettyPrinter.prototype.emitArray = function(array) {
+  this.append('[ ');
+  for (var i = 0; i < array.length; i++) {
+    if (i > 0) {
+      this.append(', ');
+    }
+    this.format(array[i]);
+  }
+  this.append(' ]');
+};
+
+jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) {
+  var self = this;
+  this.append('{ ');
+  var first = true;
+
+  this.iterateObject(obj, function(property, isGetter) {
+    if (first) {
+      first = false;
+    } else {
+      self.append(', ');
+    }
+
+    self.append(property);
+    self.append(' : ');
+    if (isGetter) {
+      self.append('<getter>');
+    } else {
+      self.format(obj[property]);
+    }
+  });
+
+  this.append(' }');
+};
+
+jasmine.StringPrettyPrinter.prototype.append = function(value) {
+  this.string += value;
+};
+jasmine.Queue = function(env) {
+  this.env = env;
+  this.blocks = [];
+  this.running = false;
+  this.index = 0;
+  this.offset = 0;
+  this.abort = false;
+};
+
+jasmine.Queue.prototype.addBefore = function(block) {
+  this.blocks.unshift(block);
+};
+
+jasmine.Queue.prototype.add = function(block) {
+  this.blocks.push(block);
+};
+
+jasmine.Queue.prototype.insertNext = function(block) {
+  this.blocks.splice((this.index + this.offset + 1), 0, block);
+  this.offset++;
+};
+
+jasmine.Queue.prototype.start = function(onComplete) {
+  this.running = true;
+  this.onComplete = onComplete;
+  this.next_();
+};
+
+jasmine.Queue.prototype.isRunning = function() {
+  return this.running;
+};
+
+jasmine.Queue.LOOP_DONT_RECURSE = true;
+
+jasmine.Queue.prototype.next_ = function() {
+  var self = this;
+  var goAgain = true;
+
+  while (goAgain) {
+    goAgain = false;
+    
+    if (self.index < self.blocks.length && !this.abort) {
+      var calledSynchronously = true;
+      var completedSynchronously = false;
+
+      var onComplete = function () {
+        if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {
+          completedSynchronously = true;
+          return;
+        }
+
+        if (self.blocks[self.index].abort) {
+          self.abort = true;
+        }
+
+        self.offset = 0;
+        self.index++;
+
+        var now = new Date().getTime();
+        if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {
+          self.env.lastUpdate = now;
+          self.env.setTimeout(function() {
+            self.next_();
+          }, 0);
+        } else {
+          if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {
+            goAgain = true;
+          } else {
+            self.next_();
+          }
+        }
+      };
+      self.blocks[self.index].execute(onComplete);
+
+      calledSynchronously = false;
+      if (completedSynchronously) {
+        onComplete();
+      }
+      
+    } else {
+      self.running = false;
+      if (self.onComplete) {
+        self.onComplete();
+      }
+    }
+  }
+};
+
+jasmine.Queue.prototype.results = function() {
+  var results = new jasmine.NestedResults();
+  for (var i = 0; i < this.blocks.length; i++) {
+    if (this.blocks[i].results) {
+      results.addResult(this.blocks[i].results());
+    }
+  }
+  return results;
+};
+
+
+/**
+ * Runner
+ *
+ * @constructor
+ * @param {jasmine.Env} env
+ */
+jasmine.Runner = function(env) {
+  var self = this;
+  self.env = env;
+  self.queue = new jasmine.Queue(env);
+  self.before_ = [];
+  self.after_ = [];
+  self.suites_ = [];
+};
+
+jasmine.Runner.prototype.execute = function() {
+  var self = this;
+  if (self.env.reporter.reportRunnerStarting) {
+    self.env.reporter.reportRunnerStarting(this);
+  }
+  self.queue.start(function () {
+    self.finishCallback();
+  });
+};
+
+jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) {
+  beforeEachFunction.typeName = 'beforeEach';
+  this.before_.splice(0,0,beforeEachFunction);
+};
+
+jasmine.Runner.prototype.afterEach = function(afterEachFunction) {
+  afterEachFunction.typeName = 'afterEach';
+  this.after_.splice(0,0,afterEachFunction);
+};
+
+
+jasmine.Runner.prototype.finishCallback = function() {
+  this.env.reporter.reportRunnerResults(this);
+};
+
+jasmine.Runner.prototype.addSuite = function(suite) {
+  this.suites_.push(suite);
+};
+
+jasmine.Runner.prototype.add = function(block) {
+  if (block instanceof jasmine.Suite) {
+    this.addSuite(block);
+  }
+  this.queue.add(block);
+};
+
+jasmine.Runner.prototype.specs = function () {
+  var suites = this.suites();
+  var specs = [];
+  for (var i = 0; i < suites.length; i++) {
+    specs = specs.concat(suites[i].specs());
+  }
+  return specs;
+};
+
+jasmine.Runner.prototype.suites = function() {
+  return this.suites_;
+};
+
+jasmine.Runner.prototype.topLevelSuites = function() {
+  var topLevelSuites = [];
+  for (var i = 0; i < this.suites_.length; i++) {
+    if (!this.suites_[i].parentSuite) {
+      topLevelSuites.push(this.suites_[i]);
+    }
+  }
+  return topLevelSuites;
+};
+
+jasmine.Runner.prototype.results = function() {
+  return this.queue.results();
+};
+/**
+ * Internal representation of a Jasmine specification, or test.
+ *
+ * @constructor
+ * @param {jasmine.Env} env
+ * @param {jasmine.Suite} suite
+ * @param {String} description
+ */
+jasmine.Spec = function(env, suite, description) {
+  if (!env) {
+    throw new Error('jasmine.Env() required');
+  }
+  if (!suite) {
+    throw new Error('jasmine.Suite() required');
+  }
+  var spec = this;
+  spec.id = env.nextSpecId ? env.nextSpecId() : null;
+  spec.env = env;
+  spec.suite = suite;
+  spec.description = description;
+  spec.queue = new jasmine.Queue(env);
+
+  spec.afterCallbacks = [];
+  spec.spies_ = [];
+
+  spec.results_ = new jasmine.NestedResults();
+  spec.results_.description = description;
+  spec.matchersClass = null;
+};
+
+jasmine.Spec.prototype.getFullName = function() {
+  return this.suite.getFullName() + ' ' + this.description + '.';
+};
+
+
+jasmine.Spec.prototype.results = function() {
+  return this.results_;
+};
+
+/**
+ * All parameters are pretty-printed and concatenated together, then written to the spec's output.
+ *
+ * Be careful not to leave calls to <code>jasmine.log</code> in production code.
+ */
+jasmine.Spec.prototype.log = function() {
+  return this.results_.log(arguments);
+};
+
+jasmine.Spec.prototype.runs = function (func) {
+  var block = new jasmine.Block(this.env, func, this);
+  this.addToQueue(block);
+  return this;
+};
+
+jasmine.Spec.prototype.addToQueue = function (block) {
+  if (this.queue.isRunning()) {
+    this.queue.insertNext(block);
+  } else {
+    this.queue.add(block);
+  }
+};
+
+/**
+ * @param {jasmine.ExpectationResult} result
+ */
+jasmine.Spec.prototype.addMatcherResult = function(result) {
+  this.results_.addResult(result);
+};
+
+jasmine.Spec.prototype.expect = function(actual) {
+  var positive = new (this.getMatchersClass_())(this.env, actual, this);
+  positive.not = new (this.getMatchersClass_())(this.env, actual, this, true);
+  return positive;
+};
+
+/**
+ * Waits a fixed time period before moving to the next block.
+ *
+ * @deprecated Use waitsFor() instead
+ * @param {Number} timeout milliseconds to wait
+ */
+jasmine.Spec.prototype.waits = function(timeout) {
+  var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this);
+  this.addToQueue(waitsFunc);
+  return this;
+};
+
+/**
+ * Waits for the latchFunction to return true before proceeding to the next block.
+ *
+ * @param {Function} latchFunction
+ * @param {String} optional_timeoutMessage
+ * @param {Number} optional_timeout
+ */
+jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
+  var latchFunction_ = null;
+  var optional_timeoutMessage_ = null;
+  var optional_timeout_ = null;
+
+  for (var i = 0; i < arguments.length; i++) {
+    var arg = arguments[i];
+    switch (typeof arg) {
+      case 'function':
+        latchFunction_ = arg;
+        break;
+      case 'string':
+        optional_timeoutMessage_ = arg;
+        break;
+      case 'number':
+        optional_timeout_ = arg;
+        break;
+    }
+  }
+
+  var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this);
+  this.addToQueue(waitsForFunc);
+  return this;
+};
+
+jasmine.Spec.prototype.fail = function (e) {
+  var expectationResult = new jasmine.ExpectationResult({
+    passed: false,
+    message: e ? jasmine.util.formatException(e) : 'Exception',
+    trace: { stack: e.stack }
+  });
+  this.results_.addResult(expectationResult);
+};
+
+jasmine.Spec.prototype.getMatchersClass_ = function() {
+  return this.matchersClass || this.env.matchersClass;
+};
+
+jasmine.Spec.prototype.addMatchers = function(matchersPrototype) {
+  var parent = this.getMatchersClass_();
+  var newMatchersClass = function() {
+    parent.apply(this, arguments);
+  };
+  jasmine.util.inherit(newMatchersClass, parent);
+  jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass);
+  this.matchersClass = newMatchersClass;
+};
+
+jasmine.Spec.prototype.finishCallback = function() {
+  this.env.reporter.reportSpecResults(this);
+};
+
+jasmine.Spec.prototype.finish = function(onComplete) {
+  this.removeAllSpies();
+  this.finishCallback();
+  if (onComplete) {
+    onComplete();
+  }
+};
+
+jasmine.Spec.prototype.after = function(doAfter) {
+  if (this.queue.isRunning()) {
+    this.queue.add(new jasmine.Block(this.env, doAfter, this));
+  } else {
+    this.afterCallbacks.unshift(doAfter);
+  }
+};
+
+jasmine.Spec.prototype.execute = function(onComplete) {
+  var spec = this;
+  if (!spec.env.specFilter(spec)) {
+    spec.results_.skipped = true;
+    spec.finish(onComplete);
+    return;
+  }
+
+  this.env.reporter.reportSpecStarting(this);
+
+  spec.env.currentSpec = spec;
+
+  spec.addBeforesAndAftersToQueue();
+
+  spec.queue.start(function () {
+    spec.finish(onComplete);
+  });
+};
+
+jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() {
+  var runner = this.env.currentRunner();
+  var i;
+
+  for (var suite = this.suite; suite; suite = suite.parentSuite) {
+    for (i = 0; i < suite.before_.length; i++) {
+      this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this));
+    }
+  }
+  for (i = 0; i < runner.before_.length; i++) {
+    this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this));
+  }
+  for (i = 0; i < this.afterCallbacks.length; i++) {
+    this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this));
+  }
+  for (suite = this.suite; suite; suite = suite.parentSuite) {
+    for (i = 0; i < suite.after_.length; i++) {
+      this.queue.add(new jasmine.Block(this.env, suite.after_[i], this));
+    }
+  }
+  for (i = 0; i < runner.after_.length; i++) {
+    this.queue.add(new jasmine.Block(this.env, runner.after_[i], this));
+  }
+};
+
+jasmine.Spec.prototype.explodes = function() {
+  throw 'explodes function should not have been called';
+};
+
+jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) {
+  if (obj == jasmine.undefined) {
+    throw "spyOn could not find an object to spy upon for " + methodName + "()";
+  }
+
+  if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) {
+    throw methodName + '() method does not exist';
+  }
+
+  if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) {
+    throw new Error(methodName + ' has already been spied upon');
+  }
+
+  var spyObj = jasmine.createSpy(methodName);
+
+  this.spies_.push(spyObj);
+  spyObj.baseObj = obj;
+  spyObj.methodName = methodName;
+  spyObj.originalValue = obj[methodName];
+
+  obj[methodName] = spyObj;
+
+  return spyObj;
+};
+
+jasmine.Spec.prototype.removeAllSpies = function() {
+  for (var i = 0; i < this.spies_.length; i++) {
+    var spy = this.spies_[i];
+    spy.baseObj[spy.methodName] = spy.originalValue;
+  }
+  this.spies_ = [];
+};
+
+/**
+ * Internal representation of a Jasmine suite.
+ *
+ * @constructor
+ * @param {jasmine.Env} env
+ * @param {String} description
+ * @param {Function} specDefinitions
+ * @param {jasmine.Suite} parentSuite
+ */
+jasmine.Suite = function(env, description, specDefinitions, parentSuite) {
+  var self = this;
+  self.id = env.nextSuiteId ? env.nextSuiteId() : null;
+  self.description = description;
+  self.queue = new jasmine.Queue(env);
+  self.parentSuite = parentSuite;
+  self.env = env;
+  self.before_ = [];
+  self.after_ = [];
+  self.children_ = [];
+  self.suites_ = [];
+  self.specs_ = [];
+};
+
+jasmine.Suite.prototype.getFullName = function() {
+  var fullName = this.description;
+  for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {
+    fullName = parentSuite.description + ' ' + fullName;
+  }
+  return fullName;
+};
+
+jasmine.Suite.prototype.finish = function(onComplete) {
+  this.env.reporter.reportSuiteResults(this);
+  this.finished = true;
+  if (typeof(onComplete) == 'function') {
+    onComplete();
+  }
+};
+
+jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) {
+  beforeEachFunction.typeName = 'beforeEach';
+  this.before_.unshift(beforeEachFunction);
+};
+
+jasmine.Suite.prototype.afterEach = function(afterEachFunction) {
+  afterEachFunction.typeName = 'afterEach';
+  this.after_.unshift(afterEachFunction);
+};
+
+jasmine.Suite.prototype.results = function() {
+  return this.queue.results();
+};
+
+jasmine.Suite.prototype.add = function(suiteOrSpec) {
+  this.children_.push(suiteOrSpec);
+  if (suiteOrSpec instanceof jasmine.Suite) {
+    this.suites_.push(suiteOrSpec);
+    this.env.currentRunner().addSuite(suiteOrSpec);
+  } else {
+    this.specs_.push(suiteOrSpec);
+  }
+  this.queue.add(suiteOrSpec);
+};
+
+jasmine.Suite.prototype.specs = function() {
+  return this.specs_;
+};
+
+jasmine.Suite.prototype.suites = function() {
+  return this.suites_;
+};
+
+jasmine.Suite.prototype.children = function() {
+  return this.children_;
+};
+
+jasmine.Suite.prototype.execute = function(onComplete) {
+  var self = this;
+  this.queue.start(function () {
+    self.finish(onComplete);
+  });
+};
+jasmine.WaitsBlock = function(env, timeout, spec) {
+  this.timeout = timeout;
+  jasmine.Block.call(this, env, null, spec);
+};
+
+jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block);
+
+jasmine.WaitsBlock.prototype.execute = function (onComplete) {
+  if (jasmine.VERBOSE) {
+    this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');
+  }
+  this.env.setTimeout(function () {
+    onComplete();
+  }, this.timeout);
+};
+/**
+ * A block which waits for some condition to become true, with timeout.
+ *
+ * @constructor
+ * @extends jasmine.Block
+ * @param {jasmine.Env} env The Jasmine environment.
+ * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true.
+ * @param {Function} latchFunction A function which returns true when the desired condition has been met.
+ * @param {String} message The message to display if the desired condition hasn't been met within the given time period.
+ * @param {jasmine.Spec} spec The Jasmine spec.
+ */
+jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) {
+  this.timeout = timeout || env.defaultTimeoutInterval;
+  this.latchFunction = latchFunction;
+  this.message = message;
+  this.totalTimeSpentWaitingForLatch = 0;
+  jasmine.Block.call(this, env, null, spec);
+};
+jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);
+
+jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10;
+
+jasmine.WaitsForBlock.prototype.execute = function(onComplete) {
+  if (jasmine.VERBOSE) {
+    this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen'));
+  }
+  var latchFunctionResult;
+  try {
+    latchFunctionResult = this.latchFunction.apply(this.spec);
+  } catch (e) {
+    this.spec.fail(e);
+    onComplete();
+    return;
+  }
+
+  if (latchFunctionResult) {
+    onComplete();
+  } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) {
+    var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen');
+    this.spec.fail({
+      name: 'timeout',
+      message: message
+    });
+
+    this.abort = true;
+    onComplete();
+  } else {
+    this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT;
+    var self = this;
+    this.env.setTimeout(function() {
+      self.execute(onComplete);
+    }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);
+  }
+};
+// Mock setTimeout, clearTimeout
+// Contributed by Pivotal Computer Systems, www.pivotalsf.com
+
+jasmine.FakeTimer = function() {
+  this.reset();
+
+  var self = this;
+  self.setTimeout = function(funcToCall, millis) {
+    self.timeoutsMade++;
+    self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false);
+    return self.timeoutsMade;
+  };
+
+  self.setInterval = function(funcToCall, millis) {
+    self.timeoutsMade++;
+    self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true);
+    return self.timeoutsMade;
+  };
+
+  self.clearTimeout = function(timeoutKey) {
+    self.scheduledFunctions[timeoutKey] = jasmine.undefined;
+  };
+
+  self.clearInterval = function(timeoutKey) {
+    self.scheduledFunctions[timeoutKey] = jasmine.undefined;
+  };
+
+};
+
+jasmine.FakeTimer.prototype.reset = function() {
+  this.timeoutsMade = 0;
+  this.scheduledFunctions = {};
+  this.nowMillis = 0;
+};
+
+jasmine.FakeTimer.prototype.tick = function(millis) {
+  var oldMillis = this.nowMillis;
+  var newMillis = oldMillis + millis;
+  this.runFunctionsWithinRange(oldMillis, newMillis);
+  this.nowMillis = newMillis;
+};
+
+jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) {
+  var scheduledFunc;
+  var funcsToRun = [];
+  for (var timeoutKey in this.scheduledFunctions) {
+    scheduledFunc = this.scheduledFunctions[timeoutKey];
+    if (scheduledFunc != jasmine.undefined &&
+        scheduledFunc.runAtMillis >= oldMillis &&
+        scheduledFunc.runAtMillis <= nowMillis) {
+      funcsToRun.push(scheduledFunc);
+      this.scheduledFunctions[timeoutKey] = jasmine.undefined;
+    }
+  }
+
+  if (funcsToRun.length > 0) {
+    funcsToRun.sort(function(a, b) {
+      return a.runAtMillis - b.runAtMillis;
+    });
+    for (var i = 0; i < funcsToRun.length; ++i) {
+      try {
+        var funcToRun = funcsToRun[i];
+        this.nowMillis = funcToRun.runAtMillis;
+        funcToRun.funcToCall();
+        if (funcToRun.recurring) {
+          this.scheduleFunction(funcToRun.timeoutKey,
+              funcToRun.funcToCall,
+              funcToRun.millis,
+              true);
+        }
+      } catch(e) {
+      }
+    }
+    this.runFunctionsWithinRange(oldMillis, nowMillis);
+  }
+};
+
+jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) {
+  this.scheduledFunctions[timeoutKey] = {
+    runAtMillis: this.nowMillis + millis,
+    funcToCall: funcToCall,
+    recurring: recurring,
+    timeoutKey: timeoutKey,
+    millis: millis
+  };
+};
+
+/**
+ * @namespace
+ */
+jasmine.Clock = {
+  defaultFakeTimer: new jasmine.FakeTimer(),
+
+  reset: function() {
+    jasmine.Clock.assertInstalled();
+    jasmine.Clock.defaultFakeTimer.reset();
+  },
+
+  tick: function(millis) {
+    jasmine.Clock.assertInstalled();
+    jasmine.Clock.defaultFakeTimer.tick(millis);
+  },
+
+  runFunctionsWithinRange: function(oldMillis, nowMillis) {
+    jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis);
+  },
+
+  scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) {
+    jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring);
+  },
+
+  useMock: function() {
+    if (!jasmine.Clock.isInstalled()) {
+      var spec = jasmine.getEnv().currentSpec;
+      spec.after(jasmine.Clock.uninstallMock);
+
+      jasmine.Clock.installMock();
+    }
+  },
+
+  installMock: function() {
+    jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer;
+  },
+
+  uninstallMock: function() {
+    jasmine.Clock.assertInstalled();
+    jasmine.Clock.installed = jasmine.Clock.real;
+  },
+
+  real: {
+    setTimeout: jasmine.getGlobal().setTimeout,
+    clearTimeout: jasmine.getGlobal().clearTimeout,
+    setInterval: jasmine.getGlobal().setInterval,
+    clearInterval: jasmine.getGlobal().clearInterval
+  },
+
+  assertInstalled: function() {
+    if (!jasmine.Clock.isInstalled()) {
+      throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");
+    }
+  },
+
+  isInstalled: function() {
+    return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer;
+  },
+
+  installed: null
+};
+jasmine.Clock.installed = jasmine.Clock.real;
+
+//else for IE support
+jasmine.getGlobal().setTimeout = function(funcToCall, millis) {
+  if (jasmine.Clock.installed.setTimeout.apply) {
+    return jasmine.Clock.installed.setTimeout.apply(this, arguments);
+  } else {
+    return jasmine.Clock.installed.setTimeout(funcToCall, millis);
+  }
+};
+
+jasmine.getGlobal().setInterval = function(funcToCall, millis) {
+  if (jasmine.Clock.installed.setInterval.apply) {
+    return jasmine.Clock.installed.setInterval.apply(this, arguments);
+  } else {
+    return jasmine.Clock.installed.setInterval(funcToCall, millis);
+  }
+};
+
+jasmine.getGlobal().clearTimeout = function(timeoutKey) {
+  if (jasmine.Clock.installed.clearTimeout.apply) {
+    return jasmine.Clock.installed.clearTimeout.apply(this, arguments);
+  } else {
+    return jasmine.Clock.installed.clearTimeout(timeoutKey);
+  }
+};
+
+jasmine.getGlobal().clearInterval = function(timeoutKey) {
+  if (jasmine.Clock.installed.clearTimeout.apply) {
+    return jasmine.Clock.installed.clearInterval.apply(this, arguments);
+  } else {
+    return jasmine.Clock.installed.clearInterval(timeoutKey);
+  }
+};
+
+jasmine.version_= {
+  "major": 1,
+  "minor": 1,
+  "build": 0,
+  "revision": 1315677058
+};
Index: /sandbox/2.4.1-3/prototype/plugins/jq-raty/test/lib/jasmine-html.js
===================================================================
--- /sandbox/2.4.1-3/prototype/plugins/jq-raty/test/lib/jasmine-html.js	(revision 6512)
+++ /sandbox/2.4.1-3/prototype/plugins/jq-raty/test/lib/jasmine-html.js	(revision 6512)
@@ -0,0 +1,190 @@
+jasmine.TrivialReporter = function(doc) {
+  this.document = doc || document;
+  this.suiteDivs = {};
+  this.logRunningSpecs = false;
+};
+
+jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
+  var el = document.createElement(type);
+
+  for (var i = 2; i < arguments.length; i++) {
+    var child = arguments[i];
+
+    if (typeof child === 'string') {
+      el.appendChild(document.createTextNode(child));
+    } else {
+      if (child) { el.appendChild(child); }
+    }
+  }
+
+  for (var attr in attrs) {
+    if (attr == "className") {
+      el[attr] = attrs[attr];
+    } else {
+      el.setAttribute(attr, attrs[attr]);
+    }
+  }
+
+  return el;
+};
+
+jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
+  var showPassed, showSkipped;
+
+  this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' },
+      this.createDom('div', { className: 'banner' },
+        this.createDom('div', { className: 'logo' },
+            this.createDom('span', { className: 'title' }, "Jasmine"),
+            this.createDom('span', { className: 'version' }, runner.env.versionString())),
+        this.createDom('div', { className: 'options' },
+            "Show ",
+            showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }),
+            this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "),
+            showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }),
+            this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped")
+            )
+          ),
+
+      this.runnerDiv = this.createDom('div', { className: 'runner running' },
+          this.createDom('a', { className: 'run_spec', href: '?' }, "run all"),
+          this.runnerMessageSpan = this.createDom('span', {}, "Running..."),
+          this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, ""))
+      );
+
+  this.document.body.appendChild(this.outerDiv);
+
+  var suites = runner.suites();
+  for (var i = 0; i < suites.length; i++) {
+    var suite = suites[i];
+    var suiteDiv = this.createDom('div', { className: 'suite' },
+        this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"),
+        this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));
+    this.suiteDivs[suite.id] = suiteDiv;
+    var parentDiv = this.outerDiv;
+    if (suite.parentSuite) {
+      parentDiv = this.suiteDivs[suite.parentSuite.id];
+    }
+    parentDiv.appendChild(suiteDiv);
+  }
+
+  this.startedAt = new Date();
+
+  var self = this;
+  showPassed.onclick = function(evt) {
+    if (showPassed.checked) {
+      self.outerDiv.className += ' show-passed';
+    } else {
+      self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
+    }
+  };
+
+  showSkipped.onclick = function(evt) {
+    if (showSkipped.checked) {
+      self.outerDiv.className += ' show-skipped';
+    } else {
+      self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
+    }
+  };
+};
+
+jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
+  var results = runner.results();
+  var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
+  this.runnerDiv.setAttribute("class", className);
+  //do it twice for IE
+  this.runnerDiv.setAttribute("className", className);
+  var specs = runner.specs();
+  var specCount = 0;
+  for (var i = 0; i < specs.length; i++) {
+    if (this.specFilter(specs[i])) {
+      specCount++;
+    }
+  }
+  var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
+  message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";
+  this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);
+
+  this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString()));
+};
+
+jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
+  var results = suite.results();
+  var status = results.passed() ? 'passed' : 'failed';
+  if (results.totalCount === 0) { // todo: change this to check results.skipped
+    status = 'skipped';
+  }
+  this.suiteDivs[suite.id].className += " " + status;
+};
+
+jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {
+  if (this.logRunningSpecs) {
+    this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
+  }
+};
+
+jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
+  var results = spec.results();
+  var status = results.passed() ? 'passed' : 'failed';
+  if (results.skipped) {
+    status = 'skipped';
+  }
+  var specDiv = this.createDom('div', { className: 'spec '  + status },
+      this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"),
+      this.createDom('a', {
+        className: 'description',
+        href: '?spec=' + encodeURIComponent(spec.getFullName()),
+        title: spec.getFullName()
+      }, spec.description));
+
+
+  var resultItems = results.getItems();
+  var messagesDiv = this.createDom('div', { className: 'messages' });
+  for (var i = 0; i < resultItems.length; i++) {
+    var result = resultItems[i];
+
+    if (result.type == 'log') {
+      messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
+    } else if (result.type == 'expect' && result.passed && !result.passed()) {
+      messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
+
+      if (result.trace.stack) {
+        messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
+      }
+    }
+  }
+
+  if (messagesDiv.childNodes.length > 0) {
+    specDiv.appendChild(messagesDiv);
+  }
+
+  this.suiteDivs[spec.suite.id].appendChild(specDiv);
+};
+
+jasmine.TrivialReporter.prototype.log = function() {
+  var console = jasmine.getGlobal().console;
+  if (console && console.log) {
+    if (console.log.apply) {
+      console.log.apply(console, arguments);
+    } else {
+      console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
+    }
+  }
+};
+
+jasmine.TrivialReporter.prototype.getLocation = function() {
+  return this.document.location;
+};
+
+jasmine.TrivialReporter.prototype.specFilter = function(spec) {
+  var paramMap = {};
+  var params = this.getLocation().search.substring(1).split('&');
+  for (var i = 0; i < params.length; i++) {
+    var p = params[i].split('=');
+    paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
+  }
+
+  if (!paramMap.spec) {
+    return true;
+  }
+  return spec.getFullName().indexOf(paramMap.spec) === 0;
+};
Index: /sandbox/2.4.1-3/prototype/plugins/jq-raty/test/lib/jasmine.css
===================================================================
--- /sandbox/2.4.1-3/prototype/plugins/jq-raty/test/lib/jasmine.css	(revision 6512)
+++ /sandbox/2.4.1-3/prototype/plugins/jq-raty/test/lib/jasmine.css	(revision 6512)
@@ -0,0 +1,166 @@
+body {
+  font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif;
+}
+
+
+.jasmine_reporter a:visited, .jasmine_reporter a {
+  color: #303; 
+}
+
+.jasmine_reporter a:hover, .jasmine_reporter a:active {
+  color: blue; 
+}
+
+.run_spec {
+  float:right;
+  padding-right: 5px;
+  font-size: .8em;
+  text-decoration: none;
+}
+
+.jasmine_reporter {
+  margin: 0 5px;
+}
+
+.banner {
+  color: #303;
+  background-color: #fef;
+  padding: 5px;
+}
+
+.logo {
+  float: left;
+  font-size: 1.1em;
+  padding-left: 5px;
+}
+
+.logo .version {
+  font-size: .6em;
+  padding-left: 1em;
+}
+
+.runner.running {
+  background-color: yellow;
+}
+
+
+.options {
+  text-align: right;
+  font-size: .8em;
+}
+
+
+
+
+.suite {
+  border: 1px outset gray;
+  margin: 5px 0;
+  padding-left: 1em;
+}
+
+.suite .suite {
+  margin: 5px; 
+}
+
+.suite.passed {
+  background-color: #dfd;
+}
+
+.suite.failed {
+  background-color: #fdd;
+}
+
+.spec {
+  margin: 5px;
+  padding-left: 1em;
+  clear: both;
+}
+
+.spec.failed, .spec.passed, .spec.skipped {
+  padding-bottom: 5px;
+  border: 1px solid gray;
+}
+
+.spec.failed {
+  background-color: #fbb;
+  border-color: red;
+}
+
+.spec.passed {
+  background-color: #bfb;
+  border-color: green;
+}
+
+.spec.skipped {
+  background-color: #bbb;
+}
+
+.messages {
+  border-left: 1px dashed gray;
+  padding-left: 1em;
+  padding-right: 1em;
+}
+
+.passed {
+  background-color: #cfc;
+  display: none;
+}
+
+.failed {
+  background-color: #fbb;
+}
+
+.skipped {
+  color: #777;
+  background-color: #eee;
+  display: none;
+}
+
+
+/*.resultMessage {*/
+  /*white-space: pre;*/
+/*}*/
+
+.resultMessage span.result {
+  display: block;
+  line-height: 2em;
+  color: black;
+}
+
+.resultMessage .mismatch {
+  color: black;
+}
+
+.stackTrace {
+  white-space: pre;
+  font-size: .8em;
+  margin-left: 10px;
+  max-height: 5em;
+  overflow: auto;
+  border: 1px inset red;
+  padding: 1em;
+  background: #eef;
+}
+
+.finished-at {
+  padding-left: 1em;
+  font-size: .6em;
+}
+
+.show-passed .passed,
+.show-skipped .skipped {
+  display: block;
+}
+
+
+#jasmine_content {
+  position:fixed;
+  right: 100%;
+}
+
+.runner {
+  border: 1px solid gray;
+  display: block;
+  margin: 5px 0;
+  padding: 2px 0 2px 10px;
+}
Index: /sandbox/2.4.1-3/prototype/plugins/jq-raty/test/lib/jasmine-jquery.js
===================================================================
--- /sandbox/2.4.1-3/prototype/plugins/jq-raty/test/lib/jasmine-jquery.js	(revision 6512)
+++ /sandbox/2.4.1-3/prototype/plugins/jq-raty/test/lib/jasmine-jquery.js	(revision 6512)
@@ -0,0 +1,288 @@
+var readFixtures = function() {
+  return jasmine.getFixtures().proxyCallTo_('read', arguments);
+};
+
+var preloadFixtures = function() {
+  jasmine.getFixtures().proxyCallTo_('preload', arguments);
+};
+
+var loadFixtures = function() {
+  jasmine.getFixtures().proxyCallTo_('load', arguments);
+};
+
+var setFixtures = function(html) {
+  jasmine.getFixtures().set(html);
+};
+
+var sandbox = function(attributes) {
+  return jasmine.getFixtures().sandbox(attributes);
+};
+
+var spyOnEvent = function(selector, eventName) {
+  jasmine.JQuery.events.spyOn(selector, eventName);
+}
+
+jasmine.getFixtures = function() {
+  return jasmine.currentFixtures_ = jasmine.currentFixtures_ || new jasmine.Fixtures();
+};
+
+jasmine.Fixtures = function() {
+  this.containerId = 'jasmine-fixtures';
+  this.fixturesCache_ = {};
+  this.fixturesPath = 'spec/javascripts/fixtures';
+};
+
+jasmine.Fixtures.prototype.set = function(html) {
+  this.cleanUp();
+  this.createContainer_(html);
+};
+
+jasmine.Fixtures.prototype.preload = function() {
+  this.read.apply(this, arguments);
+};
+
+jasmine.Fixtures.prototype.load = function() {
+  this.cleanUp();
+  this.createContainer_(this.read.apply(this, arguments));
+};
+
+jasmine.Fixtures.prototype.read = function() {
+  var htmlChunks = [];
+
+  var fixtureUrls = arguments;
+  for(var urlCount = fixtureUrls.length, urlIndex = 0; urlIndex < urlCount; urlIndex++) {
+    htmlChunks.push(this.getFixtureHtml_(fixtureUrls[urlIndex]));
+  }
+
+  return htmlChunks.join('');
+};
+
+jasmine.Fixtures.prototype.clearCache = function() {
+  this.fixturesCache_ = {};
+};
+
+jasmine.Fixtures.prototype.cleanUp = function() {
+  jQuery('#' + this.containerId).remove();
+};
+
+jasmine.Fixtures.prototype.sandbox = function(attributes) {
+  var attributesToSet = attributes || {};
+  return jQuery('<div id="sandbox" />').attr(attributesToSet);
+};
+
+jasmine.Fixtures.prototype.createContainer_ = function(html) {
+  var container;
+  if(html instanceof jQuery) {
+    container = jQuery('<div id="' + this.containerId + '" />');
+    container.html(html);
+  } else {
+    container = '<div id="' + this.containerId + '">' + html + '</div>'
+  }
+  jQuery('body').append(container);
+};
+
+jasmine.Fixtures.prototype.getFixtureHtml_ = function(url) {  
+  if (typeof this.fixturesCache_[url] == 'undefined') {
+    this.loadFixtureIntoCache_(url);
+  }
+  return this.fixturesCache_[url];
+};
+
+jasmine.Fixtures.prototype.loadFixtureIntoCache_ = function(relativeUrl) {
+  var self = this;
+  var url = this.fixturesPath.match('/$') ? this.fixturesPath + relativeUrl : this.fixturesPath + '/' + relativeUrl;
+  jQuery.ajax({
+    async: false, // must be synchronous to guarantee that no tests are run before fixture is loaded
+    cache: false,
+    dataType: 'html',
+    url: url,
+    success: function(data) {
+      self.fixturesCache_[relativeUrl] = data;
+    },
+    error: function(jqXHR, status, errorThrown) {
+        throw Error('Fixture could not be loaded: ' + url + ' (status: ' + status + ', message: ' + errorThrown.message + ')');
+    }
+  });
+};
+
+jasmine.Fixtures.prototype.proxyCallTo_ = function(methodName, passedArguments) {
+  return this[methodName].apply(this, passedArguments);
+};
+
+
+jasmine.JQuery = function() {};
+
+jasmine.JQuery.browserTagCaseIndependentHtml = function(html) {
+  return jQuery('<div/>').append(html).html();
+};
+
+jasmine.JQuery.elementToString = function(element) {
+  return jQuery('<div />').append(element.clone()).html();
+};
+
+jasmine.JQuery.matchersClass = {};
+
+(function(namespace) {
+  var data = {
+    spiedEvents: {},
+    handlers:    []
+  };
+
+  namespace.events = {
+    spyOn: function(selector, eventName) {
+      var handler = function(e) {
+        data.spiedEvents[[selector, eventName]] = e;
+      };
+      jQuery(selector).bind(eventName, handler);
+      data.handlers.push(handler);
+    },
+
+    wasTriggered: function(selector, eventName) {
+      return !!(data.spiedEvents[[selector, eventName]]);
+    },
+
+    cleanUp: function() {
+      data.spiedEvents = {};
+      data.handlers    = [];
+    }
+  }
+})(jasmine.JQuery);
+
+(function(){
+  var jQueryMatchers = {
+    toHaveClass: function(className) {
+      return this.actual.hasClass(className);
+    },
+
+    toBeVisible: function() {
+      return this.actual.is(':visible');
+    },
+
+    toBeHidden: function() {
+      return this.actual.is(':hidden');
+    },
+
+    toBeSelected: function() {
+      return this.actual.is(':selected');
+    },
+
+    toBeChecked: function() {
+      return this.actual.is(':checked');
+    },
+
+    toBeEmpty: function() {
+      return this.actual.is(':empty');
+    },
+
+    toExist: function() {
+      return this.actual.size() > 0;
+    },
+
+    toHaveAttr: function(attributeName, expectedAttributeValue) {
+      return hasProperty(this.actual.attr(attributeName), expectedAttributeValue);
+    },
+
+    toHaveId: function(id) {
+      return this.actual.attr('id') == id;
+    },
+
+    toHaveHtml: function(html) {
+      return this.actual.html() == jasmine.JQuery.browserTagCaseIndependentHtml(html);
+    },
+
+    toHaveText: function(text) {
+      if (text && jQuery.isFunction(text.test)) {
+        return text.test(this.actual.text());
+      } else {
+        return this.actual.text() == text;
+      }
+    },
+
+    toHaveValue: function(value) {
+      return this.actual.val() == value;
+    },
+
+    toHaveData: function(key, expectedValue) {
+      return hasProperty(this.actual.data(key), expectedValue);
+    },
+
+    toBe: function(selector) {
+      return this.actual.is(selector);
+    },
+
+    toContain: function(selector) {
+      return this.actual.find(selector).size() > 0;
+    },
+
+    toBeDisabled: function(selector){
+      return this.actual.is(':disabled');
+    },
+
+    // tests the existence of a specific event binding
+    toHandle: function(eventName) {
+      var events = this.actual.data("events");
+      return events && events[eventName].length > 0;
+    },
+    
+    // tests the existence of a specific event binding + handler
+    toHandleWith: function(eventName, eventHandler) {
+      var stack = this.actual.data("events")[eventName];
+      var i;
+      for (i = 0; i < stack.length; i++) {
+        if (stack[i].handler == eventHandler) {
+          return true;
+        }
+      }
+      return false;
+    }
+  };
+
+  var hasProperty = function(actualValue, expectedValue) {
+    if (expectedValue === undefined) {
+      return actualValue !== undefined;
+    }
+    return actualValue == expectedValue;
+  };
+
+  var bindMatcher = function(methodName) {
+    var builtInMatcher = jasmine.Matchers.prototype[methodName];
+
+    jasmine.JQuery.matchersClass[methodName] = function() {
+      if (this.actual instanceof jQuery) {
+        var result = jQueryMatchers[methodName].apply(this, arguments);
+        this.actual = jasmine.JQuery.elementToString(this.actual);
+        return result;
+      }
+
+      if (builtInMatcher) {
+        return builtInMatcher.apply(this, arguments);
+      }
+
+      return false;
+    };
+  };
+
+  for(var methodName in jQueryMatchers) {
+    bindMatcher(methodName);
+  }
+})();
+
+beforeEach(function() {
+  this.addMatchers(jasmine.JQuery.matchersClass);
+  this.addMatchers({
+    toHaveBeenTriggeredOn: function(selector) {
+      this.message = function() {
+        return [
+          "Expected event " + this.actual + " to have been triggered on" + selector,
+          "Expected event " + this.actual + " not to have been triggered on" + selector
+        ];
+      };
+      return jasmine.JQuery.events.wasTriggered(selector, this.actual);
+    }
+  })
+});
+
+afterEach(function() {
+  jasmine.getFixtures().cleanUp();
+  jasmine.JQuery.events.cleanUp();
+});
Index: /sandbox/2.4.1-3/prototype/plugins/jq-raty/test/runner.html
===================================================================
--- /sandbox/2.4.1-3/prototype/plugins/jq-raty/test/runner.html	(revision 6512)
+++ /sandbox/2.4.1-3/prototype/plugins/jq-raty/test/runner.html	(revision 6512)
@@ -0,0 +1,24 @@
+	<!DOCTYPE html>
+
+<html>
+	<head>
+		<title>jQuery Test Runner</title>
+
+		<link rel="stylesheet" type="text/css" href="lib/jasmine.css">
+
+		<script type="text/javascript" charset="utf-8" src="../js/jquery.min.js"></script>
+		<script type="text/javascript" charset="utf-8" src="../js/jquery.raty.js"></script>
+
+		<script type="text/javascript" charset="utf-8" src="lib/jasmine.js"></script>
+		<script type="text/javascript" charset="utf-8" src="lib/jasmine-html.js"></script>
+		<script type="text/javascript" charset="utf-8" src="lib/jasmine-jquery.js"></script>
+
+		<script type="text/javascript" charset="utf-8" src="spec.js"></script>
+	</head>
+	<body>
+		<script type="text/javascript">
+			jasmine.getEnv().addReporter(new jasmine.TrivialReporter());
+			jasmine.getEnv().execute();
+		</script>
+	</body>
+</html>
Index: /sandbox/2.4.1-3/prototype/plugins/jq-raty/doc/css/stylesheet.css
===================================================================
--- /sandbox/2.4.1-3/prototype/plugins/jq-raty/doc/css/stylesheet.css	(revision 6512)
+++ /sandbox/2.4.1-3/prototype/plugins/jq-raty/doc/css/stylesheet.css	(revision 6512)
@@ -0,0 +1,72 @@
+@CHARSET 'UTF-8'; 
+
+/* This CSS does not belong to the plugin. */
+
+body { background: url('../img/background.gif'); font: normal 11px verdana; }
+
+a { color: #2C8CBD; text-decoration: none; }
+a:hover { color: #48A5D4; }
+
+hr { border-top: medium none; height: 1px; margin-bottom: 16px; margin-top: 15px; }
+
+#coffee { background: url('../img/coffee.png') 6px 2px no-repeat #DC5; border: 1px solid #D9C640; color: #FFF; display: block; float: right; font-size: 10px; font-weight: bold; letter-spacing: .9px; margin-right: 9px; padding: 4px 5px 4px 26px; text-decoration: none; -khtml-border-radius: 4px; -moz-border-radius: 4px; -opera-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; }
+#coffee:hover { text-decoration: underline; }
+
+#content { background-color: #FFF; border: 1px solid #DEDEDE; box-shadow: 0 1px 3px rgba(100, 100, 100, 0.4); margin: 0 auto; padding: 15px; width: 1100px; min-height: 510px; }
+
+#menu-feature { color: #AAA; float: left; margin-bottom: 20px; }
+#menu-feature a { float: left; width: 120px }
+#menu-feature a.disabled { color: #999; cursor: default; }
+#menu-feature a.selected { color: #2C8CBD; cursor: default; font-weight: bold; }
+
+#footer { clear: both; height: 25px; margin-top: 5px; width: 100%; }
+#footer div { margin: 0 auto; text-align: center; width: 1100px; }
+
+#header { margin: 0 auto; padding-left: 20px; width: 1130px; }
+
+#menu { color: #AB9927; font: bold 14px 'Lucida Grande', 'Helvetica', 'Times New Roman', serif; text-shadow: 1px 1px 1px #FFF; text-transform: uppercase; }
+#menu a { color: #EA9C00; font: bold 10px verdana; letter-spacing: .9px; text-decoration: none; }
+#menu a:hover { color: #DC5; font-weight: bold; letter-spacing: .9px; text-decoration: underline; }
+
+#title { font: bold 17px verdana; color: #269; letter-spacing: .7px; margin-bottom: 10px; text-align: left; }
+#title span { color: #777; font: 10px verdana; }
+
+#version { color: #777; font: 10px verdana; }
+
+.action-field { border: 1px solid #CCC; height: 20px; padding-left: 3px; width: 80px; }
+.action-link { margin-left: 5px; }
+.action-wrapper { margin-top: 15px; }
+
+.comment { color: #444; font: 11px verdana; letter-spacing: 0.4px; line-height: 1.6; padding-bottom: 5px; text-align: left; }
+.comment-personal { color: #444; font: italic 11px verdana; letter-spacing: 0.4px; line-height: 1.6; text-align: left; }
+
+.description { color: #555; letter-spacing: .1px; margin-bottom: 15px; margin-top: 10px; text-align: left; }
+.description-code { color: #555; letter-spacing: .1px; margin-bottom: 10px; text-indent: 7px; }
+
+.highlight { color: #369; }
+
+.session { clear: both;  font: bold 13px verdana; border-bottom: 1px solid #EFEFEF; color: #444; letter-spacing: .7px; margin-bottom: 18px; margin-top: 24px; text-align: left; }
+.session-first { clear: both; font: bold 13px verdana; border-bottom: 1px solid #EFEFEF; color: #444; letter-spacing: .7px; margin-bottom: 18px; text-align: left; }
+.session-image { display: block; margin: 5px auto 0; }
+.session-option { font: bold 10px verdana; color: #444; letter-spacing: .7px; }
+.session-option span { color: #BBB; font: 11px arial; }
+
+.source { background: #FFF7FF; border: 1px solid #EFEFEF; border-left: 3px solid #CCC; clear: both; color: #444; font: 12px monospace; border-radius: 2px; letter-spacing: .1px; margin-bottom: 7px; margin-top: 15px; padding: 7px; width: 1081px; -khtml-border-radius: 2px; -moz-border-radius: 2px; -opera-border-radius: 2px; -webkit-border-radius: 2px; }
+
+/* custom */
+
+.left { float: left; }
+
+#target, #target-out, #function, #format, #mouseover { float: left; }
+
+#target-number { float: left; }
+
+#hint, #hint-out, #hint-function, #hint-format, #mouseover-target { background-color: #F0F0F0; border-radius: 3px; float: left; height: 15px; margin-left: 5px; padding-bottom: 2px; padding-left: 8px; padding-right: 8px; text-align: center; width: 70px; }
+
+#hint-format { width: 120px; }
+
+#precision { float: left; }
+
+#precision-target { background-color: #F0F0F0; border-radius: 3px; float: left; height: 20px; margin-left: 5px; padding-left: 8px; padding-right: 8px; padding-top: 4px; text-align: center; width: 50px; }
+
+#score-target { float: left; margin-left: 5px }
Index: /sandbox/2.4.1-3/prototype/plugins/jq-raty/changelog.md
===================================================================
--- /sandbox/2.4.1-3/prototype/plugins/jq-raty/changelog.md	(revision 6512)
+++ /sandbox/2.4.1-3/prototype/plugins/jq-raty/changelog.md	(revision 6512)
@@ -0,0 +1,174 @@
+# jQuery Raty - A Star Rating Plugin - http://wbotelhos.com/raty
+
+### 2.4.5
+
++ Now the error messages is displayed in place of stars to be more visible;
++ Fixed the 'score' function to handle undefined score when we have no vote;
++ Fixed the mouseover function to handle undefined score when we have no vote;
+	- For cancel button we get 'null' to know when mouse over it;
++ Fixed multiple mouseout actions on cancel function and mouseout bind;
++ Fixed functions that was not applying not continuing to apply if someone was invalid; 
++ Fixed the flag that indicates read-only or not.
+
+### 2.4.0
+
++ Added the function 'reload' to reload the rating with the current configuration;
++ Added the function 'set' to reload the rating applying new configurations;
++ Added the option 'mouseover' to handle a callback on mouseover the stars (by packowitz);
++ Fixed error when 'start' options receives a string number (by eskimoblood);
++ Fixed multiples events when readOnly is applied more then time by public function (by janapol).
++ Now attribute 'hintList' is called just of 'hints';
++ Now attribute 'start' is called as 'score' to make more sense;
++ Now the method 'start' is called as 'score' too.
+
+### 2.1.0
+
++ Now Raty keeps the state of the elements and no longer depends on ID for each one:
+	+ The score no longer has ID;
+	+ The stars images no longer has ID;
+	+ The stars images no longer has class.
++ Added function 'score' to recover the current score. 
+
+### 2.0.0
+
++ Added option 'halfShow' to just display and separate from the option to vote 'half';
++ Added option 'targetText' to choose default value when there is no score or targetKepp is off.
++ Added option 'precision' to be able rating with precision values, without star representation;
++ Added option 'space' to be able take off the spaces between the star;
++ Added option 'round' to customize the visual rounding of values;
++ Added option 'targetFormat' to customize the target with a template;
++ Added option 'single' to present only the selected star; (suggestion by newcube)
++ Fixed bug in IE 7 that returns void instead undefined when there is no an attribute;
++ Fixed bug that not set custom width when 'readOnly' is enabled;
++ Fixed bug that not set back the hints after disable read only option;
++ Fixed bug that not create cancel button when starts with 'readOnly';
++ Fixed the function cancel() to set the right hint on target score;
++ Fixed the functions start() and click() to set the value on target when 'target' option is enabled;
++ Fixed the functions start() and click() not to be executed when 'readOnly' is enabled;
++ Fixed the 'target' option to work with 'half' and 'precision' option;
++ Fixed the index number given to Raty binded by class without id; (by "Remember me, please?")
++ Refactored the code to make it cleanner and faster;
++ Changed the class of the cancel button to 'raty-cancel' to avoid CSS conflicts;
++ Now is possible to use 'start' option as callback function to get start value; (by hpgihan)
++ Now the scope of click callback is the raty element as DOM, not jQuery selection, to follow the usual;
++ Now the field score is set to readonly when 'readOnly' is enabled.
++ Now attribute 'iconRange' is represented as a list of object with option to choose starOn and starOff;
++ Now we using the best pratice to build the plugin;
++ Now the plugin is under test with Jasmine and Jasmine jQuery.
+
+### 1.4.3
+
++ Now public function return the context to be able the chaining;
++ Fixed: the option 'readOnly' brokes the plugin;
++ Prevented the processing of the set of classes in public function.
+
+### 1.4.0
+
++ Added attribute 'target' to choose a element to display the score when the mouse is on the star;
++ Added attribute 'targetKeep' to keep the selected value on the target element;
++ Added attribute 'targetType' to choose what display in the target element: hint or number;
++ New function called $.fn.raty.cancel() to cancel the rating;
++ Now the action of cancel removes the score value instead set it to zero;
++ Using mouseover when the half star is disabled to avoid to waste actions trigger;
++ Now is possible pass a empty string in the $.fn.raty.start() to cancel the rating;
++ Public functions without specify ID or class is no longer supported.
+
+### 1.3.3
+
++ Fixed the icon presentation when the start attribute is setted and the iconRange is enabled;
++ Now the click function receives the event as argument. (by Eric Wendelin)
+
+### 1.3.2
+
++ Fixed: the last Raty configuration will not be applied in others targets Raty anymore;
++ Now is possible to use the element as identifier like div.star on direct actions.
+
+### 1.3.0
+
++ Added attribute size for to choose the size of the icons that will be used;
++ Added attribute width for to choose the container width of the stars;
++ Changed the name of the attribute showCancel to just cancel.
+
+### 1.2.1
+
++ Fixed half star when click function is enabled.
+
+### 1.2.0
+
++ Added support to half star selection;
++ Changed the name of the attribute onClick to just click;
++ Changed the name of the attribute showHalf to half, because of the selection support.
+
+### 1.0.1
+
++ Fixed the ID's auto generation to work in IE6 and IE7.
+
+### 1.0.0
+
++ Now you can pass a optionally ID or a class to be the target of the public function's actions;
++ Fixed the read-only that wasn't begin applied by the public function readOnly.
+
+### 0.9
+
++ Improved the selector to accept bind by class name;
++ Now if you don't pass a ID for the element, then it will be created;
++ Now the hint list will be applied even if the quantity are less than the stars.
+
+### 0.8
+
++ Added iconRange attribute. Now you can set custom icons for especific ranges;
++ Fixed the cancel button that didn't hidden when using the public function readOnly.
+
+### 0.7
+
++ Added noRatedMsg attribute. A hint for no rated elements when it's read-only;
++ Avoided negative star number in public function start;
++ Avoided a number bigger than the number of star in public function start;
++ Fixed the public function start when the star are read-only and is not passed a start value;
++ Fixed the half star function on it is made by public function start;
+
+### 0.6
+
++ Now you can use the key "this" to refer the star element itself in the onClick handler;
++ Fixed the reference context when using public functions or local functions;
++ When the stars are read-only, all titles are transformed in the corresponding title score;
++ Avoided negative star number;
++ Avoided more than 20 stars. But it's can be changed in the script if you need.
+
+### 0.5
+
++ Now you can put a cancel button to cancel your rating;
++ Choose the cancel image off;
++ Choose the cancel image on;
++ Choose the left or right side position for the cancel button;
++ Change the hint of the cancel button.
+
+### 0.4
+
++ Added support to display half star.
+
+### 0.3
+
++ Fixed some mistakes to work on IE browser. 
+
+### 0.2
+
++ Added the public function click, that do the click on a star; 
++ Was removed the execution of the onClick when used the function start;
++ Added onClick function that enable a callback when a star is clicked.
+
+### 0.1
+
++ Change the path of images;
++ Change the name image files;
++ Choose the number of stars that will be presented;
++ Choose a hint information of each star;
++ Start with a default score;
++ Set the stars read-only;
++ Choose the name of the hidden score field.
+
+### known Bugs
+
++ On versions before 1.6 if a attribute not exists, then empty string is returned instead undefined;
++ On 1.5.2 the opt.click callback is never called, because this version always returns undefined to .call() and .apply();
++ On 1.5.2 the attribute readonly is setted with empty value as following readonly="".
Index: /sandbox/2.4.1-3/prototype/plugins/jq-raty/index.html
===================================================================
--- /sandbox/2.4.1-3/prototype/plugins/jq-raty/index.html	(revision 6512)
+++ /sandbox/2.4.1-3/prototype/plugins/jq-raty/index.html	(revision 6512)
@@ -0,0 +1,916 @@
+<!DOCTYPE html>
+
+<html lang="en" dir="ltr">
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+		<meta http-equiv="Pragma" content="no-cache">
+		<meta http-equiv="Expires" content="-1">
+		<meta name="keywords" content="jquery,rating,raty,voto,star,staring,classificacao,classificar,votar,plugin" />
+		<meta name="description" content="jQuery Raty - A Star Rating Plugin" />
+
+		<title>jQuery Raty - A Star Rating Plugin</title>
+
+		<!-- This CSS does not belong to the plugin. -->
+		<link type="text/css" rel="stylesheet" href="doc/css/stylesheet.css"/>
+
+		<script type="text/javascript" charset="utf-8" src="js/jquery.min.js"></script>
+		<script type="text/javascript" charset="utf-8" src="js/jquery.raty.min.js"></script>
+
+		<script type="text/javascript">
+			// This code does NOT belong the plugin. See the example code at the bottom of this page.
+			var _gaq = _gaq || [];
+			_gaq.push(['_setAccount', 'UA-194992347-3']);
+			_gaq.push(['_trackPageview']);
+			
+			(function() {
+				var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+				ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+				var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+			})();
+		</script>
+	</head>
+	<body>
+		<div id="header">
+			<div id="title">
+				<a href="http://wbotelhos.com/raty">jQuery Raty - A Star Rating Plugin</a>
+				<span id="version">(current version: 2.4.5)</span>
+			</div>
+
+			<div id="menu">
+				<a href="http://github.com/downloads/wbotelhos/raty/jquery.raty-2.4.5.zip" target="_blank">Download</a> |
+				<a href="http://github.com/wbotelhos/raty" target="_blank">Github</a> |
+				<a href="http://www.wbotelhos.com/raty/changelog.md" target="_blank">Change Log</a> |
+				<a href="http://www.wbotelhos.com/raty/README.md" target="_blank">Readme</a> |
+				<a href="http://www.wbotelhos.com/2010/07/14/jquery-raty-a-star-rating-plugin" target="_blank">Article</a> |
+				<a href="http://www.opensource.org/licenses/mit-license.php" target="_blank">License</a> |
+				<a href="http://www.wbotelhos.com/2010/07/14/jquery-raty-a-star-rating-plugin#comments" target="_blank" style="color: #2C8CBD;">Doubt</a> |
+				<a href="http://www.wbotelhos.com/lab" target="_blank" style="color: #000;">yLab</a>
+			</div>
+
+			<a id="coffee" href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&amp;business=X8HEP2878NDEG&amp;item_name=jQuery%20Raty" target="_blank">buy me a coffee</a>
+
+			<div class="description">jQuery <strong>Raty</strong> is a plugin that generates a customizable star rating.</div>
+		</div>
+
+		<div id="content">
+			<div id="default-demo" class="session-first">Default options:</div>
+
+			<div id="default"></div>
+
+			<div class="source">
+				$('#star').raty();<br/><br/>
+
+				&lt;div id="star"&gt;&lt;/div&gt;
+			</div>
+
+			<div id="fixed-demo" class="session">Started with a score and read only value:</div>
+			<div id="fixed"></div>
+
+			<div class="source">
+			 	$('#star').raty({<br/>
+				&#160;&#160;readOnly : true,<br/>
+				&#160;&#160;score&#160;&#160;&#160; : 2<br/>
+				});<br/><br/>
+				
+				&lt;div id="star"&gt;&lt;/div&gt;
+			</div>
+
+			<div id="score-demo" class="session">Starting with a callback:</div>
+			<div id="score" data-rating="3"></div>
+
+			<div class="source">
+			 	$('#score').raty({<br/>
+				&#160;&#160;score: function() {<br/>
+				&#160;&#160;&#160;&#160;return $(this).attr('data-rating');<br/>
+				&#160;&#160;}<br/>
+				});<br/><br/>
+
+				&lt;div id="star" data-rating="3"&gt;&lt;/div&gt;
+			</div>
+
+			<div id="anyone-demo" class="session">A hint for no rated elements when it's read-only:</div>
+			<div id="anyone"></div>
+
+			<div class="source">
+			 	$('#star').raty({<br/>
+				&#160;&#160;readOnly&#160;&#160; : true,<br/>
+				&#160;&#160;noRatedMsg : 'anyone rated this product yet!'<br/>
+				});<br/><br/>
+
+				&lt;div id="star"&gt;&lt;/div&gt;
+			</div>
+
+			<div id="number-demo" class="session">Custom score name and a number of stars:</div>
+			<div id="number"></div>
+
+			<div class="source">
+			 	$('#star').raty({<br/>
+				&#160;&#160;scoreName : 'entity.score',<br/>
+				&#160;&#160;number&#160;&#160;&#160; : 10<br/>
+				});<br/><br/>
+
+				&lt;div id="star"&gt;&lt;/div&gt;
+			</div>
+
+			<div id="click-demo" class="session">Using click function:</div>
+			<div id="click"></div>
+
+			<div class="source">
+			 	$('#star').raty({<br/>
+				&#160;&#160;click: function(score, evt) {<br/>
+				&#160;&#160;&#160;&#160;alert('ID: ' + $(this).attr('id') + '\nscore: ' + score + '\nevent: ' + evt);<br/>
+				&#160;&#160;}<br/>
+				});<br/><br/>
+
+				&lt;div id="star"&gt;&lt;/div&gt;
+			</div><br/>
+
+			<span class="comment">
+				 - The argument score is the selected value;<br/>
+				 - The argument evt is the click event;<br/>
+				 - You can mension the star element (DOM) itself using 'this'.<br/>
+			</span>
+
+			<div id="cancel-demo" class="session">Default cancel button:</div>
+			<div id="cancel"></div>
+
+			<div class="source">
+			 	$('#star').raty({<br/>
+				&#160;&#160;cancel: true<br/>
+				});<br/><br/>
+
+				&lt;div id="star"&gt;&lt;/div&gt;
+			</div><br/>
+
+			<span class="comment">
+				 - The score value for the click on cancel button is null.<br/>
+			</span>
+
+			<div id="cancel-custom-demo" class="session">Custom cancel button:</div>
+			<div id="cancel-custom"></div>
+
+			<div class="source">
+			 	$('#star').raty({<br/>
+				&#160;&#160;cancel&#160;&#160;&#160;&#160;&#160; : true,<br/>
+				&#160;&#160;cancelHint&#160; : 'remove my rating!',<br/>
+				&#160;&#160;cancelPlace : 'right',<br/>
+				&#160;&#160;click&#160;&#160;&#160;&#160;&#160;&#160; : function(score, evt) {<br/>
+				&#160;&#160;&#160;&#160;alert('score: ' + score);<br/>
+				&#160;&#160;}<br/>
+				});<br/><br/>
+
+				&lt;div id="star"&gt;&lt;/div&gt;
+			</div>
+
+			<div id="half-demo" class="session">Half star voting:</div>
+			<div id="half"></div>
+
+			<div class="source">
+			 	$('#star').raty({<br/>
+				&#160;&#160;half&#160; : true,<br/>
+				&#160;&#160;score : 3.3<br/>
+				});<br/><br/>
+
+				&lt;div id="star"&gt;&lt;/div&gt;
+			</div><br/>
+
+			<span class="comment">
+				- You can disable the 'halfShow' option to just vote with half star but not show it.<br/>
+				- If 'halfShow' is disabled, then score &gt;= x.6 will be rounded up visually.<br/>
+				- The interval can be:<br/>
+				-- Rounded down: [x.00 .. x.25]<br/>
+				-- Half star:&#160;&#160;&#160; [x.26 .. x.75]<br/>
+				-- Rounded up:&#160;&#160; [x.76 .. x.99]
+			</span>
+
+			<div id="round-demo" class="session">Custom round option:</div>
+			<div id="round"></div>
+
+			<div class="source">
+			 	$('#star').raty({<br/>
+				&#160;&#160;score : 1.26,<br/>
+				&#160;&#160;round : { down: .25, full: .6, up: .76 }<br/>
+				});<br/><br/>
+
+				&lt;div id="star"&gt;&lt;/div&gt;
+			</div><br/>
+
+			<span class="comment">
+				- This example use the default round values;<br/>
+				- down: with halfShow enabled, score &lt;= x.25 will be rounded down; (inclusive)<br/>
+				- up: with halfShow enabled, score &gt;= x.76 will be rounded up; (inclusive)<br/>
+				- down-up: with halfShow enabled, score &gt; x.25 and score &lt; .76 will be half star; (inclusive)<br/>
+				- full: with halfShow disabled, score &gt;= x.6 will be rounded up; (inclusive)<br/>
+			</span>
+
+			<div id="icon-demo" class="session">Custom hint and icons:</div>
+			<div id="icon"></div>
+
+			<div class="source">
+			 	$('#star').raty({<br/>
+				&#160;&#160;hints&#160;&#160; : ['a', '', null, 'd', '5'],<br/>
+				&#160;&#160;starOn&#160; : 'medal-on.png',<br/>
+				&#160;&#160;starOff : 'medal-off.png'<br/>
+				});<br/><br/>
+
+				&lt;div id="star"&gt;&lt;/div&gt;
+			</div><br/>
+
+			<span class="comment">
+				- To display the number of the star, set null.
+			</span>
+
+			<div id="range-demo" class="session">Range of custom icons:</div>
+			<div id="range"></div>
+
+			<div class="source">
+			 	$('#star').raty({<br/>
+			 	&#160;&#160;iconRange: [<br/>
+				&#160;&#160;&#160;&#160;{ range: 2, on: 'face-a.png', off: 'face-a-off.png' },<br/>
+				&#160;&#160;&#160;&#160;{ range: 3, on: 'face-b.png', off: 'face-b-off.png' },<br/>
+				&#160;&#160;&#160;&#160;{ range: 4, on: 'face-c.png', off: 'face-c-off.png' },<br/>
+				&#160;&#160;&#160;&#160;{ range: 5, on: 'face-d.png', off: 'face-d-off.png' }<br/>
+				&#160;&#160;]<br/>
+				});<br/><br/>
+
+				&lt;div id="star"&gt;&lt;/div&gt;
+			</div><br/>
+
+			<span class="comment">
+				- It's a array of objects where each one represents a custom icon;<br/>
+				- The value range is until wich position the icon will be displayed;<br/>
+				- The value on is the active icon;<br/>
+				- The value off is the inactive icon;<br/>
+				- The sequence of the range interval should be in a ascending order;<br/>
+				- If the value on or off is omitted then the attribute starOn or starOff will be used.
+			</span>
+
+			<div id="big-demo" class="session">Bigger icon:</div>
+			<div id="big"></div>
+
+			<div class="source">
+			 	$('#star').raty({<br/>
+			 	&#160;&#160;cancel&#160;&#160;&#160; : true,<br/>
+				&#160;&#160;cancelOff : 'cancel-off-big.png',<br/>
+				&#160;&#160;cancelOn&#160; : 'cancel-on-big.png',<br/>
+				&#160;&#160;half&#160;&#160;&#160;&#160;&#160; : true,<br/>
+				&#160;&#160;size&#160;&#160;&#160;&#160;&#160; : 24,<br/>
+				&#160;&#160;starHalf&#160; : 'star-half-big.png',<br/>
+				&#160;&#160;starOff&#160;&#160; : 'star-off-big.png',<br/>
+				&#160;&#160;starOn&#160;&#160;&#160; : 'star-on-big.png'<br/>
+				});<br/><br/>
+			   
+				&lt;div id="star"&gt;&lt;/div&gt;
+			</div><br/>
+
+			<span class="comment">
+				- You can specify your own width as following: width: 120.
+			</span>
+
+			<div id="group-demo" class="session">Group of elements:</div>
+			<div class="group"></div>
+			<div class="group"></div>
+			<div class="group"></div>
+
+			<div class="source">
+				$('.star').raty();<br/><br/>
+	
+				&lt;div class="star"&gt;&lt;/div&gt;<br/>
+				&lt;div class="star"&gt;&lt;/div&gt;<br/>
+				&lt;div class="star"&gt;&lt;/div&gt;
+			</div><br/>
+
+			<span class="comment">
+				- The ID is optional and must be unique;<br/>
+				- If you don't pass a ID for the element, then it will be created.
+			</span>
+
+			<div id="target-demo" class="session">Displaying hint in a target element:</div>
+
+			<div id="target"></div>
+			<div id="hint"></div><br/>
+
+			<div class="source">
+				$('#star').raty({<br/>
+				&#160;&#160;cancel&#160;&#160;&#160;&#160; : true,<br/>
+				&#160;&#160;cancelHint : 'none',<br/>
+				&#160;&#160;target&#160;&#160;&#160;&#160; : '#hint'<br/>
+				});<br/><br/>
+
+				&lt;div id="star"&gt;&lt;/div&gt;<br/>
+				&lt;div id="target"&gt;&lt;/div&gt;
+			</div>
+
+			<div id="target-number-demo" class="session">Displaying and keeping the score in a target element:</div>
+
+			<div id="target-number"></div>
+
+			<select id="score-target">
+				<option value="">--</option>
+				<option value="1">1</option>
+				<option value="2">2</option>
+				<option value="3">3</option>
+				<option value="4">4</option>
+				<option value="5">5</option>
+			</select>
+
+			<div class="source left">
+				$('#star').raty({<br/>
+				&#160;&#160;cancel&#160;&#160;&#160;&#160; : true,<br/>
+				&#160;&#160;target&#160;&#160;&#160;&#160; : '#score',<br/>
+				&#160;&#160;targetKeep : true,<br/>
+				&#160;&#160;targetType : 'number'<br/>
+				});<br/><br/>
+
+				&lt;select id="target"&gt;<br/>
+					&#160;&#160;&lt;option value=""&gt;0&lt;/option&gt;<br/>
+					&#160;&#160;&lt;option value="1"&gt;1&lt;/option&gt;<br/>
+					&#160;&#160;&lt;option value="2"&gt;2&lt;/option&gt;<br/>
+					&#160;&#160;&lt;option value="3"&gt;3&lt;/option&gt;<br/>
+					&#160;&#160;&lt;option value="4"&gt;4&lt;/option&gt;<br/>
+					&#160;&#160;&lt;option value="5"&gt;5&lt;/option&gt;<br/>
+				&lt;/select&gt;<br/>
+			</div><br/>
+
+			<span class="comment">
+				- You can to choose the target types 'hint' or 'number'.
+			</span>
+
+			<div id="target-out-demo" class="session">Setting default value to the target on mouseout:</div>
+
+			<div id="target-out"></div>
+			<div id="hint-out"></div><br/>
+
+			<div class="source">
+				$('#star').raty({<br/>
+				&#160;&#160;target&#160;&#160;&#160;&#160; : '#hint',<br/>
+				&#160;&#160;targetText : '--'<br/>
+				});<br/><br/>
+
+				&lt;div id="star"&gt;&lt;/div&gt;<br/>
+				&lt;div id="target"&gt;&lt;/div&gt;
+			</div>
+
+			<div id="format-demo" class="session">Displaying hint with format template:</div>
+
+			<div id="format"></div>
+			<div id="hint-format"></div><br/>
+
+			<div class="source">
+				$('#star').raty({<br/>
+				&#160;&#160;cancel&#160;&#160;&#160;&#160;&#160;&#160; : true,<br/>
+				&#160;&#160;cancelHint&#160;&#160; : 'Sure?',<br/>
+				&#160;&#160;target&#160;&#160;&#160;&#160;&#160;&#160; : '#hint',<br/>
+				&#160;&#160;targetFormat : 'your score: {score}',<br/>
+				&#160;&#160;targetText&#160;&#160; : 'none',<br/>
+				&#160;&#160;targetKeep&#160;&#160; : true<br/>
+				});<br/><br/>
+
+				&lt;div id="star"&gt;&lt;/div&gt;<br/>
+				&lt;div id="target"&gt;&lt;/div&gt;
+			</div>
+
+			<div id="mouseover-demo" class="session">Using mouseover callback:</div>
+
+			<div id="mouseover"></div>
+			<div id="mouseover-target"></div><br/>
+
+			<div class="source" style="margin-top: 15px;">
+				$('#star').raty({<br/>
+				&#160;&#160;cancel&#160;&#160;&#160; : true,<br />
+				&#160;&#160;mouseover : function(score, evt) {<br />
+				&#160;&#160;&#160;&#160;var target = $('#mouseover-target');<br /><br />
+
+				&#160;&#160;&#160;&#160;if (score === null) {<br />
+				&#160;&#160;&#160;&#160;&#160;&#160;target.html('Boring!');<br />
+				&#160;&#160;&#160;&#160;} else if (score === undefined) {<br />
+				&#160;&#160;&#160;&#160;&#160;&#160;target.empty();<br />
+				&#160;&#160;&#160;&#160;} else {<br />
+				&#160;&#160;&#160;&#160;&#160;&#160;target.html('score: ' + score);<br />
+				&#160;&#160;&#160;&#160;}<br />
+				&#160;&#160;}<br />
+				});<br/><br/>
+
+				&lt;div id="star"&gt;&lt;/div&gt;<br/>
+				&lt;div id="target"&gt;&lt;/div&gt;
+			</div>
+
+			<span class="comment">
+				- The options target, targetFormat, targetKeep, targetText and targetType are abstractions of this callback.
+			</span>
+
+			<div id="precision-demo" class="session">Half star voting precision:</div>
+
+			<div id="precision"></div>
+			<div id="precision-target"></div><br/>
+
+			<div class="source" style="margin-top: 15px;">
+				$('#star').raty({<br/>
+				&#160;&#160;half&#160;&#160;&#160;&#160;&#160;&#160; : true,<br/>
+				&#160;&#160;precision&#160; : true,<br/>
+				&#160;&#160;size&#160;&#160;&#160;&#160;&#160;&#160; : 24,<br/>
+				&#160;&#160;starHalf&#160;&#160; : 'star-half-big.png',<br/>
+				&#160;&#160;starOff&#160;&#160;&#160; : 'star-off-big.png',<br/>
+				&#160;&#160;starOn&#160;&#160;&#160;&#160; : 'star-on-big.png'<br/>
+				&#160;&#160;target&#160;&#160;&#160;&#160; : '#precision-target'<br/>
+				&#160;&#160;targetType : 'number'<br/>
+				});<br/><br/>
+
+				&lt;div id="star"&gt;&lt;/div&gt;<br/>
+				&lt;div id="target"&gt;&lt;/div&gt;
+			</div>
+
+			<div id="space-demo" class="session">Without space between stars:</div>
+
+			<div id="space"></div>
+
+			<div class="source">
+				$('#star').raty({<br/>
+				&#160;&#160;space: false<br/>
+				});<br/><br/>
+
+				&lt;div id="star"&gt;&lt;/div&gt;<br/>
+			</div>
+
+			<div id="single-demo" class="session">Single icon:</div>
+
+			<div id="single"></div>
+
+			<div class="source">
+				$('#star').raty({<br/>
+				&#160;&#160;single: true<br/>
+				});<br/><br/>
+
+				&lt;div id="star"&gt;&lt;/div&gt;<br/>
+			</div>
+
+			<div id="action-demo" class="session">Directed actions with public functions:</div>
+
+			love:
+			<div class="action"></div>
+
+			happy:
+			<div class="action"></div><br/>
+
+			your last rate:
+			<div id="result"></div>
+
+			<div class="source">
+				$('.star').raty({<br/>
+				&#160;&#160;half&#160; : true,<br/>
+				&#160;&#160;click : function(score, evt) {<br/>
+				&#160;&#160;&#160;&#160;$(this).raty('cancel');<br/>
+				&#160;&#160;&#160;&#160;$('#result').raty('score', score);<br/>
+				&#160;&#160;}<br/>
+				});<br/><br/>
+
+				&lt;div class="star"&gt;&lt;/div&gt;<br/>
+				&lt;div class="star"&gt;&lt;/div&gt;<br/><br/>
+				&lt;div id="result"&gt;&lt;/div&gt;
+			</div><br/>
+
+			<span class="comment">
+				- All functions have a optional second parameter to specify which container will be executed;<br/>
+				- You can pass a ID or a class to be the target of the action;<br/>
+				- If the ID or class are not specified, then the last element Raty will be takes.
+			</span>
+
+			<div id="function-demo" class="session">Functions Demo:</div>
+
+			<div id="function"></div>
+			<div id="hint-function"></div><br/>
+
+			<div style="color: #CCC; margin-top: 15px;">
+				<a href="javascript:void(0);" title="1" class="score">Score 1</a> |
+				<a href="javascript:void(0);" title="2" class="score">Score 2</a> |
+				<a href="javascript:void(0);" title="3" class="score">Score 3</a> |
+				<a href="javascript:void(0);" title="4" class="score">Score 4</a> |
+				<a href="javascript:void(0);" title="5" class="score">Score 5</a>
+			</div>
+
+			<div style="color: #CCC; margin-top: 15px;">
+				<a href="javascript:void(0);" title="1" class="click">Click 1</a> |
+				<a href="javascript:void(0);" title="2" class="click">Click 2</a> |
+				<a href="javascript:void(0);" title="3" class="click">Click 3</a> |
+				<a href="javascript:void(0);" title="4" class="click">Click 4</a> |
+				<a href="javascript:void(0);" title="5" class="click">Click 5</a>
+			</div>
+
+			<div style="color: #CCC; margin-top: 15px;">
+				<a href="javascript:void(0);" title="true" class="readOnly">ReadOnly (true)</a> |
+				<a href="javascript:void(0);" title="false" class="readOnly">ReadOnly (false)</a>
+			</div>
+
+			<div style="color: #CCC; margin-top: 15px;">
+				<a href="javascript:void(0);" title="false" class="cancel">Cancel</a> |
+				<a href="javascript:void(0);" title="true" class="cancel">Cancel (trigger)</a>
+			</div>
+
+			<div style="color: #CCC; margin-top: 15px;">
+				<a id="reload" href="javascript:void(0);" title="reload">Reload</a> |
+				<a id="get-score" href="javascript:void(0);" title="score">Score</a>
+			</div>
+
+			<div class="action-wrapper">
+				settings: <input id="set-id" type="text" value="{ number: 3 }" class="action-field" />
+				<a id="set-action" href="javascript:void(0);" title="set" class="action-link">set</a>
+			</div>
+
+			<div id="global-demo" class="session">Changing the settings globally:</div>
+
+			<div class="source">
+				$.fn.raty.defaults.starOn = 'star-on.gif';<br/>
+				$.fn.raty.defaults.starOff = 'star-off.gif';
+			</div>
+
+			<span class="comment">
+				- You can change any option mention the scope <b>$.fn.raty.defaults.</b> + <i>option_name</i>;<br/>
+				- This setup must be called before you bind the Raty, of course.
+			</span>
+
+			<div class="session">Default options:</div>
+
+			<div class="session-option">cancel: <span>false</span></div>
+			<div class="comment">If will be showed a button to cancel the rating.</div>
+
+			<hr />
+
+			<div class="session-option">cancelHint: <span>'cancel this rating!'</span></div>
+			<div class="comment">The hint information.</div>
+
+			<hr />
+
+		 	<div class="session-option">cancelHint: 'cancel this rating!'<br/>
+		 	<div class="comment">The hint information.</div>
+
+			<hr />
+
+		 	<div class="session-option">cancelOff: <span>'cancel-off.png'</span></div>
+		 	<div class="comment">Name of the cancel image off.</div>
+
+			<hr />
+
+		 	<div class="session-option">cancelOn: <span>'cancel-on.png'</span></div>
+		 	<div class="comment">Name of the cancel image on.</div>
+
+			<hr />
+
+		 	<div class="session-option">cancelPlace: <span>'left'</span></div>
+		 	<div class="comment">Position of the cancel button.</div>
+
+			<hr />
+
+			<div class="session-option">click: <span>undefined</span></div>
+		 	<div class="comment">Function that returns the selected value.</div>
+
+			<hr />
+
+			<div class="session-option">half: <span>false</span></div>
+		 	<div class="comment">Enables half star selection.</div>
+
+			<hr />
+
+			<div class="session-option">halfShow: <span>true</span></div>
+		 	<div class="comment">Enables half star display.</div>
+
+			<hr />
+
+		 	<div class="session-option">hints: <span>['bad', 'poor', 'regular', 'good', 'gorgeous']</span></div>
+		 	<div class="comment">List of names that will be used as a hint on each star.</div>
+
+			<hr />
+
+			<div class="session-option">iconRange: <span>undefined</span></div>
+			<div class="comment">List of object that represent each icon with position and names.</div>
+
+			<hr />
+
+			<div class="session-option">noRatedMsg: <span>'not rated yet'</span></div>
+		 	<div class="comment">A hint for no rated elements when it's read-only.</div>
+
+			<hr />
+
+			<div class="session-option">number: <span>5</span></div>
+		 	<div class="comment">Number of stars that will be presented.</div>
+
+			<hr />
+
+			<div class="session-option">path: <span>'img/'</span></div>
+		 	<div class="comment">A range of custom icons that you can set.</div>
+
+			<hr />
+
+			<div class="session-option">precision: <span>false</span></div>
+		 	<div class="comment">Enables the selection of a precision score.</div>
+
+			<hr />
+
+			<div class="session-option">readOnly: <span>false</span></div>
+		 	<div class="comment">If the stars will be read-only.</div>
+
+			<hr />
+
+			<div class="session-option">round: <span>{ down: <span>.25, full: <span>.6, up: <span>.76 }</span></div>
+		 	<div class="comment">Configuration to set the round rules.</div>
+
+			<hr />
+
+			<div class="session-option">score: <span>undefined</span></div>
+			<div class="comment">Number of stars to be selected.</div>
+
+			<hr />
+
+			<div class="session-option">scoreName: <span>'score'</span></div>
+		 	<div class="comment">Name of the hidden field that holds the score value.</div>
+
+			<hr />
+
+			<div class="session-option">single: <span>false</span></div>
+		 	<div class="comment">Enables the single star selection.</div>
+
+			<hr />
+
+			<div class="session-option">space: <span>true</span></div>
+		 	<div class="comment">Puts space between the stars.</div>
+
+			<hr />
+
+			<div class="session-option">size: <span>16</span></div>
+		 	<div class="comment">The icons size.</div>
+
+			<hr />
+
+			<div class="session-option">starHalf: <span>'star-half.png'</span></div>
+		 	<div class="comment">The name of the half star image.</div>
+
+			<hr />
+
+			<div class="session-option">starOff: <span>'star-off.png'</span></div>
+		 	<div class="comment">Name of the star image off.</div>
+
+			<hr />
+
+			<div class="session-option">starOn: <span>'star-on.png'</span></div>
+		 	<div class="comment">Name of the star image on.</div>
+
+			<hr />
+
+			<div class="session-option">target: <span>undefined</span></div>
+			<div class="comment">Element selector where the rating will be displayed.</div>
+
+			<hr />
+
+			<div class="session-option">targetFormat: <span>'{score}'</span></div>
+			<div class="comment">Template to interpolate the score with some thing.</div>
+
+			<hr />
+
+			<div class="session-option">targetKeep: <span>false</span></div>
+			<div class="comment">If the last choose value will be keeped on mouseout.</div>
+
+			<hr />
+
+			<div class="session-option">targetText: <span>''</span></div>
+			<div class="comment">Default value when there is no score or targetKeep is off.</div>
+
+			<hr />
+
+			<div class="session-option">targetType: <span>'hint'</span></div>
+			<div class="comment">What display on target element hint or number.</div>
+
+			<hr />
+
+			<div class="session-option">width&#160;: <span>undefined</span></div>
+			<div class="comment">The container width of the stars.</div>
+
+			<div class="session">Functions:</div>
+
+			<div class="source">$('#star').raty('score');</div>
+			<div class="comment">Recovers the current score or undefined for no rated. Class returns an array of score</div>
+
+			<div class="source">$('#star').raty('score', 3);</div>
+			<div class="comment">Set the score with 3 stars.</div>
+
+			<div class="source">$('#star').raty('click', 2);</div>
+			<div class="comment">Click on the second star of the Raty with ID called 'raty'.</div>
+
+			<div class="source">$('.star').raty('readOnly', true);</div>
+			<div class="comment">Adjusts all Raty with class called 'raty' for read-only.</div>
+
+			<div class="source">$('#star').raty('cancel', true);</div>
+			<div class="comment">Cancel the rating. The second optional parameter enable thes click callback.</div>
+
+			<div class="source">$('#star').raty('reload');</div>
+			<div class="comment">Reload the rating with the current configuration.</div>
+
+			<div class="source">$('#star').raty('set', { number: 10 });</div>
+			<div class="comment">Reload the rating applying new configurations.</div>
+		</div>
+
+		<div id="footer">
+			<div id="copy">&copy; 2010 <a href="http://www.wbotelhos.com/" target="_blank">wbotelhos.com</a></div>
+		</div>
+
+		<script type="text/javascript">
+			$(function() {
+
+				$('#default').raty();
+
+				$('#fixed').raty({
+					readOnly	: true,
+					score		: 2
+				});
+
+				$('#score').raty({
+				    score: function() {
+				        return $(this).attr('data-rating');
+				    }
+				});
+
+				$('#anyone').raty({
+					readOnly	: true,
+					noRatedMsg	: 'anyone rated this product yet!'
+				});
+
+				$('#number').raty({
+					scoreName	: 'entity.score',
+					number		: 10
+				});
+
+				$('#click').raty({
+					click: function(score, evt) {
+						alert('ID: ' + $(this).attr('id') + '\nscore: ' + score + '\nevent: ' + evt);
+					}
+				});
+
+				$('#cancel').raty({
+					cancel: true
+				});
+
+				$('#cancel-custom').raty({
+					cancel		: true,
+					cancelHint	: 'remove my rating!',
+					cancelPlace	: 'right',
+					click		: function(score, evt) {
+						alert('score: ' + score);
+					}
+				});
+
+				$('#half').raty({
+					half	: true,
+					score	: 3.3
+				});
+
+				$('#round').raty({
+					score	: 1.26,
+					round	: { down: .25, full: .6, up: .76 }
+				});
+
+				$('#icon').raty({
+					hints		: ['a', '', null, 'd', '5'],
+					path		: 'doc/img/',
+				   	starOn		: 'medal-on.png',
+				   	starOff		: 'medal-off.png'
+				});
+
+				$('#range').raty({
+					iconRange	: [
+						{ range: 2, on: 'face-a.png', off: 'face-a-off.png' },
+						{ range: 3, on: 'face-b.png', off: 'face-b-off.png' },
+						{ range: 4, on: 'face-c.png', off: 'face-c-off.png' },
+						{ range: 5, on: 'face-d.png', off: 'face-d-off.png' }
+					],
+					path		: 'doc/img/'
+				});
+
+				$('#big').raty({
+					cancel		: true,
+					cancelOff	: 'cancel-off-big.png',
+					cancelOn	: 'cancel-on-big.png',
+					half		: true,
+					path		: 'doc/img/',
+					size		: 24,
+					starOff		: 'star-off-big.png',
+					starOn		: 'star-on-big.png',
+					starHalf	: 'star-half-big.png'
+				});
+
+				$('.group').raty();
+
+				$('#target').raty({
+					cancel		: true,
+					cancelHint	: 'none',
+					target		: '#hint'
+				});
+
+				$('#format').raty({
+					cancel			: true,
+					cancelHint		: 'Sure?',
+					target			: '#hint-format',
+					targetFormat	: 'your score: {score}',
+					targetKeep		: true,
+					targetText		: 'none'
+				});
+
+				$('#target-number').raty({
+					cancel		: true,
+					target		: '#score-target',
+					targetKeep	: true,
+					targetType	: 'number'
+				});
+
+				$('#target-out').raty({
+					target		: '#hint-out',
+					targetText	: '--'
+				});
+
+				$('#mouseover').raty({
+  					cancel		: true,
+  					mouseover	: function(score, evt) {
+  						var target = $('#mouseover-target');
+
+  						if (score === null) {
+  							target.html('Boring!');
+  						} else if (score === undefined) {
+  							target.empty();
+  						} else {
+  							target.html('score: ' + score);
+  						}
+  					}
+  				});
+
+				$('#precision').raty({
+					half		: true,
+					path		: 'doc/img/',
+					precision	: true,
+					size		: 24,
+					starOff		: 'star-off-big.png',
+					starOn		: 'star-on-big.png',
+					starHalf	: 'star-half-big.png',
+					target		: '#precision-target',
+					targetType	: 'number'
+				});
+
+				$('#space').raty({
+					space: false
+				});
+
+				$('#single').raty({
+					single: true
+				});
+
+				var $result = $('#result').raty();
+
+				$('.action').raty({
+					click: function(score, evt) {
+						$(this).raty('cancel');
+						$result.raty('score', score);
+					}
+				});
+
+				$('#function').raty({
+					cancel		: true,
+					cancelHint	: 'Boring!',
+					click		: function(score, evt) {
+						$(this).fadeOut(function() { $(this).fadeIn(); });
+					},
+					targetKeep	: true,
+					score		: 2,
+					target		: '#hint-function',
+					targetText	: '--'
+				});
+
+				$('.score').click(function() {
+					$('#function').raty('score', this.title);
+				});
+
+				$('.click').click(function() {
+					$('#function').raty('click', this.title);
+				});
+
+				$('.readOnly').click(function() {
+					$('#function').raty('readOnly', (this.title == 'true') ? true : false);
+				});
+
+				$('.cancel').click(function() {
+					$('#function').raty('cancel', (this.title == 'true') ? true : false);
+				});
+
+				$('#reload').click(function() {
+					$('#function').raty('reload');
+				});
+
+				$('#get-score').click(function() {
+					alert($('#function').raty('score'));
+				});
+
+				$('#set-action').on('click', function() {
+					var options = $('#set-id').val();
+
+					eval("$('#function').raty('set', " + options + ");");
+				});
+
+			});
+		</script>
+	</body>
+</html>
Index: /sandbox/2.4.1-3/prototype/plugins/jq-raty/README.md
===================================================================
--- /sandbox/2.4.1-3/prototype/plugins/jq-raty/README.md	(revision 6512)
+++ /sandbox/2.4.1-3/prototype/plugins/jq-raty/README.md	(revision 6512)
@@ -0,0 +1,108 @@
+# jQuery Raty - A Star Rating Plugin - http://wbotelhos.com/raty
+
+jQuery Raty is a plugin that generates a customizable star rating.
+
+## Version
+
+	@version        2.4.5
+	@since          2010.06.11
+	@author         Washington Botelho
+	@documentation  wbotelhos.com/raty
+	@twitter        twitter.com/wbotelhos
+
+## Required Files
+
++ jquery.raty.min.js
++ star-on.png
++ star-off.png
+
+## Default values
+
+	cancel       : false                                          // Show a button to cancel the rating or not.   
+	cancelHint   : 'cancel this rating!'                          // The hint information.
+	cancelOff    : 'cancel-off.png'                               // Name of the cancel image off.
+	cancelOn     : 'cancel-on.png'                                // Name of the cancel image on.
+	cancelPlace  : 'left'                                         // Position of the cancel button.
+	click        : undefined                                      // Callback for click actions.
+	half         : false                                          // Active the half star.
+	halfShow     : true                                           // Enables half star display.
+	hints        : ['bad', 'poor', 'regular', 'good', 'gorgeous'] // A hint information for default 5 stars.
+	iconRange    : undefined                                      // Object list representing each icon with position and names.
+	mouseover    : undefined                                      // Callback for mouseover actions.
+	noRatedMsg   : 'not rated yet'                                // A hint for no rated elements when it's read-only.
+	number       : 5                                              // Number of star.
+	path         : 'img                                           // Path of images.
+	precision    : false                                          // Enables the selection of a precision score.
+	readOnly     : false                                          // read-only or not.
+	round        : { down: .25, full: .6, up: .76 }               // Configuration to set the round rules.
+	score        : undefined                                      // Initial score value.
+	scoreName    : 'score'                                        // The name of target score.
+	single       : false                                          // Enables the single star selection.
+	size         : 16                                             // The icons size.
+	space        : true                                           // Puts space between the stars.
+	starHalf     : 'star-half.png'                                // The image of the half star.
+	starOff      : 'star-off.png'                                 // Name of the star image off.
+	starOn       : 'star-on.png'                                  // Name of the star image on.
+	target       : undefined                                      // Element selector where the rating will be displayed.
+	targetFormat : '{score}'                                      // Template to interpolate the score with some thing.
+	targetKeep   : false                                          // If the last choose value will be keeped on mouseout.
+	targetText   : ''                                             // Default value when there's no score or targetKeep is off.
+	targetType   : 'hint'                                         // What display on target element: hint or number.
+	width        : undefined                                      // The container width of the stars.
+
+## Usage
+
+	$('#star').raty();
+
+	<div id="star"></div>
+
+	$('.star').raty();
+
+	<div class="star"></div>
+	<div class="star"></div>
+	<div class="star"></div>
+
+## Functions
+
+	$('#star').raty('score');                // Recovers the current score or undefined for no rated. Class returns an array of score.
+
+	$('#star').raty('score', 3);             // Set the score to 3 stars.
+
+	$('#star').raty('click', 2);             // Click on the second star.
+
+	$('.star').raty('readOnly', true);       // Adjusts all elements with class called 'star' for read-only.
+
+	$('#star').raty('cancel', true);         // Cancel the rating. The second optional parameter enables the callback.
+
+	$('#star').raty('reload');               // Reload the rating with the current configuration.
+
+	$('#star').raty('set', { number: 10 });  // Reload the rating applying new configurations.
+
+## Contributors
+
++ Andreas KÃ¶berle
++ Daniel Faria
++ Eric Wendelin
++ Francisco Souza
++ Gabriel Benz
++ hpgihan
++ janapol
++ jeongee
++ Olle Jonsson
++ packowitz
+
+## Licence
+
+The MIT License
+
+Copyright (c) 2010 Washington Botelho
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+## Buy me a coffee
+
+You can do it by [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=X8HEP2878NDEG&item_name=jQuery%20Raty). Thanks! (:
Index: /sandbox/2.4.1-3/prototype/plugins/jq-raty/js/jquery.raty.js
===================================================================
--- /sandbox/2.4.1-3/prototype/plugins/jq-raty/js/jquery.raty.js	(revision 6512)
+++ /sandbox/2.4.1-3/prototype/plugins/jq-raty/js/jquery.raty.js	(revision 6512)
@@ -0,0 +1,460 @@
+/*!
+ * jQuery Raty - A Star Rating Plugin - http://wbotelhos.com/raty
+ * -------------------------------------------------------------------
+ *
+ * jQuery Raty is a plugin that generates a customizable star rating.
+ *
+ * Licensed under The MIT License
+ *
+ * @version        2.4.5
+ * @since          2010.06.11
+ * @author         Washington Botelho
+ * @documentation  wbotelhos.com/raty
+ * @twitter        twitter.com/wbotelhos
+ *
+ * Usage:
+ * -------------------------------------------------------------------
+ * $('#star').raty();
+ *
+ * <div id="star"></div>
+ *
+ */
+
+;(function($) {
+
+	var methods = {
+		init: function(settings) {
+			return this.each(function() {
+				var self	= this,
+					$this	= $(self).empty();
+	
+				self.opt = $.extend(true, {}, $.fn.raty.defaults, settings);
+
+				$this.data('settings', self.opt);
+
+				self.opt.number = methods.between(self.opt.number, 0, 20);
+
+				if (self.opt.path.substring(self.opt.path.length - 1, self.opt.path.length) != '/') {
+					self.opt.path += '/';
+				}
+
+				if (typeof self.opt.score == 'function') {
+					self.opt.score = self.opt.score.call(self);
+				}
+
+				if (self.opt.score) {
+					self.opt.score = methods.between(self.opt.score, 0, self.opt.number);					
+				}
+
+				for (var i = 1; i <= self.opt.number; i++) {
+					$('<img />', {
+						src		: self.opt.path + ((!self.opt.score || self.opt.score < i) ? self.opt.starOff : self.opt.starOn),
+						alt		: i,
+						title	: (i <= self.opt.hints.length && self.opt.hints[i - 1] !== null) ? self.opt.hints[i - 1] : i
+					}).appendTo(self);
+
+					if (self.opt.space) {
+						$this.append((i < self.opt.number) ? '&#160;' : '');
+					}
+				}
+
+				self.stars = $this.children('img:not(".raty-cancel")');
+				self.score = $('<input />', { type: 'hidden', name: self.opt.scoreName }).appendTo(self);
+
+				if (self.opt.score && self.opt.score > 0) {
+					self.score.val(self.opt.score);
+					methods.roundStar.call(self, self.opt.score);
+				}
+
+				if (self.opt.iconRange) {
+					methods.fill.call(self, self.opt.score);	
+				}
+
+				methods.setTarget.call(self, self.opt.score, self.opt.targetKeep);
+
+				var space	= self.opt.space ? 4 : 0,
+					width	= self.opt.width || (self.opt.number * self.opt.size + self.opt.number * space);
+
+				if (self.opt.cancel) {
+					self.cancel = $('<img />', { src: self.opt.path + self.opt.cancelOff, alt: 'x', title: self.opt.cancelHint, 'class': 'raty-cancel' });
+
+					if (self.opt.cancelPlace == 'left') {
+						$this.prepend('&#160;').prepend(self.cancel);
+					} else {
+						$this.append('&#160;').append(self.cancel);
+					}
+
+					width += (self.opt.size + space);
+				}
+
+				if (self.opt.readOnly) {
+					methods.fixHint.call(self);
+
+					if (self.cancel) {
+						self.cancel.hide();
+					}
+				} else {
+					$this.css('cursor', 'pointer');
+
+					methods.bindAction.call(self);
+				}
+
+				$this.css('width', width);
+			});
+		}, between: function(value, min, max) {
+			return Math.min(Math.max(parseFloat(value), min), max);
+		}, bindAction: function() {
+			var self	= this,
+				$this	= $(self);
+
+			$this.mouseleave(function() {
+				var score = self.score.val() || undefined;
+
+				methods.initialize.call(self, score);
+				methods.setTarget.call(self, score, self.opt.targetKeep);
+
+				if (self.opt.mouseover) {
+					self.opt.mouseover.call(self, score);
+				}
+			});
+
+			var action = self.opt.half ? 'mousemove' : 'mouseover';
+
+			if (self.opt.cancel) {
+				self.cancel.mouseenter(function() {
+					$(this).attr('src', self.opt.path + self.opt.cancelOn);
+
+					self.stars.attr('src', self.opt.path + self.opt.starOff);
+
+					methods.setTarget.call(self, null, true);
+
+					if (self.opt.mouseover) {
+						self.opt.mouseover.call(self, null);
+					}
+				}).mouseleave(function() {
+					$(this).attr('src', self.opt.path + self.opt.cancelOff);
+
+					if (self.opt.mouseover) {
+						self.opt.mouseover.call(self, self.score.val() || null);
+					}
+				}).click(function(evt) {
+					self.score.removeAttr('value');
+
+					if (self.opt.click) {
+			          self.opt.click.call(self, null, evt);
+			        }
+				});
+			}
+
+			self.stars.bind(action, function(evt) {
+				var value = parseInt(this.alt, 10);
+
+				if (self.opt.half) {
+					var position	= parseFloat((evt.pageX - $(this).offset().left) / self.opt.size),
+						diff		= (position > .5) ? 1 : .5;
+
+					value = parseFloat(this.alt) - 1 + diff;
+
+					methods.fill.call(self, value);
+
+					if (self.opt.precision) {
+						value = value - diff + position;
+					}
+
+					methods.showHalf.call(self, value);
+				} else {
+					methods.fill.call(self, value);
+				}
+
+				$this.data('score', value);
+
+				methods.setTarget.call(self, value, true);
+
+				if (self.opt.mouseover) {
+					self.opt.mouseover.call(self, value, evt);
+				}
+			}).click(function(evt) {
+				self.score.val((self.opt.half || self.opt.precision) ? $this.data('score') : this.alt);
+
+				if (self.opt.click) {
+					self.opt.click.call(self, self.score.val(), evt);
+				}
+			});
+		}, cancel: function(isClick) {
+			return $(this).each(function() {
+				var self	= this, 
+					$this	= $(self);
+
+				if ($this.data('readonly') === true) {
+					return this;
+				}
+
+				if (isClick) {
+					methods.click.call(self, null);
+				} else {
+					methods.score.call(self, null);
+				}
+
+				self.score.removeAttr('value');
+			});
+		}, click: function(score) {
+			return $(this).each(function() {
+				if ($(this).data('readonly') === true) {
+					return this;
+				}
+
+				methods.initialize.call(this, score);
+
+				if (this.opt.click) {
+					this.opt.click.call(this, score);
+				} else {
+					methods.error.call(this, 'you must add the "click: function(score, evt) { }" callback.');
+				}
+
+				methods.setTarget.call(this, score, true);
+			});
+		}, error: function(message) {
+			$(this).html(message);
+
+			$.error(message);
+		}, fill: function(score) {
+			var self	= this,
+				number	= self.stars.length,
+				count	= 0,
+				$star	,
+				star	,
+				icon	;
+
+			for (var i = 1; i <= number; i++) {
+				$star = self.stars.eq(i - 1);
+
+				if (self.opt.iconRange && self.opt.iconRange.length > count) {
+					star = self.opt.iconRange[count];
+
+					if (self.opt.single) {
+						icon = (i == score) ? (star.on || self.opt.starOn) : (star.off || self.opt.starOff);
+					} else {
+						icon = (i <= score) ? (star.on || self.opt.starOn) : (star.off || self.opt.starOff);
+					}
+
+					if (i <= star.range) {
+						$star.attr('src', self.opt.path + icon);
+					}
+
+					if (i == star.range) {
+						count++;
+					}
+				} else {
+					if (self.opt.single) {
+						icon = (i == score) ? self.opt.starOn : self.opt.starOff;
+					} else {
+						icon = (i <= score) ? self.opt.starOn : self.opt.starOff;
+					}
+
+					$star.attr('src', self.opt.path + icon);
+				}
+			}
+		}, fixHint: function() {
+			var $this	= $(this),
+				score	= parseInt(this.score.val(), 10),
+				hint	= this.opt.noRatedMsg;
+
+			if (!isNaN(score) && score > 0) {
+				hint = (score <= this.opt.hints.length && this.opt.hints[score - 1] !== null) ? this.opt.hints[score - 1] : score;
+			}
+
+			$this.data('readonly', true).css('cursor', 'default').attr('title', hint);
+
+			this.score.attr('readonly', 'readonly');
+			this.stars.attr('title', hint);
+		}, getScore: function() {
+			var score	= [],
+				value	;
+
+			$(this).each(function() {
+				value = this.score.val();
+
+				score.push(value ? parseFloat(value) : undefined);
+			});
+
+			return (score.length > 1) ? score : score[0];
+		}, readOnly: function(isReadOnly) {
+			return this.each(function() {
+				var $this = $(this);
+
+				if ($this.data('readonly') === isReadOnly) {
+					return this;
+				}
+
+				if (this.cancel) {
+					if (isReadOnly) {
+						this.cancel.hide();
+					} else {
+						this.cancel.show();
+					}
+				}
+
+				if (isReadOnly) {
+					$this.unbind();
+
+					$this.children('img').unbind();
+
+					methods.fixHint.call(this);
+				} else {
+					methods.bindAction.call(this);
+					methods.unfixHint.call(this);
+				}
+
+				$this.data('readonly', isReadOnly);
+			});
+		}, reload: function() {
+			return methods.set.call(this, {});
+		}, roundStar: function(score) {
+			var diff = (score - Math.floor(score)).toFixed(2);
+
+			if (diff > this.opt.round.down) {
+				var icon = this.opt.starOn;								// Full up: [x.76 .. x.99]
+
+				if (diff < this.opt.round.up && this.opt.halfShow) {	// Half: [x.26 .. x.75]
+					icon = this.opt.starHalf;
+				} else if (diff < this.opt.round.full) {				// Full down: [x.00 .. x.5]
+					icon = this.opt.starOff;
+				}
+
+				this.stars.eq(Math.ceil(score) - 1).attr('src', this.opt.path + icon);
+			}															// Full down: [x.00 .. x.25]
+		}, score: function() {
+			return arguments.length ? methods.setScore.apply(this, arguments) : methods.getScore.call(this);
+		}, set: function(settings) {
+			this.each(function() {
+				var $this	= $(this),
+					actual	= $this.data('settings'),
+					clone	= $this.clone().removeAttr('style').insertBefore($this);
+
+				$this.remove();
+
+				clone.raty($.extend(actual, settings));
+			});
+
+			return $(this.selector);
+		}, setScore: function(score) {
+			return $(this).each(function() {
+				if ($(this).data('readonly') === true) {
+					return this;
+				}
+
+				methods.initialize.call(this, score);
+				methods.setTarget.call(this, score, true);
+			});
+		}, setTarget: function(value, isKeep) {
+			if (this.opt.target) {
+				var $target = $(this.opt.target);
+
+				if ($target.length == 0) {
+					methods.error.call(this, 'target selector invalid or missing!');
+				}
+
+				var score = value;
+
+				if (!isKeep || score === undefined) {
+					score = this.opt.targetText;
+				} else {
+					if (this.opt.targetType == 'hint') {
+						score = (score === null && this.opt.cancel)
+								? this.opt.cancelHint
+								: this.opt.hints[Math.ceil(score - 1)];
+					} else {
+						score = this.opt.precision
+								? parseFloat(score).toFixed(1)
+								: parseInt(score, 10);
+					}
+				}
+
+				if (this.opt.targetFormat.indexOf('{score}') < 0) {
+					methods.error.call(this, 'template "{score}" missing!');
+				}
+
+				if (value !== null) {
+					score = this.opt.targetFormat.toString().replace('{score}', score);
+				}
+
+				if ($target.is(':input')) {
+					$target.val(score);
+				} else {
+					$target.html(score);
+				}
+			}
+		}, showHalf: function(score) {
+			var diff = (score - Math.floor(score)).toFixed(1);
+
+			if (diff > 0 && diff < .6) {
+				this.stars.eq(Math.ceil(score) - 1).attr('src', this.opt.path + this.opt.starHalf);
+			}
+		}, initialize: function(score) {
+			score = !score ? 0 : methods.between(score, 0, this.opt.number);
+
+			methods.fill.call(this, score);
+
+			if (score > 0) {
+				if (this.opt.halfShow) {
+					methods.roundStar.call(this, score);
+				}
+
+				this.score.val(score);
+			}
+		}, unfixHint: function() {
+			for (var i = 0; i < this.opt.number; i++) {
+				this.stars.eq(i).attr('title', (i < this.opt.hints.length && this.opt.hints[i] !== null) ? this.opt.hints[i] : i);
+			}
+
+			$(this).data('readonly', false).css('cursor', 'pointer').removeAttr('title');
+
+			this.score.attr('readonly', 'readonly');
+		}
+	};
+
+	$.fn.raty = function(method) {
+		if (methods[method]) {
+			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
+		} else if (typeof method === 'object' || !method) {
+			return methods.init.apply(this, arguments);
+		} else {
+			$.error('Method ' + method + ' does not exist!');
+		} 
+	};
+
+	$.fn.raty.defaults = {
+		cancel			: false,
+		cancelHint		: 'cancel this rating!',
+		cancelOff		: 'cancel-off.png',
+		cancelOn		: 'cancel-on.png',
+		cancelPlace		: 'left',
+		click			: undefined,
+		half			: false,
+		halfShow		: true,
+		hints			: ['bad', 'poor', 'regular', 'good', 'gorgeous'],
+		iconRange		: undefined,
+		mouseover		: undefined,
+		noRatedMsg		: 'not rated yet',
+		number			: 5,
+		path			: 'img/',
+		precision		: false,
+		round			: { down: .25, full: .6, up: .76 },
+		readOnly		: false,
+		score			: undefined,
+		scoreName		: 'score',
+		single			: false,
+		size			: 16,
+		space			: true,
+		starHalf		: 'star-half.png',
+		starOff			: 'star-off.png',
+		starOn			: 'star-on.png',
+		target			: undefined,
+		targetFormat	: '{score}',
+		targetKeep		: false,
+		targetText		: '',
+		targetType		: 'hint',
+		width			: undefined
+	};
+
+})(jQuery);
Index: /sandbox/2.4.1-3/prototype/plugins/jq-raty/js/jquery.raty.min.js
===================================================================
--- /sandbox/2.4.1-3/prototype/plugins/jq-raty/js/jquery.raty.min.js	(revision 6512)
+++ /sandbox/2.4.1-3/prototype/plugins/jq-raty/js/jquery.raty.min.js	(revision 6512)
@@ -0,0 +1,12 @@
+/*!
+ * jQuery Raty - A Star Rating Plugin
+ *
+ * Licensed under The MIT License
+ *
+ * @version        2.4.5
+ * @author         Washington Botelho
+ * @documentation  wbotelhos.com/raty
+ * 
+ */
+
+;(function(b){var a={init:function(c){return this.each(function(){var d=this,h=b(d).empty();d.opt=b.extend(true,{},b.fn.raty.defaults,c);h.data("settings",d.opt);d.opt.number=a.between(d.opt.number,0,20);if(d.opt.path.substring(d.opt.path.length-1,d.opt.path.length)!="/"){d.opt.path+="/";}if(typeof d.opt.score=="function"){d.opt.score=d.opt.score.call(d);}if(d.opt.score){d.opt.score=a.between(d.opt.score,0,d.opt.number);}for(var e=1;e<=d.opt.number;e++){b("<img />",{src:d.opt.path+((!d.opt.score||d.opt.score<e)?d.opt.starOff:d.opt.starOn),alt:e,title:(e<=d.opt.hints.length&&d.opt.hints[e-1]!==null)?d.opt.hints[e-1]:e}).appendTo(d);if(d.opt.space){h.append((e<d.opt.number)?"&#160;":"");}}d.stars=h.children('img:not(".raty-cancel")');d.score=b("<input />",{type:"hidden",name:d.opt.scoreName}).appendTo(d);if(d.opt.score&&d.opt.score>0){d.score.val(d.opt.score);a.roundStar.call(d,d.opt.score);}if(d.opt.iconRange){a.fill.call(d,d.opt.score);}a.setTarget.call(d,d.opt.score,d.opt.targetKeep);var g=d.opt.space?4:0,f=d.opt.width||(d.opt.number*d.opt.size+d.opt.number*g);if(d.opt.cancel){d.cancel=b("<img />",{src:d.opt.path+d.opt.cancelOff,alt:"x",title:d.opt.cancelHint,"class":"raty-cancel"});if(d.opt.cancelPlace=="left"){h.prepend("&#160;").prepend(d.cancel);}else{h.append("&#160;").append(d.cancel);}f+=(d.opt.size+g);}if(d.opt.readOnly){a.fixHint.call(d);if(d.cancel){d.cancel.hide();}}else{h.css("cursor","pointer");a.bindAction.call(d);}h.css("width",f);});},between:function(e,d,c){return Math.min(Math.max(parseFloat(e),d),c);},bindAction:function(){var c=this,e=b(c);e.mouseleave(function(){var f=c.score.val()||undefined;a.initialize.call(c,f);a.setTarget.call(c,f,c.opt.targetKeep);if(c.opt.mouseover){c.opt.mouseover.call(c,f);}});var d=c.opt.half?"mousemove":"mouseover";if(c.opt.cancel){c.cancel.mouseenter(function(){b(this).attr("src",c.opt.path+c.opt.cancelOn);c.stars.attr("src",c.opt.path+c.opt.starOff);a.setTarget.call(c,null,true);if(c.opt.mouseover){c.opt.mouseover.call(c,null);}}).mouseleave(function(){b(this).attr("src",c.opt.path+c.opt.cancelOff);if(c.opt.mouseover){c.opt.mouseover.call(c,c.score.val()||null);}}).click(function(f){c.score.removeAttr("value");if(c.opt.click){c.opt.click.call(c,null,f);}});}c.stars.bind(d,function(g){var h=parseInt(this.alt,10);if(c.opt.half){var f=parseFloat((g.pageX-b(this).offset().left)/c.opt.size),i=(f>0.5)?1:0.5;h=parseFloat(this.alt)-1+i;a.fill.call(c,h);if(c.opt.precision){h=h-i+f;}a.showHalf.call(c,h);}else{a.fill.call(c,h);}e.data("score",h);a.setTarget.call(c,h,true);if(c.opt.mouseover){c.opt.mouseover.call(c,h,g);}}).click(function(f){c.score.val((c.opt.half||c.opt.precision)?e.data("score"):this.alt);if(c.opt.click){c.opt.click.call(c,c.score.val(),f);}});},cancel:function(c){return b(this).each(function(){var d=this,e=b(d);if(e.data("readonly")===true){return this;}if(c){a.click.call(d,null);}else{a.score.call(d,null);}d.score.removeAttr("value");});},click:function(c){return b(this).each(function(){if(b(this).data("readonly")===true){return this;}a.initialize.call(this,c);if(this.opt.click){this.opt.click.call(this,c);}else{a.error.call(this,'you must add the "click: function(score, evt) { }" callback.');}a.setTarget.call(this,c,true);});},error:function(c){b(this).html(c);b.error(c);},fill:function(k){var c=this,h=c.stars.length,g=0,d,j,f;for(var e=1;e<=h;e++){d=c.stars.eq(e-1);if(c.opt.iconRange&&c.opt.iconRange.length>g){j=c.opt.iconRange[g];if(c.opt.single){f=(e==k)?(j.on||c.opt.starOn):(j.off||c.opt.starOff);}else{f=(e<=k)?(j.on||c.opt.starOn):(j.off||c.opt.starOff);}if(e<=j.range){d.attr("src",c.opt.path+f);}if(e==j.range){g++;}}else{if(c.opt.single){f=(e==k)?c.opt.starOn:c.opt.starOff;}else{f=(e<=k)?c.opt.starOn:c.opt.starOff;}d.attr("src",c.opt.path+f);}}},fixHint:function(){var c=b(this),e=parseInt(this.score.val(),10),d=this.opt.noRatedMsg;if(!isNaN(e)&&e>0){d=(e<=this.opt.hints.length&&this.opt.hints[e-1]!==null)?this.opt.hints[e-1]:e;}c.data("readonly",true).css("cursor","default").attr("title",d);this.score.attr("readonly","readonly");this.stars.attr("title",d);},getScore:function(){var d=[],c;b(this).each(function(){c=this.score.val();d.push(c?parseFloat(c):undefined);});return(d.length>1)?d:d[0];},readOnly:function(c){return this.each(function(){var d=b(this);if(d.data("readonly")===c){return this;}if(this.cancel){if(c){this.cancel.hide();}else{this.cancel.show();}}if(c){d.unbind();d.children("img").unbind();a.fixHint.call(this);}else{a.bindAction.call(this);a.unfixHint.call(this);}d.data("readonly",c);});},reload:function(){return a.set.call(this,{});},roundStar:function(e){var d=(e-Math.floor(e)).toFixed(2);if(d>this.opt.round.down){var c=this.opt.starOn;if(d<this.opt.round.up&&this.opt.halfShow){c=this.opt.starHalf;}else{if(d<this.opt.round.full){c=this.opt.starOff;}}this.stars.eq(Math.ceil(e)-1).attr("src",this.opt.path+c);}},score:function(){return arguments.length?a.setScore.apply(this,arguments):a.getScore.call(this);},set:function(c){this.each(function(){var d=b(this),f=d.data("settings"),e=d.clone().removeAttr("style").insertBefore(d);d.remove();e.raty(b.extend(f,c));});return b(this.selector);},setScore:function(c){return b(this).each(function(){if(b(this).data("readonly")===true){return this;}a.initialize.call(this,c);a.setTarget.call(this,c,true);});},setTarget:function(e,d){if(this.opt.target){var c=b(this.opt.target);if(c.length==0){a.error.call(this,"target selector invalid or missing!");}var f=e;if(!d||f===undefined){f=this.opt.targetText;}else{if(this.opt.targetType=="hint"){f=(f===null&&this.opt.cancel)?this.opt.cancelHint:this.opt.hints[Math.ceil(f-1)];}else{f=this.opt.precision?parseFloat(f).toFixed(1):parseInt(f,10);}}if(this.opt.targetFormat.indexOf("{score}")<0){a.error.call(this,'template "{score}" missing!');}if(e!==null){f=this.opt.targetFormat.toString().replace("{score}",f);}if(c.is(":input")){c.val(f);}else{c.html(f);}}},showHalf:function(d){var c=(d-Math.floor(d)).toFixed(1);if(c>0&&c<0.6){this.stars.eq(Math.ceil(d)-1).attr("src",this.opt.path+this.opt.starHalf);}},initialize:function(c){c=!c?0:a.between(c,0,this.opt.number);a.fill.call(this,c);if(c>0){if(this.opt.halfShow){a.roundStar.call(this,c);}this.score.val(c);}},unfixHint:function(){for(var c=0;c<this.opt.number;c++){this.stars.eq(c).attr("title",(c<this.opt.hints.length&&this.opt.hints[c]!==null)?this.opt.hints[c]:c);}b(this).data("readonly",false).css("cursor","pointer").removeAttr("title");this.score.attr("readonly","readonly");}};b.fn.raty=function(c){if(a[c]){return a[c].apply(this,Array.prototype.slice.call(arguments,1));}else{if(typeof c==="object"||!c){return a.init.apply(this,arguments);}else{b.error("Method "+c+" does not exist!");}}};b.fn.raty.defaults={cancel:false,cancelHint:"cancel this rating!",cancelOff:"cancel-off.png",cancelOn:"cancel-on.png",cancelPlace:"left",click:undefined,half:false,halfShow:true,hints:["bad","poor","regular","good","gorgeous"],iconRange:undefined,mouseover:undefined,noRatedMsg:"not rated yet",number:5,path:"img/",precision:false,round:{down:0.25,full:0.6,up:0.76},readOnly:false,score:undefined,scoreName:"score",single:false,size:16,space:true,starHalf:"star-half.png",starOff:"star-off.png",starOn:"star-on.png",target:undefined,targetFormat:"{score}",targetKeep:false,targetText:"",targetType:"hint",width:undefined};})(jQuery);
Index: /sandbox/2.4.1-3/prototype/plugins/jq-raty/js/jquery.min.js
===================================================================
--- /sandbox/2.4.1-3/prototype/plugins/jq-raty/js/jquery.min.js	(revision 6512)
+++ /sandbox/2.4.1-3/prototype/plugins/jq-raty/js/jquery.min.js	(revision 6512)
@@ -0,0 +1,23 @@
+/*!
+ * jQuery JavaScript Library v1.7.2
+ * http://jquery.com/
+ *
+ * Copyright 2011, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2011, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Wed Mar 21 12:46:34 2012 -0700
+ */
+;(function(bd,L){var av=bd.document,bu=bd.navigator,bm=bd.location;var b=(function(){var bF=function(b0,b1){return new bF.fn.init(b0,b1,bD);},bU=bd.jQuery,bH=bd.$,bD,bY=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,bM=/\S/,bI=/^\s+/,bE=/\s+$/,bA=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,bN=/^[\],:{}\s]*$/,bW=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,bP=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,bJ=/(?:^|:|,)(?:\s*\[)+/g,by=/(webkit)[ \/]([\w.]+)/,bR=/(opera)(?:.*version)?[ \/]([\w.]+)/,bQ=/(msie) ([\w.]+)/,bS=/(mozilla)(?:.*? rv:([\w.]+))?/,bB=/-([a-z]|[0-9])/ig,bZ=/^-ms-/,bT=function(b0,b1){return(b1+"").toUpperCase();},bX=bu.userAgent,bV,bC,e,bL=Object.prototype.toString,bG=Object.prototype.hasOwnProperty,bz=Array.prototype.push,bK=Array.prototype.slice,bO=String.prototype.trim,bv=Array.prototype.indexOf,bx={};bF.fn=bF.prototype={constructor:bF,init:function(b0,b4,b3){var b2,b5,b1,b6;if(!b0){return this;}if(b0.nodeType){this.context=this[0]=b0;this.length=1;return this;}if(b0==="body"&&!b4&&av.body){this.context=av;this[0]=av.body;this.selector=b0;this.length=1;return this;}if(typeof b0==="string"){if(b0.charAt(0)==="<"&&b0.charAt(b0.length-1)===">"&&b0.length>=3){b2=[null,b0,null];}else{b2=bY.exec(b0);}if(b2&&(b2[1]||!b4)){if(b2[1]){b4=b4 instanceof bF?b4[0]:b4;b6=(b4?b4.ownerDocument||b4:av);b1=bA.exec(b0);if(b1){if(bF.isPlainObject(b4)){b0=[av.createElement(b1[1])];bF.fn.attr.call(b0,b4,true);}else{b0=[b6.createElement(b1[1])];}}else{b1=bF.buildFragment([b2[1]],[b6]);b0=(b1.cacheable?bF.clone(b1.fragment):b1.fragment).childNodes;}return bF.merge(this,b0);}else{b5=av.getElementById(b2[2]);if(b5&&b5.parentNode){if(b5.id!==b2[2]){return b3.find(b0);}this.length=1;this[0]=b5;}this.context=av;this.selector=b0;return this;}}else{if(!b4||b4.jquery){return(b4||b3).find(b0);}else{return this.constructor(b4).find(b0);}}}else{if(bF.isFunction(b0)){return b3.ready(b0);}}if(b0.selector!==L){this.selector=b0.selector;this.context=b0.context;}return bF.makeArray(b0,this);},selector:"",jquery:"1.7.2",length:0,size:function(){return this.length;},toArray:function(){return bK.call(this,0);},get:function(b0){return b0==null?this.toArray():(b0<0?this[this.length+b0]:this[b0]);},pushStack:function(b1,b3,b0){var b2=this.constructor();if(bF.isArray(b1)){bz.apply(b2,b1);}else{bF.merge(b2,b1);}b2.prevObject=this;b2.context=this.context;if(b3==="find"){b2.selector=this.selector+(this.selector?" ":"")+b0;}else{if(b3){b2.selector=this.selector+"."+b3+"("+b0+")";}}return b2;},each:function(b1,b0){return bF.each(this,b1,b0);},ready:function(b0){bF.bindReady();bC.add(b0);return this;},eq:function(b0){b0=+b0;return b0===-1?this.slice(b0):this.slice(b0,b0+1);},first:function(){return this.eq(0);},last:function(){return this.eq(-1);},slice:function(){return this.pushStack(bK.apply(this,arguments),"slice",bK.call(arguments).join(","));},map:function(b0){return this.pushStack(bF.map(this,function(b2,b1){return b0.call(b2,b1,b2);}));},end:function(){return this.prevObject||this.constructor(null);},push:bz,sort:[].sort,splice:[].splice};bF.fn.init.prototype=bF.fn;bF.extend=bF.fn.extend=function(){var b9,b2,b0,b1,b6,b7,b5=arguments[0]||{},b4=1,b3=arguments.length,b8=false;if(typeof b5==="boolean"){b8=b5;b5=arguments[1]||{};b4=2;}if(typeof b5!=="object"&&!bF.isFunction(b5)){b5={};}if(b3===b4){b5=this;--b4;}for(;b4<b3;b4++){if((b9=arguments[b4])!=null){for(b2 in b9){b0=b5[b2];b1=b9[b2];if(b5===b1){continue;}if(b8&&b1&&(bF.isPlainObject(b1)||(b6=bF.isArray(b1)))){if(b6){b6=false;b7=b0&&bF.isArray(b0)?b0:[];}else{b7=b0&&bF.isPlainObject(b0)?b0:{};}b5[b2]=bF.extend(b8,b7,b1);}else{if(b1!==L){b5[b2]=b1;}}}}}return b5;};bF.extend({noConflict:function(b0){if(bd.$===bF){bd.$=bH;}if(b0&&bd.jQuery===bF){bd.jQuery=bU;}return bF;},isReady:false,readyWait:1,holdReady:function(b0){if(b0){bF.readyWait++;}else{bF.ready(true);}},ready:function(b0){if((b0===true&&!--bF.readyWait)||(b0!==true&&!bF.isReady)){if(!av.body){return setTimeout(bF.ready,1);}bF.isReady=true;if(b0!==true&&--bF.readyWait>0){return;}bC.fireWith(av,[bF]);if(bF.fn.trigger){bF(av).trigger("ready").off("ready");}}},bindReady:function(){if(bC){return;}bC=bF.Callbacks("once memory");if(av.readyState==="complete"){return setTimeout(bF.ready,1);}if(av.addEventListener){av.addEventListener("DOMContentLoaded",e,false);bd.addEventListener("load",bF.ready,false);}else{if(av.attachEvent){av.attachEvent("onreadystatechange",e);bd.attachEvent("onload",bF.ready);var b0=false;try{b0=bd.frameElement==null;}catch(b1){}if(av.documentElement.doScroll&&b0){bw();}}}},isFunction:function(b0){return bF.type(b0)==="function";},isArray:Array.isArray||function(b0){return bF.type(b0)==="array";},isWindow:function(b0){return b0!=null&&b0==b0.window;},isNumeric:function(b0){return !isNaN(parseFloat(b0))&&isFinite(b0);},type:function(b0){return b0==null?String(b0):bx[bL.call(b0)]||"object";},isPlainObject:function(b2){if(!b2||bF.type(b2)!=="object"||b2.nodeType||bF.isWindow(b2)){return false;}try{if(b2.constructor&&!bG.call(b2,"constructor")&&!bG.call(b2.constructor.prototype,"isPrototypeOf")){return false;}}catch(b1){return false;}var b0;for(b0 in b2){}return b0===L||bG.call(b2,b0);},isEmptyObject:function(b1){for(var b0 in b1){return false;}return true;},error:function(b0){throw new Error(b0);},parseJSON:function(b0){if(typeof b0!=="string"||!b0){return null;}b0=bF.trim(b0);if(bd.JSON&&bd.JSON.parse){return bd.JSON.parse(b0);}if(bN.test(b0.replace(bW,"@").replace(bP,"]").replace(bJ,""))){return(new Function("return "+b0))();}bF.error("Invalid JSON: "+b0);},parseXML:function(b2){if(typeof b2!=="string"||!b2){return null;}var b0,b1;try{if(bd.DOMParser){b1=new DOMParser();b0=b1.parseFromString(b2,"text/xml");}else{b0=new ActiveXObject("Microsoft.XMLDOM");b0.async="false";b0.loadXML(b2);}}catch(b3){b0=L;}if(!b0||!b0.documentElement||b0.getElementsByTagName("parsererror").length){bF.error("Invalid XML: "+b2);}return b0;},noop:function(){},globalEval:function(b0){if(b0&&bM.test(b0)){(bd.execScript||function(b1){bd["eval"].call(bd,b1);})(b0);}},camelCase:function(b0){return b0.replace(bZ,"ms-").replace(bB,bT);},nodeName:function(b1,b0){return b1.nodeName&&b1.nodeName.toUpperCase()===b0.toUpperCase();},each:function(b3,b6,b2){var b1,b4=0,b5=b3.length,b0=b5===L||bF.isFunction(b3);if(b2){if(b0){for(b1 in b3){if(b6.apply(b3[b1],b2)===false){break;}}}else{for(;b4<b5;){if(b6.apply(b3[b4++],b2)===false){break;}}}}else{if(b0){for(b1 in b3){if(b6.call(b3[b1],b1,b3[b1])===false){break;}}}else{for(;b4<b5;){if(b6.call(b3[b4],b4,b3[b4++])===false){break;}}}}return b3;},trim:bO?function(b0){return b0==null?"":bO.call(b0);}:function(b0){return b0==null?"":b0.toString().replace(bI,"").replace(bE,"");},makeArray:function(b3,b1){var b0=b1||[];if(b3!=null){var b2=bF.type(b3);if(b3.length==null||b2==="string"||b2==="function"||b2==="regexp"||bF.isWindow(b3)){bz.call(b0,b3);}else{bF.merge(b0,b3);}}return b0;},inArray:function(b2,b3,b1){var b0;if(b3){if(bv){return bv.call(b3,b2,b1);}b0=b3.length;b1=b1?b1<0?Math.max(0,b0+b1):b1:0;for(;b1<b0;b1++){if(b1 in b3&&b3[b1]===b2){return b1;}}}return -1;},merge:function(b4,b2){var b3=b4.length,b1=0;if(typeof b2.length==="number"){for(var b0=b2.length;b1<b0;b1++){b4[b3++]=b2[b1];}}else{while(b2[b1]!==L){b4[b3++]=b2[b1++];}}b4.length=b3;return b4;},grep:function(b1,b6,b0){var b2=[],b5;b0=!!b0;for(var b3=0,b4=b1.length;b3<b4;b3++){b5=!!b6(b1[b3],b3);if(b0!==b5){b2.push(b1[b3]);}}return b2;},map:function(b0,b7,b8){var b5,b6,b4=[],b2=0,b1=b0.length,b3=b0 instanceof bF||b1!==L&&typeof b1==="number"&&((b1>0&&b0[0]&&b0[b1-1])||b1===0||bF.isArray(b0));if(b3){for(;b2<b1;b2++){b5=b7(b0[b2],b2,b8);if(b5!=null){b4[b4.length]=b5;}}}else{for(b6 in b0){b5=b7(b0[b6],b6,b8);if(b5!=null){b4[b4.length]=b5;}}}return b4.concat.apply([],b4);},guid:1,proxy:function(b4,b3){if(typeof b3==="string"){var b2=b4[b3];b3=b4;b4=b2;}if(!bF.isFunction(b4)){return L;}var b0=bK.call(arguments,2),b1=function(){return b4.apply(b3,b0.concat(bK.call(arguments)));};b1.guid=b4.guid=b4.guid||b1.guid||bF.guid++;return b1;},access:function(b0,b6,b9,b7,b4,ca,b8){var b2,b5=b9==null,b3=0,b1=b0.length;if(b9&&typeof b9==="object"){for(b3 in b9){bF.access(b0,b6,b3,b9[b3],1,ca,b7);}b4=1;}else{if(b7!==L){b2=b8===L&&bF.isFunction(b7);if(b5){if(b2){b2=b6;b6=function(cc,cb,cd){return b2.call(bF(cc),cd);};}else{b6.call(b0,b7);b6=null;}}if(b6){for(;b3<b1;b3++){b6(b0[b3],b9,b2?b7.call(b0[b3],b3,b6(b0[b3],b9)):b7,b8);}}b4=1;}}return b4?b0:b5?b6.call(b0):b1?b6(b0[0],b9):ca;},now:function(){return(new Date()).getTime();},uaMatch:function(b1){b1=b1.toLowerCase();var b0=by.exec(b1)||bR.exec(b1)||bQ.exec(b1)||b1.indexOf("compatible")<0&&bS.exec(b1)||[];return{browser:b0[1]||"",version:b0[2]||"0"};},sub:function(){function b0(b3,b4){return new b0.fn.init(b3,b4);}bF.extend(true,b0,this);b0.superclass=this;b0.fn=b0.prototype=this();b0.fn.constructor=b0;b0.sub=this.sub;b0.fn.init=function b2(b3,b4){if(b4&&b4 instanceof bF&&!(b4 instanceof b0)){b4=b0(b4);}return bF.fn.init.call(this,b3,b4,b1);};b0.fn.init.prototype=b0.fn;var b1=b0(av);return b0;},browser:{}});bF.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(b1,b0){bx["[object "+b0+"]"]=b0.toLowerCase();});bV=bF.uaMatch(bX);if(bV.browser){bF.browser[bV.browser]=true;bF.browser.version=bV.version;}if(bF.browser.webkit){bF.browser.safari=true;}if(bM.test("\xA0")){bI=/^[\s\xA0]+/;bE=/[\s\xA0]+$/;}bD=bF(av);if(av.addEventListener){e=function(){av.removeEventListener("DOMContentLoaded",e,false);bF.ready();};}else{if(av.attachEvent){e=function(){if(av.readyState==="complete"){av.detachEvent("onreadystatechange",e);bF.ready();}};}}function bw(){if(bF.isReady){return;}try{av.documentElement.doScroll("left");}catch(b0){setTimeout(bw,1);return;}bF.ready();}return bF;})();var a3={};function X(e){var bv=a3[e]={},bw,bx;e=e.split(/\s+/);for(bw=0,bx=e.length;bw<bx;bw++){bv[e[bw]]=true;}return bv;}b.Callbacks=function(bx){bx=bx?(a3[bx]||X(bx)):{};var bC=[],bD=[],by,e,bz,bw,bA,bB,bF=function(bG){var bH,bK,bJ,bI,bL;for(bH=0,bK=bG.length;bH<bK;bH++){bJ=bG[bH];bI=b.type(bJ);if(bI==="array"){bF(bJ);}else{if(bI==="function"){if(!bx.unique||!bE.has(bJ)){bC.push(bJ);}}}}},bv=function(bH,bG){bG=bG||[];by=!bx.memory||[bH,bG];e=true;bz=true;bB=bw||0;bw=0;bA=bC.length;for(;bC&&bB<bA;bB++){if(bC[bB].apply(bH,bG)===false&&bx.stopOnFalse){by=true;break;}}bz=false;if(bC){if(!bx.once){if(bD&&bD.length){by=bD.shift();bE.fireWith(by[0],by[1]);}}else{if(by===true){bE.disable();}else{bC=[];}}}},bE={add:function(){if(bC){var bG=bC.length;bF(arguments);if(bz){bA=bC.length;}else{if(by&&by!==true){bw=bG;bv(by[0],by[1]);}}}return this;},remove:function(){if(bC){var bG=arguments,bI=0,bJ=bG.length;for(;bI<bJ;bI++){for(var bH=0;bH<bC.length;bH++){if(bG[bI]===bC[bH]){if(bz){if(bH<=bA){bA--;if(bH<=bB){bB--;}}}bC.splice(bH--,1);if(bx.unique){break;}}}}}return this;},has:function(bH){if(bC){var bG=0,bI=bC.length;for(;bG<bI;bG++){if(bH===bC[bG]){return true;}}}return false;},empty:function(){bC=[];return this;},disable:function(){bC=bD=by=L;return this;},disabled:function(){return !bC;},lock:function(){bD=L;if(!by||by===true){bE.disable();}return this;},locked:function(){return !bD;},fireWith:function(bH,bG){if(bD){if(bz){if(!bx.once){bD.push([bH,bG]);}}else{if(!(bx.once&&by)){bv(bH,bG);}}}return this;},fire:function(){bE.fireWith(this,arguments);return this;},fired:function(){return !!e;}};return bE;};var aK=[].slice;b.extend({Deferred:function(by){var bx=b.Callbacks("once memory"),bw=b.Callbacks("once memory"),bv=b.Callbacks("memory"),e="pending",bA={resolve:bx,reject:bw,notify:bv},bC={done:bx.add,fail:bw.add,progress:bv.add,state:function(){return e;},isResolved:bx.fired,isRejected:bw.fired,then:function(bE,bD,bF){bB.done(bE).fail(bD).progress(bF);return this;},always:function(){bB.done.apply(bB,arguments).fail.apply(bB,arguments);return this;},pipe:function(bF,bE,bD){return b.Deferred(function(bG){b.each({done:[bF,"resolve"],fail:[bE,"reject"],progress:[bD,"notify"]},function(bI,bL){var bH=bL[0],bK=bL[1],bJ;if(b.isFunction(bH)){bB[bI](function(){bJ=bH.apply(this,arguments);if(bJ&&b.isFunction(bJ.promise)){bJ.promise().then(bG.resolve,bG.reject,bG.notify);}else{bG[bK+"With"](this===bB?bG:this,[bJ]);}});}else{bB[bI](bG[bK]);}});}).promise();},promise:function(bE){if(bE==null){bE=bC;}else{for(var bD in bC){bE[bD]=bC[bD];}}return bE;}},bB=bC.promise({}),bz;for(bz in bA){bB[bz]=bA[bz].fire;bB[bz+"With"]=bA[bz].fireWith;}bB.done(function(){e="resolved";},bw.disable,bv.lock).fail(function(){e="rejected";},bx.disable,bv.lock);if(by){by.call(bB,bB);}return bB;},when:function(bA){var bx=aK.call(arguments,0),bv=0,e=bx.length,bB=new Array(e),bw=e,by=e,bC=e<=1&&bA&&b.isFunction(bA.promise)?bA:b.Deferred(),bE=bC.promise();function bD(bF){return function(bG){bx[bF]=arguments.length>1?aK.call(arguments,0):bG;if(!(--bw)){bC.resolveWith(bC,bx);}};}function bz(bF){return function(bG){bB[bF]=arguments.length>1?aK.call(arguments,0):bG;bC.notifyWith(bE,bB);};}if(e>1){for(;bv<e;bv++){if(bx[bv]&&bx[bv].promise&&b.isFunction(bx[bv].promise)){bx[bv].promise().then(bD(bv),bC.reject,bz(bv));}else{--bw;}}if(!bw){bC.resolveWith(bC,bx);}}else{if(bC!==bA){bC.resolveWith(bC,e?[bA]:[]);}}return bE;}});b.support=(function(){var bI,bH,bE,bF,bx,bD,bC,bz,bJ,bA,by,bw,bv=av.createElement("div"),bG=av.documentElement;bv.setAttribute("className","t");bv.innerHTML="   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";bH=bv.getElementsByTagName("*");bE=bv.getElementsByTagName("a")[0];if(!bH||!bH.length||!bE){return{};}bF=av.createElement("select");bx=bF.appendChild(av.createElement("option"));bD=bv.getElementsByTagName("input")[0];bI={leadingWhitespace:(bv.firstChild.nodeType===3),tbody:!bv.getElementsByTagName("tbody").length,htmlSerialize:!!bv.getElementsByTagName("link").length,style:/top/.test(bE.getAttribute("style")),hrefNormalized:(bE.getAttribute("href")==="/a"),opacity:/^0.55/.test(bE.style.opacity),cssFloat:!!bE.style.cssFloat,checkOn:(bD.value==="on"),optSelected:bx.selected,getSetAttribute:bv.className!=="t",enctype:!!av.createElement("form").enctype,html5Clone:av.createElement("nav").cloneNode(true).outerHTML!=="<:nav></:nav>",submitBubbles:true,changeBubbles:true,focusinBubbles:false,deleteExpando:true,noCloneEvent:true,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableMarginRight:true,pixelMargin:true};b.boxModel=bI.boxModel=(av.compatMode==="CSS1Compat");bD.checked=true;bI.noCloneChecked=bD.cloneNode(true).checked;bF.disabled=true;bI.optDisabled=!bx.disabled;try{delete bv.test;}catch(bB){bI.deleteExpando=false;}if(!bv.addEventListener&&bv.attachEvent&&bv.fireEvent){bv.attachEvent("onclick",function(){bI.noCloneEvent=false;});bv.cloneNode(true).fireEvent("onclick");}bD=av.createElement("input");bD.value="t";bD.setAttribute("type","radio");bI.radioValue=bD.value==="t";bD.setAttribute("checked","checked");bD.setAttribute("name","t");bv.appendChild(bD);bC=av.createDocumentFragment();bC.appendChild(bv.lastChild);bI.checkClone=bC.cloneNode(true).cloneNode(true).lastChild.checked;bI.appendChecked=bD.checked;bC.removeChild(bD);bC.appendChild(bv);if(bv.attachEvent){for(by in {submit:1,change:1,focusin:1}){bA="on"+by;bw=(bA in bv);if(!bw){bv.setAttribute(bA,"return;");bw=(typeof bv[bA]==="function");}bI[by+"Bubbles"]=bw;}}bC.removeChild(bv);bC=bF=bx=bv=bD=null;b(function(){var bM,bV,bW,bU,bO,bP,bR,bL,bK,bQ,bN,e,bT,bS=av.getElementsByTagName("body")[0];if(!bS){return;}bL=1;bT="padding:0;margin:0;border:";bN="position:absolute;top:0;left:0;width:1px;height:1px;";e=bT+"0;visibility:hidden;";bK="style='"+bN+bT+"5px solid #000;";bQ="<div "+bK+"display:block;'><div style='"+bT+"0;display:block;overflow:hidden;'></div></div><table "+bK+"' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";bM=av.createElement("div");bM.style.cssText=e+"width:0;height:0;position:static;top:0;margin-top:"+bL+"px";bS.insertBefore(bM,bS.firstChild);bv=av.createElement("div");bM.appendChild(bv);bv.innerHTML="<table><tr><td style='"+bT+"0;display:none'></td><td>t</td></tr></table>";bz=bv.getElementsByTagName("td");bw=(bz[0].offsetHeight===0);bz[0].style.display="";bz[1].style.display="none";bI.reliableHiddenOffsets=bw&&(bz[0].offsetHeight===0);if(bd.getComputedStyle){bv.innerHTML="";bR=av.createElement("div");bR.style.width="0";bR.style.marginRight="0";bv.style.width="2px";bv.appendChild(bR);bI.reliableMarginRight=(parseInt((bd.getComputedStyle(bR,null)||{marginRight:0}).marginRight,10)||0)===0;}if(typeof bv.style.zoom!=="undefined"){bv.innerHTML="";bv.style.width=bv.style.padding="1px";bv.style.border=0;bv.style.overflow="hidden";bv.style.display="inline";bv.style.zoom=1;bI.inlineBlockNeedsLayout=(bv.offsetWidth===3);bv.style.display="block";bv.style.overflow="visible";bv.innerHTML="<div style='width:5px;'></div>";bI.shrinkWrapBlocks=(bv.offsetWidth!==3);}bv.style.cssText=bN+e;bv.innerHTML=bQ;bV=bv.firstChild;bW=bV.firstChild;bO=bV.nextSibling.firstChild.firstChild;bP={doesNotAddBorder:(bW.offsetTop!==5),doesAddBorderForTableAndCells:(bO.offsetTop===5)};bW.style.position="fixed";bW.style.top="20px";bP.fixedPosition=(bW.offsetTop===20||bW.offsetTop===15);bW.style.position=bW.style.top="";bV.style.overflow="hidden";bV.style.position="relative";bP.subtractsBorderForOverflowNotVisible=(bW.offsetTop===-5);bP.doesNotIncludeMarginInBodyOffset=(bS.offsetTop!==bL);if(bd.getComputedStyle){bv.style.marginTop="1%";bI.pixelMargin=(bd.getComputedStyle(bv,null)||{marginTop:0}).marginTop!=="1%";}if(typeof bM.style.zoom!=="undefined"){bM.style.zoom=1;}bS.removeChild(bM);bR=bv=bM=null;b.extend(bI,bP);});return bI;})();var aT=/^(?:\{.*\}|\[.*\])$/,aA=/([A-Z])/g;b.extend({cache:{},uuid:0,expando:"jQuery"+(b.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},hasData:function(e){e=e.nodeType?b.cache[e[b.expando]]:e[b.expando];return !!e&&!S(e);},data:function(bx,bv,bz,by){if(!b.acceptData(bx)){return;}var bG,bA,bD,bE=b.expando,bC=typeof bv==="string",bF=bx.nodeType,e=bF?b.cache:bx,bw=bF?bx[bE]:bx[bE]&&bE,bB=bv==="events";if((!bw||!e[bw]||(!bB&&!by&&!e[bw].data))&&bC&&bz===L){return;}if(!bw){if(bF){bx[bE]=bw=++b.uuid;}else{bw=bE;}}if(!e[bw]){e[bw]={};if(!bF){e[bw].toJSON=b.noop;}}if(typeof bv==="object"||typeof bv==="function"){if(by){e[bw]=b.extend(e[bw],bv);}else{e[bw].data=b.extend(e[bw].data,bv);}}bG=bA=e[bw];if(!by){if(!bA.data){bA.data={};}bA=bA.data;}if(bz!==L){bA[b.camelCase(bv)]=bz;}if(bB&&!bA[bv]){return bG.events;}if(bC){bD=bA[bv];if(bD==null){bD=bA[b.camelCase(bv)];}}else{bD=bA;}return bD;},removeData:function(bx,bv,by){if(!b.acceptData(bx)){return;}var bB,bA,bz,bC=b.expando,bD=bx.nodeType,e=bD?b.cache:bx,bw=bD?bx[bC]:bC;if(!e[bw]){return;}if(bv){bB=by?e[bw]:e[bw].data;if(bB){if(!b.isArray(bv)){if(bv in bB){bv=[bv];}else{bv=b.camelCase(bv);if(bv in bB){bv=[bv];}else{bv=bv.split(" ");}}}for(bA=0,bz=bv.length;bA<bz;bA++){delete bB[bv[bA]];}if(!(by?S:b.isEmptyObject)(bB)){return;}}}if(!by){delete e[bw].data;if(!S(e[bw])){return;}}if(b.support.deleteExpando||!e.setInterval){delete e[bw];}else{e[bw]=null;}if(bD){if(b.support.deleteExpando){delete bx[bC];}else{if(bx.removeAttribute){bx.removeAttribute(bC);}else{bx[bC]=null;}}}},_data:function(bv,e,bw){return b.data(bv,e,bw,true);},acceptData:function(bv){if(bv.nodeName){var e=b.noData[bv.nodeName.toLowerCase()];if(e){return !(e===true||bv.getAttribute("classid")!==e);}}return true;}});b.fn.extend({data:function(bD,bC){var by,bv,bB,e,bx,bw=this[0],bA=0,bz=null;if(bD===L){if(this.length){bz=b.data(bw);if(bw.nodeType===1&&!b._data(bw,"parsedAttrs")){bB=bw.attributes;for(bx=bB.length;bA<bx;bA++){e=bB[bA].name;if(e.indexOf("data-")===0){e=b.camelCase(e.substring(5));a6(bw,e,bz[e]);}}b._data(bw,"parsedAttrs",true);}}return bz;}if(typeof bD==="object"){return this.each(function(){b.data(this,bD);});}by=bD.split(".",2);by[1]=by[1]?"."+by[1]:"";bv=by[1]+"!";return b.access(this,function(bE){if(bE===L){bz=this.triggerHandler("getData"+bv,[by[0]]);if(bz===L&&bw){bz=b.data(bw,bD);bz=a6(bw,bD,bz);}return bz===L&&by[1]?this.data(by[0]):bz;}by[1]=bE;this.each(function(){var bF=b(this);bF.triggerHandler("setData"+bv,by);b.data(this,bD,bE);bF.triggerHandler("changeData"+bv,by);});},null,bC,arguments.length>1,null,false);},removeData:function(e){return this.each(function(){b.removeData(this,e);});}});function a6(bx,bw,by){if(by===L&&bx.nodeType===1){var bv="data-"+bw.replace(aA,"-$1").toLowerCase();by=bx.getAttribute(bv);if(typeof by==="string"){try{by=by==="true"?true:by==="false"?false:by==="null"?null:b.isNumeric(by)?+by:aT.test(by)?b.parseJSON(by):by;}catch(bz){}b.data(bx,bw,by);}else{by=L;}}return by;}function S(bv){for(var e in bv){if(e==="data"&&b.isEmptyObject(bv[e])){continue;}if(e!=="toJSON"){return false;}}return true;}function bj(by,bx,bA){var bw=bx+"defer",bv=bx+"queue",e=bx+"mark",bz=b._data(by,bw);if(bz&&(bA==="queue"||!b._data(by,bv))&&(bA==="mark"||!b._data(by,e))){setTimeout(function(){if(!b._data(by,bv)&&!b._data(by,e)){b.removeData(by,bw,true);bz.fire();}},0);}}b.extend({_mark:function(bv,e){if(bv){e=(e||"fx")+"mark";b._data(bv,e,(b._data(bv,e)||0)+1);}},_unmark:function(by,bx,bv){if(by!==true){bv=bx;bx=by;by=false;}if(bx){bv=bv||"fx";var e=bv+"mark",bw=by?0:((b._data(bx,e)||1)-1);if(bw){b._data(bx,e,bw);}else{b.removeData(bx,e,true);bj(bx,bv,"mark");}}},queue:function(bv,e,bx){var bw;if(bv){e=(e||"fx")+"queue";bw=b._data(bv,e);if(bx){if(!bw||b.isArray(bx)){bw=b._data(bv,e,b.makeArray(bx));}else{bw.push(bx);}}return bw||[];}},dequeue:function(by,bx){bx=bx||"fx";var bv=b.queue(by,bx),bw=bv.shift(),e={};if(bw==="inprogress"){bw=bv.shift();}if(bw){if(bx==="fx"){bv.unshift("inprogress");}b._data(by,bx+".run",e);bw.call(by,function(){b.dequeue(by,bx);},e);}if(!bv.length){b.removeData(by,bx+"queue "+bx+".run",true);bj(by,bx,"queue");}}});b.fn.extend({queue:function(e,bv){var bw=2;if(typeof e!=="string"){bv=e;e="fx";bw--;}if(arguments.length<bw){return b.queue(this[0],e);}return bv===L?this:this.each(function(){var bx=b.queue(this,e,bv);if(e==="fx"&&bx[0]!=="inprogress"){b.dequeue(this,e);}});},dequeue:function(e){return this.each(function(){b.dequeue(this,e);});},delay:function(bv,e){bv=b.fx?b.fx.speeds[bv]||bv:bv;e=e||"fx";return this.queue(e,function(bx,bw){var by=setTimeout(bx,bv);bw.stop=function(){clearTimeout(by);};});},clearQueue:function(e){return this.queue(e||"fx",[]);},promise:function(bD,bw){if(typeof bD!=="string"){bw=bD;bD=L;}bD=bD||"fx";var e=b.Deferred(),bv=this,by=bv.length,bB=1,bz=bD+"defer",bA=bD+"queue",bC=bD+"mark",bx;function bE(){if(!(--bB)){e.resolveWith(bv,[bv]);}}while(by--){if((bx=b.data(bv[by],bz,L,true)||(b.data(bv[by],bA,L,true)||b.data(bv[by],bC,L,true))&&b.data(bv[by],bz,b.Callbacks("once memory"),true))){bB++;bx.add(bE);}}bE();return e.promise(bw);}});var aQ=/[\n\t\r]/g,ag=/\s+/,aV=/\r/g,g=/^(?:button|input)$/i,C=/^(?:button|input|object|select|textarea)$/i,l=/^a(?:rea)?$/i,ao=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,E=b.support.getSetAttribute,bf,aZ,aG;b.fn.extend({attr:function(e,bv){return b.access(this,b.attr,e,bv,arguments.length>1);},removeAttr:function(e){return this.each(function(){b.removeAttr(this,e);});},prop:function(e,bv){return b.access(this,b.prop,e,bv,arguments.length>1);},removeProp:function(e){e=b.propFix[e]||e;return this.each(function(){try{this[e]=L;delete this[e];}catch(bv){}});},addClass:function(by){var bA,bw,bv,bx,bz,bB,e;if(b.isFunction(by)){return this.each(function(bC){b(this).addClass(by.call(this,bC,this.className));});}if(by&&typeof by==="string"){bA=by.split(ag);for(bw=0,bv=this.length;bw<bv;bw++){bx=this[bw];if(bx.nodeType===1){if(!bx.className&&bA.length===1){bx.className=by;}else{bz=" "+bx.className+" ";for(bB=0,e=bA.length;bB<e;bB++){if(!~bz.indexOf(" "+bA[bB]+" ")){bz+=bA[bB]+" ";}}bx.className=b.trim(bz);}}}}return this;},removeClass:function(bz){var bA,bw,bv,by,bx,bB,e;if(b.isFunction(bz)){return this.each(function(bC){b(this).removeClass(bz.call(this,bC,this.className));});}if((bz&&typeof bz==="string")||bz===L){bA=(bz||"").split(ag);for(bw=0,bv=this.length;bw<bv;bw++){by=this[bw];if(by.nodeType===1&&by.className){if(bz){bx=(" "+by.className+" ").replace(aQ," ");for(bB=0,e=bA.length;bB<e;bB++){bx=bx.replace(" "+bA[bB]+" "," ");}by.className=b.trim(bx);}else{by.className="";}}}}return this;},toggleClass:function(bx,bv){var bw=typeof bx,e=typeof bv==="boolean";if(b.isFunction(bx)){return this.each(function(by){b(this).toggleClass(bx.call(this,by,this.className,bv),bv);});}return this.each(function(){if(bw==="string"){var bA,bz=0,by=b(this),bB=bv,bC=bx.split(ag);while((bA=bC[bz++])){bB=e?bB:!by.hasClass(bA);by[bB?"addClass":"removeClass"](bA);}}else{if(bw==="undefined"||bw==="boolean"){if(this.className){b._data(this,"__className__",this.className);}this.className=this.className||bx===false?"":b._data(this,"__className__")||"";}}});},hasClass:function(e){var bx=" "+e+" ",bw=0,bv=this.length;for(;bw<bv;bw++){if(this[bw].nodeType===1&&(" "+this[bw].className+" ").replace(aQ," ").indexOf(bx)>-1){return true;}}return false;},val:function(bx){var e,bv,by,bw=this[0];if(!arguments.length){if(bw){e=b.valHooks[bw.type]||b.valHooks[bw.nodeName.toLowerCase()];if(e&&"get" in e&&(bv=e.get(bw,"value"))!==L){return bv;}bv=bw.value;return typeof bv==="string"?bv.replace(aV,""):bv==null?"":bv;}return;}by=b.isFunction(bx);return this.each(function(bA){var bz=b(this),bB;if(this.nodeType!==1){return;}if(by){bB=bx.call(this,bA,bz.val());}else{bB=bx;}if(bB==null){bB="";}else{if(typeof bB==="number"){bB+="";}else{if(b.isArray(bB)){bB=b.map(bB,function(bC){return bC==null?"":bC+"";});}}}e=b.valHooks[this.type]||b.valHooks[this.nodeName.toLowerCase()];if(!e||!("set" in e)||e.set(this,bB,"value")===L){this.value=bB;}});}});b.extend({valHooks:{option:{get:function(e){var bv=e.attributes.value;return !bv||bv.specified?e.value:e.text;}},select:{get:function(e){var bA,bv,bz,bx,by=e.selectedIndex,bB=[],bC=e.options,bw=e.type==="select-one";if(by<0){return null;}bv=bw?by:0;bz=bw?by+1:bC.length;for(;bv<bz;bv++){bx=bC[bv];if(bx.selected&&(b.support.optDisabled?!bx.disabled:bx.getAttribute("disabled")===null)&&(!bx.parentNode.disabled||!b.nodeName(bx.parentNode,"optgroup"))){bA=b(bx).val();if(bw){return bA;}bB.push(bA);}}if(bw&&!bB.length&&bC.length){return b(bC[by]).val();}return bB;},set:function(bv,bw){var e=b.makeArray(bw);b(bv).find("option").each(function(){this.selected=b.inArray(b(this).val(),e)>=0;});if(!e.length){bv.selectedIndex=-1;}return e;}}},attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(bA,bx,bB,bz){var bw,e,by,bv=bA.nodeType;if(!bA||bv===3||bv===8||bv===2){return;}if(bz&&bx in b.attrFn){return b(bA)[bx](bB);}if(typeof bA.getAttribute==="undefined"){return b.prop(bA,bx,bB);}by=bv!==1||!b.isXMLDoc(bA);if(by){bx=bx.toLowerCase();e=b.attrHooks[bx]||(ao.test(bx)?aZ:bf);}if(bB!==L){if(bB===null){b.removeAttr(bA,bx);return;}else{if(e&&"set" in e&&by&&(bw=e.set(bA,bB,bx))!==L){return bw;}else{bA.setAttribute(bx,""+bB);return bB;}}}else{if(e&&"get" in e&&by&&(bw=e.get(bA,bx))!==null){return bw;}else{bw=bA.getAttribute(bx);return bw===null?L:bw;}}},removeAttr:function(by,bA){var bz,bB,bw,e,bv,bx=0;if(bA&&by.nodeType===1){bB=bA.toLowerCase().split(ag);e=bB.length;for(;bx<e;bx++){bw=bB[bx];if(bw){bz=b.propFix[bw]||bw;bv=ao.test(bw);if(!bv){b.attr(by,bw,"");}by.removeAttribute(E?bw:bz);if(bv&&bz in by){by[bz]=false;}}}}},attrHooks:{type:{set:function(e,bv){if(g.test(e.nodeName)&&e.parentNode){b.error("type property can't be changed");}else{if(!b.support.radioValue&&bv==="radio"&&b.nodeName(e,"input")){var bw=e.value;e.setAttribute("type",bv);if(bw){e.value=bw;}return bv;}}}},value:{get:function(bv,e){if(bf&&b.nodeName(bv,"button")){return bf.get(bv,e);}return e in bv?bv.value:null;},set:function(bv,bw,e){if(bf&&b.nodeName(bv,"button")){return bf.set(bv,bw,e);}bv.value=bw;}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(bz,bx,bA){var bw,e,by,bv=bz.nodeType;if(!bz||bv===3||bv===8||bv===2){return;}by=bv!==1||!b.isXMLDoc(bz);if(by){bx=b.propFix[bx]||bx;e=b.propHooks[bx];}if(bA!==L){if(e&&"set" in e&&(bw=e.set(bz,bA,bx))!==L){return bw;}else{return(bz[bx]=bA);}}else{if(e&&"get" in e&&(bw=e.get(bz,bx))!==null){return bw;}else{return bz[bx];}}},propHooks:{tabIndex:{get:function(bv){var e=bv.getAttributeNode("tabindex");return e&&e.specified?parseInt(e.value,10):C.test(bv.nodeName)||l.test(bv.nodeName)&&bv.href?0:L;}}}});b.attrHooks.tabindex=b.propHooks.tabIndex;aZ={get:function(bv,e){var bx,bw=b.prop(bv,e);return bw===true||typeof bw!=="boolean"&&(bx=bv.getAttributeNode(e))&&bx.nodeValue!==false?e.toLowerCase():L;},set:function(bv,bx,e){var bw;if(bx===false){b.removeAttr(bv,e);}else{bw=b.propFix[e]||e;if(bw in bv){bv[bw]=true;}bv.setAttribute(e,e.toLowerCase());}return e;}};if(!E){aG={name:true,id:true,coords:true};bf=b.valHooks.button={get:function(bw,bv){var e;e=bw.getAttributeNode(bv);return e&&(aG[bv]?e.nodeValue!=="":e.specified)?e.nodeValue:L;},set:function(bw,bx,bv){var e=bw.getAttributeNode(bv);if(!e){e=av.createAttribute(bv);bw.setAttributeNode(e);}return(e.nodeValue=bx+"");}};b.attrHooks.tabindex.set=bf.set;b.each(["width","height"],function(bv,e){b.attrHooks[e]=b.extend(b.attrHooks[e],{set:function(bw,bx){if(bx===""){bw.setAttribute(e,"auto");return bx;}}});});b.attrHooks.contenteditable={get:bf.get,set:function(bv,bw,e){if(bw===""){bw="false";}bf.set(bv,bw,e);}};}if(!b.support.hrefNormalized){b.each(["href","src","width","height"],function(bv,e){b.attrHooks[e]=b.extend(b.attrHooks[e],{get:function(bx){var bw=bx.getAttribute(e,2);return bw===null?L:bw;}});});}if(!b.support.style){b.attrHooks.style={get:function(e){return e.style.cssText.toLowerCase()||L;},set:function(e,bv){return(e.style.cssText=""+bv);}};}if(!b.support.optSelected){b.propHooks.selected=b.extend(b.propHooks.selected,{get:function(bv){var e=bv.parentNode;if(e){e.selectedIndex;if(e.parentNode){e.parentNode.selectedIndex;}}return null;}});}if(!b.support.enctype){b.propFix.enctype="encoding";}if(!b.support.checkOn){b.each(["radio","checkbox"],function(){b.valHooks[this]={get:function(e){return e.getAttribute("value")===null?"on":e.value;}};});}b.each(["radio","checkbox"],function(){b.valHooks[this]=b.extend(b.valHooks[this],{set:function(e,bv){if(b.isArray(bv)){return(e.checked=b.inArray(b(e).val(),bv)>=0);}}});});var be=/^(?:textarea|input|select)$/i,n=/^([^\.]*)?(?:\.(.+))?$/,J=/(?:^|\s)hover(\.\S+)?\b/,aP=/^key/,bg=/^(?:mouse|contextmenu)|click/,T=/^(?:focusinfocus|focusoutblur)$/,U=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,Y=function(e){var bv=U.exec(e);if(bv){bv[1]=(bv[1]||"").toLowerCase();bv[3]=bv[3]&&new RegExp("(?:^|\\s)"+bv[3]+"(?:\\s|$)");}return bv;},j=function(bw,e){var bv=bw.attributes||{};return((!e[1]||bw.nodeName.toLowerCase()===e[1])&&(!e[2]||(bv.id||{}).value===e[2])&&(!e[3]||e[3].test((bv["class"]||{}).value)));},bt=function(e){return b.event.special.hover?e:e.replace(J,"mouseenter$1 mouseleave$1");};b.event={add:function(bx,bC,bJ,bA,by){var bD,bB,bK,bI,bH,bF,e,bG,bv,bz,bw,bE;if(bx.nodeType===3||bx.nodeType===8||!bC||!bJ||!(bD=b._data(bx))){return;}if(bJ.handler){bv=bJ;bJ=bv.handler;by=bv.selector;}if(!bJ.guid){bJ.guid=b.guid++;}bK=bD.events;if(!bK){bD.events=bK={};}bB=bD.handle;if(!bB){bD.handle=bB=function(bL){return typeof b!=="undefined"&&(!bL||b.event.triggered!==bL.type)?b.event.dispatch.apply(bB.elem,arguments):L;};bB.elem=bx;}bC=b.trim(bt(bC)).split(" ");for(bI=0;bI<bC.length;bI++){bH=n.exec(bC[bI])||[];bF=bH[1];e=(bH[2]||"").split(".").sort();bE=b.event.special[bF]||{};bF=(by?bE.delegateType:bE.bindType)||bF;bE=b.event.special[bF]||{};bG=b.extend({type:bF,origType:bH[1],data:bA,handler:bJ,guid:bJ.guid,selector:by,quick:by&&Y(by),namespace:e.join(".")},bv);bw=bK[bF];if(!bw){bw=bK[bF]=[];bw.delegateCount=0;if(!bE.setup||bE.setup.call(bx,bA,e,bB)===false){if(bx.addEventListener){bx.addEventListener(bF,bB,false);}else{if(bx.attachEvent){bx.attachEvent("on"+bF,bB);}}}}if(bE.add){bE.add.call(bx,bG);if(!bG.handler.guid){bG.handler.guid=bJ.guid;}}if(by){bw.splice(bw.delegateCount++,0,bG);}else{bw.push(bG);}b.event.global[bF]=true;}bx=null;},global:{},remove:function(bJ,bE,bv,bH,bB){var bI=b.hasData(bJ)&&b._data(bJ),bF,bx,bz,bL,bC,bA,bG,bw,by,bK,bD,e;if(!bI||!(bw=bI.events)){return;}bE=b.trim(bt(bE||"")).split(" ");for(bF=0;bF<bE.length;bF++){bx=n.exec(bE[bF])||[];bz=bL=bx[1];bC=bx[2];if(!bz){for(bz in bw){b.event.remove(bJ,bz+bE[bF],bv,bH,true);}continue;}by=b.event.special[bz]||{};bz=(bH?by.delegateType:by.bindType)||bz;bD=bw[bz]||[];bA=bD.length;bC=bC?new RegExp("(^|\\.)"+bC.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(bG=0;bG<bD.length;bG++){e=bD[bG];if((bB||bL===e.origType)&&(!bv||bv.guid===e.guid)&&(!bC||bC.test(e.namespace))&&(!bH||bH===e.selector||bH==="**"&&e.selector)){bD.splice(bG--,1);if(e.selector){bD.delegateCount--;}if(by.remove){by.remove.call(bJ,e);}}}if(bD.length===0&&bA!==bD.length){if(!by.teardown||by.teardown.call(bJ,bC)===false){b.removeEvent(bJ,bz,bI.handle);}delete bw[bz];}}if(b.isEmptyObject(bw)){bK=bI.handle;if(bK){bK.elem=null;}b.removeData(bJ,["events","handle"],true);}},customEvent:{getData:true,setData:true,changeData:true},trigger:function(bv,bD,bA,bJ){if(bA&&(bA.nodeType===3||bA.nodeType===8)){return;}var bG=bv.type||bv,bx=[],e,bw,bC,bH,bz,by,bF,bE,bB,bI;if(T.test(bG+b.event.triggered)){return;}if(bG.indexOf("!")>=0){bG=bG.slice(0,-1);bw=true;}if(bG.indexOf(".")>=0){bx=bG.split(".");bG=bx.shift();bx.sort();}if((!bA||b.event.customEvent[bG])&&!b.event.global[bG]){return;}bv=typeof bv==="object"?bv[b.expando]?bv:new b.Event(bG,bv):new b.Event(bG);bv.type=bG;bv.isTrigger=true;bv.exclusive=bw;bv.namespace=bx.join(".");bv.namespace_re=bv.namespace?new RegExp("(^|\\.)"+bx.join("\\.(?:.*\\.)?")+"(\\.|$)"):null;by=bG.indexOf(":")<0?"on"+bG:"";if(!bA){e=b.cache;for(bC in e){if(e[bC].events&&e[bC].events[bG]){b.event.trigger(bv,bD,e[bC].handle.elem,true);}}return;}bv.result=L;if(!bv.target){bv.target=bA;}bD=bD!=null?b.makeArray(bD):[];bD.unshift(bv);bF=b.event.special[bG]||{};if(bF.trigger&&bF.trigger.apply(bA,bD)===false){return;}bB=[[bA,bF.bindType||bG]];if(!bJ&&!bF.noBubble&&!b.isWindow(bA)){bI=bF.delegateType||bG;bH=T.test(bI+bG)?bA:bA.parentNode;bz=null;for(;bH;bH=bH.parentNode){bB.push([bH,bI]);bz=bH;}if(bz&&bz===bA.ownerDocument){bB.push([bz.defaultView||bz.parentWindow||bd,bI]);}}for(bC=0;bC<bB.length&&!bv.isPropagationStopped();bC++){bH=bB[bC][0];bv.type=bB[bC][1];bE=(b._data(bH,"events")||{})[bv.type]&&b._data(bH,"handle");if(bE){bE.apply(bH,bD);}bE=by&&bH[by];if(bE&&b.acceptData(bH)&&bE.apply(bH,bD)===false){bv.preventDefault();}}bv.type=bG;if(!bJ&&!bv.isDefaultPrevented()){if((!bF._default||bF._default.apply(bA.ownerDocument,bD)===false)&&!(bG==="click"&&b.nodeName(bA,"a"))&&b.acceptData(bA)){if(by&&bA[bG]&&((bG!=="focus"&&bG!=="blur")||bv.target.offsetWidth!==0)&&!b.isWindow(bA)){bz=bA[by];if(bz){bA[by]=null;}b.event.triggered=bG;bA[bG]();b.event.triggered=L;if(bz){bA[by]=bz;}}}}return bv.result;},dispatch:function(bH){bH=b.event.fix(bH||bd.event);var bD=((b._data(this,"events")||{})[bH.type]||[]),bC=bD.delegateCount,bx=[].slice.call(arguments,0),bE=!bH.exclusive&&!bH.namespace,bz=b.event.special[bH.type]||{},bv=[],bJ,bG,by,bA,bK,bI,bB,bw,e,bF,bL;bx[0]=bH;bH.delegateTarget=this;if(bz.preDispatch&&bz.preDispatch.call(this,bH)===false){return;}if(bC&&!(bH.button&&bH.type==="click")){bA=b(this);bA.context=this.ownerDocument||this;for(by=bH.target;by!=this;by=by.parentNode||this){if(by.disabled!==true){bI={};bw=[];bA[0]=by;for(bJ=0;bJ<bC;bJ++){e=bD[bJ];bF=e.selector;if(bI[bF]===L){bI[bF]=(e.quick?j(by,e.quick):bA.is(bF));}if(bI[bF]){bw.push(e);}}if(bw.length){bv.push({elem:by,matches:bw});}}}}if(bD.length>bC){bv.push({elem:this,matches:bD.slice(bC)});}for(bJ=0;bJ<bv.length&&!bH.isPropagationStopped();bJ++){bB=bv[bJ];bH.currentTarget=bB.elem;for(bG=0;bG<bB.matches.length&&!bH.isImmediatePropagationStopped();bG++){e=bB.matches[bG];if(bE||(!bH.namespace&&!e.namespace)||bH.namespace_re&&bH.namespace_re.test(e.namespace)){bH.data=e.data;bH.handleObj=e;bK=((b.event.special[e.origType]||{}).handle||e.handler).apply(bB.elem,bx);if(bK!==L){bH.result=bK;if(bK===false){bH.preventDefault();bH.stopPropagation();}}}}}if(bz.postDispatch){bz.postDispatch.call(this,bH);}return bH.result;},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(bv,e){if(bv.which==null){bv.which=e.charCode!=null?e.charCode:e.keyCode;}return bv;}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(bx,bw){var by,bz,e,bv=bw.button,bA=bw.fromElement;if(bx.pageX==null&&bw.clientX!=null){by=bx.target.ownerDocument||av;bz=by.documentElement;e=by.body;bx.pageX=bw.clientX+(bz&&bz.scrollLeft||e&&e.scrollLeft||0)-(bz&&bz.clientLeft||e&&e.clientLeft||0);bx.pageY=bw.clientY+(bz&&bz.scrollTop||e&&e.scrollTop||0)-(bz&&bz.clientTop||e&&e.clientTop||0);}if(!bx.relatedTarget&&bA){bx.relatedTarget=bA===bx.target?bw.toElement:bA;}if(!bx.which&&bv!==L){bx.which=(bv&1?1:(bv&2?3:(bv&4?2:0)));}return bx;}},fix:function(bw){if(bw[b.expando]){return bw;}var bv,bz,e=bw,bx=b.event.fixHooks[bw.type]||{},by=bx.props?this.props.concat(bx.props):this.props;bw=b.Event(e);for(bv=by.length;bv;){bz=by[--bv];bw[bz]=e[bz];}if(!bw.target){bw.target=e.srcElement||av;}if(bw.target.nodeType===3){bw.target=bw.target.parentNode;}if(bw.metaKey===L){bw.metaKey=bw.ctrlKey;}return bx.filter?bx.filter(bw,e):bw;},special:{ready:{setup:b.bindReady},load:{noBubble:true},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(bw,bv,e){if(b.isWindow(this)){this.onbeforeunload=e;}},teardown:function(bv,e){if(this.onbeforeunload===e){this.onbeforeunload=null;}}}},simulate:function(bw,by,bx,bv){var bz=b.extend(new b.Event(),bx,{type:bw,isSimulated:true,originalEvent:{}});if(bv){b.event.trigger(bz,null,by);}else{b.event.dispatch.call(by,bz);}if(bz.isDefaultPrevented()){bx.preventDefault();}}};b.event.handle=b.event.dispatch;b.removeEvent=av.removeEventListener?function(bv,e,bw){if(bv.removeEventListener){bv.removeEventListener(e,bw,false);}}:function(bv,e,bw){if(bv.detachEvent){bv.detachEvent("on"+e,bw);}};b.Event=function(bv,e){if(!(this instanceof b.Event)){return new b.Event(bv,e);}if(bv&&bv.type){this.originalEvent=bv;this.type=bv.type;this.isDefaultPrevented=(bv.defaultPrevented||bv.returnValue===false||bv.getPreventDefault&&bv.getPreventDefault())?i:bl;}else{this.type=bv;}if(e){b.extend(this,e);}this.timeStamp=bv&&bv.timeStamp||b.now();this[b.expando]=true;};function bl(){return false;}function i(){return true;}b.Event.prototype={preventDefault:function(){this.isDefaultPrevented=i;var bv=this.originalEvent;if(!bv){return;}if(bv.preventDefault){bv.preventDefault();}else{bv.returnValue=false;}},stopPropagation:function(){this.isPropagationStopped=i;var bv=this.originalEvent;if(!bv){return;}if(bv.stopPropagation){bv.stopPropagation();}bv.cancelBubble=true;},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=i;this.stopPropagation();},isDefaultPrevented:bl,isPropagationStopped:bl,isImmediatePropagationStopped:bl};b.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(bv,e){b.event.special[bv]={delegateType:e,bindType:e,handle:function(bz){var bB=this,bA=bz.relatedTarget,by=bz.handleObj,bw=by.selector,bx;if(!bA||(bA!==bB&&!b.contains(bB,bA))){bz.type=by.origType;bx=by.handler.apply(this,arguments);bz.type=e;}return bx;}};});if(!b.support.submitBubbles){b.event.special.submit={setup:function(){if(b.nodeName(this,"form")){return false;}b.event.add(this,"click._submit keypress._submit",function(bx){var bw=bx.target,bv=b.nodeName(bw,"input")||b.nodeName(bw,"button")?bw.form:L;if(bv&&!bv._submit_attached){b.event.add(bv,"submit._submit",function(e){e._submit_bubble=true;});bv._submit_attached=true;}});},postDispatch:function(e){if(e._submit_bubble){delete e._submit_bubble;if(this.parentNode&&!e.isTrigger){b.event.simulate("submit",this.parentNode,e,true);}}},teardown:function(){if(b.nodeName(this,"form")){return false;}b.event.remove(this,"._submit");}};}if(!b.support.changeBubbles){b.event.special.change={setup:function(){if(be.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio"){b.event.add(this,"propertychange._change",function(e){if(e.originalEvent.propertyName==="checked"){this._just_changed=true;}});b.event.add(this,"click._change",function(e){if(this._just_changed&&!e.isTrigger){this._just_changed=false;b.event.simulate("change",this,e,true);}});}return false;}b.event.add(this,"beforeactivate._change",function(bw){var bv=bw.target;if(be.test(bv.nodeName)&&!bv._change_attached){b.event.add(bv,"change._change",function(e){if(this.parentNode&&!e.isSimulated&&!e.isTrigger){b.event.simulate("change",this.parentNode,e,true);}});bv._change_attached=true;}});},handle:function(bv){var e=bv.target;if(this!==e||bv.isSimulated||bv.isTrigger||(e.type!=="radio"&&e.type!=="checkbox")){return bv.handleObj.handler.apply(this,arguments);}},teardown:function(){b.event.remove(this,"._change");return be.test(this.nodeName);}};}if(!b.support.focusinBubbles){b.each({focus:"focusin",blur:"focusout"},function(bx,e){var bv=0,bw=function(by){b.event.simulate(e,by.target,b.event.fix(by),true);};b.event.special[e]={setup:function(){if(bv++===0){av.addEventListener(bx,bw,true);}},teardown:function(){if(--bv===0){av.removeEventListener(bx,bw,true);}}};});}b.fn.extend({on:function(bw,e,bz,by,bv){var bA,bx;if(typeof bw==="object"){if(typeof e!=="string"){bz=bz||e;e=L;}for(bx in bw){this.on(bx,e,bz,bw[bx],bv);}return this;}if(bz==null&&by==null){by=e;bz=e=L;}else{if(by==null){if(typeof e==="string"){by=bz;bz=L;}else{by=bz;bz=e;e=L;}}}if(by===false){by=bl;}else{if(!by){return this;}}if(bv===1){bA=by;by=function(bB){b().off(bB);return bA.apply(this,arguments);};by.guid=bA.guid||(bA.guid=b.guid++);}return this.each(function(){b.event.add(this,bw,by,bz,e);});},one:function(bv,e,bx,bw){return this.on(bv,e,bx,bw,1);},off:function(bw,e,by){if(bw&&bw.preventDefault&&bw.handleObj){var bv=bw.handleObj;b(bw.delegateTarget).off(bv.namespace?bv.origType+"."+bv.namespace:bv.origType,bv.selector,bv.handler);return this;}if(typeof bw==="object"){for(var bx in bw){this.off(bx,e,bw[bx]);}return this;}if(e===false||typeof e==="function"){by=e;e=L;}if(by===false){by=bl;}return this.each(function(){b.event.remove(this,bw,by,e);});},bind:function(e,bw,bv){return this.on(e,null,bw,bv);},unbind:function(e,bv){return this.off(e,null,bv);},live:function(e,bw,bv){b(this.context).on(e,this.selector,bw,bv);return this;},die:function(e,bv){b(this.context).off(e,this.selector||"**",bv);return this;},delegate:function(e,bv,bx,bw){return this.on(bv,e,bx,bw);},undelegate:function(e,bv,bw){return arguments.length==1?this.off(e,"**"):this.off(bv,e,bw);},trigger:function(e,bv){return this.each(function(){b.event.trigger(e,bv,this);});},triggerHandler:function(e,bv){if(this[0]){return b.event.trigger(e,bv,this[0],true);}},toggle:function(bx){var bv=arguments,e=bx.guid||b.guid++,bw=0,by=function(bz){var bA=(b._data(this,"lastToggle"+bx.guid)||0)%bw;b._data(this,"lastToggle"+bx.guid,bA+1);bz.preventDefault();return bv[bA].apply(this,arguments)||false;};by.guid=e;while(bw<bv.length){bv[bw++].guid=e;}return this.click(by);},hover:function(e,bv){return this.mouseenter(e).mouseleave(bv||e);}});b.each(("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu").split(" "),function(bv,e){b.fn[e]=function(bx,bw){if(bw==null){bw=bx;bx=null;}return arguments.length>0?this.on(e,null,bx,bw):this.trigger(e);};if(b.attrFn){b.attrFn[e]=true;}if(aP.test(e)){b.event.fixHooks[e]=b.event.keyHooks;}if(bg.test(e)){b.event.fixHooks[e]=b.event.mouseHooks;}});
+/*!
+ * Sizzle CSS Selector Engine
+ *  Copyright 2011, The Dojo Foundation
+ *  Released under the MIT, BSD, and GPL Licenses.
+ *  More information: http://sizzlejs.com/
+ */
+;(function(){var bH=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,bC="sizcache"+(Math.random()+"").replace(".",""),bI=0,bL=Object.prototype.toString,bB=false,bA=true,bK=/\\/g,bO=/\r\n/g,bQ=/\W/;[0,0].sort(function(){bA=false;return 0;});var by=function(bV,e,bY,bZ){bY=bY||[];e=e||av;var b1=e;if(e.nodeType!==1&&e.nodeType!==9){return[];}if(!bV||typeof bV!=="string"){return bY;}var bS,b3,b6,bR,b2,b5,b4,bX,bU=true,bT=by.isXML(e),bW=[],b0=bV;do{bH.exec("");bS=bH.exec(b0);if(bS){b0=bS[3];bW.push(bS[1]);if(bS[2]){bR=bS[3];break;}}}while(bS);if(bW.length>1&&bD.exec(bV)){if(bW.length===2&&bE.relative[bW[0]]){b3=bM(bW[0]+bW[1],e,bZ);}else{b3=bE.relative[bW[0]]?[e]:by(bW.shift(),e);while(bW.length){bV=bW.shift();if(bE.relative[bV]){bV+=bW.shift();}b3=bM(bV,b3,bZ);}}}else{if(!bZ&&bW.length>1&&e.nodeType===9&&!bT&&bE.match.ID.test(bW[0])&&!bE.match.ID.test(bW[bW.length-1])){b2=by.find(bW.shift(),e,bT);e=b2.expr?by.filter(b2.expr,b2.set)[0]:b2.set[0];}if(e){b2=bZ?{expr:bW.pop(),set:bF(bZ)}:by.find(bW.pop(),bW.length===1&&(bW[0]==="~"||bW[0]==="+")&&e.parentNode?e.parentNode:e,bT);b3=b2.expr?by.filter(b2.expr,b2.set):b2.set;if(bW.length>0){b6=bF(b3);}else{bU=false;}while(bW.length){b5=bW.pop();b4=b5;if(!bE.relative[b5]){b5="";}else{b4=bW.pop();}if(b4==null){b4=e;}bE.relative[b5](b6,b4,bT);}}else{b6=bW=[];}}if(!b6){b6=b3;}if(!b6){by.error(b5||bV);}if(bL.call(b6)==="[object Array]"){if(!bU){bY.push.apply(bY,b6);}else{if(e&&e.nodeType===1){for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&(b6[bX]===true||b6[bX].nodeType===1&&by.contains(e,b6[bX]))){bY.push(b3[bX]);}}}else{for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&b6[bX].nodeType===1){bY.push(b3[bX]);}}}}}else{bF(b6,bY);}if(bR){by(bR,b1,bY,bZ);by.uniqueSort(bY);}return bY;};by.uniqueSort=function(bR){if(bJ){bB=bA;bR.sort(bJ);if(bB){for(var e=1;e<bR.length;e++){if(bR[e]===bR[e-1]){bR.splice(e--,1);}}}}return bR;};by.matches=function(e,bR){return by(e,null,null,bR);};by.matchesSelector=function(e,bR){return by(bR,null,null,[e]).length>0;};by.find=function(bX,e,bY){var bW,bS,bU,bT,bV,bR;if(!bX){return[];}for(bS=0,bU=bE.order.length;bS<bU;bS++){bV=bE.order[bS];if((bT=bE.leftMatch[bV].exec(bX))){bR=bT[1];bT.splice(1,1);if(bR.substr(bR.length-1)!=="\\"){bT[1]=(bT[1]||"").replace(bK,"");bW=bE.find[bV](bT,e,bY);if(bW!=null){bX=bX.replace(bE.match[bV],"");break;}}}}if(!bW){bW=typeof e.getElementsByTagName!=="undefined"?e.getElementsByTagName("*"):[];}return{set:bW,expr:bX};};by.filter=function(b1,b0,b4,bU){var bW,e,bZ,b6,b3,bR,bT,bV,b2,bS=b1,b5=[],bY=b0,bX=b0&&b0[0]&&by.isXML(b0[0]);while(b1&&b0.length){for(bZ in bE.filter){if((bW=bE.leftMatch[bZ].exec(b1))!=null&&bW[2]){bR=bE.filter[bZ];bT=bW[1];e=false;bW.splice(1,1);if(bT.substr(bT.length-1)==="\\"){continue;}if(bY===b5){b5=[];}if(bE.preFilter[bZ]){bW=bE.preFilter[bZ](bW,bY,b4,b5,bU,bX);if(!bW){e=b6=true;}else{if(bW===true){continue;}}}if(bW){for(bV=0;(b3=bY[bV])!=null;bV++){if(b3){b6=bR(b3,bW,bV,bY);b2=bU^b6;if(b4&&b6!=null){if(b2){e=true;}else{bY[bV]=false;}}else{if(b2){b5.push(b3);e=true;}}}}}if(b6!==L){if(!b4){bY=b5;}b1=b1.replace(bE.match[bZ],"");if(!e){return[];}break;}}}if(b1===bS){if(e==null){by.error(b1);}else{break;}}bS=b1;}return bY;};by.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e);};var bw=by.getText=function(bU){var bS,bT,e=bU.nodeType,bR="";if(e){if(e===1||e===9||e===11){if(typeof bU.textContent==="string"){return bU.textContent;}else{if(typeof bU.innerText==="string"){return bU.innerText.replace(bO,"");}else{for(bU=bU.firstChild;bU;bU=bU.nextSibling){bR+=bw(bU);}}}}else{if(e===3||e===4){return bU.nodeValue;}}}else{for(bS=0;(bT=bU[bS]);bS++){if(bT.nodeType!==8){bR+=bw(bT);}}}return bR;};var bE=by.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(e){return e.getAttribute("href");},type:function(e){return e.getAttribute("type");}},relative:{"+":function(bW,bR){var bT=typeof bR==="string",bV=bT&&!bQ.test(bR),bX=bT&&!bV;if(bV){bR=bR.toLowerCase();}for(var bS=0,e=bW.length,bU;bS<e;bS++){if((bU=bW[bS])){while((bU=bU.previousSibling)&&bU.nodeType!==1){}bW[bS]=bX||bU&&bU.nodeName.toLowerCase()===bR?bU||false:bU===bR;}}if(bX){by.filter(bR,bW,true);}},">":function(bW,bR){var bV,bU=typeof bR==="string",bS=0,e=bW.length;if(bU&&!bQ.test(bR)){bR=bR.toLowerCase();for(;bS<e;bS++){bV=bW[bS];if(bV){var bT=bV.parentNode;bW[bS]=bT.nodeName.toLowerCase()===bR?bT:false;}}}else{for(;bS<e;bS++){bV=bW[bS];if(bV){bW[bS]=bU?bV.parentNode:bV.parentNode===bR;}}if(bU){by.filter(bR,bW,true);}}},"":function(bT,bR,bV){var bU,bS=bI++,e=bN;if(typeof bR==="string"&&!bQ.test(bR)){bR=bR.toLowerCase();bU=bR;e=bv;}e("parentNode",bR,bS,bT,bU,bV);},"~":function(bT,bR,bV){var bU,bS=bI++,e=bN;if(typeof bR==="string"&&!bQ.test(bR)){bR=bR.toLowerCase();bU=bR;e=bv;}e("previousSibling",bR,bS,bT,bU,bV);}},find:{ID:function(bR,bS,bT){if(typeof bS.getElementById!=="undefined"&&!bT){var e=bS.getElementById(bR[1]);return e&&e.parentNode?[e]:[];}},NAME:function(bS,bV){if(typeof bV.getElementsByName!=="undefined"){var bR=[],bU=bV.getElementsByName(bS[1]);for(var bT=0,e=bU.length;bT<e;bT++){if(bU[bT].getAttribute("name")===bS[1]){bR.push(bU[bT]);}}return bR.length===0?null:bR;}},TAG:function(e,bR){if(typeof bR.getElementsByTagName!=="undefined"){return bR.getElementsByTagName(e[1]);}}},preFilter:{CLASS:function(bT,bR,bS,e,bW,bX){bT=" "+bT[1].replace(bK,"")+" ";if(bX){return bT;}for(var bU=0,bV;(bV=bR[bU])!=null;bU++){if(bV){if(bW^(bV.className&&(" "+bV.className+" ").replace(/[\t\n\r]/g," ").indexOf(bT)>=0)){if(!bS){e.push(bV);}}else{if(bS){bR[bU]=false;}}}}return false;},ID:function(e){return e[1].replace(bK,"");},TAG:function(bR,e){return bR[1].replace(bK,"").toLowerCase();},CHILD:function(e){if(e[1]==="nth"){if(!e[2]){by.error(e[0]);}e[2]=e[2].replace(/^\+|\s*/g,"");var bR=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(e[2]==="even"&&"2n"||e[2]==="odd"&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=(bR[1]+(bR[2]||1))-0;e[3]=bR[3]-0;}else{if(e[2]){by.error(e[0]);}}e[0]=bI++;return e;},ATTR:function(bU,bR,bS,e,bV,bW){var bT=bU[1]=bU[1].replace(bK,"");if(!bW&&bE.attrMap[bT]){bU[1]=bE.attrMap[bT];}bU[4]=(bU[4]||bU[5]||"").replace(bK,"");if(bU[2]==="~="){bU[4]=" "+bU[4]+" ";}return bU;},PSEUDO:function(bU,bR,bS,e,bV){if(bU[1]==="not"){if((bH.exec(bU[3])||"").length>1||/^\w/.test(bU[3])){bU[3]=by(bU[3],null,null,bR);}else{var bT=by.filter(bU[3],bR,bS,true^bV);if(!bS){e.push.apply(e,bT);}return false;}}else{if(bE.match.POS.test(bU[0])||bE.match.CHILD.test(bU[0])){return true;}}return bU;},POS:function(e){e.unshift(true);return e;}},filters:{enabled:function(e){return e.disabled===false&&e.type!=="hidden";},disabled:function(e){return e.disabled===true;},checked:function(e){return e.checked===true;},selected:function(e){if(e.parentNode){e.parentNode.selectedIndex;}return e.selected===true;},parent:function(e){return !!e.firstChild;},empty:function(e){return !e.firstChild;},has:function(bS,bR,e){return !!by(e[3],bS).length;},header:function(e){return(/h\d/i).test(e.nodeName);},text:function(bS){var e=bS.getAttribute("type"),bR=bS.type;return bS.nodeName.toLowerCase()==="input"&&"text"===bR&&(e===bR||e===null);},radio:function(e){return e.nodeName.toLowerCase()==="input"&&"radio"===e.type;},checkbox:function(e){return e.nodeName.toLowerCase()==="input"&&"checkbox"===e.type;},file:function(e){return e.nodeName.toLowerCase()==="input"&&"file"===e.type;},password:function(e){return e.nodeName.toLowerCase()==="input"&&"password"===e.type;},submit:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"submit"===bR.type;},image:function(e){return e.nodeName.toLowerCase()==="input"&&"image"===e.type;},reset:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"reset"===bR.type;},button:function(bR){var e=bR.nodeName.toLowerCase();return e==="input"&&"button"===bR.type||e==="button";},input:function(e){return(/input|select|textarea|button/i).test(e.nodeName);},focus:function(e){return e===e.ownerDocument.activeElement;}},setFilters:{first:function(bR,e){return e===0;},last:function(bS,bR,e,bT){return bR===bT.length-1;},even:function(bR,e){return e%2===0;},odd:function(bR,e){return e%2===1;},lt:function(bS,bR,e){return bR<e[3]-0;},gt:function(bS,bR,e){return bR>e[3]-0;},nth:function(bS,bR,e){return e[3]-0===bR;},eq:function(bS,bR,e){return e[3]-0===bR;}},filter:{PSEUDO:function(bS,bX,bW,bY){var e=bX[1],bR=bE.filters[e];if(bR){return bR(bS,bW,bX,bY);}else{if(e==="contains"){return(bS.textContent||bS.innerText||bw([bS])||"").indexOf(bX[3])>=0;}else{if(e==="not"){var bT=bX[3];for(var bV=0,bU=bT.length;bV<bU;bV++){if(bT[bV]===bS){return false;}}return true;}else{by.error(e);}}}},CHILD:function(bS,bU){var bT,b0,bW,bZ,e,bV,bY,bX=bU[1],bR=bS;switch(bX){case"only":case"first":while((bR=bR.previousSibling)){if(bR.nodeType===1){return false;}}if(bX==="first"){return true;}bR=bS;case"last":while((bR=bR.nextSibling)){if(bR.nodeType===1){return false;}}return true;case"nth":bT=bU[2];b0=bU[3];if(bT===1&&b0===0){return true;}bW=bU[0];bZ=bS.parentNode;if(bZ&&(bZ[bC]!==bW||!bS.nodeIndex)){bV=0;for(bR=bZ.firstChild;bR;bR=bR.nextSibling){if(bR.nodeType===1){bR.nodeIndex=++bV;}}bZ[bC]=bW;}bY=bS.nodeIndex-b0;if(bT===0){return bY===0;}else{return(bY%bT===0&&bY/bT>=0);}}},ID:function(bR,e){return bR.nodeType===1&&bR.getAttribute("id")===e;},TAG:function(bR,e){return(e==="*"&&bR.nodeType===1)||!!bR.nodeName&&bR.nodeName.toLowerCase()===e;},CLASS:function(bR,e){return(" "+(bR.className||bR.getAttribute("class"))+" ").indexOf(e)>-1;},ATTR:function(bV,bT){var bS=bT[1],e=by.attr?by.attr(bV,bS):bE.attrHandle[bS]?bE.attrHandle[bS](bV):bV[bS]!=null?bV[bS]:bV.getAttribute(bS),bW=e+"",bU=bT[2],bR=bT[4];return e==null?bU==="!=":!bU&&by.attr?e!=null:bU==="="?bW===bR:bU==="*="?bW.indexOf(bR)>=0:bU==="~="?(" "+bW+" ").indexOf(bR)>=0:!bR?bW&&e!==false:bU==="!="?bW!==bR:bU==="^="?bW.indexOf(bR)===0:bU==="$="?bW.substr(bW.length-bR.length)===bR:bU==="|="?bW===bR||bW.substr(0,bR.length+1)===bR+"-":false;},POS:function(bU,bR,bS,bV){var e=bR[2],bT=bE.setFilters[e];if(bT){return bT(bU,bS,bR,bV);}}}};var bD=bE.match.POS,bx=function(bR,e){return"\\"+(e-0+1);};for(var bz in bE.match){bE.match[bz]=new RegExp(bE.match[bz].source+(/(?![^\[]*\])(?![^\(]*\))/.source));bE.leftMatch[bz]=new RegExp(/(^(?:.|\r|\n)*?)/.source+bE.match[bz].source.replace(/\\(\d+)/g,bx));}bE.match.globalPOS=bD;var bF=function(bR,e){bR=Array.prototype.slice.call(bR,0);if(e){e.push.apply(e,bR);return e;}return bR;};try{Array.prototype.slice.call(av.documentElement.childNodes,0)[0].nodeType;}catch(bP){bF=function(bU,bT){var bS=0,bR=bT||[];if(bL.call(bU)==="[object Array]"){Array.prototype.push.apply(bR,bU);}else{if(typeof bU.length==="number"){for(var e=bU.length;bS<e;bS++){bR.push(bU[bS]);}}else{for(;bU[bS];bS++){bR.push(bU[bS]);}}}return bR;};}var bJ,bG;if(av.documentElement.compareDocumentPosition){bJ=function(bR,e){if(bR===e){bB=true;return 0;}if(!bR.compareDocumentPosition||!e.compareDocumentPosition){return bR.compareDocumentPosition?-1:1;}return bR.compareDocumentPosition(e)&4?-1:1;};}else{bJ=function(bY,bX){if(bY===bX){bB=true;return 0;}else{if(bY.sourceIndex&&bX.sourceIndex){return bY.sourceIndex-bX.sourceIndex;}}var bV,bR,bS=[],e=[],bU=bY.parentNode,bW=bX.parentNode,bZ=bU;if(bU===bW){return bG(bY,bX);}else{if(!bU){return -1;}else{if(!bW){return 1;}}}while(bZ){bS.unshift(bZ);bZ=bZ.parentNode;}bZ=bW;while(bZ){e.unshift(bZ);bZ=bZ.parentNode;}bV=bS.length;bR=e.length;for(var bT=0;bT<bV&&bT<bR;bT++){if(bS[bT]!==e[bT]){return bG(bS[bT],e[bT]);}}return bT===bV?bG(bY,e[bT],-1):bG(bS[bT],bX,1);};bG=function(bR,e,bS){if(bR===e){return bS;}var bT=bR.nextSibling;while(bT){if(bT===e){return -1;}bT=bT.nextSibling;}return 1;};}(function(){var bR=av.createElement("div"),bS="script"+(new Date()).getTime(),e=av.documentElement;bR.innerHTML="<a name='"+bS+"'/>";e.insertBefore(bR,e.firstChild);if(av.getElementById(bS)){bE.find.ID=function(bU,bV,bW){if(typeof bV.getElementById!=="undefined"&&!bW){var bT=bV.getElementById(bU[1]);return bT?bT.id===bU[1]||typeof bT.getAttributeNode!=="undefined"&&bT.getAttributeNode("id").nodeValue===bU[1]?[bT]:L:[];}};bE.filter.ID=function(bV,bT){var bU=typeof bV.getAttributeNode!=="undefined"&&bV.getAttributeNode("id");return bV.nodeType===1&&bU&&bU.nodeValue===bT;};}e.removeChild(bR);e=bR=null;})();(function(){var e=av.createElement("div");e.appendChild(av.createComment(""));if(e.getElementsByTagName("*").length>0){bE.find.TAG=function(bR,bV){var bU=bV.getElementsByTagName(bR[1]);if(bR[1]==="*"){var bT=[];for(var bS=0;bU[bS];bS++){if(bU[bS].nodeType===1){bT.push(bU[bS]);}}bU=bT;}return bU;};}e.innerHTML="<a href='#'></a>";if(e.firstChild&&typeof e.firstChild.getAttribute!=="undefined"&&e.firstChild.getAttribute("href")!=="#"){bE.attrHandle.href=function(bR){return bR.getAttribute("href",2);};}e=null;})();if(av.querySelectorAll){(function(){var e=by,bT=av.createElement("div"),bS="__sizzle__";bT.innerHTML="<p class='TEST'></p>";if(bT.querySelectorAll&&bT.querySelectorAll(".TEST").length===0){return;}by=function(b4,bV,bZ,b3){bV=bV||av;if(!b3&&!by.isXML(bV)){var b2=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b4);if(b2&&(bV.nodeType===1||bV.nodeType===9)){if(b2[1]){return bF(bV.getElementsByTagName(b4),bZ);}else{if(b2[2]&&bE.find.CLASS&&bV.getElementsByClassName){return bF(bV.getElementsByClassName(b2[2]),bZ);}}}if(bV.nodeType===9){if(b4==="body"&&bV.body){return bF([bV.body],bZ);}else{if(b2&&b2[3]){var bY=bV.getElementById(b2[3]);if(bY&&bY.parentNode){if(bY.id===b2[3]){return bF([bY],bZ);}}else{return bF([],bZ);}}}try{return bF(bV.querySelectorAll(b4),bZ);}catch(b0){}}else{if(bV.nodeType===1&&bV.nodeName.toLowerCase()!=="object"){var bW=bV,bX=bV.getAttribute("id"),bU=bX||bS,b6=bV.parentNode,b5=/^\s*[+~]/.test(b4);if(!bX){bV.setAttribute("id",bU);}else{bU=bU.replace(/'/g,"\\$&");}if(b5&&b6){bV=bV.parentNode;}try{if(!b5||b6){return bF(bV.querySelectorAll("[id='"+bU+"'] "+b4),bZ);}}catch(b1){}finally{if(!bX){bW.removeAttribute("id");}}}}}return e(b4,bV,bZ,b3);};for(var bR in e){by[bR]=e[bR];}bT=null;})();}(function(){var e=av.documentElement,bS=e.matchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.msMatchesSelector;if(bS){var bU=!bS.call(av.createElement("div"),"div"),bR=false;try{bS.call(av.documentElement,"[test!='']:sizzle");}catch(bT){bR=true;}by.matchesSelector=function(bW,bY){bY=bY.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!by.isXML(bW)){try{if(bR||!bE.match.PSEUDO.test(bY)&&!/!=/.test(bY)){var bV=bS.call(bW,bY);if(bV||!bU||bW.document&&bW.document.nodeType!==11){return bV;}}}catch(bX){}}return by(bY,null,null,[bW]).length>0;};}})();(function(){var e=av.createElement("div");e.innerHTML="<div class='test e'></div><div class='test'></div>";if(!e.getElementsByClassName||e.getElementsByClassName("e").length===0){return;}e.lastChild.className="e";if(e.getElementsByClassName("e").length===1){return;}bE.order.splice(1,0,"CLASS");bE.find.CLASS=function(bR,bS,bT){if(typeof bS.getElementsByClassName!=="undefined"&&!bT){return bS.getElementsByClassName(bR[1]);}};e=null;})();function bv(bR,bW,bV,bZ,bX,bY){for(var bT=0,bS=bZ.length;bT<bS;bT++){var e=bZ[bT];if(e){var bU=false;e=e[bR];while(e){if(e[bC]===bV){bU=bZ[e.sizset];break;}if(e.nodeType===1&&!bY){e[bC]=bV;e.sizset=bT;}if(e.nodeName.toLowerCase()===bW){bU=e;break;}e=e[bR];}bZ[bT]=bU;}}}function bN(bR,bW,bV,bZ,bX,bY){for(var bT=0,bS=bZ.length;bT<bS;bT++){var e=bZ[bT];if(e){var bU=false;e=e[bR];while(e){if(e[bC]===bV){bU=bZ[e.sizset];break;}if(e.nodeType===1){if(!bY){e[bC]=bV;e.sizset=bT;}if(typeof bW!=="string"){if(e===bW){bU=true;break;}}else{if(by.filter(bW,[e]).length>0){bU=e;break;}}}e=e[bR];}bZ[bT]=bU;}}}if(av.documentElement.contains){by.contains=function(bR,e){return bR!==e&&(bR.contains?bR.contains(e):true);};}else{if(av.documentElement.compareDocumentPosition){by.contains=function(bR,e){return !!(bR.compareDocumentPosition(e)&16);};}else{by.contains=function(){return false;};}}by.isXML=function(e){var bR=(e?e.ownerDocument||e:0).documentElement;return bR?bR.nodeName!=="HTML":false;};var bM=function(bS,e,bW){var bV,bX=[],bU="",bY=e.nodeType?[e]:e;while((bV=bE.match.PSEUDO.exec(bS))){bU+=bV[0];bS=bS.replace(bE.match.PSEUDO,"");}bS=bE.relative[bS]?bS+"*":bS;for(var bT=0,bR=bY.length;bT<bR;bT++){by(bS,bY[bT],bX,bW);}return by.filter(bU,bX);};by.attr=b.attr;by.selectors.attrMap={};b.find=by;b.expr=by.selectors;b.expr[":"]=b.expr.filters;b.unique=by.uniqueSort;b.text=by.getText;b.isXMLDoc=by.isXML;b.contains=by.contains;})();var ab=/Until$/,aq=/^(?:parents|prevUntil|prevAll)/,bb=/,/,bp=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,H=b.expr.match.globalPOS,ay={children:true,contents:true,next:true,prev:true};b.fn.extend({find:function(e){var bw=this,by,bv;if(typeof e!=="string"){return b(e).filter(function(){for(by=0,bv=bw.length;by<bv;by++){if(b.contains(bw[by],this)){return true;}}});}var bx=this.pushStack("","find",e),bA,bB,bz;for(by=0,bv=this.length;by<bv;by++){bA=bx.length;b.find(e,this[by],bx);if(by>0){for(bB=bA;bB<bx.length;bB++){for(bz=0;bz<bA;bz++){if(bx[bz]===bx[bB]){bx.splice(bB--,1);break;}}}}}return bx;},has:function(bv){var e=b(bv);return this.filter(function(){for(var bx=0,bw=e.length;bx<bw;bx++){if(b.contains(this,e[bx])){return true;}}});},not:function(e){return this.pushStack(aH(this,e,false),"not",e);},filter:function(e){return this.pushStack(aH(this,e,true),"filter",e);},is:function(e){return !!e&&(typeof e==="string"?H.test(e)?b(e,this.context).index(this[0])>=0:b.filter(e,this).length>0:this.filter(e).length>0);},closest:function(by,bx){var bv=[],bw,e,bz=this[0];if(b.isArray(by)){var bB=1;while(bz&&bz.ownerDocument&&bz!==bx){for(bw=0;bw<by.length;bw++){if(b(bz).is(by[bw])){bv.push({selector:by[bw],elem:bz,level:bB});}}bz=bz.parentNode;bB++;}return bv;}var bA=H.test(by)||typeof by!=="string"?b(by,bx||this.context):0;for(bw=0,e=this.length;bw<e;bw++){bz=this[bw];while(bz){if(bA?bA.index(bz)>-1:b.find.matchesSelector(bz,by)){bv.push(bz);break;}else{bz=bz.parentNode;if(!bz||!bz.ownerDocument||bz===bx||bz.nodeType===11){break;}}}}bv=bv.length>1?b.unique(bv):bv;return this.pushStack(bv,"closest",by);},index:function(e){if(!e){return(this[0]&&this[0].parentNode)?this.prevAll().length:-1;}if(typeof e==="string"){return b.inArray(this[0],b(e));}return b.inArray(e.jquery?e[0]:e,this);},add:function(e,bv){var bx=typeof e==="string"?b(e,bv):b.makeArray(e&&e.nodeType?[e]:e),bw=b.merge(this.get(),bx);return this.pushStack(B(bx[0])||B(bw[0])?bw:b.unique(bw));},andSelf:function(){return this.add(this.prevObject);}});function B(e){return !e||!e.parentNode||e.parentNode.nodeType===11;}b.each({parent:function(bv){var e=bv.parentNode;return e&&e.nodeType!==11?e:null;},parents:function(e){return b.dir(e,"parentNode");},parentsUntil:function(bv,e,bw){return b.dir(bv,"parentNode",bw);},next:function(e){return b.nth(e,2,"nextSibling");},prev:function(e){return b.nth(e,2,"previousSibling");},nextAll:function(e){return b.dir(e,"nextSibling");},prevAll:function(e){return b.dir(e,"previousSibling");},nextUntil:function(bv,e,bw){return b.dir(bv,"nextSibling",bw);},prevUntil:function(bv,e,bw){return b.dir(bv,"previousSibling",bw);},siblings:function(e){return b.sibling((e.parentNode||{}).firstChild,e);},children:function(e){return b.sibling(e.firstChild);},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.makeArray(e.childNodes);}},function(e,bv){b.fn[e]=function(by,bw){var bx=b.map(this,bv,by);if(!ab.test(e)){bw=by;}if(bw&&typeof bw==="string"){bx=b.filter(bw,bx);}bx=this.length>1&&!ay[e]?b.unique(bx):bx;if((this.length>1||bb.test(bw))&&aq.test(e)){bx=bx.reverse();}return this.pushStack(bx,e,P.call(arguments).join(","));};});b.extend({filter:function(bw,e,bv){if(bv){bw=":not("+bw+")";}return e.length===1?b.find.matchesSelector(e[0],bw)?[e[0]]:[]:b.find.matches(bw,e);},dir:function(bw,bv,by){var e=[],bx=bw[bv];while(bx&&bx.nodeType!==9&&(by===L||bx.nodeType!==1||!b(bx).is(by))){if(bx.nodeType===1){e.push(bx);}bx=bx[bv];}return e;},nth:function(by,e,bw,bx){e=e||1;var bv=0;for(;by;by=by[bw]){if(by.nodeType===1&&++bv===e){break;}}return by;},sibling:function(bw,bv){var e=[];for(;bw;bw=bw.nextSibling){if(bw.nodeType===1&&bw!==bv){e.push(bw);}}return e;}});function aH(bx,bw,e){bw=bw||0;if(b.isFunction(bw)){return b.grep(bx,function(bz,by){var bA=!!bw.call(bz,by,bz);return bA===e;});}else{if(bw.nodeType){return b.grep(bx,function(bz,by){return(bz===bw)===e;});}else{if(typeof bw==="string"){var bv=b.grep(bx,function(by){return by.nodeType===1;});if(bp.test(bw)){return b.filter(bw,bv,!e);}else{bw=b.filter(bw,bv);}}}}return b.grep(bx,function(bz,by){return(b.inArray(bz,bw)>=0)===e;});}function a(e){var bw=aS.split("|"),bv=e.createDocumentFragment();if(bv.createElement){while(bw.length){bv.createElement(bw.pop());}}return bv;}var aS="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ah=/ jQuery\d+="(?:\d+|null)"/g,ar=/^\s+/,R=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,d=/<([\w:]+)/,v=/<tbody/i,W=/<|&#?\w+;/,ae=/<(?:script|style)/i,O=/<(?:script|object|embed|option|style)/i,ai=new RegExp("<(?:"+aS+")[\\s/>]","i"),o=/checked\s*(?:[^=]|=\s*.checked.)/i,bn=/\/(java|ecma)script/i,aO=/^\s*<!(?:\[CDATA\[|\-\-)/,ax={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},ac=a(av);ax.optgroup=ax.option;ax.tbody=ax.tfoot=ax.colgroup=ax.caption=ax.thead;ax.th=ax.td;if(!b.support.htmlSerialize){ax._default=[1,"div<div>","</div>"];}b.fn.extend({text:function(e){return b.access(this,function(bv){return bv===L?b.text(this):this.empty().append((this[0]&&this[0].ownerDocument||av).createTextNode(bv));},null,e,arguments.length);},wrapAll:function(e){if(b.isFunction(e)){return this.each(function(bw){b(this).wrapAll(e.call(this,bw));});}if(this[0]){var bv=b(e,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){bv.insertBefore(this[0]);}bv.map(function(){var bw=this;while(bw.firstChild&&bw.firstChild.nodeType===1){bw=bw.firstChild;}return bw;}).append(this);}return this;},wrapInner:function(e){if(b.isFunction(e)){return this.each(function(bv){b(this).wrapInner(e.call(this,bv));});}return this.each(function(){var bv=b(this),bw=bv.contents();if(bw.length){bw.wrapAll(e);}else{bv.append(e);}});},wrap:function(e){var bv=b.isFunction(e);return this.each(function(bw){b(this).wrapAll(bv?e.call(this,bw):e);});},unwrap:function(){return this.parent().each(function(){if(!b.nodeName(this,"body")){b(this).replaceWith(this.childNodes);}}).end();},append:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.appendChild(e);}});},prepend:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.insertBefore(e,this.firstChild);}});},before:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this);});}else{if(arguments.length){var e=b.clean(arguments);e.push.apply(e,this.toArray());return this.pushStack(e,"before",arguments);}}},after:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this.nextSibling);});}else{if(arguments.length){var e=this.pushStack(this,"after",arguments);e.push.apply(e,b.clean(arguments));return e;}}},remove:function(e,bx){for(var bv=0,bw;(bw=this[bv])!=null;bv++){if(!e||b.filter(e,[bw]).length){if(!bx&&bw.nodeType===1){b.cleanData(bw.getElementsByTagName("*"));b.cleanData([bw]);}if(bw.parentNode){bw.parentNode.removeChild(bw);}}}return this;},empty:function(){for(var e=0,bv;(bv=this[e])!=null;e++){if(bv.nodeType===1){b.cleanData(bv.getElementsByTagName("*"));}while(bv.firstChild){bv.removeChild(bv.firstChild);}}return this;},clone:function(bv,e){bv=bv==null?false:bv;e=e==null?bv:e;return this.map(function(){return b.clone(this,bv,e);});},html:function(e){return b.access(this,function(by){var bx=this[0]||{},bw=0,bv=this.length;if(by===L){return bx.nodeType===1?bx.innerHTML.replace(ah,""):null;}if(typeof by==="string"&&!ae.test(by)&&(b.support.leadingWhitespace||!ar.test(by))&&!ax[(d.exec(by)||["",""])[1].toLowerCase()]){by=by.replace(R,"<$1></$2>");try{for(;bw<bv;bw++){bx=this[bw]||{};if(bx.nodeType===1){b.cleanData(bx.getElementsByTagName("*"));bx.innerHTML=by;}}bx=0;}catch(bz){}}if(bx){this.empty().append(by);}},null,e,arguments.length);},replaceWith:function(e){if(this[0]&&this[0].parentNode){if(b.isFunction(e)){return this.each(function(bx){var bw=b(this),bv=bw.html();bw.replaceWith(e.call(this,bx,bv));});}if(typeof e!=="string"){e=b(e).detach();}return this.each(function(){var bw=this.nextSibling,bv=this.parentNode;b(this).remove();if(bw){b(bw).before(e);}else{b(bv).append(e);}});}else{return this.length?this.pushStack(b(b.isFunction(e)?e():e),"replaceWith",e):this;}},detach:function(e){return this.remove(e,true);},domManip:function(bB,bF,bE){var bx,by,bA,bD,bC=bB[0],bv=[];if(!b.support.checkClone&&arguments.length===3&&typeof bC==="string"&&o.test(bC)){return this.each(function(){b(this).domManip(bB,bF,bE,true);});}if(b.isFunction(bC)){return this.each(function(bH){var bG=b(this);bB[0]=bC.call(this,bH,bF?bG.html():L);bG.domManip(bB,bF,bE);});}if(this[0]){bD=bC&&bC.parentNode;if(b.support.parentNode&&bD&&bD.nodeType===11&&bD.childNodes.length===this.length){bx={fragment:bD};}else{bx=b.buildFragment(bB,this,bv);}bA=bx.fragment;if(bA.childNodes.length===1){by=bA=bA.firstChild;}else{by=bA.firstChild;}if(by){bF=bF&&b.nodeName(by,"tr");for(var bw=0,e=this.length,bz=e-1;bw<e;bw++){bE.call(bF?bc(this[bw],by):this[bw],bx.cacheable||(e>1&&bw<bz)?b.clone(bA,true,true):bA);}}if(bv.length){b.each(bv,function(bG,bH){if(bH.src){b.ajax({type:"GET",global:false,url:bH.src,async:false,dataType:"script"});}else{b.globalEval((bH.text||bH.textContent||bH.innerHTML||"").replace(aO,"/*$0*/"));}if(bH.parentNode){bH.parentNode.removeChild(bH);}});}}return this;}});function bc(e,bv){return b.nodeName(e,"table")?(e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody"))):e;}function s(bB,bv){if(bv.nodeType!==1||!b.hasData(bB)){return;}var by,bx,e,bA=b._data(bB),bz=b._data(bv,bA),bw=bA.events;if(bw){delete bz.handle;bz.events={};for(by in bw){for(bx=0,e=bw[by].length;bx<e;bx++){b.event.add(bv,by,bw[by][bx]);}}}if(bz.data){bz.data=b.extend({},bz.data);}}function aj(bv,e){var bw;if(e.nodeType!==1){return;}if(e.clearAttributes){e.clearAttributes();}if(e.mergeAttributes){e.mergeAttributes(bv);}bw=e.nodeName.toLowerCase();if(bw==="object"){e.outerHTML=bv.outerHTML;}else{if(bw==="input"&&(bv.type==="checkbox"||bv.type==="radio")){if(bv.checked){e.defaultChecked=e.checked=bv.checked;}if(e.value!==bv.value){e.value=bv.value;}}else{if(bw==="option"){e.selected=bv.defaultSelected;}else{if(bw==="input"||bw==="textarea"){e.defaultValue=bv.defaultValue;}else{if(bw==="script"&&e.text!==bv.text){e.text=bv.text;}}}}}e.removeAttribute(b.expando);e.removeAttribute("_submit_attached");e.removeAttribute("_change_attached");}b.buildFragment=function(bz,bx,bv){var by,e,bw,bA,bB=bz[0];if(bx&&bx[0]){bA=bx[0].ownerDocument||bx[0];}if(!bA.createDocumentFragment){bA=av;}if(bz.length===1&&typeof bB==="string"&&bB.length<512&&bA===av&&bB.charAt(0)==="<"&&!O.test(bB)&&(b.support.checkClone||!o.test(bB))&&(b.support.html5Clone||!ai.test(bB))){e=true;bw=b.fragments[bB];if(bw&&bw!==1){by=bw;}}if(!by){by=bA.createDocumentFragment();b.clean(bz,bA,by,bv);}if(e){b.fragments[bB]=bw?by:1;}return{fragment:by,cacheable:e};};b.fragments={};b.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,bv){b.fn[e]=function(bw){var bz=[],bC=b(bw),bB=this.length===1&&this[0].parentNode;if(bB&&bB.nodeType===11&&bB.childNodes.length===1&&bC.length===1){bC[bv](this[0]);return this;}else{for(var bA=0,bx=bC.length;bA<bx;bA++){var by=(bA>0?this.clone(true):this).get();b(bC[bA])[bv](by);bz=bz.concat(by);}return this.pushStack(bz,e,bC.selector);}};});function bh(e){if(typeof e.getElementsByTagName!=="undefined"){return e.getElementsByTagName("*");}else{if(typeof e.querySelectorAll!=="undefined"){return e.querySelectorAll("*");}else{return[];}}}function az(e){if(e.type==="checkbox"||e.type==="radio"){e.defaultChecked=e.checked;}}function D(e){var bv=(e.nodeName||"").toLowerCase();if(bv==="input"){az(e);}else{if(bv!=="script"&&typeof e.getElementsByTagName!=="undefined"){b.grep(e.getElementsByTagName("input"),az);}}}function am(e){var bv=av.createElement("div");ac.appendChild(bv);bv.innerHTML=e.outerHTML;return bv.firstChild;}b.extend({clone:function(by,bA,bw){var e,bv,bx,bz=b.support.html5Clone||b.isXMLDoc(by)||!ai.test("<"+by.nodeName+">")?by.cloneNode(true):am(by);if((!b.support.noCloneEvent||!b.support.noCloneChecked)&&(by.nodeType===1||by.nodeType===11)&&!b.isXMLDoc(by)){aj(by,bz);e=bh(by);bv=bh(bz);for(bx=0;e[bx];++bx){if(bv[bx]){aj(e[bx],bv[bx]);}}}if(bA){s(by,bz);if(bw){e=bh(by);bv=bh(bz);for(bx=0;e[bx];++bx){s(e[bx],bv[bx]);}}}e=bv=null;return bz;},clean:function(bI,bw,bv,bx){var bA,bH,bD,bJ=[];bw=bw||av;if(typeof bw.createElement==="undefined"){bw=bw.ownerDocument||bw[0]&&bw[0].ownerDocument||av;}for(var bE=0,bG;(bG=bI[bE])!=null;bE++){if(typeof bG==="number"){bG+="";}if(!bG){continue;}if(typeof bG==="string"){if(!W.test(bG)){bG=bw.createTextNode(bG);}else{bG=bG.replace(R,"<$1></$2>");var bN=(d.exec(bG)||["",""])[1].toLowerCase(),bz=ax[bN]||ax._default,bK=bz[0],bB=bw.createElement("div"),bL=ac.childNodes,bM;if(bw===av){ac.appendChild(bB);}else{a(bw).appendChild(bB);}bB.innerHTML=bz[1]+bG+bz[2];while(bK--){bB=bB.lastChild;}if(!b.support.tbody){var by=v.test(bG),e=bN==="table"&&!by?bB.firstChild&&bB.firstChild.childNodes:bz[1]==="<table>"&&!by?bB.childNodes:[];for(bD=e.length-1;bD>=0;--bD){if(b.nodeName(e[bD],"tbody")&&!e[bD].childNodes.length){e[bD].parentNode.removeChild(e[bD]);}}}if(!b.support.leadingWhitespace&&ar.test(bG)){bB.insertBefore(bw.createTextNode(ar.exec(bG)[0]),bB.firstChild);}bG=bB.childNodes;if(bB){bB.parentNode.removeChild(bB);if(bL.length>0){bM=bL[bL.length-1];if(bM&&bM.parentNode){bM.parentNode.removeChild(bM);}}}}}var bF;if(!b.support.appendChecked){if(bG[0]&&typeof(bF=bG.length)==="number"){for(bD=0;bD<bF;bD++){D(bG[bD]);}}else{D(bG);}}if(bG.nodeType){bJ.push(bG);}else{bJ=b.merge(bJ,bG);}}if(bv){bA=function(bO){return !bO.type||bn.test(bO.type);};for(bE=0;bJ[bE];bE++){bH=bJ[bE];if(bx&&b.nodeName(bH,"script")&&(!bH.type||bn.test(bH.type))){bx.push(bH.parentNode?bH.parentNode.removeChild(bH):bH);}else{if(bH.nodeType===1){var bC=b.grep(bH.getElementsByTagName("script"),bA);bJ.splice.apply(bJ,[bE+1,0].concat(bC));}bv.appendChild(bH);}}}return bJ;},cleanData:function(bv){var by,bw,e=b.cache,bB=b.event.special,bA=b.support.deleteExpando;for(var bz=0,bx;(bx=bv[bz])!=null;bz++){if(bx.nodeName&&b.noData[bx.nodeName.toLowerCase()]){continue;}bw=bx[b.expando];if(bw){by=e[bw];if(by&&by.events){for(var bC in by.events){if(bB[bC]){b.event.remove(bx,bC);}else{b.removeEvent(bx,bC,by.handle);}}if(by.handle){by.handle.elem=null;}}if(bA){delete bx[b.expando];}else{if(bx.removeAttribute){bx.removeAttribute(b.expando);}}delete e[bw];}}}});var al=/alpha\([^)]*\)/i,au=/opacity=([^)]*)/,y=/([A-Z]|^ms)/g,bo=/^[\-+]?(?:\d*\.)?\d+$/i,a1=/^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i,I=/^([\-+])=([\-+.\de]+)/,aE=/^margin/,a9={position:"absolute",visibility:"hidden",display:"block"},G=["Top","Right","Bottom","Left"],Z,aJ,aY;b.fn.css=function(e,bv){return b.access(this,function(bx,bw,by){return by!==L?b.style(bx,bw,by):b.css(bx,bw);},e,bv,arguments.length>1);};b.extend({cssHooks:{opacity:{get:function(bw,bv){if(bv){var e=Z(bw,"opacity");return e===""?"1":e;}else{return bw.style.opacity;}}}},cssNumber:{fillOpacity:true,fontWeight:true,lineHeight:true,opacity:true,orphans:true,widows:true,zIndex:true,zoom:true},cssProps:{"float":b.support.cssFloat?"cssFloat":"styleFloat"},style:function(bx,bw,bD,by){if(!bx||bx.nodeType===3||bx.nodeType===8||!bx.style){return;}var bB,bC,bz=b.camelCase(bw),bv=bx.style,bE=b.cssHooks[bz];bw=b.cssProps[bz]||bz;if(bD!==L){bC=typeof bD;if(bC==="string"&&(bB=I.exec(bD))){bD=(+(bB[1]+1)*+bB[2])+parseFloat(b.css(bx,bw));bC="number";}if(bD==null||bC==="number"&&isNaN(bD)){return;}if(bC==="number"&&!b.cssNumber[bz]){bD+="px";}if(!bE||!("set" in bE)||(bD=bE.set(bx,bD))!==L){try{bv[bw]=bD;}catch(bA){}}}else{if(bE&&"get" in bE&&(bB=bE.get(bx,false,by))!==L){return bB;}return bv[bw];}},css:function(by,bx,bv){var bw,e;bx=b.camelCase(bx);e=b.cssHooks[bx];bx=b.cssProps[bx]||bx;if(bx==="cssFloat"){bx="float";}if(e&&"get" in e&&(bw=e.get(by,true,bv))!==L){return bw;}else{if(Z){return Z(by,bx);}}},swap:function(by,bx,bz){var e={},bw,bv;for(bv in bx){e[bv]=by.style[bv];by.style[bv]=bx[bv];}bw=bz.call(by);for(bv in bx){by.style[bv]=e[bv];}return bw;}});b.curCSS=b.css;if(av.defaultView&&av.defaultView.getComputedStyle){aJ=function(bA,bw){var bv,bz,e,by,bx=bA.style;bw=bw.replace(y,"-$1").toLowerCase();if((bz=bA.ownerDocument.defaultView)&&(e=bz.getComputedStyle(bA,null))){bv=e.getPropertyValue(bw);if(bv===""&&!b.contains(bA.ownerDocument.documentElement,bA)){bv=b.style(bA,bw);}}if(!b.support.pixelMargin&&e&&aE.test(bw)&&a1.test(bv)){by=bx.width;bx.width=bv;bv=e.width;bx.width=by;}return bv;};}if(av.documentElement.currentStyle){aY=function(bz,bw){var bA,e,by,bv=bz.currentStyle&&bz.currentStyle[bw],bx=bz.style;if(bv==null&&bx&&(by=bx[bw])){bv=by;}if(a1.test(bv)){bA=bx.left;e=bz.runtimeStyle&&bz.runtimeStyle.left;if(e){bz.runtimeStyle.left=bz.currentStyle.left;}bx.left=bw==="fontSize"?"1em":bv;bv=bx.pixelLeft+"px";bx.left=bA;if(e){bz.runtimeStyle.left=e;}}return bv===""?"auto":bv;};}Z=aJ||aY;function af(by,bw,bv){var bz=bw==="width"?by.offsetWidth:by.offsetHeight,bx=bw==="width"?1:0,e=4;if(bz>0){if(bv!=="border"){for(;bx<e;bx+=2){if(!bv){bz-=parseFloat(b.css(by,"padding"+G[bx]))||0;}if(bv==="margin"){bz+=parseFloat(b.css(by,bv+G[bx]))||0;}else{bz-=parseFloat(b.css(by,"border"+G[bx]+"Width"))||0;}}}return bz+"px";}bz=Z(by,bw);if(bz<0||bz==null){bz=by.style[bw];}if(a1.test(bz)){return bz;}bz=parseFloat(bz)||0;if(bv){for(;bx<e;bx+=2){bz+=parseFloat(b.css(by,"padding"+G[bx]))||0;if(bv!=="padding"){bz+=parseFloat(b.css(by,"border"+G[bx]+"Width"))||0;}if(bv==="margin"){bz+=parseFloat(b.css(by,bv+G[bx]))||0;}}}return bz+"px";}b.each(["height","width"],function(bv,e){b.cssHooks[e]={get:function(by,bx,bw){if(bx){if(by.offsetWidth!==0){return af(by,e,bw);}else{return b.swap(by,a9,function(){return af(by,e,bw);});}}},set:function(bw,bx){return bo.test(bx)?bx+"px":bx;}};});if(!b.support.opacity){b.cssHooks.opacity={get:function(bv,e){return au.test((e&&bv.currentStyle?bv.currentStyle.filter:bv.style.filter)||"")?(parseFloat(RegExp.$1)/100)+"":e?"1":"";},set:function(by,bz){var bx=by.style,bv=by.currentStyle,e=b.isNumeric(bz)?"alpha(opacity="+bz*100+")":"",bw=bv&&bv.filter||bx.filter||"";bx.zoom=1;if(bz>=1&&b.trim(bw.replace(al,""))===""){bx.removeAttribute("filter");if(bv&&!bv.filter){return;}}bx.filter=al.test(bw)?bw.replace(al,e):bw+" "+e;}};}b(function(){if(!b.support.reliableMarginRight){b.cssHooks.marginRight={get:function(bv,e){return b.swap(bv,{display:"inline-block"},function(){if(e){return Z(bv,"margin-right");}else{return bv.style.marginRight;}});}};}});if(b.expr&&b.expr.filters){b.expr.filters.hidden=function(bw){var bv=bw.offsetWidth,e=bw.offsetHeight;return(bv===0&&e===0)||(!b.support.reliableHiddenOffsets&&((bw.style&&bw.style.display)||b.css(bw,"display"))==="none");};b.expr.filters.visible=function(e){return !b.expr.filters.hidden(e);};}b.each({margin:"",padding:"",border:"Width"},function(e,bv){b.cssHooks[e+bv]={expand:function(by){var bx,bz=typeof by==="string"?by.split(" "):[by],bw={};for(bx=0;bx<4;bx++){bw[e+G[bx]+bv]=bz[bx]||bz[bx-2]||bz[0];}return bw;}};});var k=/%20/g,ap=/\[\]$/,bs=/\r?\n/g,bq=/#.*$/,aD=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,a0=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,aN=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,aR=/^(?:GET|HEAD)$/,c=/^\/\//,M=/\?/,a7=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,p=/^(?:select|textarea)/i,h=/\s+/,br=/([?&])_=[^&]*/,K=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,z=b.fn.load,aa={},q={},aF,r,aW=["*/"]+["*"];try{aF=bm.href;}catch(aw){aF=av.createElement("a");aF.href="";aF=aF.href;}r=K.exec(aF.toLowerCase())||[];function f(e){return function(by,bA){if(typeof by!=="string"){bA=by;by="*";}if(b.isFunction(bA)){var bx=by.toLowerCase().split(h),bw=0,bz=bx.length,bv,bB,bC;for(;bw<bz;bw++){bv=bx[bw];bC=/^\+/.test(bv);if(bC){bv=bv.substr(1)||"*";}bB=e[bv]=e[bv]||[];bB[bC?"unshift":"push"](bA);}}};}function aX(bv,bE,bz,bD,bB,bx){bB=bB||bE.dataTypes[0];bx=bx||{};bx[bB]=true;var bA=bv[bB],bw=0,e=bA?bA.length:0,by=(bv===aa),bC;for(;bw<e&&(by||!bC);bw++){bC=bA[bw](bE,bz,bD);if(typeof bC==="string"){if(!by||bx[bC]){bC=L;}else{bE.dataTypes.unshift(bC);bC=aX(bv,bE,bz,bD,bC,bx);}}}if((by||!bC)&&!bx["*"]){bC=aX(bv,bE,bz,bD,"*",bx);}return bC;}function an(bw,bx){var bv,e,by=b.ajaxSettings.flatOptions||{};for(bv in bx){if(bx[bv]!==L){(by[bv]?bw:(e||(e={})))[bv]=bx[bv];}}if(e){b.extend(true,bw,e);}}b.fn.extend({load:function(bw,bz,bA){if(typeof bw!=="string"&&z){return z.apply(this,arguments);}else{if(!this.length){return this;}}var by=bw.indexOf(" ");if(by>=0){var e=bw.slice(by,bw.length);bw=bw.slice(0,by);}var bx="GET";if(bz){if(b.isFunction(bz)){bA=bz;bz=L;}else{if(typeof bz==="object"){bz=b.param(bz,b.ajaxSettings.traditional);bx="POST";}}}var bv=this;b.ajax({url:bw,type:bx,dataType:"html",data:bz,complete:function(bC,bB,bD){bD=bC.responseText;if(bC.isResolved()){bC.done(function(bE){bD=bE;});bv.html(e?b("<div>").append(bD.replace(a7,"")).find(e):bD);}if(bA){bv.each(bA,[bD,bB,bC]);}}});return this;},serialize:function(){return b.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return this.elements?b.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||p.test(this.nodeName)||a0.test(this.type));}).map(function(e,bv){var bw=b(this).val();return bw==null?null:b.isArray(bw)?b.map(bw,function(by,bx){return{name:bv.name,value:by.replace(bs,"\r\n")};}):{name:bv.name,value:bw.replace(bs,"\r\n")};}).get();}});b.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,bv){b.fn[bv]=function(bw){return this.on(bv,bw);};});b.each(["get","post"],function(e,bv){b[bv]=function(bw,by,bz,bx){if(b.isFunction(by)){bx=bx||bz;bz=by;by=L;}return b.ajax({type:bv,url:bw,data:by,success:bz,dataType:bx});};});b.extend({getScript:function(e,bv){return b.get(e,L,bv,"script");},getJSON:function(e,bv,bw){return b.get(e,bv,bw,"json");},ajaxSetup:function(bv,e){if(e){an(bv,b.ajaxSettings);}else{e=bv;bv=b.ajaxSettings;}an(bv,e);return bv;},ajaxSettings:{url:aF,isLocal:aN.test(r[1]),global:true,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:true,async:true,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":aW},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":bd.String,"text html":true,"text json":b.parseJSON,"text xml":b.parseXML},flatOptions:{context:true,url:true}},ajaxPrefilter:f(aa),ajaxTransport:f(q),ajax:function(bz,bx){if(typeof bz==="object"){bx=bz;bz=L;}bx=bx||{};var bD=b.ajaxSetup({},bx),bS=bD.context||bD,bG=bS!==bD&&(bS.nodeType||bS instanceof b)?b(bS):b.event,bR=b.Deferred(),bN=b.Callbacks("once memory"),bB=bD.statusCode||{},bC,bH={},bO={},bQ,by,bL,bE,bI,bA=0,bw,bK,bJ={readyState:0,setRequestHeader:function(bT,bU){if(!bA){var e=bT.toLowerCase();bT=bO[e]=bO[e]||bT;bH[bT]=bU;}return this;},getAllResponseHeaders:function(){return bA===2?bQ:null;},getResponseHeader:function(bT){var e;if(bA===2){if(!by){by={};while((e=aD.exec(bQ))){by[e[1].toLowerCase()]=e[2];}}e=by[bT.toLowerCase()];}return e===L?null:e;},overrideMimeType:function(e){if(!bA){bD.mimeType=e;}return this;},abort:function(e){e=e||"abort";if(bL){bL.abort(e);}bF(0,e);return this;}};function bF(bZ,bU,b0,bW){if(bA===2){return;}bA=2;if(bE){clearTimeout(bE);}bL=L;bQ=bW||"";bJ.readyState=bZ>0?4:0;var bT,b4,b3,bX=bU,bY=b0?bk(bD,bJ,b0):L,bV,b2;if(bZ>=200&&bZ<300||bZ===304){if(bD.ifModified){if((bV=bJ.getResponseHeader("Last-Modified"))){b.lastModified[bC]=bV;}if((b2=bJ.getResponseHeader("Etag"))){b.etag[bC]=b2;}}if(bZ===304){bX="notmodified";bT=true;}else{try{b4=F(bD,bY);bX="success";bT=true;}catch(b1){bX="parsererror";b3=b1;}}}else{b3=bX;if(!bX||bZ){bX="error";if(bZ<0){bZ=0;}}}bJ.status=bZ;bJ.statusText=""+(bU||bX);if(bT){bR.resolveWith(bS,[b4,bX,bJ]);}else{bR.rejectWith(bS,[bJ,bX,b3]);}bJ.statusCode(bB);bB=L;if(bw){bG.trigger("ajax"+(bT?"Success":"Error"),[bJ,bD,bT?b4:b3]);}bN.fireWith(bS,[bJ,bX]);if(bw){bG.trigger("ajaxComplete",[bJ,bD]);if(!(--b.active)){b.event.trigger("ajaxStop");}}}bR.promise(bJ);bJ.success=bJ.done;bJ.error=bJ.fail;bJ.complete=bN.add;bJ.statusCode=function(bT){if(bT){var e;if(bA<2){for(e in bT){bB[e]=[bB[e],bT[e]];}}else{e=bT[bJ.status];bJ.then(e,e);}}return this;};bD.url=((bz||bD.url)+"").replace(bq,"").replace(c,r[1]+"//");bD.dataTypes=b.trim(bD.dataType||"*").toLowerCase().split(h);if(bD.crossDomain==null){bI=K.exec(bD.url.toLowerCase());bD.crossDomain=!!(bI&&(bI[1]!=r[1]||bI[2]!=r[2]||(bI[3]||(bI[1]==="http:"?80:443))!=(r[3]||(r[1]==="http:"?80:443))));}if(bD.data&&bD.processData&&typeof bD.data!=="string"){bD.data=b.param(bD.data,bD.traditional);}aX(aa,bD,bx,bJ);if(bA===2){return false;}bw=bD.global;bD.type=bD.type.toUpperCase();bD.hasContent=!aR.test(bD.type);if(bw&&b.active++===0){b.event.trigger("ajaxStart");}if(!bD.hasContent){if(bD.data){bD.url+=(M.test(bD.url)?"&":"?")+bD.data;delete bD.data;}bC=bD.url;if(bD.cache===false){var bv=b.now(),bP=bD.url.replace(br,"$1_="+bv);bD.url=bP+((bP===bD.url)?(M.test(bD.url)?"&":"?")+"_="+bv:"");}}if(bD.data&&bD.hasContent&&bD.contentType!==false||bx.contentType){bJ.setRequestHeader("Content-Type",bD.contentType);}if(bD.ifModified){bC=bC||bD.url;if(b.lastModified[bC]){bJ.setRequestHeader("If-Modified-Since",b.lastModified[bC]);}if(b.etag[bC]){bJ.setRequestHeader("If-None-Match",b.etag[bC]);}}bJ.setRequestHeader("Accept",bD.dataTypes[0]&&bD.accepts[bD.dataTypes[0]]?bD.accepts[bD.dataTypes[0]]+(bD.dataTypes[0]!=="*"?", "+aW+"; q=0.01":""):bD.accepts["*"]);for(bK in bD.headers){bJ.setRequestHeader(bK,bD.headers[bK]);}if(bD.beforeSend&&(bD.beforeSend.call(bS,bJ,bD)===false||bA===2)){bJ.abort();return false;}for(bK in {success:1,error:1,complete:1}){bJ[bK](bD[bK]);}bL=aX(q,bD,bx,bJ);if(!bL){bF(-1,"No Transport");}else{bJ.readyState=1;if(bw){bG.trigger("ajaxSend",[bJ,bD]);}if(bD.async&&bD.timeout>0){bE=setTimeout(function(){bJ.abort("timeout");},bD.timeout);}try{bA=1;bL.send(bH,bF);}catch(bM){if(bA<2){bF(-1,bM);}else{throw bM;}}}return bJ;},param:function(e,bw){var bv=[],by=function(bz,bA){bA=b.isFunction(bA)?bA():bA;bv[bv.length]=encodeURIComponent(bz)+"="+encodeURIComponent(bA);};if(bw===L){bw=b.ajaxSettings.traditional;}if(b.isArray(e)||(e.jquery&&!b.isPlainObject(e))){b.each(e,function(){by(this.name,this.value);});}else{for(var bx in e){u(bx,e[bx],bw,by);}}return bv.join("&").replace(k,"+");}});function u(bw,by,bv,bx){if(b.isArray(by)){b.each(by,function(bA,bz){if(bv||ap.test(bw)){bx(bw,bz);}else{u(bw+"["+(typeof bz==="object"?bA:"")+"]",bz,bv,bx);}});}else{if(!bv&&b.type(by)==="object"){for(var e in by){u(bw+"["+e+"]",by[e],bv,bx);}}else{bx(bw,by);}}}b.extend({active:0,lastModified:{},etag:{}});function bk(bD,bC,bz){var bv=bD.contents,bB=bD.dataTypes,bw=bD.responseFields,by,bA,bx,e;for(bA in bw){if(bA in bz){bC[bw[bA]]=bz[bA];}}while(bB[0]==="*"){bB.shift();if(by===L){by=bD.mimeType||bC.getResponseHeader("content-type");}}if(by){for(bA in bv){if(bv[bA]&&bv[bA].test(by)){bB.unshift(bA);break;}}}if(bB[0] in bz){bx=bB[0];}else{for(bA in bz){if(!bB[0]||bD.converters[bA+" "+bB[0]]){bx=bA;break;}if(!e){e=bA;}}bx=bx||e;}if(bx){if(bx!==bB[0]){bB.unshift(bx);}return bz[bx];}}function F(bH,bz){if(bH.dataFilter){bz=bH.dataFilter(bz,bH.dataType);}var bD=bH.dataTypes,bG={},bA,bE,bw=bD.length,bB,bC=bD[0],bx,by,bF,bv,e;for(bA=1;bA<bw;bA++){if(bA===1){for(bE in bH.converters){if(typeof bE==="string"){bG[bE.toLowerCase()]=bH.converters[bE];}}}bx=bC;bC=bD[bA];if(bC==="*"){bC=bx;}else{if(bx!=="*"&&bx!==bC){by=bx+" "+bC;bF=bG[by]||bG["* "+bC];if(!bF){e=L;for(bv in bG){bB=bv.split(" ");if(bB[0]===bx||bB[0]==="*"){e=bG[bB[1]+" "+bC];if(e){bv=bG[bv];if(bv===true){bF=e;}else{if(e===true){bF=bv;}}break;}}}}if(!(bF||e)){b.error("No conversion from "+by.replace(" "," to "));}if(bF!==true){bz=bF?bF(bz):e(bv(bz));}}}}return bz;}var aC=b.now(),t=/(\=)\?(&|$)|\?\?/i;b.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return b.expando+"_"+(aC++);}});b.ajaxPrefilter("json jsonp",function(bD,bA,bC){var bx=(typeof bD.data==="string")&&/^application\/x\-www\-form\-urlencoded/.test(bD.contentType);if(bD.dataTypes[0]==="jsonp"||bD.jsonp!==false&&(t.test(bD.url)||bx&&t.test(bD.data))){var bB,bw=bD.jsonpCallback=b.isFunction(bD.jsonpCallback)?bD.jsonpCallback():bD.jsonpCallback,bz=bd[bw],e=bD.url,by=bD.data,bv="$1"+bw+"$2";if(bD.jsonp!==false){e=e.replace(t,bv);if(bD.url===e){if(bx){by=by.replace(t,bv);}if(bD.data===by){e+=(/\?/.test(e)?"&":"?")+bD.jsonp+"="+bw;}}}bD.url=e;bD.data=by;bd[bw]=function(bE){bB=[bE];};bC.always(function(){bd[bw]=bz;if(bB&&b.isFunction(bz)){bd[bw](bB[0]);}});bD.converters["script json"]=function(){if(!bB){b.error(bw+" was not called");}return bB[0];};bD.dataTypes[0]="json";return"script";}});b.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){b.globalEval(e);return e;}}});b.ajaxPrefilter("script",function(e){if(e.cache===L){e.cache=false;}if(e.crossDomain){e.type="GET";e.global=false;}});b.ajaxTransport("script",function(bw){if(bw.crossDomain){var e,bv=av.head||av.getElementsByTagName("head")[0]||av.documentElement;return{send:function(bx,by){e=av.createElement("script");e.async="async";if(bw.scriptCharset){e.charset=bw.scriptCharset;}e.src=bw.url;e.onload=e.onreadystatechange=function(bA,bz){if(bz||!e.readyState||/loaded|complete/.test(e.readyState)){e.onload=e.onreadystatechange=null;if(bv&&e.parentNode){bv.removeChild(e);}e=L;if(!bz){by(200,"success");}}};bv.insertBefore(e,bv.firstChild);},abort:function(){if(e){e.onload(0,1);}}};}});var A=bd.ActiveXObject?function(){for(var e in N){N[e](0,1);}}:false,x=0,N;function aM(){try{return new bd.XMLHttpRequest();}catch(bv){}}function ak(){try{return new bd.ActiveXObject("Microsoft.XMLHTTP");}catch(bv){}}b.ajaxSettings.xhr=bd.ActiveXObject?function(){return !this.isLocal&&aM()||ak();}:aM;(function(e){b.extend(b.support,{ajax:!!e,cors:!!e&&("withCredentials" in e)});})(b.ajaxSettings.xhr());if(b.support.ajax){b.ajaxTransport(function(e){if(!e.crossDomain||b.support.cors){var bv;return{send:function(bB,bw){var bA=e.xhr(),bz,by;if(e.username){bA.open(e.type,e.url,e.async,e.username,e.password);}else{bA.open(e.type,e.url,e.async);}if(e.xhrFields){for(by in e.xhrFields){bA[by]=e.xhrFields[by];}}if(e.mimeType&&bA.overrideMimeType){bA.overrideMimeType(e.mimeType);}if(!e.crossDomain&&!bB["X-Requested-With"]){bB["X-Requested-With"]="XMLHttpRequest";}try{for(by in bB){bA.setRequestHeader(by,bB[by]);}}catch(bx){}bA.send((e.hasContent&&e.data)||null);bv=function(bK,bE){var bF,bD,bC,bI,bH;try{if(bv&&(bE||bA.readyState===4)){bv=L;if(bz){bA.onreadystatechange=b.noop;if(A){delete N[bz];}}if(bE){if(bA.readyState!==4){bA.abort();}}else{bF=bA.status;bC=bA.getAllResponseHeaders();bI={};bH=bA.responseXML;if(bH&&bH.documentElement){bI.xml=bH;}try{bI.text=bA.responseText;}catch(bK){}try{bD=bA.statusText;}catch(bJ){bD="";}if(!bF&&e.isLocal&&!e.crossDomain){bF=bI.text?200:404;}else{if(bF===1223){bF=204;}}}}}catch(bG){if(!bE){bw(-1,bG);}}if(bI){bw(bF,bD,bI,bC);}};if(!e.async||bA.readyState===4){bv();}else{bz=++x;if(A){if(!N){N={};b(bd).unload(A);}N[bz]=bv;}bA.onreadystatechange=bv;}},abort:function(){if(bv){bv(0,1);}}};}});}var Q={},ba,m,aB=/^(?:toggle|show|hide)$/,aU=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,a4,aI=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],a5;b.fn.extend({show:function(bx,bA,bz){var bw,by;if(bx||bx===0){return this.animate(a2("show",3),bx,bA,bz);}else{for(var bv=0,e=this.length;bv<e;bv++){bw=this[bv];if(bw.style){by=bw.style.display;if(!b._data(bw,"olddisplay")&&by==="none"){by=bw.style.display="";}if((by===""&&b.css(bw,"display")==="none")||!b.contains(bw.ownerDocument.documentElement,bw)){b._data(bw,"olddisplay",w(bw.nodeName));}}}for(bv=0;bv<e;bv++){bw=this[bv];if(bw.style){by=bw.style.display;if(by===""||by==="none"){bw.style.display=b._data(bw,"olddisplay")||"";}}}return this;}},hide:function(bx,bA,bz){if(bx||bx===0){return this.animate(a2("hide",3),bx,bA,bz);}else{var bw,by,bv=0,e=this.length;for(;bv<e;bv++){bw=this[bv];if(bw.style){by=b.css(bw,"display");if(by!=="none"&&!b._data(bw,"olddisplay")){b._data(bw,"olddisplay",by);}}}for(bv=0;bv<e;bv++){if(this[bv].style){this[bv].style.display="none";}}return this;}},_toggle:b.fn.toggle,toggle:function(bw,bv,bx){var e=typeof bw==="boolean";if(b.isFunction(bw)&&b.isFunction(bv)){this._toggle.apply(this,arguments);}else{if(bw==null||e){this.each(function(){var by=e?bw:b(this).is(":hidden");b(this)[by?"show":"hide"]();});}else{this.animate(a2("toggle",3),bw,bv,bx);}}return this;},fadeTo:function(e,bx,bw,bv){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:bx},e,bw,bv);},animate:function(bz,bw,by,bx){var e=b.speed(bw,by,bx);if(b.isEmptyObject(bz)){return this.each(e.complete,[false]);}bz=b.extend({},bz);function bv(){if(e.queue===false){b._mark(this);}var bE=b.extend({},e),bL=this.nodeType===1,bJ=bL&&b(this).is(":hidden"),bB,bG,bD,bK,bN,bF,bI,bC,bH,bM,bA;bE.animatedProperties={};for(bD in bz){bB=b.camelCase(bD);if(bD!==bB){bz[bB]=bz[bD];delete bz[bD];}if((bN=b.cssHooks[bB])&&"expand" in bN){bF=bN.expand(bz[bB]);delete bz[bB];for(bD in bF){if(!(bD in bz)){bz[bD]=bF[bD];}}}}for(bB in bz){bG=bz[bB];if(b.isArray(bG)){bE.animatedProperties[bB]=bG[1];bG=bz[bB]=bG[0];}else{bE.animatedProperties[bB]=bE.specialEasing&&bE.specialEasing[bB]||bE.easing||"swing";}if(bG==="hide"&&bJ||bG==="show"&&!bJ){return bE.complete.call(this);}if(bL&&(bB==="height"||bB==="width")){bE.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY];if(b.css(this,"display")==="inline"&&b.css(this,"float")==="none"){if(!b.support.inlineBlockNeedsLayout||w(this.nodeName)==="inline"){this.style.display="inline-block";}else{this.style.zoom=1;}}}}if(bE.overflow!=null){this.style.overflow="hidden";}for(bD in bz){bK=new b.fx(this,bE,bD);bG=bz[bD];if(aB.test(bG)){bA=b._data(this,"toggle"+bD)||(bG==="toggle"?bJ?"show":"hide":0);if(bA){b._data(this,"toggle"+bD,bA==="show"?"hide":"show");bK[bA]();}else{bK[bG]();}}else{bI=aU.exec(bG);bC=bK.cur();if(bI){bH=parseFloat(bI[2]);bM=bI[3]||(b.cssNumber[bD]?"":"px");if(bM!=="px"){b.style(this,bD,(bH||1)+bM);bC=((bH||1)/bK.cur())*bC;b.style(this,bD,bC+bM);}if(bI[1]){bH=((bI[1]==="-="?-1:1)*bH)+bC;}bK.custom(bC,bH,bM);}else{bK.custom(bC,bG,"");}}}return true;}return e.queue===false?this.each(bv):this.queue(e.queue,bv);},stop:function(bw,bv,e){if(typeof bw!=="string"){e=bv;bv=bw;bw=L;}if(bv&&bw!==false){this.queue(bw||"fx",[]);}return this.each(function(){var bx,by=false,bA=b.timers,bz=b._data(this);if(!e){b._unmark(true,this);}function bB(bE,bF,bD){var bC=bF[bD];b.removeData(bE,bD,true);bC.stop(e);}if(bw==null){for(bx in bz){if(bz[bx]&&bz[bx].stop&&bx.indexOf(".run")===bx.length-4){bB(this,bz,bx);}}}else{if(bz[bx=bw+".run"]&&bz[bx].stop){bB(this,bz,bx);}}for(bx=bA.length;bx--;){if(bA[bx].elem===this&&(bw==null||bA[bx].queue===bw)){if(e){bA[bx](true);}else{bA[bx].saveState();}by=true;bA.splice(bx,1);}}if(!(e&&by)){b.dequeue(this,bw);}});}});function bi(){setTimeout(at,0);return(a5=b.now());}function at(){a5=L;}function a2(bv,e){var bw={};b.each(aI.concat.apply([],aI.slice(0,e)),function(){bw[this]=bv;});return bw;}b.each({slideDown:a2("show",1),slideUp:a2("hide",1),slideToggle:a2("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,bv){b.fn[e]=function(bw,by,bx){return this.animate(bv,bw,by,bx);};});b.extend({speed:function(bw,bx,bv){var e=bw&&typeof bw==="object"?b.extend({},bw):{complete:bv||!bv&&bx||b.isFunction(bw)&&bw,duration:bw,easing:bv&&bx||bx&&!b.isFunction(bx)&&bx};e.duration=b.fx.off?0:typeof e.duration==="number"?e.duration:e.duration in b.fx.speeds?b.fx.speeds[e.duration]:b.fx.speeds._default;if(e.queue==null||e.queue===true){e.queue="fx";}e.old=e.complete;e.complete=function(by){if(b.isFunction(e.old)){e.old.call(this);}if(e.queue){b.dequeue(this,e.queue);}else{if(by!==false){b._unmark(this);}}};return e;},easing:{linear:function(e){return e;},swing:function(e){return(-Math.cos(e*Math.PI)/2)+0.5;}},timers:[],fx:function(bv,e,bw){this.options=e;this.elem=bv;this.prop=bw;e.orig=e.orig||{};}});b.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this);}(b.fx.step[this.prop]||b.fx.step._default)(this);},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop];}var e,bv=b.css(this.elem,this.prop);return isNaN(e=parseFloat(bv))?!bv||bv==="auto"?0:bv:e;},custom:function(bz,by,bx){var e=this,bw=b.fx;this.startTime=a5||bi();this.end=by;this.now=this.start=bz;this.pos=this.state=0;this.unit=bx||this.unit||(b.cssNumber[this.prop]?"":"px");function bv(bA){return e.step(bA);}bv.queue=this.options.queue;bv.elem=this.elem;bv.saveState=function(){if(b._data(e.elem,"fxshow"+e.prop)===L){if(e.options.hide){b._data(e.elem,"fxshow"+e.prop,e.start);}else{if(e.options.show){b._data(e.elem,"fxshow"+e.prop,e.end);}}}};if(bv()&&b.timers.push(bv)&&!a4){a4=setInterval(bw.tick,bw.interval);}},show:function(){var e=b._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=e||b.style(this.elem,this.prop);this.options.show=true;if(e!==L){this.custom(this.cur(),e);}else{this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());}b(this.elem).show();},hide:function(){this.options.orig[this.prop]=b._data(this.elem,"fxshow"+this.prop)||b.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0);},step:function(by){var bA,bB,bv,bx=a5||bi(),e=true,bz=this.elem,bw=this.options;if(by||bx>=bw.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();bw.animatedProperties[this.prop]=true;for(bA in bw.animatedProperties){if(bw.animatedProperties[bA]!==true){e=false;}}if(e){if(bw.overflow!=null&&!b.support.shrinkWrapBlocks){b.each(["","X","Y"],function(bC,bD){bz.style["overflow"+bD]=bw.overflow[bC];});}if(bw.hide){b(bz).hide();}if(bw.hide||bw.show){for(bA in bw.animatedProperties){b.style(bz,bA,bw.orig[bA]);b.removeData(bz,"fxshow"+bA,true);b.removeData(bz,"toggle"+bA,true);}}bv=bw.complete;if(bv){bw.complete=false;bv.call(bz);}}return false;}else{if(bw.duration==Infinity){this.now=bx;}else{bB=bx-this.startTime;this.state=bB/bw.duration;this.pos=b.easing[bw.animatedProperties[this.prop]](this.state,bB,0,1,bw.duration);this.now=this.start+((this.end-this.start)*this.pos);}this.update();}return true;}};b.extend(b.fx,{tick:function(){var bw,bv=b.timers,e=0;for(;e<bv.length;e++){bw=bv[e];if(!bw()&&bv[e]===bw){bv.splice(e--,1);}}if(!bv.length){b.fx.stop();}},interval:13,stop:function(){clearInterval(a4);a4=null;},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(e){b.style(e.elem,"opacity",e.now);},_default:function(e){if(e.elem.style&&e.elem.style[e.prop]!=null){e.elem.style[e.prop]=e.now+e.unit;}else{e.elem[e.prop]=e.now;}}}});b.each(aI.concat.apply([],aI),function(e,bv){if(bv.indexOf("margin")){b.fx.step[bv]=function(bw){b.style(bw.elem,bv,Math.max(0,bw.now)+bw.unit);};}});if(b.expr&&b.expr.filters){b.expr.filters.animated=function(e){return b.grep(b.timers,function(bv){return e===bv.elem;}).length;};}function w(bx){if(!Q[bx]){var e=av.body,bv=b("<"+bx+">").appendTo(e),bw=bv.css("display");bv.remove();if(bw==="none"||bw===""){if(!ba){ba=av.createElement("iframe");ba.frameBorder=ba.width=ba.height=0;}e.appendChild(ba);if(!m||!ba.createElement){m=(ba.contentWindow||ba.contentDocument).document;m.write((b.support.boxModel?"<!doctype html>":"")+"<html><body>");m.close();}bv=m.createElement(bx);m.body.appendChild(bv);bw=b.css(bv,"display");e.removeChild(ba);}Q[bx]=bw;}return Q[bx];}var a8,V=/^t(?:able|d|h)$/i,ad=/^(?:body|html)$/i;if("getBoundingClientRect" in av.documentElement){a8=function(by,bH,bw,bB){try{bB=by.getBoundingClientRect();}catch(bF){}if(!bB||!b.contains(bw,by)){return bB?{top:bB.top,left:bB.left}:{top:0,left:0};}var bC=bH.body,bD=aL(bH),bA=bw.clientTop||bC.clientTop||0,bE=bw.clientLeft||bC.clientLeft||0,bv=bD.pageYOffset||b.support.boxModel&&bw.scrollTop||bC.scrollTop,bz=bD.pageXOffset||b.support.boxModel&&bw.scrollLeft||bC.scrollLeft,bG=bB.top+bv-bA,bx=bB.left+bz-bE;return{top:bG,left:bx};};}else{a8=function(bz,bE,bx){var bC,bw=bz.offsetParent,bv=bz,bA=bE.body,bB=bE.defaultView,e=bB?bB.getComputedStyle(bz,null):bz.currentStyle,bD=bz.offsetTop,by=bz.offsetLeft;while((bz=bz.parentNode)&&bz!==bA&&bz!==bx){if(b.support.fixedPosition&&e.position==="fixed"){break;}bC=bB?bB.getComputedStyle(bz,null):bz.currentStyle;bD-=bz.scrollTop;by-=bz.scrollLeft;if(bz===bw){bD+=bz.offsetTop;by+=bz.offsetLeft;if(b.support.doesNotAddBorder&&!(b.support.doesAddBorderForTableAndCells&&V.test(bz.nodeName))){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0;}bv=bw;bw=bz.offsetParent;}if(b.support.subtractsBorderForOverflowNotVisible&&bC.overflow!=="visible"){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0;}e=bC;}if(e.position==="relative"||e.position==="static"){bD+=bA.offsetTop;by+=bA.offsetLeft;}if(b.support.fixedPosition&&e.position==="fixed"){bD+=Math.max(bx.scrollTop,bA.scrollTop);by+=Math.max(bx.scrollLeft,bA.scrollLeft);}return{top:bD,left:by};};}b.fn.offset=function(e){if(arguments.length){return e===L?this:this.each(function(bx){b.offset.setOffset(this,e,bx);});}var bv=this[0],bw=bv&&bv.ownerDocument;if(!bw){return null;}if(bv===bw.body){return b.offset.bodyOffset(bv);}return a8(bv,bw,bw.documentElement);};b.offset={bodyOffset:function(e){var bw=e.offsetTop,bv=e.offsetLeft;if(b.support.doesNotIncludeMarginInBodyOffset){bw+=parseFloat(b.css(e,"marginTop"))||0;bv+=parseFloat(b.css(e,"marginLeft"))||0;}return{top:bw,left:bv};},setOffset:function(bx,bG,bA){var bB=b.css(bx,"position");if(bB==="static"){bx.style.position="relative";}var bz=b(bx),bv=bz.offset(),e=b.css(bx,"top"),bE=b.css(bx,"left"),bF=(bB==="absolute"||bB==="fixed")&&b.inArray("auto",[e,bE])>-1,bD={},bC={},bw,by;if(bF){bC=bz.position();bw=bC.top;by=bC.left;}else{bw=parseFloat(e)||0;by=parseFloat(bE)||0;}if(b.isFunction(bG)){bG=bG.call(bx,bA,bv);}if(bG.top!=null){bD.top=(bG.top-bv.top)+bw;}if(bG.left!=null){bD.left=(bG.left-bv.left)+by;}if("using" in bG){bG.using.call(bx,bD);}else{bz.css(bD);}}};b.fn.extend({position:function(){if(!this[0]){return null;}var bw=this[0],bv=this.offsetParent(),bx=this.offset(),e=ad.test(bv[0].nodeName)?{top:0,left:0}:bv.offset();bx.top-=parseFloat(b.css(bw,"marginTop"))||0;bx.left-=parseFloat(b.css(bw,"marginLeft"))||0;e.top+=parseFloat(b.css(bv[0],"borderTopWidth"))||0;e.left+=parseFloat(b.css(bv[0],"borderLeftWidth"))||0;return{top:bx.top-e.top,left:bx.left-e.left};},offsetParent:function(){return this.map(function(){var e=this.offsetParent||av.body;while(e&&(!ad.test(e.nodeName)&&b.css(e,"position")==="static")){e=e.offsetParent;}return e;});}});b.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(bw,bv){var e=/Y/.test(bv);b.fn[bw]=function(bx){return b.access(this,function(by,bB,bA){var bz=aL(by);if(bA===L){return bz?(bv in bz)?bz[bv]:b.support.boxModel&&bz.document.documentElement[bB]||bz.document.body[bB]:by[bB];}if(bz){bz.scrollTo(!e?bA:b(bz).scrollLeft(),e?bA:b(bz).scrollTop());}else{by[bB]=bA;}},bw,bx,arguments.length,null);};});function aL(e){return b.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:false;}b.each({Height:"height",Width:"width"},function(bw,bx){var bv="client"+bw,e="scroll"+bw,by="offset"+bw;b.fn["inner"+bw]=function(){var bz=this[0];return bz?bz.style?parseFloat(b.css(bz,bx,"padding")):this[bx]():null;};b.fn["outer"+bw]=function(bA){var bz=this[0];return bz?bz.style?parseFloat(b.css(bz,bx,bA?"margin":"border")):this[bx]():null;};b.fn[bx]=function(bz){return b.access(this,function(bC,bB,bD){var bF,bE,bG,bA;if(b.isWindow(bC)){bF=bC.document;bE=bF.documentElement[bv];return b.support.boxModel&&bE||bF.body&&bF.body[bv]||bE;}if(bC.nodeType===9){bF=bC.documentElement;if(bF[bv]>=bF[e]){return bF[bv];}return Math.max(bC.body[e],bF[e],bC.body[by],bF[by]);}if(bD===L){bG=b.css(bC,bB);bA=parseFloat(bG);return b.isNumeric(bA)?bA:bG;}b(bC).css(bB,bD);},bx,bz,arguments.length,null);};});bd.jQuery=bd.$=b;if(typeof define==="function"&&define.amd&&define.amd.jQuery){define("jquery",[],function(){return b;});}})(window);
Index: /sandbox/2.4.1-3/prototype/rest/catalog/DynamicContactsResource.php
===================================================================
--- /sandbox/2.4.1-3/prototype/rest/catalog/DynamicContactsResource.php	(revision 6473)
+++ /sandbox/2.4.1-3/prototype/rest/catalog/DynamicContactsResource.php	(revision 6512)
@@ -90,4 +90,15 @@
 
                 $i->addData($d);
+				
+				$d = new Data();
+                $d->setName('id');
+                $d->setValue($value['id']);
+                $d->setPrompt('Id do contato dinamico');
+                $d->setDataType('integer');
+                $d->setMaxLength('100');
+                $d->setMinLength(null);
+                $d->setRequired(false);
+
+                $i->addData($d);
 
                 $l = new Link();
Index: /sandbox/2.4.1-3/prototype/rest/catalog/ContactResource.php
===================================================================
--- /sandbox/2.4.1-3/prototype/rest/catalog/ContactResource.php	(revision 6460)
+++ /sandbox/2.4.1-3/prototype/rest/catalog/ContactResource.php	(revision 6512)
@@ -30,5 +30,5 @@
 
 	try {
-	    $this->secured();
+	    //$this->secured();
 
             $contact = Controller::find( array( 'concept' => 'contact' ), false, array( 'filter' => array( 'AND', array('=', 'user',  Config::me("uidNumber") ), array('=', 'id', $id) )  ) );
Index: /sandbox/2.4.1-3/prototype/rest/catalog/GroupResource.php
===================================================================
--- /sandbox/2.4.1-3/prototype/rest/catalog/GroupResource.php	(revision 6439)
+++ /sandbox/2.4.1-3/prototype/rest/catalog/GroupResource.php	(revision 6512)
@@ -30,5 +30,5 @@
 
 	try {
-	    $this->secured();
+	    //$this->secured();
 
             $group = Controller::find( array( 'concept' => 'contactGroup' ), false, array( 'filter' => array( 'AND', array('=', 'user',  Config::me("uidNumber") ), array('=', 'id', $id) )  ) );
Index: /sandbox/2.4.1-3/prototype/rest/catalog/ContactsResource.php
===================================================================
--- /sandbox/2.4.1-3/prototype/rest/catalog/ContactsResource.php	(revision 6455)
+++ /sandbox/2.4.1-3/prototype/rest/catalog/ContactsResource.php	(revision 6512)
@@ -30,5 +30,5 @@
 
 	try {
-	    $this->secured();
+	    //$this->secured();
 
             $contacts = Controller::find( array( 'concept' => 'contact' ), false, array( 'filter' => array( '=', 'user',  Config::me("uidNumber") ) ) );
Index: /sandbox/2.4.1-3/prototype/rest/catalog/GroupsResource.php
===================================================================
--- /sandbox/2.4.1-3/prototype/rest/catalog/GroupsResource.php	(revision 6439)
+++ /sandbox/2.4.1-3/prototype/rest/catalog/GroupsResource.php	(revision 6512)
@@ -30,5 +30,5 @@
 	
 	try {
-	    $this->secured();
+	    //$this->secured();
 
         $groups = Controller::find( array( 'concept' => 'contactGroup' ), false, array( 'filter' => array('=', 'user',  Config::me("uidNumber") ), 'order' => array('name') ) );			
Index: /sandbox/2.4.1-3/prototype/rest/catalog/DynamicContactResource.php
===================================================================
--- /sandbox/2.4.1-3/prototype/rest/catalog/DynamicContactResource.php	(revision 6473)
+++ /sandbox/2.4.1-3/prototype/rest/catalog/DynamicContactResource.php	(revision 6512)
@@ -216,5 +216,4 @@
         //completar os atributos
         $params['owner']                = Config::me("uidNumber");
-        $params['number_of_messages']   = '1';
         $params['timestamp']            = time();
 	$params['id']			= $id;
@@ -238,11 +237,11 @@
 		);
 
-
+		
                 //Se existe o recurso
                 if($dynamicContact){
-		    $params['number_of_messages']++;
-
-                    $dynamicContact = Controller::update(
-                                                        array('concept' => 'dynamicContact'),
+					$params['number_of_messages'] = $dynamicContact[0]['number_of_messages'] + 1;
+					$dynamicContact = Controller::update(
+                                                        array('concept' => 'dynamicContact',
+														'id'=>$id),
                                                         $params
                     );
@@ -254,5 +253,5 @@
                 }
                 else{
-
+					$params['number_of_messages']   = '1';
                     $idDynamicContact = Controller::create(
                                                         array('concept' => 'dynamicContact'),
Index: /sandbox/2.4.1-3/prototype/rest/user/UsersResource.php
===================================================================
--- /sandbox/2.4.1-3/prototype/rest/user/UsersResource.php	(revision 6437)
+++ /sandbox/2.4.1-3/prototype/rest/user/UsersResource.php	(revision 6512)
@@ -30,5 +30,5 @@
 
 	try {
-	    $this->secured();
+	    //$this->secured();
 
 	    //Executa uma consulta de usuários do LDAP a partir de um determinado atributo e valor
Index: /sandbox/2.4.1-3/prototype/rest/user/UserResource.php
===================================================================
--- /sandbox/2.4.1-3/prototype/rest/user/UserResource.php	(revision 6460)
+++ /sandbox/2.4.1-3/prototype/rest/user/UserResource.php	(revision 6512)
@@ -29,5 +29,5 @@
 	try {
 
-	    $this->secured();
+	    //$this->secured();
 
 	    $user = Controller::find(array('concept' => 'user','service'=>'OpenLDAP'), false, array('filter' => array('=', 'uid', $id )));
Index: /sandbox/2.4.1-3/expressoMail1_2/index.php
===================================================================
--- /sandbox/2.4.1-3/expressoMail1_2/index.php	(revision 6376)
+++ /sandbox/2.4.1-3/expressoMail1_2/index.php	(revision 6512)
@@ -57,4 +57,5 @@
 		<script type="text/javascript" src="../prototype/plugins/datejs/sugarpak.js"></script>
 		<script type="text/javascript" src="../prototype/plugins/datejs/parser.js"></script>
+		<script type="text/javascript" src="../prototype/plugins/jq-raty/js/jquery.raty.min.js"></script>
 
 		<script type="text/javascript" src="../prototype/plugins/watermark/jquery.watermarkinput.js"></script>
Index: /sandbox/2.4.1-3/expressoMail1_2/templates/default/main.css
===================================================================
--- /sandbox/2.4.1-3/expressoMail1_2/templates/default/main.css	(revision 6374)
+++ /sandbox/2.4.1-3/expressoMail1_2/templates/default/main.css	(revision 6512)
@@ -703,5 +703,5 @@
 }
 .message_options_trash {
-	background-image: url(../../../phpgwapi/templates/default/images/foldertree_trash.png);
+	background-image: url(images/page_white_delete.png);
 	background-repeat: no-repeat;
 	background-position:left center;
@@ -1330,5 +1330,6 @@
 
 .line-separator{
-	background: url(images/linha.png) repeat-x 0 96% ;
+	background: url("images/linha.png") repeat-x scroll 0 8px transparent;
+	clear : both;
 }
 
Index: /sandbox/2.4.1-3/expressoMail1_2/setup/tables_update.inc.php
===================================================================
--- /sandbox/2.4.1-3/expressoMail1_2/setup/tables_update.inc.php	(revision 6468)
+++ /sandbox/2.4.1-3/expressoMail1_2/setup/tables_update.inc.php	(revision 6512)
@@ -291,19 +291,20 @@
 		$oProc->query('SELECT * FROM phpgw_expressomail_contacts');
 		$return = array();
-        while($oProc->next_record())
-        	$return[$oProc->f('id_owner')] = $oProc->f('data');
-
-        foreach ($return as $owner => &$value) {
-        	$contacts = unserialize($value);
-        	foreach ($contacts as &$contact) {
-        		$info = explode('#', $contact['email']);
-        		$oProc->query("INSERT INTO expressomail_dynamic_contact (owner, name ,mail , number_of_messages ,timestamp) values ('".$owner."', '".$info[0]."', '".$info[1]."', 1, '".$contact['timestamp']."');");
+	        while($oProc->next_record())
+	        	$return[$oProc->f('id_owner')] = $oProc->f('data');
+
+	        foreach ($return as $owner => &$value) {
+        		$contacts = unserialize($value);
+        		foreach ($contacts as &$contact) {
+	        		$info = explode('#', $contact['email']);
+        			$oProc->query("INSERT INTO expressomail_dynamic_contact (owner, name ,mail , number_of_messages ,timestamp) values ('".$owner."', '".$info[0]."', '".$info[1]."', 1, '".$contact['timestamp']."');");
+	        	}
         	}
-        }
-        ////////////////////////////////////////////////////////////
-
-        //Deleta tabela antiga
+
+	        //Deleta tabela antiga
 		$oProc->DropTable('phpgw_expressomail_contacts');
-        
+
+		/* Remove a restricao de quantidade de contatos recentes */
+		$oProc->query("DELETE FROM phpgw_config WHERE config_app = 'expressoMail1_2' AND config_name = 'expressoMail_Number_of_dynamic_contacts'");
 
 		$GLOBALS['setup_info']['expressoMail1_2']['currentver'] = '2.4.7';
Index: /sandbox/2.4.1-3/expressoMail1_2/inc/class.db_functions.inc.php
===================================================================
--- /sandbox/2.4.1-3/expressoMail1_2/inc/class.db_functions.inc.php	(revision 6105)
+++ /sandbox/2.4.1-3/expressoMail1_2/inc/class.db_functions.inc.php	(revision 6512)
@@ -24,5 +24,4 @@
 	include_once(PHPGW_API_INC.'/class.db.inc.php'); 
 } 
-include_once('class.dynamic_contacts.inc.php');
 	
 class db_functions
@@ -249,5 +248,5 @@
 
 	//Gera lista de contatos para ser gravado e acessado pelo expresso offline.
-	function get_dropdown_contacts_to_cache() {
+	/*function get_dropdown_contacts_to_cache() {
 		return $this->get_dropdown_contacts();
 	}
@@ -275,5 +274,5 @@
 		}
 		return $stringDropDownContacts;	
-	}
+	}*/
 	function getUserByEmail($params){	
 		// Follow the referral
@@ -308,5 +307,5 @@
 		return $result;
 	}
-	
+	/*
 	function get_dynamic_contacts()
 	{				
@@ -333,4 +332,6 @@
 		return $contacts;
 	}
+	*/
+	/*
 	function update_contacts($contacts=array())
 	{			
@@ -364,5 +365,6 @@
 		}
 		return $contacts;
-	}	
+	}	*/
+	
 	function update_preferences($params){
 		$string_serial = urldecode($params['prefe_string']);				
@@ -377,4 +379,5 @@
 	}
 	
+	/*
 	function insert_contact($contact)	
 	{
@@ -396,5 +399,5 @@
 		$this->db->delete('phpgw_expressomail_contacts',$where,$line,$file);	
 	}
-	
+	*/ 
 	function import_vcard($params){
             include_once('class.imap_functions.inc.php');
Index: /sandbox/2.4.1-3/expressoMail1_2/inc/class.imap_functions.inc.php
===================================================================
--- /sandbox/2.4.1-3/expressoMail1_2/inc/class.imap_functions.inc.php	(revision 6212)
+++ /sandbox/2.4.1-3/expressoMail1_2/inc/class.imap_functions.inc.php	(revision 6512)
@@ -3108,14 +3108,7 @@
                     error_log("$now - $userip - $sent [$subject] - $userid => $addrs\r\n", 3, "/home/expressolivre/mail_senders.log");
                 }
-                if ($_SESSION['phpgw_info']['user']['preferences']['expressoMail']['use_dynamic_contacts']) {
-                    $contacts = new dynamic_contacts();
-                    $new_contacts = $contacts->add_dynamic_contacts($toaddress . "," . $ccaddress . "," . $ccoaddress);
-                    return array("success" => true, "new_contacts" => $new_contacts);
-                }
-                
-                   if($params['uids_save'] )
-                        $this->delete_msgs(array('folder'=> $params['save_folder'] , 'msgs_number' => $params['uids_save']));
+                if($params['uids_save'] )
+					$this->delete_msgs(array('folder'=> $params['save_folder'] , 'msgs_number' => $params['uids_save']));
                        
-                
                 //return array("success" => true, "folder" => $folder_list);
 				return array("success" => true, "load" => $has_new_folder);
Index: /sandbox/2.4.1-3/expressoMail1_2/js/main.js
===================================================================
--- /sandbox/2.4.1-3/expressoMail1_2/js/main.js	(revision 6461)
+++ /sandbox/2.4.1-3/expressoMail1_2/js/main.js	(revision 6512)
@@ -7,9 +7,15 @@
 var cabecalho = '<h4>ExpressoLivre - ExpressoMail</h4>'; 
 
+var dynamicPersonalContacts = new Array();
+var dynamicPersonalGroups = new Array();
+var dynamicContacts = new Array();
+var dynamicContactList = new Array();
+var topContact = 0;
+
 //Os IE's < 9 não possui suporte a trim() introduzida no JavaScript 1.8.1
 if(!String.prototype.trim){  
 	String.prototype.trim = function(){
-								return this.replace(/^\s+|\s+$/g,'');
-							} 
+		return this.replace(/^\s+|\s+$/g,'');
+	} 
 }
 	
@@ -19,4 +25,67 @@
 	return folders.join(cyrus_delimiter);
 } 
+
+function updateDynamicContactList(){
+	dynamicContactList = new Array();
+	$.merge(dynamicContactList, dynamicContacts);
+	$.merge(dynamicContactList, dynamicPersonalGroups);
+	$.merge(dynamicContactList, dynamicPersonalContacts);
+}
+
+function updateDynamicContact(){
+	dynamicContacts = new Array();
+	var dynamicData = DataLayer.read("/dynamiccontacts").collection.itens;
+	if(dynamicData){
+		$.each(dynamicData, function(index, value){
+			if(index ==0){
+				topContact = parseInt(value.data[2].value);
+			}
+			var dynamic = {
+				name : value.data[0].value,
+				email : value.data[1].value,
+				value: value.data[0].value + " - " + value.data[1].value,
+				type: "",
+				id: parseInt(value.data[3].value),
+				qtd : parseInt(value.data[2].value)
+			};
+			dynamicContacts.push(dynamic);
+		});
+	}
+}
+
+function updateDynamicPersonalGroups(){
+	dynamicPersonalGroups = new Array();
+	var groupsData = DataLayer.read("/groups").collection.itens;
+	if(groupsData){
+		$.each(groupsData, function(index, value){
+			var group = {
+				id : parseInt(value.data[0].value),
+				name : value.data[2].value,
+				email : value.data[2].value,
+				value: value.data[2].value + " - " + value.data[2].value,
+				type: "G"
+			};
+			dynamicPersonalGroups.push(group);
+		});
+	}
+}
+
+function updateDynamicPersonalContacts(){
+	dynamicPersonalContacts = new Array();
+	var contactsData = DataLayer.read("/contacts").collection.itens;
+	if(contactsData){
+		$.each(contactsData, function(index, value){
+			var contact = {
+				id : parseInt(value.data[0].value),
+				name : value.data[1].value,
+				email : value.data[2].value,
+				value: value.data[1].value + " - " + value.data[2].value,
+				type: "P"
+			};
+			dynamicPersonalContacts.push(contact);
+		});
+	}
+}
+
 function init(){
 	if (!is_ie)
@@ -30,4 +99,12 @@
 
 	}*/
+	var load_dynamics = function(){
+		updateDynamicContact();
+		updateDynamicPersonalGroups();
+		updateDynamicPersonalContacts();
+		updateDynamicContactList();
+	};
+	load_dynamics();
+	
 	var save_preferences = function(data){
 
@@ -2127,6 +2204,8 @@
 	watch_changes_in_msg(ID);
 
+	var content = $("#content_id_"+ID);
 	var sign = false;
 	var crypt = false;
+	var reComplexEmail = /<([^<]*)>[\s]*$/;
 	if ((preferences.use_assinar_criptografar != '0') && (preferences.use_signature_digital_cripto != '0')){
 		var checkSign = document.getElementById('return_digital_'+ID)
@@ -2168,6 +2247,6 @@
 	if(data && data.success == true ){
 		// if send ok, set a flag as answered or forwarded
-		var msg_number_replied = $("#content_id_" + ID).find('[name="msg_reply_from"]');
-		var msg_number_forwarded = $("#content_id_" + ID).find('[name="msg_forward_from"]');
+		var msg_number_replied = content.find('[name="msg_reply_from"]');
+		var msg_number_forwarded = content.find('[name="msg_forward_from"]');
 
 		if (msg_number_replied.val()){
@@ -2190,6 +2269,9 @@
 			}
 		}
+		
+		$
+		//REFAZER ISTO COM UMA CHAMADA ASSINCRONA PARA REGISTRAR E ATUALIZAR A LISTA DOS NOVOS CONTATOS DINAMICOS
 		// If new dynamic contacts were added, update the autocomplete ....
-		if(data.new_contacts){
+		/*if(data.new_contacts){
 			var ar_contacts = data.new_contacts.split(',;');
 			for(var j in ar_contacts){
@@ -2199,12 +2281,71 @@
 			}
 		}
+		var dynamicPersonalContacts = new Array();
+		var dynamicPersonalGroups = new Array();
+		var dynamicContacts = new Array();
+		var dynamicContactList = new Array();
+
+		*/
+		var array = content.find(".to-tr").find(".box").clone();
 		delete_border(ID,'true'); 
+		$.each(array, function(i, value){
+			var stop = false;
+			$.each(dynamicPersonalContacts, function(x, valuex){
+				if(valuex.email == $(value).find("input").val().match(reComplexEmail)[1]){
+					stop = true;
+					return false;
+				}
+			});
+			console.log(stop ? "Nem cria ;p" : "Vai entra no IF");
+			if(!stop){
+				var exist = 0;
+				$.each(dynamicContacts, function(x, valuex){
+					if(valuex.email == $(value).find("input").val().match(reComplexEmail)[1]){
+						exist = valuex.id;
+						return false;
+					}
+				});
+				if(exist){
+					console.log("Atualizou");
+					DataLayer.update("/dynamiccontact/"+exist, {name: $(value).find("input").val().split('"')[1], mail:$(value).find("input").val().match(reComplexEmail)[1]});
+				}else{
+					console.log("Criou");
+					DataLayer.create("/dynamiccontacts", {name: $(value).find("input").val().split('"')[1], mail:$(value).find("input").val().match(reComplexEmail)[1]});
+				}
+			}
+		});
+		updateDynamicContact();
+		updateDynamicContactList();
  	}
 	else{
 		if(data == 'Post-Content-Length')
 			write_msg(get_lang('The size of this message has exceeded  the limit (%1B).',Element('upload_max_filesize').value));
-		else if(data)
+		else if(data){
+			var error_mail = $.trim(data.split(":")[data.split(":").length-1]);
+			var array = content.find(".to-tr").find(".box");
+			//$(value).find("input").val()
+			$.each(array, function(index, value){
+				if(error_mail == $(value).find("input").val().match(reComplexEmail)[1])
+					$(value).addClass("invalid-email-box");
+			});
+			if ( content.find('[name="input_cco"]').length){
+				if(content.find(".cco-tr").css("display") != "none"){
+					var array = content.find(".cco-tr").find(".box");
+					$.each(array, function(index, value){
+						if(error_mail == $(value).find("input").val().match(reComplexEmail)[1])
+							$(value).addClass("invalid-email-box");
+					});
+				}
+			}
+			if(content.find(".cc-tr").css("display") != "none")
+			{
+				var array = content.find(".cc-tr").find(".box");
+				$.each(array, function(index, value){
+					if(error_mail == $(value).find("input").val().match(reComplexEmail)[1])
+						$(value).addClass("invalid-email-box");
+				});				
+			} 
 			write_msg(data);
-		else
+		}else
 			write_msg(get_lang("Connection failed with %1 Server. Try later.", "Web"));
 		
Index: /sandbox/2.4.1-3/expressoMail1_2/js/ccQuickAdd.js
===================================================================
--- /sandbox/2.4.1-3/expressoMail1_2/js/ccQuickAdd.js	(revision 5878)
+++ /sandbox/2.4.1-3/expressoMail1_2/js/ccQuickAdd.js	(revision 6512)
@@ -32,5 +32,5 @@
 										data = data + $(this).find('#quickAddOne_nickName').val() + ',';
 										data = data + $(this).find('#quickAddOne_firstName').val() + ',';
-										data = data + $(this).find('#quickAddOne_lastName').val() + ',';
+										data = data + $(this).find('#quickAddOne_lastName').val() + ',,';
 										data = data + $(this).find('#quickAddOne_email').val();
 										if(ccQuickAddOne.send(data))
@@ -47,5 +47,5 @@
 	{
 		var sdata 		= data.split(",");
-		var email		= trim(sdata[3]);
+		var email		= trim(sdata[4]);
 		var full_name	= trim(sdata[1]) + ' ' + trim(sdata[2]);
 		var _this 		= this;
@@ -102,4 +102,7 @@
 		
 		connector.newRequest('cQuickAdd.Send', CC_url+'quick_add', 'POST', handler, sdata);
+		
+		updateDynamicPersonalContacts();
+		updateDynamicContactList();
 		return true;
 	}
Index: /sandbox/2.4.1-3/expressoMail1_2/js/search.js
===================================================================
--- /sandbox/2.4.1-3/expressoMail1_2/js/search.js	(revision 6334)
+++ /sandbox/2.4.1-3/expressoMail1_2/js/search.js	(revision 6512)
@@ -64,5 +64,5 @@
 				"Search_the_messages_in_these_folders" : get_lang('Search the messages in these folders'),
 				"In_all_the_folders"		: get_lang('In all the folders'),
-				"From_value" : data
+				"From_value" : (data != "undefined" ? data : "")
 			}
 				
@@ -516,8 +516,8 @@
 				td.id = "td_message_answered_"+uid_msg;
 				if (aux.flag.match('X'))
-					td1 = '<img src=templates/'+template+'/images/forwarded.gif title="'+get_lang('Forwarded')+'">';
+					td1 = '<img src=templates/'+template+'/images/forwarded.png title="'+get_lang('Forwarded')+'">';
 				else
 					if (aux.flag.match('A'))
-						td1 = '<img src=templates/'+template+'/images/answered.gif title="'+get_lang('Answered')+'">';
+						td1 = '<img src=templates/'+template+'/images/answered.png title="'+get_lang('Answered')+'">';
 					else
 						td1 = '';
Index: /sandbox/2.4.1-3/expressoMail1_2/js/draw_api.js
===================================================================
--- /sandbox/2.4.1-3/expressoMail1_2/js/draw_api.js	(revision 6460)
+++ /sandbox/2.4.1-3/expressoMail1_2/js/draw_api.js	(revision 6512)
@@ -9,7 +9,4 @@
  */
 onceOpenedHeadersMessages = {};
-
-var dynamicPersonalContacts = new Array();
-var dynamicPersonalGroups = new Array();
 
 var openTab = {
@@ -1480,5 +1477,5 @@
 		if ((headers_msgs.Forwarded == 'F')  || (headers_msgs.Draft == 'X' && headers_msgs.Answered == 'A')){
 			td_element21.onclick=function(){search_emails(headers_msgs.subject.replace(/^(re: ?|fw: ?|enc: ?|res: ?|fwd: ?)*/gi,''),true);};
-                        td_element21.innerHTML = "<img src ='templates/"+template+"/images/forwarded.gif' title='"+get_lang('Forwarded')+"'>";
+                        td_element21.innerHTML = "<img src ='templates/"+template+"/images/forwarded.png' title='"+get_lang('Forwarded')+"'>";
 			headers_msgs.Draft = ''
 			headers_msgs.Answered = '';
@@ -1486,8 +1483,8 @@
 		}
 		else if (headers_msgs.Draft == 'X')
-			td_element21.innerHTML = "<img src ='templates/"+template+"/images/draft.gif' title='"+get_lang('Draft')+"'>";
+			td_element21.innerHTML = "<img src ='templates/"+template+"/images/draft.png' title='"+get_lang('Draft')+"'>";
 		else if (headers_msgs.Answered == 'A'){
                         td_element21.onclick=function(){search_emails(headers_msgs.subject.replace(/^(re: ?|fw: ?|enc: ?|res: ?|fwd: ?)*/gi,''),true);};
-			td_element21.innerHTML = "<img src ='templates/"+template+"/images/answered.gif' title='"+get_lang('Answered')+"'>";
+			td_element21.innerHTML = "<img src ='templates/"+template+"/images/answered.png' title='"+get_lang('Answered')+"'>";
                     }else
 			td_element21.innerHTML = "&nbsp;&nbsp;&nbsp;";
@@ -3510,5 +3507,5 @@
 			var newBox = location.before(html).prev();
 			box_actions(newBox);
-			if(preferences.expressoMail_ldap_identifier_recipient && $(newBox).hasClass("invalid-email-box")){
+			if((preferences.expressoMail_ldap_identifier_recipient || personal)&& $(newBox).hasClass("invalid-email-box")){
 				//$(newBox).find(".loading").css("background-image", "../prototype/modules/mail/img/ajax-loader.gif");
 				show_detais(newBox, input_data, personal);
@@ -3672,13 +3669,15 @@
 	//AO SAIR DO FOCO MONTAGEM DA CAIXA DE EMAIL
 	.focusout(function(){
-		if(!(f9 || $(this).parents("tr:first").find("button").hasClass("ui-state-active"))){
-			if($(input).val() != "")
-				draw_email_box(input.val(), input);
-			if(input.hasClass("box-input"))
-				input.remove();
-		}
-		
-		input_search = $(input).val();
-		$(input).val("");
+		if(!$(this).data('is_open')){
+			if(!(f9 || $(this).parents("tr:first").find("button").hasClass("ui-state-active"))){
+				if($(input).val() != "")
+					draw_email_box(input.val(), input);
+				if(input.hasClass("box-input"))
+					input.remove();
+			}
+		
+			input_search = $(input).val();
+			$(input).val("");
+		}
 	})
 	//AO COLAR UM TEXTO NO CAMPO
@@ -3793,4 +3792,34 @@
 function show_detais(box, value, personal){
 	var ldap_id = preferences.expressoMail_ldap_identifier_recipient;
+	var group = (personal != undefined ? (personal == "G" ? true : false) : false);
+	
+	if(group){
+		DataLayer.read("/group/"+value, {}, function(data){
+			if(!data.error){
+				if(data.collection.error)
+					box.find(".box-loading").remove();
+				else{
+					//box.find(".box-loading").css("background-image", "url(templates/default/images/information.png) no-repeat! !important");
+					box.find(".box-loading").removeClass("box-loading").addClass("box-info");
+					box.addClass("box-"+value).removeClass("invalid-email-box");
+					loadGroupBox(data.collection, ".box-"+value);
+					box.unbind("dblclick").bind("dblclick", function(e){
+						new $.Zebra_Dialog('<strong>Impossivel editar</strong> um contato do catálogo pessoal\n' +
+							'<strong>Porém</strong> é possivel remove-lo', {
+							'buttons':  false,
+							'modal': false,
+							'position': ['right - 20', 'top + 20'],
+							'auto_close': 3000
+						});
+					}).find(".box-input").val("\""+data.collection.data[1].value+"\" <"+data.collection.data[1].value+">");
+					box.find(".email-box-value").html( (data.collection.data[1].value.length > 18 ? data.collection.data[1].value.substring(0, 15)+"...": data.collection.data[1].value))
+				}
+			}else{
+				box.find(".box-loading").remove();
+			}
+		});
+		return;
+	}
+	
 	if(personal){
 		DataLayer.read("/contact/"+value, {}, function(data){
@@ -3892,44 +3921,27 @@
 	if(parseInt(preferences.use_dynamic_contacts)){
 		//PREPARAÇÃO DA ARRAY DOS CONTATOS DINÂMICOS
-		var dynamicContactList = new Array();
-		var groupsData = DataLayer.read("/groups").collection.itens;
-		var contactsData = DataLayer.read("/contacts").collection.itens;
-		dynamicPersonalGroups = new Array();
-		
-		$.each(groupsData, function(index, value){
-			var group = {
-				id : parseInt(value.data[0].value),
-				name : value.data[2].value,
-				email : value.data[2].value,
-				value: value.data[2].value + " - " + value.data[2].value,
-				type: "G"
-			};
-			dynamicContactList.push(group);
-			dynamicPersonalGroups.push(group);
-		});
-		
-		dynamicPersonalContacts = new Array();
-		
-		$.each(contactsData, function(index, value){
-			var contact = {
-				id : parseInt(value.data[0].value),
-				name : value.data[1].value,
-				email : value.data[2].value,
-				value: value.data[1].value + " - " + value.data[2].value,
-				type: "P"
-			};
-			dynamicContactList.push(contact);
-			dynamicPersonalGroups.push(contact);
-		});
+
 		$.widget( "custom.catcomplete", $.ui.autocomplete, {
 			_renderMenu: function( ul, items ) {
 				var self = this,
-				currentType = "G";
+				currentType = "";
 				$.each( items, function( index, item ) {
 					if ( item.type != currentType) {
-						self._renderItem( ul, {name:"", value:"", type:"linha"} );
+						if(item.type == "G" && $(ul).find(".dynamic-recent").length)
+							self._renderItem( ul, {name:"", value:"", type:"linha"} );
+						if(item.type == "P" && $(ul).find(".dynamic-group").length)
+							self._renderItem( ul, {name:"", value:"", type:"linha"} );	
 						currentType = item.type;
 					}
 					self._renderItem( ul, item );
+					$(ul).find("li:last").find(".dynamic-stars").raty({
+						readOnly : true,
+						half : true,
+						hints : ['','','','',''],
+						score    : ((parseInt(item.qtd)*5)/topContact),
+						starOn  : '../../prototype/plugins/jq-raty/img/star-on.png',
+						starOff : '../../prototype/plugins/jq-raty/img/star-off.png',
+						starHalf : '../../prototype/plugins/jq-raty/img/star-half.png'
+					});
 				});
 			}
@@ -3938,5 +3950,7 @@
 		div.find("input").catcomplete({
 			minLength: 1,			
-			source: dynamicContactList,
+			source: function(request, response){
+				response( $.ui.autocomplete.filter(dynamicContactList, request.term ) );
+			},
 			focus: function() {
 				return false;
@@ -3947,18 +3961,24 @@
 				event.preventDefault();
 				$(this).val("");
-				draw_email_box(ui.item.name ? "\""+ui.item.name+"\" <"+ui.item.email+">" : ui.item.email, $(this));
+				if(ui.item.type == "P")
+					draw_email_box(""+ui.item.id, $(this), true);
+				else if(ui.item.type == "G")
+					draw_email_box(""+ui.item.id, $(this), "G");
+				else
+					draw_email_box(ui.item.name ? "\""+ui.item.name+"\" <"+ui.item.email+">" : ui.item.email, $(this));
 				return false;
 			},
-			autoFocus: true
+			autoFocus: true,
+			position : { my: "left top", at: "left bottom", collision: "fit" }
+		}).bind('catcompleteopen', function(event, ui) {
+			$(this).data('is_open',true);
+		}).bind('catcompleteclose', function(event, ui) {
+			$(this).data('is_open',false);
 		})
 		
 		//MONTAGEM DA LISTA DE CONTATOS DINÂMICOS DO AUTO COMPLETE
 		.data( "catcomplete" )._renderItem = function( ul, item ) {
-			ul.css({"min-width":"280px", "width":"50%", "max-height" : "180px", "overflow-y" : "auto"});
-			if( $(ul).find("li").length > 10 ){
-				return;
-			}
-			var listContacts = DataLayer.render("../expressoMail1_2/templates/default/listContacts.ejs", item);
-			
+			ul.css({"min-width":"400px", "width":"50%", "max-height" : "180px", "overflow-y" : "auto"});
+			var listContacts = DataLayer.render("../prototype/modules/mail/templates/listContacts.ejs", item);
 			return $(listContacts).data( "item.autocomplete", item ).appendTo( ul ).find("span:last").button({
 					icons : {
@@ -3968,5 +3988,5 @@
 			}).click(function(){
 				var removeLi = $(this).parents("li:first");
-				$.Zebra_Dialog('Deseja remover este contato?', {
+				$.Zebra_Dialog('Deseja remover <b>'+(item.name ? item.name+" - " : "")+ item.email+'</b>?', {
 						'type':     'question',
 						'custom_class': (is_ie ? 'configure-zebra-dialog' : ''),
@@ -3975,6 +3995,10 @@
 						'overlay_opacity': '0.5',
 						'onClose':  function(caption) {
-							if(caption == 'Sim')
+							if(caption == 'Sim'){
 								$(removeLi).remove();
+								DataLayer.delete("/dynamiccontact/"+item.id);
+								updateDynamicContact();
+								updateDynamicContactList();
+							}
 						}
 				});
Index: /sandbox/2.4.1-3/expressoMail1_2/js/doiMenuData.js
===================================================================
--- /sandbox/2.4.1-3/expressoMail1_2/js/doiMenuData.js	(revision 6460)
+++ /sandbox/2.4.1-3/expressoMail1_2/js/doiMenuData.js	(revision 6512)
@@ -200,9 +200,9 @@
 	autoHide:true,
 	items: {
-		"add" : {name:"Adicao Rapida de Contato", icon : "quick-add",callback: function(key, opt){ var fname = $(opt.$trigger).find("input").val().split('"')[1];ccQuickAddOne.showList(','+fname+', ,'+$.trim($(opt.$trigger).find("input").val()).match(reComplexEmail)[1]); }},
-		"remove" : {name:"Remover este contato", icon:"delete-box",callback: function(key, opt){ $(opt.$trigger).remove(); }},
+		"add" : {name:"Adicao Rapida", icon : "quick-add",callback: function(key, opt){ var fname = $(opt.$trigger).find("input").val().split('"')[1];ccQuickAddOne.showList(','+fname+', ,'+$.trim($(opt.$trigger).find("input").val()).match(reComplexEmail)[1]); }},
+		"remove" : {name:"Remover Destinatario", icon:"delete-box",callback: function(key, opt){ $(opt.$trigger).remove(); }},
 		"sep1": "---------",
-		"quick_search" : {name:"Pesquisa Rapida de Mensagens", icon: "quick-search-contact",callback: function(key, opt){ search_emails($.trim($(opt.$trigger).find("input").val()).match(reComplexEmail)[1]); }},
-		"full_search" : {name:"Pesquisa Avancada de Mensagens", icon: "quick-search-contact",callback: function(key, opt){ search_emails("", $.trim($(opt.$trigger).find("input").val()).match(reComplexEmail)[1]);}}		
+		"quick_search" : {name:"Busca Rapida de Mensagens", icon: "quick-search-contact",callback: function(key, opt){ search_emails($.trim($(opt.$trigger).find("input").val()).match(reComplexEmail)[1]); }},
+		"full_search" : {name:"Buscar Mensagens de ...", icon: "quick-search-contact",callback: function(key, opt){ search_emails("", $.trim($(opt.$trigger).find("input").val()).match(reComplexEmail)[1]);}}		
 	}
 });
@@ -322,8 +322,34 @@
 }
 
-
-
-
-
-
-
+function loadGroupBox(data, element){
+	menuItensLabel = {};
+	menuItensLabel["ContactGroupLabelAll"] = {name:"<b>Contatos do Grupo</b>", disabled: true};
+	menuItensLabel["sep1"] = "---------";
+	if(data.itens){
+		var aux = 0;
+		for(var item in data.itens){
+			if(parseInt(item) <= 4){
+				menuItensLabel["ContactGroupLabel"+item] = {name: "<b>"+data.itens[item].data[0].value+"</b>", disabled: true};
+				menuItensLabel["ContactGroupValue"+item] = {name: data.itens[item].data[2].value, disabled: true};
+			}else{
+				aux++;
+				if(aux == 1)
+					menuItensLabel["MoreContactGroupValue"] = {name : "E mais "+aux+" contato...", disabled: true };
+				else
+					menuItensLabel["MoreContactGroupValue"] = {name : "E mais "+aux+" contatos...", disabled: true };
+			}
+		}
+	}
+	$.contextMenu({
+		selector: "#content_id_"+currentTab+" "+element+" .box-info",
+		trigger: 'hover',
+		delay:100,
+		autoHide:true,
+		items: menuItensLabel
+	});	
+}
+
+
+
+
+
Index: /sandbox/2.4.1-3/expressoMail1_2/js/QuickCatalogSearch.js
===================================================================
--- /sandbox/2.4.1-3/expressoMail1_2/js/QuickCatalogSearch.js	(revision 6422)
+++ /sandbox/2.4.1-3/expressoMail1_2/js/QuickCatalogSearch.js	(revision 6512)
@@ -598,9 +598,10 @@
 
 		final_contact = final_contact.replace(/\/n/, ""); 
-		if(data_[parseInt(divs.split("_")[1])-1].type_contact == "G"){
+		var index = parseInt(divs.split("_")[1])-1;
+		if(data_[index].type_contact == "G"){
 			var ldap_id = preferences.expressoMail_ldap_identifier_recipient;
 			if(ldap_id){
 				draw_email_box(
-					(data_[parseInt(divs.split("_")[1])-1][ldap_id.toLowerCase()] ? data_[parseInt(divs.split("_")[1])-1][ldap_id.toLowerCase()][0] : final_contact)
+					(data_[index][ldap_id.toLowerCase()] ? data_[index][ldap_id.toLowerCase()][0] : final_contact)
 					, content.find(field_).filter("input")
 				);
@@ -609,5 +610,5 @@
 			}
 		}else{
-			draw_email_box(data_[0].id_contact, content.find(field_).filter("input"), true);
+			draw_email_box((data_[index].id_contact ? data_[index].id_contact : data_[index].id), content.find(field_).filter("input"), (data_[index].id_contact ? true : "G"));
 		}
 		button.onclick = function(){
