Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBryan Berry <bryan@olenepal.org>2009-12-31 12:56:45 (GMT)
committer Bryan Berry <bryan@olenepal.org>2009-12-31 12:56:45 (GMT)
commit4f86b1c1e847c0e960aad83763b3769c86aad439 (patch)
tree5bffb6411ae7a6a37da9ffc79a9b2bbba8379c37
initial commitHEADmaster
-rwxr-xr-xassets/audio/correct.oggbin0 -> 12811 bytes
-rwxr-xr-xassets/audio/incorrect.oggbin0 -> 12683 bytes
-rwxr-xr-xassets/audio/trigger.oggbin0 -> 10771 bytes
-rwxr-xr-xassets/en/sounds/en_correct.oggbin0 -> 12811 bytes
-rwxr-xr-xassets/en/sounds/en_incorrect.oggbin0 -> 12683 bytes
-rwxr-xr-xassets/es-MX/sounds/es-MX_correct.oggbin0 -> 14432 bytes
-rwxr-xr-xassets/es-MX/sounds/es-MX_incorrect.oggbin0 -> 13705 bytes
-rwxr-xr-xassets/he/sounds/he_correct.oggbin0 -> 38612 bytes
-rwxr-xr-xassets/he/sounds/he_incorrect.oggbin0 -> 51319 bytes
-rwxr-xr-xassets/image/ball37px.pngbin0 -> 2745 bytes
-rwxr-xr-xassets/image/balloon37px.pngbin0 -> 2020 bytes
-rwxr-xr-xassets/image/banana37px.pngbin0 -> 2063 bytes
-rwxr-xr-xassets/image/chilli.pngbin0 -> 2692 bytes
-rwxr-xr-xassets/image/fish64px.pngbin0 -> 2515 bytes
-rwxr-xr-xassets/image/flower37px.pngbin0 -> 2957 bytes
-rwxr-xr-xassets/image/happyChimp_120x125.pngbin0 -> 16261 bytes
-rwxr-xr-xassets/image/happyMonkey.jpgbin0 -> 12348 bytes
-rwxr-xr-xassets/image/normalChimp_120x125.pngbin0 -> 15326 bytes
-rwxr-xr-xassets/image/plussign.pngbin0 -> 1080 bytes
-rwxr-xr-xassets/image/sadChimp_120x125.pngbin0 -> 15698 bytes
-rwxr-xr-xassets/image/scorebox.pngbin0 -> 5015 bytes
-rwxr-xr-xassets/image/sidebar.pngbin0 -> 8189 bytes
-rwxr-xr-xassets/image/yellowBox.pngbin0 -> 1524 bytes
-rwxr-xr-xassets/ne/sounds/ne_correct.oggbin0 -> 11930 bytes
-rwxr-xr-xassets/ne/sounds/ne_incorrect.oggbin0 -> 15827 bytes
-rwxr-xr-xcss/knavbar.css139
-rwxr-xr-xcss/lesson.css171
-rwxr-xr-xexercise.html95
-rwxr-xr-xindex.html83
-rwxr-xr-xindex.html~83
-rwxr-xr-xindex_knavbar.html39
-rwxr-xr-xjs/jquery-1.3.2.min.js19
-rwxr-xr-xjs/jquery.jgrowl_minimized.js4
-rw-r--r--js/jquery.svg.js1325
-rwxr-xr-xjs/jquery.svg.pack.js7
-rw-r--r--js/jquery.svgdom.js356
-rwxr-xr-xjs/jquery.svgdom.pack.js7
-rwxr-xr-xjs/karma.js1650
-rwxr-xr-xjs/lesson.js363
-rwxr-xr-xpo/en.po28
-rwxr-xr-xpo/es-MX.po29
-rwxr-xr-xpo/es.po29
-rwxr-xr-xpo/he-IL.po28
-rwxr-xr-xresources.html37
44 files changed, 4492 insertions, 0 deletions
diff --git a/assets/audio/correct.ogg b/assets/audio/correct.ogg
new file mode 100755
index 0000000..a0d9e3a
--- /dev/null
+++ b/assets/audio/correct.ogg
Binary files differ
diff --git a/assets/audio/incorrect.ogg b/assets/audio/incorrect.ogg
new file mode 100755
index 0000000..4805e55
--- /dev/null
+++ b/assets/audio/incorrect.ogg
Binary files differ
diff --git a/assets/audio/trigger.ogg b/assets/audio/trigger.ogg
new file mode 100755
index 0000000..f22512a
--- /dev/null
+++ b/assets/audio/trigger.ogg
Binary files differ
diff --git a/assets/en/sounds/en_correct.ogg b/assets/en/sounds/en_correct.ogg
new file mode 100755
index 0000000..a0d9e3a
--- /dev/null
+++ b/assets/en/sounds/en_correct.ogg
Binary files differ
diff --git a/assets/en/sounds/en_incorrect.ogg b/assets/en/sounds/en_incorrect.ogg
new file mode 100755
index 0000000..4805e55
--- /dev/null
+++ b/assets/en/sounds/en_incorrect.ogg
Binary files differ
diff --git a/assets/es-MX/sounds/es-MX_correct.ogg b/assets/es-MX/sounds/es-MX_correct.ogg
new file mode 100755
index 0000000..a54f738
--- /dev/null
+++ b/assets/es-MX/sounds/es-MX_correct.ogg
Binary files differ
diff --git a/assets/es-MX/sounds/es-MX_incorrect.ogg b/assets/es-MX/sounds/es-MX_incorrect.ogg
new file mode 100755
index 0000000..0474b93
--- /dev/null
+++ b/assets/es-MX/sounds/es-MX_incorrect.ogg
Binary files differ
diff --git a/assets/he/sounds/he_correct.ogg b/assets/he/sounds/he_correct.ogg
new file mode 100755
index 0000000..4e12c65
--- /dev/null
+++ b/assets/he/sounds/he_correct.ogg
Binary files differ
diff --git a/assets/he/sounds/he_incorrect.ogg b/assets/he/sounds/he_incorrect.ogg
new file mode 100755
index 0000000..9e314bb
--- /dev/null
+++ b/assets/he/sounds/he_incorrect.ogg
Binary files differ
diff --git a/assets/image/ball37px.png b/assets/image/ball37px.png
new file mode 100755
index 0000000..4388283
--- /dev/null
+++ b/assets/image/ball37px.png
Binary files differ
diff --git a/assets/image/balloon37px.png b/assets/image/balloon37px.png
new file mode 100755
index 0000000..8f47d6a
--- /dev/null
+++ b/assets/image/balloon37px.png
Binary files differ
diff --git a/assets/image/banana37px.png b/assets/image/banana37px.png
new file mode 100755
index 0000000..90728e6
--- /dev/null
+++ b/assets/image/banana37px.png
Binary files differ
diff --git a/assets/image/chilli.png b/assets/image/chilli.png
new file mode 100755
index 0000000..5f8b64d
--- /dev/null
+++ b/assets/image/chilli.png
Binary files differ
diff --git a/assets/image/fish64px.png b/assets/image/fish64px.png
new file mode 100755
index 0000000..a29f12c
--- /dev/null
+++ b/assets/image/fish64px.png
Binary files differ
diff --git a/assets/image/flower37px.png b/assets/image/flower37px.png
new file mode 100755
index 0000000..224e707
--- /dev/null
+++ b/assets/image/flower37px.png
Binary files differ
diff --git a/assets/image/happyChimp_120x125.png b/assets/image/happyChimp_120x125.png
new file mode 100755
index 0000000..5e721c9
--- /dev/null
+++ b/assets/image/happyChimp_120x125.png
Binary files differ
diff --git a/assets/image/happyMonkey.jpg b/assets/image/happyMonkey.jpg
new file mode 100755
index 0000000..bfe0d38
--- /dev/null
+++ b/assets/image/happyMonkey.jpg
Binary files differ
diff --git a/assets/image/normalChimp_120x125.png b/assets/image/normalChimp_120x125.png
new file mode 100755
index 0000000..a731df4
--- /dev/null
+++ b/assets/image/normalChimp_120x125.png
Binary files differ
diff --git a/assets/image/plussign.png b/assets/image/plussign.png
new file mode 100755
index 0000000..915c5aa
--- /dev/null
+++ b/assets/image/plussign.png
Binary files differ
diff --git a/assets/image/sadChimp_120x125.png b/assets/image/sadChimp_120x125.png
new file mode 100755
index 0000000..1dec5f0
--- /dev/null
+++ b/assets/image/sadChimp_120x125.png
Binary files differ
diff --git a/assets/image/scorebox.png b/assets/image/scorebox.png
new file mode 100755
index 0000000..424b60b
--- /dev/null
+++ b/assets/image/scorebox.png
Binary files differ
diff --git a/assets/image/sidebar.png b/assets/image/sidebar.png
new file mode 100755
index 0000000..9632788
--- /dev/null
+++ b/assets/image/sidebar.png
Binary files differ
diff --git a/assets/image/yellowBox.png b/assets/image/yellowBox.png
new file mode 100755
index 0000000..f7a72ca
--- /dev/null
+++ b/assets/image/yellowBox.png
Binary files differ
diff --git a/assets/ne/sounds/ne_correct.ogg b/assets/ne/sounds/ne_correct.ogg
new file mode 100755
index 0000000..8ced3cd
--- /dev/null
+++ b/assets/ne/sounds/ne_correct.ogg
Binary files differ
diff --git a/assets/ne/sounds/ne_incorrect.ogg b/assets/ne/sounds/ne_incorrect.ogg
new file mode 100755
index 0000000..106fe0f
--- /dev/null
+++ b/assets/ne/sounds/ne_incorrect.ogg
Binary files differ
diff --git a/css/knavbar.css b/css/knavbar.css
new file mode 100755
index 0000000..b39f205
--- /dev/null
+++ b/css/knavbar.css
@@ -0,0 +1,139 @@
+body
+{
+background: #D8D8D8;
+margin:0;
+padding:0;
+}
+
+#knavbar {
+display: table;
+width: 800px;
+margin: 0 auto;
+}
+
+nav
+{
+list-style: none;
+padding: 0;
+margin: 0;
+float:left;
+width:100%;
+background: #FFFFFF;
+}
+
+nav img
+{
+border: none;
+width: 58px;
+}
+
+#welcome
+{
+padding-left: 1em;
+padding-right: 1em;
+line-height: 3em;
+}
+
+#subject
+{
+text-align: center;
+font-weight: bold;
+font-size: 130%;
+}
+
+#lesson_name
+{
+text-align: center;
+font-weight: bold;
+font-size: 150%;
+padding: 0.8em;
+}
+
+#welcome_refs
+{
+text-align: center;
+font-weight: bold;
+font-size: 150%;
+width: 50%;
+float: left;
+}
+
+#tutorial_link
+{
+width: 50%;
+float: left;
+}
+
+#tutorial_link img
+{
+padding: 2em;
+
+}
+
+#exercise_link
+{
+width: 50%;
+float: left;
+}
+
+#exercise_link img
+{
+padding: 2em;
+}
+
+#lesson
+{
+width:800px;
+background: #BDBDBD;
+}
+
+#welcome_logo img
+{
+padding: 2em;
+}
+
+img
+{
+border: none;
+}
+
+#lessonTitle
+{
+display: block;
+}
+
+nav a:hover {
+text-decoration: underline;
+outline-width:1px;
+outline-style:solid;
+}
+
+nav a.selected {
+text-decoration: underline;
+background: #BDBDBD;
+}
+
+.centeredImage
+{
+text-align:center;
+margin-top:0px;
+margin-bottom:0px;
+padding:0px;
+}
+
+.icon_right
+{
+float: right;
+}
+
+.floatLeft {
+ float: left;
+ margin-left: 5px;
+ margin-bottom: 5px;
+}
+
+.floatRight {
+ float: right;
+ margin-right: 5px;
+ margin-bottom: 5px;
+} \ No newline at end of file
diff --git a/css/lesson.css b/css/lesson.css
new file mode 100755
index 0000000..e368b14
--- /dev/null
+++ b/css/lesson.css
@@ -0,0 +1,171 @@
+@charset "UTF-8";
+
+#karma-main {
+width:800px;
+height:600px;
+position:absolute;
+}
+
+#main {
+float:left;
+position:relative;
+width: 650px;
+height: 600px;
+
+}
+#side {
+background-image: url(../assets/generic/images/sidebar.png);
+background:none none repeat scroll 0 0;
+float:left;
+height:600px;
+position:relative;
+width:150px;
+}
+
+#top {
+width: 650px;
+height: 300px;
+position:relative;
+}
+
+#bottom {
+clear:both;
+float:left;
+width: 650px;
+height: 300px;
+position:relative;
+}
+#topLeftArea {
+float:left;
+width: 300px;
+height: 300px;
+position:relative;
+}
+#topMiddleArea {
+background:none none repeat scroll 0 0;
+float:left;
+width: 50px;
+height: 300px;
+position:relative;
+}
+#topRightArea {
+float:left;
+width: 300px;
+height:300px;
+position:relative;
+}
+#topLeftCard {
+background:none none repeat scroll 0 0;
+width: 200px;
+height: 200px;
+left: 75px;
+position:absolute;
+top:50px;
+}
+
+#topLeftPaper {
+background:none none repeat scroll 0 0;
+position:absolute;
+top: 50px;
+left: 75px;
+width:200px;
+height:200px;
+}
+
+#plusSign {
+display: block;
+margin-left: auto;
+margin-right: auto;
+margin-top: 150px;
+}
+#topRightCard {
+background: none none repeat scroll 0 0;
+width: 200px;
+height: 200px;
+position:absolute;
+right: 50px;
+top: 50px;
+}
+#topRightPaper {
+background:none none repeat scroll 0 0;
+position:absolute;
+left: 50px;
+right:50px;
+top:50px;
+width:200px;
+height:200px;
+}
+
+.bottom {
+background:none none repeat scroll 0 0;
+float:left;
+width: 216.5px;
+height: 300px;
+position:relative;
+}
+
+.bottomCard {
+ left:25px;
+ position:absolute;
+ width: 200px;
+ height: 200px;
+ top: 20px;
+}
+
+
+.sideItem {
+ clear:both;
+ float:left;
+ width:150px;
+ height: 200px;
+ position: relative;
+}
+
+#timer {
+position:absolute;
+width:100px;
+height:150px;
+top:10px;
+left:25px;
+}
+
+#timerPaper {
+position:absolute;
+width:100px;
+height:150px;
+top:10px;
+left:25px;
+}
+
+#scoreBox {
+position:absolute;
+width:100px;
+height:150px;
+top:10px;
+left:25px;
+z-index: 10;
+}
+
+#scoreBoxText {
+position:relative;
+top:60px;
+font: 70px Arial;
+color: #fff;
+text-align: center;
+z-index: 100;
+}
+
+
+#chimpPaper {
+position:absolute;
+top:10px;
+left:25px;
+width:120px;
+height:125px;
+}
+
+#buttons {
+position:absolute;
+top:80%;
+}
+
diff --git a/exercise.html b/exercise.html
new file mode 100755
index 0000000..97d0855
--- /dev/null
+++ b/exercise.html
@@ -0,0 +1,95 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <title>Adding up to 10 - Exercise (Alpha)</title>
+ <meta name="keywords" content="karma,javascript,html5,sugar,sugarlabs,gsoc,ole,nepal" />
+ <link type="text/css" rel="stylesheet" href="css/lesson.css" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ <link type="image/ico" rel="icon" href="../../assets/default/images/favicon.ico" />
+ <link type="text/css" rel="stylesheet" href="../../css/karma.css" />
+ <script type="text/javascript" src="../../js/raphael-min.js"></script>
+ <script type="text/javascript" src="../../js/jquery-1.3.2.min.js"></script>
+ <script type="text/javascript" src="../../js/karma.Gettext.js"></script>
+ <script type="text/javascript" src="../../js/jquery.karma.js"></script>
+ <script type="text/javascript" src="js/lesson.js"></script>
+ <link rel="stylesheet" href="css/knavbar.css" type="text/css"/>
+
+</head>
+
+<body>
+
+<section id="navigation">
+ <nav id="knavbar">
+ <a href="../../chakra/grade1mathematics.html"><img src="../../assets/default/images/back.png" alt="Back" title="Back" class="floatLeft"></a>
+ <div id="lessonTitle" class="floatLeft"><a id="welcome" href="index_knavbar.html">Adding up to 10</a></div>
+ <a href="http://olenepal.org/" target="_blank"><img src="../../assets/default/images/olenepal_logo.gif" alt="OLE Nepal logo" title="OLE Nepal Web site" class="floatRight"></a>
+ <a href="#tab_help"><img src="../../assets/default/images/help.png" alt="Help" title="Help" class="floatRight"></a>
+ <img src="../../assets/default/images/tutorial_bw.png" alt="Tutorial" title="Tutorial" class="floatRight">
+ <a href="exercise.html" class="selected"><img src="../../assets/default/images/exercise.png" alt="Exercise" title="Exercise" class="floatRight"></a>
+ </nav>
+</section>
+
+ <div id="karma-main">
+ <div id="main">
+ <div id="top">
+
+ <div id="topLeftArea">
+ <img id="topLeftCard" src="assets/generic/images/yellowBox.png" alt="" />
+ <div id="topLeftPaper" ></div>
+
+ </div>
+ <div id="topMiddleArea">
+ <img id="plusSign" src="assets/generic/images/plussign.png" alt=""/>
+ </div>
+ <div id="topRightArea">
+ <img id="topRightCard" src="assets/generic/images/yellowBox.png" alt=""/>
+ <div id="topRightPaper"></div>
+ </div>
+
+ </div>
+
+ <div id="bottom">
+ <div id="bottomLeft" class="bottom">
+ <img class="bottomCard" src="assets/generic/images/yellowBox.png" alt=""/>
+ <div id="bottomLeftPaper" class="bottomCard"> </div>
+ </div>
+ <div id="bottomMiddle" class="bottom">
+ <img class="bottomCard" src="assets/generic/images/yellowBox.png" alt=""/>
+ <div id="bottomMiddlePaper" class="bottomCard"> </div>
+ </div>
+ <div id="bottomRight" class="bottom">
+ <img class="bottomCard" src="assets/generic/images/yellowBox.png" alt=""/>
+ <div id="bottomRightPaper" class="bottomCard"> </div>
+ </div>
+
+ </div>
+
+ </div>
+ <div id="side">
+ <div class="sideItem">
+ <img id="timer" src="assets/generic/images/scorebox.png" alt=""/>
+ <div id="timerPaper"> </div>
+ </div>
+ <div class="sideItem">
+ <img id="scoreBox" src="assets/generic/images/scorebox.png" alt=""/>
+ <div id="scoreBoxText"></div>
+ </div>
+ <div class="sideItem">
+ <div id="chimpPaper"> </div>
+ <div id="buttons">
+ <button id="start">Start</button>
+ <button id="stop">Stop</button>
+ <button id="reset">Restart</button>
+ </div>
+ </div>
+
+
+ </div>
+ <div id="overlay"></div>
+ <div id="overlayPaper"></div>
+ </div>
+</div>
+
+</body>
+
+</html>
diff --git a/index.html b/index.html
new file mode 100755
index 0000000..3b5b479
--- /dev/null
+++ b/index.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <title>Karma - Adding Up to 10</title>
+ <meta name="keywords" content="karma,javascript,html5,sugar,sugarlabs,gsoc,ole,nepal" />
+ <link type="text/css" rel="stylesheet" href="css/lesson.css" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ <link type="image/ico" rel="icon" href="../../assets/default/image/favicon.ico" />
+ <link type="text/css" rel="stylesheet" href="../../css/karma.css" />
+ <script type="text/javascript" src="./js/raphael-min.js"></script>
+ <script type="text/javascript" src="./js/jquery-1.3.2.min.js"></script>
+ <script type="text/javascript" src="./js/karma.js"></script>
+ <script type="text/javascript" src="js/lesson.js"></script>
+
+
+
+</head>
+
+<body>
+ <div>
+ <div id="main">
+ <div id="top">
+
+ <div id="topLeftArea">
+ <img id="topLeftCard" src="assets/image/yellowBox.png" alt="" />
+ <div id="topLeftPaper" ></div>
+
+ </div>
+ <div id="topMiddleArea">
+ <img id="plusSign" src="assets/image/plussign.png" alt=""/>
+ </div>
+ <div id="topRightArea">
+ <img id="topRightCard" src="assets/image/yellowBox.png" alt=""/>
+ <div id="topRightPaper"></div>
+ </div>
+
+ </div>
+
+ <div id="bottom">
+ <div id="bottomLeft" class="bottom">
+ <img class="bottomCard" src="assets/image/yellowBox.png" alt=""/>
+ <div id="bottomLeftPaper" class="bottomCard"> </div>
+ </div>
+ <div id="bottomMiddle" class="bottom">
+ <img class="bottomCard" src="assets/image/yellowBox.png" alt=""/>
+ <div id="bottomMiddlePaper" class="bottomCard"> </div>
+ </div>
+ <div id="bottomRight" class="bottom">
+ <img class="bottomCard" src="assets/image/yellowBox.png" alt=""/>
+ <div id="bottomRightPaper" class="bottomCard"> </div>
+ </div>
+
+ </div>
+
+ </div>
+ <div id="side">
+ <div class="sideItem">
+ <img id="timer" src="assets/image/scorebox.png" alt=""/>
+ <div id="timerPaper"> </div>
+ </div>
+ <div class="sideItem">
+ <img id="scoreBox" src="assets/image/scorebox.png" alt=""/>
+ <div id="scoreBoxText"></div>
+ </div>
+ <div class="sideItem">
+ <div id="chimpPaper"> </div>
+ <div id="buttons">
+ <button id="start">Start</button>
+ <button id="stop">Stop</button>
+ <button id="reset">Restart</button>
+ </div>
+ </div>
+
+
+ </div>
+ <div id="overlay"></div>
+ <div id="overlayPaper"></div>
+ </div>
+
+
+</body>
+
+</html>
diff --git a/index.html~ b/index.html~
new file mode 100755
index 0000000..7ecbfa3
--- /dev/null
+++ b/index.html~
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <title>Karma - Adding Up to 10</title>
+ <meta name="keywords" content="karma,javascript,html5,sugar,sugarlabs,gsoc,ole,nepal" />
+ <link type="text/css" rel="stylesheet" href="css/lesson.css" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ <link type="image/ico" rel="icon" href="../../assets/default/image/favicon.ico" />
+ <link type="text/css" rel="stylesheet" href="../../css/karma.css" />
+ <script type="text/javascript" src="../../js/raphael-min.js"></script>
+ <script type="text/javascript" src="../../js/jquery-1.3.2.min.js"></script>
+ <script type="text/javascript" src="../../js/karma.js"></script>
+ <script type="text/javascript" src="js/lesson.js"></script>
+
+
+
+</head>
+
+<body>
+ <div>
+ <div id="main">
+ <div id="top">
+
+ <div id="topLeftArea">
+ <img id="topLeftCard" src="assets/image/yellowBox.png" alt="" />
+ <div id="topLeftPaper" ></div>
+
+ </div>
+ <div id="topMiddleArea">
+ <img id="plusSign" src="assets/image/plussign.png" alt=""/>
+ </div>
+ <div id="topRightArea">
+ <img id="topRightCard" src="assets/image/yellowBox.png" alt=""/>
+ <div id="topRightPaper"></div>
+ </div>
+
+ </div>
+
+ <div id="bottom">
+ <div id="bottomLeft" class="bottom">
+ <img class="bottomCard" src="assets/image/yellowBox.png" alt=""/>
+ <div id="bottomLeftPaper" class="bottomCard"> </div>
+ </div>
+ <div id="bottomMiddle" class="bottom">
+ <img class="bottomCard" src="assets/image/yellowBox.png" alt=""/>
+ <div id="bottomMiddlePaper" class="bottomCard"> </div>
+ </div>
+ <div id="bottomRight" class="bottom">
+ <img class="bottomCard" src="assets/image/yellowBox.png" alt=""/>
+ <div id="bottomRightPaper" class="bottomCard"> </div>
+ </div>
+
+ </div>
+
+ </div>
+ <div id="side">
+ <div class="sideItem">
+ <img id="timer" src="assets/image/scorebox.png" alt=""/>
+ <div id="timerPaper"> </div>
+ </div>
+ <div class="sideItem">
+ <img id="scoreBox" src="assets/image/scorebox.png" alt=""/>
+ <div id="scoreBoxText"></div>
+ </div>
+ <div class="sideItem">
+ <div id="chimpPaper"> </div>
+ <div id="buttons">
+ <button id="start">Start</button>
+ <button id="stop">Stop</button>
+ <button id="reset">Restart</button>
+ </div>
+ </div>
+
+
+ </div>
+ <div id="overlay"></div>
+ <div id="overlayPaper"></div>
+ </div>
+
+
+</body>
+
+</html>
diff --git a/index_knavbar.html b/index_knavbar.html
new file mode 100755
index 0000000..6bd5e7a
--- /dev/null
+++ b/index_knavbar.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<html lang="en">
+
+<head>
+<title>Adding up to 10 - Index (Alpha)</title>
+<meta name="keywords" content="karma,javascript,html5,sugar,sugarlabs,gsoc,ole,nepal">
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<meta charset="utf-8">
+
+<link rel="stylesheet" href="css/knavbar.css" type="text/css"/>
+
+<script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
+<script type="text/javascript" src="js/jquery.ui.all.js"></script>
+
+</head>
+
+<body>
+
+<div id="lesson">
+
+<nav>
+<a href="../../chakra/grade1mathematics.html"><img src="../../assets/default/images/back.png" alt="Back" title="Back" class="floatLeft"></a>
+<div id="lessonTitle" class="floatLeft"><a id="welcome" href="index_knavbar.html" class="selected">Adding up to 10</a></div>
+</nav>
+
+<div id="subject">Mathematics</div>
+<div id="lesson_name">Adding up to 10</div>
+
+<div id="tutorial_link" class="centeredImage"><img src="../../assets/default/images/tutorial_bw.png" alt="Tutorial" title="Tutorial"></div>
+<div id="exercise_link" class="centeredImage"><a href="exercise.html"><img src="../../assets/default/images/exercise.png" alt="Exercise" title="Exercise"></a></div>
+
+<div id="welcome_refs"><a href="assets/en/docs/teachernotes.swf" target="_blank">Teacher's note</a></div>
+<div id="welcome_refs"><a href="assets/en/docs/lessonplan.swf" target="_blank">Lesson plan</a></div>
+
+<div id="welcome_logo" class="centeredImage"><img src="../../assets/default/images/olenepal_logo.gif" alt="OLE Nepal logo" title="OLE Nepal"></div>
+</div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/js/jquery-1.3.2.min.js b/js/jquery-1.3.2.min.js
new file mode 100755
index 0000000..b1ae21d
--- /dev/null
+++ b/js/jquery-1.3.2.min.js
@@ -0,0 +1,19 @@
+/*
+ * jQuery JavaScript Library v1.3.2
+ * http://jquery.com/
+ *
+ * Copyright (c) 2009 John Resig
+ * Dual licensed under the MIT and GPL licenses.
+ * http://docs.jquery.com/License
+ *
+ * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
+ * Revision: 6246
+ */
+(function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},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(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F<J;F++){var G=M[F];if(G.selected){K=o(G).val();if(H){return K}L.push(K)}}return L}return(E.value||"").replace(/\r/g,"")}return g}if(typeof K==="number"){K+=""}return this.each(function(){if(this.nodeType!=1){return}if(o.isArray(K)&&/radio|checkbox/.test(this.type)){this.checked=(o.inArray(this.value,K)>=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G<E;G++){L.call(K(this[G],H),this.length>1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H<I;H++){if((G=arguments[H])!=null){for(var F in G){var K=J[F],L=G[F];if(J===L){continue}if(E&&L&&typeof L==="object"&&!L.nodeType){J[F]=o.extend(E,K||(L.length!=null?[]:{}),L)}else{if(L!==g){J[F]=L}}}}}return J};var b=/z-?index|font-?weight|opacity|zoom|line-?height/i,q=document.defaultView||{},s=Object.prototype.toString;o.extend({noConflict:function(E){l.$=p;if(E){l.jQuery=y}return o},isFunction:function(E){return s.call(E)==="[object Function]"},isArray:function(E){return s.call(E)==="[object Array]"},isXMLDoc:function(E){return E.nodeType===9&&E.documentElement.nodeName!=="HTML"||!!E.ownerDocument&&o.isXMLDoc(E.ownerDocument)},globalEval:function(G){if(G&&/\S/.test(G)){var F=document.getElementsByTagName("head")[0]||document.documentElement,E=document.createElement("script");E.type="text/javascript";if(o.support.scriptEval){E.appendChild(document.createTextNode(G))}else{E.text=G}F.insertBefore(E,F.firstChild);F.removeChild(E)}},nodeName:function(F,E){return F.nodeName&&F.nodeName.toUpperCase()==E.toUpperCase()},each:function(G,K,F){var E,H=0,I=G.length;if(F){if(I===g){for(E in G){if(K.apply(G[E],F)===false){break}}}else{for(;H<I;){if(K.apply(G[H++],F)===false){break}}}}else{if(I===g){for(E in G){if(K.call(G[E],E,G[E])===false){break}}}else{for(var J=G[0];H<I&&K.call(J,H,J)!==false;J=G[++H]){}}}return G},prop:function(H,I,G,F,E){if(o.isFunction(I)){I=I.call(H,F)}return typeof I==="number"&&G=="curCSS"&&!b.test(E)?I+"px":I},className:{add:function(E,F){o.each((F||"").split(/\s+/),function(G,H){if(E.nodeType==1&&!o.className.has(E.className,H)){E.className+=(E.className?" ":"")+H}})},remove:function(E,F){if(E.nodeType==1){E.className=F!==g?o.grep(E.className.split(/\s+/),function(G){return !o.className.has(F,G)}).join(" "):""}},has:function(F,E){return F&&o.inArray(E,(F.className||F).toString().split(/\s+/))>-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+"></"+T+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!O.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!O.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!O.indexOf("<td")||!O.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!O.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||!o.support.htmlSerialize&&[1,"div<div>","</div>"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/<tbody/i.test(S),N=!O.indexOf("<table")&&!R?L.firstChild&&L.firstChild.childNodes:Q[1]=="<table>"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E<F;E++){if(H[E]===G){return E}}return -1},merge:function(H,E){var F=0,G,I=H.length;if(!o.support.getAll){while((G=E[F++])!=null){if(G.nodeType!=8){H[I++]=G}}}else{while((G=E[F++])!=null){H[I++]=G}}return H},unique:function(K){var F=[],E={};try{for(var G=0,H=K.length;G<H;G++){var J=o.data(K[G]);if(!E[J]){E[J]=true;F.push(K[G])}}}catch(I){F=K}return F},grep:function(F,J,E){var G=[];for(var H=0,I=F.length;H<I;H++){if(!E!=!J(F[H],H)){G.push(F[H])}}return G},map:function(E,J){var F=[];for(var G=0,H=E.length;G<H;G++){var I=J(E[G],G);if(I!=null){F[F.length]=I}}return F.concat.apply([],F)}});var C=navigator.userAgent.toLowerCase();o.browser={version:(C.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[0,"0"])[1],safari:/webkit/.test(C),opera:/opera/.test(C),msie:/msie/.test(C)&&!/opera/.test(C),mozilla:/mozilla/.test(C)&&!/(compatible|webkit)/.test(C)};o.each({parent:function(E){return E.parentNode},parents:function(E){return o.dir(E,"parentNode")},next:function(E){return o.nth(E,2,"nextSibling")},prev:function(E){return o.nth(E,2,"previousSibling")},nextAll:function(E){return o.dir(E,"nextSibling")},prevAll:function(E){return o.dir(E,"previousSibling")},siblings:function(E){return o.sibling(E.parentNode.firstChild,E)},children:function(E){return o.sibling(E.firstChild)},contents:function(E){return o.nodeName(E,"iframe")?E.contentDocument||E.contentWindow.document:o.makeArray(E.childNodes)}},function(E,F){o.fn[E]=function(G){var H=o.map(this,F);if(G&&typeof G=="string"){H=o.multiFilter(G,H)}return this.pushStack(o.unique(H),E,G)}});o.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(E,F){o.fn[E]=function(G){var J=[],L=o(G);for(var K=0,H=L.length;K<H;K++){var I=(K>0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}});
+/*
+ * Sizzle CSS Selector Engine - v0.9.3
+ * Copyright 2009, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+(function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa<ab.length;aa++){if(ab[aa]===ab[aa-1]){ab.splice(aa--,1)}}}}}return ab};F.matches=function(T,U){return F(T,null,null,U)};F.find=function(aa,T,ab){var Z,X;if(!aa){return[]}for(var W=0,V=I.order.length;W<V;W++){var Y=I.order[W],X;if((X=I.match[Y].exec(aa))){var U=RegExp.leftContext;if(U.substr(U.length-1)!=="\\"){X[1]=(X[1]||"").replace(/\\/g,"");Z=I.find[Y](X,T,ab);if(Z!=null){aa=aa.replace(I.match[Y],"");break}}}}if(!Z){Z=T.getElementsByTagName("*")}return{set:Z,expr:aa}};F.filter=function(ad,ac,ag,W){var V=ad,ai=[],aa=ac,Y,T,Z=ac&&ac[0]&&Q(ac[0]);while(ad&&ac.length){for(var ab in I.filter){if((Y=I.match[ab].exec(ad))!=null){var U=I.filter[ab],ah,af;T=false;if(aa==ai){ai=[]}if(I.preFilter[ab]){Y=I.preFilter[ab](Y,aa,ag,ai,W,Z);if(!Y){T=ah=true}else{if(Y===true){continue}}}if(Y){for(var X=0;(af=aa[X])!=null;X++){if(af){ah=U(af,Y,X,aa);var ae=W^!!ah;if(ag&&ah!=null){if(ae){T=true}else{aa[X]=false}}else{if(ae){ai.push(af);T=true}}}}}if(ah!==g){if(!ag){aa=ai}ad=ad.replace(I.match[ab],"");if(!T){return[]}break}}}if(ad==V){if(T==null){throw"Syntax error, unrecognized expression: "+ad}else{break}}V=ad}return aa};var I=F.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|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(T){return T.getAttribute("href")}},relative:{"+":function(aa,T,Z){var X=typeof T==="string",ab=X&&!/\W/.test(T),Y=X&&!ab;if(ab&&!Z){T=T.toUpperCase()}for(var W=0,V=aa.length,U;W<V;W++){if((U=aa[W])){while((U=U.previousSibling)&&U.nodeType!==1){}aa[W]=Y||U&&U.nodeName===T?U||false:U===T}}if(Y){F.filter(T,aa,true)}},">":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){var W=Y.parentNode;Z[V]=W.nodeName===U?W:false}}}else{for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){Z[V]=X?Y.parentNode:Y.parentNode===U}}if(X){F.filter(U,Z,true)}}},"":function(W,U,Y){var V=L++,T=S;if(!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("parentNode",U,V,W,X,Y)},"~":function(W,U,Y){var V=L++,T=S;if(typeof U==="string"&&!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("previousSibling",U,V,W,X,Y)}},find:{ID:function(U,V,W){if(typeof V.getElementById!=="undefined"&&!W){var T=V.getElementById(U[1]);return T?[T]:[]}},NAME:function(V,Y,Z){if(typeof Y.getElementsByName!=="undefined"){var U=[],X=Y.getElementsByName(V[1]);for(var W=0,T=X.length;W<T;W++){if(X[W].getAttribute("name")===V[1]){U.push(X[W])}}return U.length===0?null:U}},TAG:function(T,U){return U.getElementsByTagName(T[1])}},preFilter:{CLASS:function(W,U,V,T,Z,aa){W=" "+W[1].replace(/\\/g,"")+" ";if(aa){return W}for(var X=0,Y;(Y=U[X])!=null;X++){if(Y){if(Z^(Y.className&&(" "+Y.className+" ").indexOf(W)>=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return U<T[3]-0},gt:function(V,U,T){return U>T[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W<T;W++){if(Y[W]===Z){return false}}return true}}}},CHILD:function(T,W){var Z=W[1],U=T;switch(Z){case"only":case"first":while(U=U.previousSibling){if(U.nodeType===1){return false}}if(Z=="first"){return true}U=T;case"last":while(U=U.nextSibling){if(U.nodeType===1){return false}}return true;case"nth":var V=W[2],ac=W[3];if(V==1&&ac==0){return true}var Y=W[0],ab=T.parentNode;if(ab&&(ab.sizcache!==Y||!T.nodeIndex)){var X=0;for(U=ab.firstChild;U;U=U.nextSibling){if(U.nodeType===1){U.nodeIndex=++X}}ab.sizcache=Y}var aa=T.nodeIndex-ac;if(V==0){return aa==0}else{return(aa%V==0&&aa/V>=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V<T;V++){U.push(X[V])}}else{for(var V=0;X[V];V++){U.push(X[V])}}}return U}}var G;if(document.documentElement.compareDocumentPosition){G=function(U,T){var V=U.compareDocumentPosition(T)&4?-1:U===T?0:1;if(V===0){hasDuplicate=true}return V}}else{if("sourceIndex" in document.documentElement){G=function(U,T){var V=U.sourceIndex-T.sourceIndex;if(V===0){hasDuplicate=true}return V}}else{if(document.createRange){G=function(W,U){var V=W.ownerDocument.createRange(),T=U.ownerDocument.createRange();V.selectNode(W);V.collapse(true);T.selectNode(U);T.collapse(true);var X=V.compareBoundaryPoints(Range.START_TO_END,T);if(X===0){hasDuplicate=true}return X}}}}(function(){var U=document.createElement("form"),V="script"+(new Date).getTime();U.innerHTML="<input name='"+V+"'/>";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="<a href='#'></a>";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="<p class='TEST'></p>";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="<div class='test e'></div><div class='test'></div>";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1&&!ac){T.sizcache=Y;T.sizset=W}if(T.nodeName===Z){X=T;break}T=T[U]}ad[W]=X}}}function S(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1){if(!ac){T.sizcache=Y;T.sizset=W}if(typeof Z!=="string"){if(T===Z){X=true;break}}else{if(F.filter(Z,[T]).length>0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z<U;Z++){F(T,V[Z],W)}return F.filter(X,W)};o.find=F;o.filter=F.filter;o.expr=F.selectors;o.expr[":"]=o.expr.filters;F.selectors.filters.hidden=function(T){return T.offsetWidth===0||T.offsetHeight===0};F.selectors.filters.visible=function(T){return T.offsetWidth>0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F<E.length){o.event.proxy(G,E[F++])}return this.click(o.event.proxy(G,function(H){this.lastToggle=(this.lastToggle||0)%F;H.preventDefault();return E[this.lastToggle++].apply(this,arguments)||false}))},hover:function(E,F){return this.mouseenter(E).mouseleave(F)},ready:function(E){B();if(o.isReady){E.call(document,o)}else{o.readyList.push(E)}return this},live:function(G,F){var E=o.event.proxy(F);E.guid+=this.selector+G;o(document).bind(i(G,this.selector),this.selector,E);return this},die:function(F,E){o(document).unbind(i(F,this.selector),E?{guid:E.guid+this.selector+F}:null);return this}});function c(H){var E=RegExp("(^|\\.)"+H.type+"(\\.|$)"),G=true,F=[];o.each(o.data(this,"events").live||[],function(I,J){if(E.test(J.type)){var K=o(H.target).closest(J.data)[0];if(K){F.push({elem:K,fn:J})}}});F.sort(function(J,I){return o.data(J.elem,"closest")-o.data(I.elem,"closest")});o.each(F,function(){if(this.fn.call(this.elem,H,this.fn.data)===false){return(G=false)}});return G}function i(F,E){return["live",F,E.replace(/\./g,"`").replace(/ /g,"|")].join(".")}o.extend({isReady:false,readyList:[],ready:function(){if(!o.isReady){o.isReady=true;if(o.readyList){o.each(o.readyList,function(){this.call(document,o)});o.readyList=null}o(document).triggerHandler("ready")}}});var x=false;function B(){if(x){return}x=true;if(document.addEventListener){document.addEventListener("DOMContentLoaded",function(){document.removeEventListener("DOMContentLoaded",arguments.callee,false);o.ready()},false)}else{if(document.attachEvent){document.attachEvent("onreadystatechange",function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",arguments.callee);o.ready()}});if(document.documentElement.doScroll&&l==l.top){(function(){if(o.isReady){return}try{document.documentElement.doScroll("left")}catch(E){setTimeout(arguments.callee,0);return}o.ready()})()}}}o.event.add(l,"load",o.ready)}o.each(("blur,focus,load,resize,scroll,unload,click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,change,select,submit,keydown,keypress,keyup,error").split(","),function(F,E){o.fn[E]=function(G){return G?this.bind(E,G):this.trigger(E)}});o(l).bind("unload",function(){for(var E in o.cache){if(E!=1&&o.cache[E].handle){o.event.remove(o.cache[E].handle.elem)}}});(function(){o.support={};var F=document.documentElement,G=document.createElement("script"),K=document.createElement("div"),J="script"+(new Date).getTime();K.style.display="none";K.innerHTML=' <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';var H=K.getElementsByTagName("*"),E=K.getElementsByTagName("a")[0];if(!H||!H.length||!E){return}o.support={leadingWhitespace:K.firstChild.nodeType==3,tbody:!K.getElementsByTagName("tbody").length,objectAll:!!K.getElementsByTagName("object")[0].getElementsByTagName("*").length,htmlSerialize:!!K.getElementsByTagName("link").length,style:/red/.test(E.getAttribute("style")),hrefNormalized:E.getAttribute("href")==="/a",opacity:E.style.opacity==="0.5",cssFloat:!!E.style.cssFloat,scriptEval:false,noCloneEvent:true,boxModel:null};G.type="text/javascript";try{G.appendChild(document.createTextNode("window."+J+"=1;"))}catch(I){}F.insertBefore(G,F.firstChild);if(l[J]){o.support.scriptEval=true;delete l[J]}F.removeChild(G);if(K.attachEvent&&K.fireEvent){K.attachEvent("onclick",function(){o.support.noCloneEvent=false;K.detachEvent("onclick",arguments.callee)});K.cloneNode(true).fireEvent("onclick")}o(function(){var L=document.createElement("div");L.style.width=L.style.paddingLeft="1px";document.body.appendChild(L);o.boxModel=o.support.boxModel=L.offsetWidth===2;document.body.removeChild(L).style.display="none"})})();var w=o.support.cssFloat?"cssFloat":"styleFloat";o.props={"for":"htmlFor","class":"className","float":w,cssFloat:w,styleFloat:w,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",tabindex:"tabIndex"};o.fn.extend({_load:o.fn.load,load:function(G,J,K){if(typeof G!=="string"){return this._load(G)}var I=G.indexOf(" ");if(I>=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("<div/>").append(M.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H<F;H++){var E=o.data(this[H],"olddisplay");this[H].style.display=E||"";if(o.css(this[H],"display")==="none"){var G=this[H].tagName,K;if(m[G]){K=m[G]}else{var I=o("<"+G+" />").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H<F;H++){this[H].style.display=o.data(this[H],"olddisplay")||""}return this}},hide:function(H,I){if(H){return this.animate(t("hide",3),H,I)}else{for(var G=0,F=this.length;G<F;G++){var E=o.data(this[G],"olddisplay");if(!E&&E!=="none"){o.data(this[G],"olddisplay",o.css(this[G],"display"))}}for(var G=0,F=this.length;G<F;G++){this[G].style.display="none"}return this}},_toggle:o.fn.toggle,toggle:function(G,F){var E=typeof G==="boolean";return o.isFunction(G)&&o.isFunction(F)?this._toggle.apply(this,arguments):G==null||E?this.each(function(){var H=E?G:o(this).is(":hidden");o(this)[H?"show":"hide"]()}):this.animate(t("toggle",3),G,F)},fadeTo:function(E,G,F){return this.animate({opacity:G},E,F)},animate:function(I,F,H,G){var E=o.speed(F,H,G);return this[E.queue===false?"each":"queue"](function(){var K=o.extend({},E),M,L=this.nodeType==1&&o(this).is(":hidden"),J=this;for(M in I){if(I[M]=="hide"&&L||I[M]=="show"&&!L){return K.complete.call(this)}if((M=="height"||M=="width")&&this.style){K.display=o.css(this,"display");K.overflow=this.style.overflow}}if(K.overflow!=null){this.style.overflow="hidden"}K.curAnim=o.extend({},I);o.each(I,function(O,S){var R=new o.fx(J,K,O);if(/toggle|show|hide/.test(S)){R[S=="toggle"?L?"show":"hide":S](I)}else{var Q=S.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),T=R.cur(true)||0;if(Q){var N=parseFloat(Q[2]),P=Q[3]||"px";if(P!="px"){J.style[O]=(N||1)+P;T=((N||1)/R.cur(true))*T;J.style[O]=T+P}if(Q[1]){N=((Q[1]=="-="?-1:1)*N)+T}R.custom(T,N,P)}else{R.custom(T,S,"")}}});return true})},stop:function(F,E){var G=o.timers;if(F){this.queue([])}this.each(function(){for(var H=G.length-1;H>=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J<K.length;J++){if(!K[J]()){K.splice(J--,1)}}if(!K.length){clearInterval(n);n=g}},13)}},show:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.show=true;this.custom(this.prop=="width"||this.prop=="height"?1:0,this.cur());o(this.elem).show()},hide:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(H){var G=e();if(H||G>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"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}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})(); \ No newline at end of file
diff --git a/js/jquery.jgrowl_minimized.js b/js/jquery.jgrowl_minimized.js
new file mode 100755
index 0000000..09ddc88
--- /dev/null
+++ b/js/jquery.jgrowl_minimized.js
@@ -0,0 +1,4 @@
+
+(function($){$.jGrowl=function(m,o){if($('#jGrowl').size()==0)$('<div id="jGrowl"></div>').addClass($.jGrowl.defaults.position).appendTo('body');$('#jGrowl').jGrowl(m,o);};$.fn.jGrowl=function(m,o){if($.isFunction(this.each)){var args=arguments;return this.each(function(){var self=this;if($(this).data('jGrowl.instance')==undefined){$(this).data('jGrowl.instance',new $.fn.jGrowl());$(this).data('jGrowl.instance').startup(this);}
+if($.isFunction($(this).data('jGrowl.instance')[m])){$(this).data('jGrowl.instance')[m].apply($(this).data('jGrowl.instance'),$.makeArray(args).slice(1));}else{$(this).data('jGrowl.instance').create(m,o);}});};};$.extend($.fn.jGrowl.prototype,{defaults:{pool:0,header:'',group:'',sticky:false,position:'top-right',glue:'after',theme:'default',corners:'10px',check:250,life:3000,speed:'normal',easing:'swing',closer:true,closeTemplate:'&times;',closerTemplate:'<div>[ close all ]</div>',log:function(e,m,o){},beforeOpen:function(e,m,o){},open:function(e,m,o){},beforeClose:function(e,m,o){},close:function(e,m,o){},animateOpen:{opacity:'show'},animateClose:{opacity:'hide'}},notifications:[],element:null,interval:null,create:function(message,o){var o=$.extend({},this.defaults,o);this.notifications[this.notifications.length]={message:message,options:o};o.log.apply(this.element,[this.element,message,o]);},render:function(notification){var self=this;var message=notification.message;var o=notification.options;var notification=$('<div class="jGrowl-notification'+((o.group!=undefined&&o.group!='')?' '+o.group:'')+'"><div class="close">'+o.closeTemplate+'</div><div class="header">'+o.header+'</div><div class="message">'+message+'</div></div>').data("jGrowl",o).addClass(o.theme).children('div.close').bind("click.jGrowl",function(){$(this).parent().trigger('jGrowl.close');}).parent();(o.glue=='after')?$('div.jGrowl-notification:last',this.element).after(notification):$('div.jGrowl-notification:first',this.element).before(notification);$(notification).bind("mouseover.jGrowl",function(){$(this).data("jGrowl").pause=true;}).bind("mouseout.jGrowl",function(){$(this).data("jGrowl").pause=false;}).bind('jGrowl.beforeOpen',function(){o.beforeOpen.apply(self.element,[self.element,message,o]);}).bind('jGrowl.open',function(){o.open.apply(self.element,[self.element,message,o]);}).bind('jGrowl.beforeClose',function(){o.beforeClose.apply(self.element,[self.element,message,o]);}).bind('jGrowl.close',function(){$(this).trigger('jGrowl.beforeClose').animate(o.animateClose,o.speed,o.easing,function(){$(this).remove();o.close.apply(self.element,[self.element,message,o]);});}).trigger('jGrowl.beforeOpen').animate(o.animateOpen,o.speed,o.easing,function(){$(this).data("jGrowl").created=new Date();}).trigger('jGrowl.open');if($.fn.corner!=undefined)$(notification).corner(o.corners);if($('div.jGrowl-notification:parent',this.element).size()>1&&$('div.jGrowl-closer',this.element).size()==0&&this.defaults.closer!=false){$(this.defaults.closerTemplate).addClass('jGrowl-closer').addClass(this.defaults.theme).appendTo(this.element).animate(this.defaults.animateOpen,this.defaults.speed,this.defaults.easing).bind("click.jGrowl",function(){$(this).siblings().children('div.close').trigger("click.jGrowl");if($.isFunction(self.defaults.closer))self.defaults.closer.apply($(this).parent()[0],[$(this).parent()[0]]);});};},update:function(){$(this.element).find('div.jGrowl-notification:parent').each(function(){if($(this).data("jGrowl")!=undefined&&$(this).data("jGrowl").created!=undefined&&($(this).data("jGrowl").created.getTime()+$(this).data("jGrowl").life)<(new Date()).getTime()&&$(this).data("jGrowl").sticky!=true&&($(this).data("jGrowl").pause==undefined||$(this).data("jGrowl").pause!=true)){$(this).trigger('jGrowl.close');}});if(this.notifications.length>0&&(this.defaults.pool==0||$(this.element).find('div.jGrowl-notification:parent').size()<this.defaults.pool)){this.render(this.notifications.shift());}
+if($(this.element).find('div.jGrowl-notification:parent').size()<2){$(this.element).find('div.jGrowl-closer').animate(this.defaults.animateClose,this.defaults.speed,this.defaults.easing,function(){$(this).remove();});};},startup:function(e){this.element=$(e).addClass('jGrowl').append('<div class="jGrowl-notification"></div>');this.interval=setInterval(function(){jQuery(e).data('jGrowl.instance').update();},this.defaults.check);if($.browser.msie&&parseInt($.browser.version)<7&&!window["XMLHttpRequest"])$(this.element).addClass('ie6');},shutdown:function(){$(this.element).removeClass('jGrowl').find('div.jGrowl-notification').remove();clearInterval(this.interval);}});$.jGrowl.defaults=$.fn.jGrowl.prototype.defaults;})(jQuery); \ No newline at end of file
diff --git a/js/jquery.svg.js b/js/jquery.svg.js
new file mode 100644
index 0000000..3d13d94
--- /dev/null
+++ b/js/jquery.svg.js
@@ -0,0 +1,1325 @@
+/* http://keith-wood.name/svg.html
+ SVG for jQuery v1.4.2.
+ Written by Keith Wood (kbwood{at}iinet.com.au) August 2007.
+ Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+ MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+ Please attribute the author if you use it. */
+
+(function($) { // Hide scope, no $ conflict
+
+/* SVG manager.
+ Use the singleton instance of this class, $.svg,
+ to interact with the SVG functionality. */
+function SVGManager() {
+ this._settings = []; // Settings to be remembered per SVG object
+ this._extensions = []; // List of SVG extensions added to SVGWrapper
+ // for each entry [0] is extension name, [1] is extension class (function)
+ // the function takes one parameter - the SVGWrapper instance
+ this.regional = []; // Localisations, indexed by language, '' for default (English)
+ this.regional[''] = {errorLoadingText: 'Error loading',
+ notSupportedText: 'This browser does not support SVG'};
+ this.local = this.regional['']; // Current localisation
+ this._uuid = new Date().getTime();
+ this._renesis = detectActiveX('RenesisX.RenesisCtrl');
+}
+
+/* Determine whether a given ActiveX control is available.
+ @param classId (string) the ID for the ActiveX control
+ @return (boolean) true if found, false if not */
+function detectActiveX(classId) {
+ try {
+ return !!(window.ActiveXObject && new ActiveXObject(classId));
+ }
+ catch (e) {
+ return false;
+ }
+}
+
+var PROP_NAME = 'svgwrapper';
+
+$.extend(SVGManager.prototype, {
+ /* Class name added to elements to indicate already configured with SVG. */
+ markerClassName: 'hasSVG',
+
+ /* SVG namespace. */
+ svgNS: 'http://www.w3.org/2000/svg',
+ /* XLink namespace. */
+ xlinkNS: 'http://www.w3.org/1999/xlink',
+
+ /* SVG wrapper class. */
+ _wrapperClass: SVGWrapper,
+
+ /* Camel-case versions of attribute names containing dashes or are reserved words. */
+ _attrNames: {class_: 'class', in_: 'in',
+ alignmentBaseline: 'alignment-baseline', baselineShift: 'baseline-shift',
+ clipPath: 'clip-path', clipRule: 'clip-rule',
+ colorInterpolation: 'color-interpolation',
+ colorInterpolationFilters: 'color-interpolation-filters',
+ colorRendering: 'color-rendering', dominantBaseline: 'dominant-baseline',
+ enableBackground: 'enable-background', fillOpacity: 'fill-opacity',
+ fillRule: 'fill-rule', floodColor: 'flood-color',
+ floodOpacity: 'flood-opacity', fontFamily: 'font-family',
+ fontSize: 'font-size', fontSizeAdjust: 'font-size-adjust',
+ fontStretch: 'font-stretch', fontStyle: 'font-style',
+ fontVariant: 'font-variant', fontWeight: 'font-weight',
+ glyphOrientationHorizontal: 'glyph-orientation-horizontal',
+ glyphOrientationVertical: 'glyph-orientation-vertical',
+ horizAdvX: 'horiz-adv-x', horizOriginX: 'horiz-origin-x',
+ imageRendering: 'image-rendering', letterSpacing: 'letter-spacing',
+ lightingColor: 'lighting-color', markerEnd: 'marker-end',
+ markerMid: 'marker-mid', markerStart: 'marker-start',
+ stopColor: 'stop-color', stopOpacity: 'stop-opacity',
+ strikethroughPosition: 'strikethrough-position',
+ strikethroughThickness: 'strikethrough-thickness',
+ strokeDashArray: 'stroke-dasharray', strokeDashOffset: 'stroke-dashoffset',
+ strokeLineCap: 'stroke-linecap', strokeLineJoin: 'stroke-linejoin',
+ strokeMiterLimit: 'stroke-miterlimit', strokeOpacity: 'stroke-opacity',
+ strokeWidth: 'stroke-width', textAnchor: 'text-anchor',
+ textDecoration: 'text-decoration', textRendering: 'text-rendering',
+ underlinePosition: 'underline-position', underlineThickness: 'underline-thickness',
+ vertAdvY: 'vert-adv-y', vertOriginY: 'vert-origin-y',
+ wordSpacing: 'word-spacing', writingMode: 'writing-mode'},
+
+ /* Add the SVG object to its container. */
+ _attachSVG: function(container, settings) {
+ if ($(container).hasClass(this.markerClassName)) {
+ return;
+ }
+ if (typeof settings == 'string') {
+ settings = {loadURL: settings};
+ }
+ else if (typeof settings == 'function') {
+ settings = {onLoad: settings};
+ }
+ $(container).addClass(this.markerClassName);
+ try {
+ var svg = document.createElementNS(this.svgNS, 'svg');
+ svg.setAttribute('version', '1.1');
+ svg.setAttribute('width', container.clientWidth);
+ svg.setAttribute('height', container.clientHeight);
+ container.appendChild(svg);
+ this._afterLoad(container, svg, settings);
+ }
+ catch (e) {
+ if ($.browser.msie) {
+ if (!container.id) {
+ container.id = 'svg' + (this._uuid++);
+ }
+ this._settings[container.id] = settings;
+ container.innerHTML = '<embed type="image/svg+xml" width="100%" ' +
+ 'height="100%" src="' + (settings.initPath || '') + 'blank.svg"/>';
+ }
+ else {
+ container.innerHTML = '<p class="svg_error">' +
+ this.local.notSupportedText + '</p>';
+ }
+ }
+ },
+
+ /* SVG callback after loading - register SVG root. */
+ _registerSVG: function() {
+ for (var i = 0; i < document.embeds.length; i++) { // Check all
+ var container = document.embeds[i].parentNode;
+ if (!$(container).hasClass($.svg.markerClassName) || // Not SVG
+ $.data(container, PROP_NAME)) { // Already done
+ continue;
+ }
+ var svg = null;
+ try {
+ svg = document.embeds[i].getSVGDocument();
+ }
+ catch(e) {
+ setTimeout($.svg._registerSVG, 250); // Renesis takes longer to load
+ return;
+ }
+ svg = (svg ? svg.documentElement : null);
+ if (svg) {
+ $.svg._afterLoad(container, svg);
+ }
+ }
+ },
+
+ /* Post-processing once loaded. */
+ _afterLoad: function(container, svg, settings) {
+ var settings = settings || this._settings[container.id];
+ this._settings[container.id] = null;
+ var wrapper = new this._wrapperClass(svg, container);
+ $.data(container, PROP_NAME, wrapper);
+ try {
+ if (settings.loadURL) { // Load URL
+ wrapper.load(settings.loadURL, settings);
+ }
+ if (settings.settings) { // Additional settings
+ wrapper.configure(settings.settings);
+ }
+ if (settings.onLoad && !settings.loadURL) { // Onload callback
+ settings.onLoad.apply(container, [wrapper]);
+ }
+ }
+ catch (e) {
+ alert(e);
+ }
+ },
+
+ /* Return the SVG wrapper created for a given container.
+ @param container (string) selector for the container or
+ (element) the container for the SVG object or
+ jQuery collection - first entry is the container
+ @return (SVGWrapper) the corresponding SVG wrapper element, or null if not attached */
+ _getSVG: function(container) {
+ container = (typeof container == 'string' ? $(container)[0] :
+ (container.jquery ? container[0] : container));
+ return $.data(container, PROP_NAME);
+ },
+
+ /* Remove the SVG functionality from a div.
+ @param container (element) the container for the SVG object */
+ _destroySVG: function(container) {
+ var $container = $(container);
+ if (!$container.hasClass(this.markerClassName)) {
+ return;
+ }
+ $container.removeClass(this.markerClassName).empty();
+ $.removeData(container, PROP_NAME);
+ },
+
+ /* Extend the SVGWrapper object with an embedded class.
+ The constructor function must take a single parameter that is
+ a reference to the owning SVG root object. This allows the
+ extension to access the basic SVG functionality.
+ @param name (string) the name of the SVGWrapper attribute to access the new class
+ @param extClass (function) the extension class constructor */
+ addExtension: function(name, extClass) {
+ this._extensions.push([name, extClass]);
+ }
+});
+
+/* The main SVG interface, which encapsulates the SVG element.
+ Obtain a reference from $().svg('get') */
+function SVGWrapper(svg, container) {
+ this._svg = svg; // The SVG root node
+ this._container = container; // The containing div
+ for (var i = 0; i < $.svg._extensions.length; i++) {
+ var extension = $.svg._extensions[i];
+ this[extension[0]] = new extension[1](this);
+ }
+}
+
+$.extend(SVGWrapper.prototype, {
+
+ /* Retrieve the width of the SVG object. */
+ _width: function() {
+ return this._container.clientWidth;
+ },
+
+ /* Retrieve the height of the SVG object. */
+ _height: function() {
+ return this._container.clientHeight;
+ },
+
+ /* Retrieve the root SVG element.
+ @return the top-level SVG element */
+ root: function() {
+ return this._svg;
+ },
+
+ /* Configure the SVG root.
+ @param settings (object) additional settings for the root
+ @param clear (boolean) true to remove existing attributes first,
+ false to add to what is already there (optional)
+ @return (SVGWrapper) this root */
+ configure: function(settings, clear) {
+ if (clear) {
+ for (var i = this._svg.attributes.length - 1; i >= 0; i--) {
+ var attr = this._svg.attributes.item(i);
+ if (!(attr.nodeName == 'onload' || attr.nodeName == 'version' ||
+ attr.nodeName.substring(0, 5) == 'xmlns')) {
+ this._svg.attributes.removeNamedItem(attr.nodeName);
+ }
+ }
+ }
+ for (var attrName in settings) {
+ this._svg.setAttribute(attrName, settings[attrName]);
+ }
+ return this;
+ },
+
+ /* Locate a specific element in the SVG document.
+ @param id (string) the element's identifier
+ @return (element) the element reference, or null if not found */
+ getElementById: function(id) {
+ return this._svg.ownerDocument.getElementById(id);
+ },
+
+ /* Change the attributes for a SVG node.
+ @param element (SVG element) the node to change
+ @param settings (object) the new settings
+ @return (SVGWrapper) this root */
+ change: function(element, settings) {
+ if (element) {
+ for (var name in settings) {
+ if (settings[name] == null) {
+ element.removeAttribute(name);
+ }
+ else {
+ element.setAttribute(name, settings[name]);
+ }
+ }
+ }
+ return this;
+ },
+
+ /* Check for parent being absent and adjust arguments accordingly. */
+ _args: function(values, names, optSettings) {
+ names.splice(0, 0, 'parent');
+ names.splice(names.length, 0, 'settings');
+ var args = {};
+ var offset = 0;
+ if (values[0] != null && (typeof values[0] != 'object' || !values[0].nodeName)) {
+ args['parent'] = null;
+ offset = 1;
+ }
+ for (var i = 0; i < values.length; i++) {
+ args[names[i + offset]] = values[i];
+ }
+ if (optSettings) {
+ $.each(optSettings, function(i, value) {
+ if (typeof args[value] == 'object') {
+ args.settings = args[value];
+ args[value] = null;
+ }
+ });
+ }
+ return args;
+ },
+
+ /* Add a title.
+ @param parent (element) the parent node for the new title (optional)
+ @param text (string) the text of the title
+ @param settings (object) additional settings for the title (optional)
+ @return (element) the new title node */
+ title: function(parent, text, settings) {
+ var args = this._args(arguments, ['text']);
+ var node = this._makeNode(args.parent, 'title', args.settings || {});
+ node.appendChild(this._svg.ownerDocument.createTextNode(args.text));
+ return node;
+ },
+
+ /* Add a description.
+ @param parent (element) the parent node for the new description (optional)
+ @param text (string) the text of the description
+ @param settings (object) additional settings for the description (optional)
+ @return (element) the new description node */
+ describe: function(parent, text, settings) {
+ var args = this._args(arguments, ['text']);
+ var node = this._makeNode(args.parent, 'desc', args.settings || {});
+ node.appendChild(this._svg.ownerDocument.createTextNode(args.text));
+ return node;
+ },
+
+ /* Add a definitions node.
+ @param parent (element) the parent node for the new definitions (optional)
+ @param id (string) the ID of this definitions (optional)
+ @param settings (object) additional settings for the definitions (optional)
+ @return (element) the new definitions node */
+ defs: function(parent, id, settings) {
+ var args = this._args(arguments, ['id'], ['id']);
+ return this._makeNode(args.parent, 'defs', $.extend(
+ (args.id ? {id: args.id} : {}), args.settings || {}));
+ },
+
+ /* Add a symbol definition.
+ @param parent (element) the parent node for the new symbol (optional)
+ @param id (string) the ID of this symbol
+ @param x1 (number) the left coordinate for this symbol
+ @param y1 (number) the top coordinate for this symbol
+ @param x2 (number) the right coordinate for this symbol
+ @param y2 (number) the bottom coordinate for this symbol
+ @param settings (object) additional settings for the symbol (optional)
+ @return (element) the new symbol node */
+ symbol: function(parent, id, x1, y1, x2, y2, settings) {
+ var args = this._args(arguments, ['id', 'x1', 'y1', 'x2', 'y2']);
+ return this._makeNode(args.parent, 'symbol', $.extend(
+ {id: args.id, viewBox: args.x1 + ' ' + args.y1 + ' ' + args.x2 + ' ' + args.y2},
+ args.settings || {}));
+ },
+
+ /* Add a marker definition.
+ @param parent (element) the parent node for the new marker (optional)
+ @param id (string) the ID of this marker
+ @param refX (number) the x-coordinate for the reference point
+ @param refY (number) the y-coordinate for the reference point
+ @param mWidth (number) the marker viewport width
+ @param mHeight (number) the marker viewport height
+ @param orient (string or int) 'auto' or angle (degrees) (optional)
+ @param settings (object) additional settings for the marker (optional)
+ @return (element) the new marker node */
+ marker: function(parent, id, refX, refY, mWidth, mHeight, orient, settings) {
+ var args = this._args(arguments, ['id', 'refX', 'refY',
+ 'mWidth', 'mHeight', 'orient'], ['orient']);
+ return this._makeNode(args.parent, 'marker', $.extend(
+ {id: args.id, refX: args.refX, refY: args.refY, markerWidth: args.mWidth,
+ markerHeight: args.mHeight, orient: args.orient || 'auto'}, args.settings || {}));
+ },
+
+ /* Add a style node.
+ @param parent (element) the parent node for the new node (optional)
+ @param styles (string) the CSS styles
+ @param settings (object) additional settings for the node (optional)
+ @return (element) the new style node */
+ style: function(parent, styles, settings) {
+ var args = this._args(arguments, ['styles']);
+ var node = this._makeNode(args.parent, 'style', $.extend(
+ {type: 'text/css'}, args.settings || {}));
+ node.appendChild(this._svg.ownerDocument.createTextNode(args.styles));
+ if ($.browser.opera) {
+ $('head').append('<style type="text/css">' + args.styles + '</style>');
+ }
+ return node;
+ },
+
+ /* Add a script node.
+ @param parent (element) the parent node for the new node (optional)
+ @param script (string) the JavaScript code
+ @param type (string) the MIME type for the code (optional, default 'text/javascript')
+ @param settings (object) additional settings for the node (optional)
+ @return (element) the new script node */
+ script: function(parent, script, type, settings) {
+ var args = this._args(arguments, ['script', 'type'], ['type']);
+ var node = this._makeNode(args.parent, 'script', $.extend(
+ {type: args.type || 'text/javascript'}, args.settings || {}));
+ node.appendChild(this._svg.ownerDocument.createTextNode(this._escapeXML(args.script)));
+ if (!$.browser.mozilla) {
+ $.globalEval(args.script);
+ }
+ return node;
+ },
+
+ /* Add a linear gradient definition.
+ Specify all of x1, y1, x2, y2 or none of them.
+ @param parent (element) the parent node for the new gradient (optional)
+ @param id (string) the ID for this gradient
+ @param stops (string[][]) the gradient stops, each entry is
+ [0] is offset (0.0-1.0 or 0%-100%), [1] is colour,
+ [2] is opacity (optional)
+ @param x1 (number) the x-coordinate of the gradient start (optional)
+ @param y1 (number) the y-coordinate of the gradient start (optional)
+ @param x2 (number) the x-coordinate of the gradient end (optional)
+ @param y2 (number) the y-coordinate of the gradient end (optional)
+ @param settings (object) additional settings for the gradient (optional)
+ @return (element) the new gradient node */
+ linearGradient: function(parent, id, stops, x1, y1, x2, y2, settings) {
+ var args = this._args(arguments,
+ ['id', 'stops', 'x1', 'y1', 'x2', 'y2'], ['x1']);
+ var sets = $.extend({id: args.id},
+ (args.x1 != null ? {x1: args.x1, y1: args.y1, x2: args.x2, y2: args.y2} : {}));
+ return this._gradient(args.parent, 'linearGradient',
+ $.extend(sets, args.settings || {}), args.stops);
+ },
+
+ /* Add a radial gradient definition.
+ Specify all of cx, cy, r, fx, fy or none of them.
+ @param parent (element) the parent node for the new gradient (optional)
+ @param id (string) the ID for this gradient
+ @param stops (string[][]) the gradient stops, each entry
+ [0] is offset, [1] is colour, [2] is opacity (optional)
+ @param cx (number) the x-coordinate of the largest circle centre (optional)
+ @param cy (number) the y-coordinate of the largest circle centre (optional)
+ @param r (number) the radius of the largest circle (optional)
+ @param fx (number) the x-coordinate of the gradient focus (optional)
+ @param fy (number) the y-coordinate of the gradient focus (optional)
+ @param settings (object) additional settings for the gradient (optional)
+ @return (element) the new gradient node */
+ radialGradient: function(parent, id, stops, cx, cy, r, fx, fy, settings) {
+ var args = this._args(arguments,
+ ['id', 'stops', 'cx', 'cy', 'r', 'fx', 'fy'], ['cx']);
+ var sets = $.extend({id: args.id}, (args.cx != null ?
+ {cx: args.cx, cy: args.cy, r: args.r, fx: args.fx, fy: args.fy} : {}));
+ return this._gradient(args.parent, 'radialGradient',
+ $.extend(sets, args.settings || {}), args.stops);
+ },
+
+ /* Add a gradient node. */
+ _gradient: function(parent, name, settings, stops) {
+ var node = this._makeNode(parent, name, settings);
+ for (var i = 0; i < stops.length; i++) {
+ var stop = stops[i];
+ this._makeNode(node, 'stop', $.extend(
+ {offset: stop[0], stopColor: stop[1]},
+ (stop[2] != null ? {stopOpacity: stop[2]} : {})));
+ }
+ return node;
+ },
+
+ /* Add a pattern definition.
+ Specify all of vx, vy, xwidth, vheight or none of them.
+ @param parent (element) the parent node for the new pattern (optional)
+ @param id (string) the ID for this pattern
+ @param x (number) the x-coordinate for the left edge of the pattern
+ @param y (number) the y-coordinate for the top edge of the pattern
+ @param width (number) the width of the pattern
+ @param height (number) the height of the pattern
+ @param vx (number) the minimum x-coordinate for view box (optional)
+ @param vy (number) the minimum y-coordinate for the view box (optional)
+ @param vwidth (number) the width of the view box (optional)
+ @param vheight (number) the height of the view box (optional)
+ @param settings (object) additional settings for the pattern (optional)
+ @return (element) the new pattern node */
+ pattern: function(parent, id, x, y, width, height, vx, vy, vwidth, vheight, settings) {
+ var args = this._args(arguments, ['id', 'x', 'y', 'width', 'height',
+ 'vx', 'vy', 'vwidth', 'vheight'], ['vx']);
+ var sets = $.extend({id: args.id, x: args.x, y: args.y,
+ width: args.width, height: args.height}, (args.vx != null ?
+ {viewBox: args.vx + ' ' + args.vy + ' ' + args.vwidth + ' ' + args.vheight} : {}));
+ return this._makeNode(args.parent, 'pattern', $.extend(sets, args.settings || {}));
+ },
+
+ /* Add a mask definition.
+ @param parent (element) the parent node for the new mask (optional)
+ @param id (string) the ID for this mask
+ @param x (number) the x-coordinate for the left edge of the mask
+ @param y (number) the y-coordinate for the top edge of the mask
+ @param width (number) the width of the mask
+ @param height (number) the height of the mask
+ @param settings (object) additional settings for the mask (optional)
+ @return (element) the new mask node */
+ mask: function(parent, id, x, y, width, height, settings) {
+ var args = this._args(arguments, ['id', 'x', 'y', 'width', 'height']);
+ return this._makeNode(args.parent, 'mask', $.extend(
+ {id: args.id, x: args.x, y: args.y, width: args.width, height: args.height},
+ args.settings || {}));
+ },
+
+ /* Create a new path object.
+ @return (SVGPath) a new path object */
+ createPath: function() {
+ return new SVGPath();
+ },
+
+ /* Create a new text object.
+ @return (SVGText) a new text object */
+ createText: function() {
+ return new SVGText();
+ },
+
+ /* Add an embedded SVG element.
+ Specify all of vx, vy, vwidth, vheight or none of them.
+ @param parent (element) the parent node for the new node (optional)
+ @param x (number) the x-coordinate for the left edge of the node
+ @param y (number) the y-coordinate for the top edge of the node
+ @param width (number) the width of the node
+ @param height (number) the height of the node
+ @param vx (number) the minimum x-coordinate for view box (optional)
+ @param vy (number) the minimum y-coordinate for the view box (optional)
+ @param vwidth (number) the width of the view box (optional)
+ @param vheight (number) the height of the view box (optional)
+ @param settings (object) additional settings for the node (optional)
+ @return (element) the new node */
+ svg: function(parent, x, y, width, height, vx, vy, vwidth, vheight, settings) {
+ var args = this._args(arguments, ['x', 'y', 'width', 'height',
+ 'vx', 'vy', 'vwidth', 'vheight'], ['vx']);
+ var sets = $.extend({x: args.x, y: args.y, width: args.width, height: args.height},
+ (args.vx != null ? {viewBox: args.vx + ' ' + args.vy + ' ' +
+ args.vwidth + ' ' + args.vheight} : {}));
+ return this._makeNode(args.parent, 'svg', $.extend(sets, args.settings || {}));
+ },
+
+ /* Create a group.
+ @param parent (element) the parent node for the new group (optional)
+ @param id (string) the ID of this group (optional)
+ @param settings (object) additional settings for the group (optional)
+ @return (element) the new group node */
+ group: function(parent, id, settings) {
+ var args = this._args(arguments, ['id'], ['id']);
+ return this._makeNode(args.parent, 'g', $.extend({id: args.id}, args.settings || {}));
+ },
+
+ /* Add a usage reference.
+ Specify all of x, y, width, height or none of them.
+ @param parent (element) the parent node for the new node (optional)
+ @param x (number) the x-coordinate for the left edge of the node (optional)
+ @param y (number) the y-coordinate for the top edge of the node (optional)
+ @param width (number) the width of the node (optional)
+ @param height (number) the height of the node (optional)
+ @param ref (string) the ID of the definition node
+ @param settings (object) additional settings for the node (optional)
+ @return (element) the new node */
+ use: function(parent, x, y, width, height, ref, settings) {
+ var args = this._args(arguments, ['x', 'y', 'width', 'height', 'ref']);
+ if (typeof args.x == 'string') {
+ args.ref = args.x;
+ args.settings = args.y;
+ args.x = args.y = args.width = args.height = null;
+ }
+ var node = this._makeNode(args.parent, 'use', $.extend(
+ {x: args.x, y: args.y, width: args.width, height: args.height},
+ args.settings || {}));
+ node.setAttributeNS($.svg.xlinkNS, 'href', args.ref);
+ return node;
+ },
+
+ /* Add a link, which applies to all child elements.
+ @param parent (element) the parent node for the new link (optional)
+ @param ref (string) the target URL
+ @param settings (object) additional settings for the link (optional)
+ @return (element) the new link node */
+ link: function(parent, ref, settings) {
+ var args = this._args(arguments, ['ref']);
+ var node = this._makeNode(args.parent, 'a', args.settings);
+ node.setAttributeNS($.svg.xlinkNS, 'href', args.ref);
+ return node;
+ },
+
+ /* Add an image.
+ @param parent (element) the parent node for the new image (optional)
+ @param x (number) the x-coordinate for the left edge of the image
+ @param y (number) the y-coordinate for the top edge of the image
+ @param width (number) the width of the image
+ @param height (number) the height of the image
+ @param ref (string) the path to the image
+ @param settings (object) additional settings for the image (optional)
+ @return (element) the new image node */
+ image: function(parent, x, y, width, height, ref, settings) {
+ var args = this._args(arguments, ['x', 'y', 'width', 'height', 'ref']);
+ var node = this._makeNode(args.parent, 'image', $.extend(
+ {x: args.x, y: args.y, width: args.width, height: args.height},
+ args.settings || {}));
+ node.setAttributeNS($.svg.xlinkNS, 'href', args.ref);
+ return node;
+ },
+
+ /* Draw a path.
+ @param parent (element) the parent node for the new shape (optional)
+ @param path (string or SVGPath) the path to draw
+ @param settings (object) additional settings for the shape (optional)
+ @return (element) the new shape node */
+ path: function(parent, path, settings) {
+ var args = this._args(arguments, ['path']);
+ return this._makeNode(args.parent, 'path', $.extend(
+ {d: (args.path.path ? args.path.path() : args.path)}, args.settings || {}));
+ },
+
+ /* Draw a rectangle.
+ Specify both of rx and ry or neither.
+ @param parent (element) the parent node for the new shape (optional)
+ @param x (number) the x-coordinate for the left edge of the rectangle
+ @param y (number) the y-coordinate for the top edge of the rectangle
+ @param width (number) the width of the rectangle
+ @param height (number) the height of the rectangle
+ @param rx (number) the x-radius of the ellipse for the rounded corners (optional)
+ @param ry (number) the y-radius of the ellipse for the rounded corners (optional)
+ @param settings (object) additional settings for the shape (optional)
+ @return (element) the new shape node */
+ rect: function(parent, x, y, width, height, rx, ry, settings) {
+ var args = this._args(arguments, ['x', 'y', 'width', 'height', 'rx', 'ry'], ['rx']);
+ return this._makeNode(args.parent, 'rect', $.extend(
+ {x: args.x, y: args.y, width: args.width, height: args.height},
+ (args.rx ? {rx: args.rx, ry: args.ry} : {}), args.settings || {}));
+ },
+
+ /* Draw a circle.
+ @param parent (element) the parent node for the new shape (optional)
+ @param cx (number) the x-coordinate for the centre of the circle
+ @param cy (number) the y-coordinate for the centre of the circle
+ @param r (number) the radius of the circle
+ @param settings (object) additional settings for the shape (optional)
+ @return (element) the new shape node */
+ circle: function(parent, cx, cy, r, settings) {
+ var args = this._args(arguments, ['cx', 'cy', 'r']);
+ return this._makeNode(args.parent, 'circle', $.extend(
+ {cx: args.cx, cy: args.cy, r: args.r}, args.settings || {}));
+ },
+
+ /* Draw an ellipse.
+ @param parent (element) the parent node for the new shape (optional)
+ @param cx (number) the x-coordinate for the centre of the ellipse
+ @param cy (number) the y-coordinate for the centre of the ellipse
+ @param rx (number) the x-radius of the ellipse
+ @param ry (number) the y-radius of the ellipse
+ @param settings (object) additional settings for the shape (optional)
+ @return (element) the new shape node */
+ ellipse: function(parent, cx, cy, rx, ry, settings) {
+ var args = this._args(arguments, ['cx', 'cy', 'rx', 'ry']);
+ return this._makeNode(args.parent, 'ellipse', $.extend(
+ {cx: args.cx, cy: args.cy, rx: args.rx, ry: args.ry}, args.settings || {}));
+ },
+
+ /* Draw a line.
+ @param parent (element) the parent node for the new shape (optional)
+ @param x1 (number) the x-coordinate for the start of the line
+ @param y1 (number) the y-coordinate for the start of the line
+ @param x2 (number) the x-coordinate for the end of the line
+ @param y2 (number) the y-coordinate for the end of the line
+ @param settings (object) additional settings for the shape (optional)
+ @return (element) the new shape node */
+ line: function(parent, x1, y1, x2, y2, settings) {
+ var args = this._args(arguments, ['x1', 'y1', 'x2', 'y2']);
+ return this._makeNode(args.parent, 'line', $.extend(
+ {x1: args.x1, y1: args.y1, x2: args.x2, y2: args.y2}, args.settings || {}));
+ },
+
+ /* Draw a polygonal line.
+ @param parent (element) the parent node for the new shape (optional)
+ @param points (number[][]) the x-/y-coordinates for the points on the line
+ @param settings (object) additional settings for the shape (optional)
+ @return (element) the new shape node */
+ polyline: function(parent, points, settings) {
+ var args = this._args(arguments, ['points']);
+ return this._poly(args.parent, 'polyline', args.points, args.settings);
+ },
+
+ /* Draw a polygonal shape.
+ @param parent (element) the parent node for the new shape (optional)
+ @param points (number[][]) the x-/y-coordinates for the points on the shape
+ @param settings (object) additional settings for the shape (optional)
+ @return (element) the new shape node */
+ polygon: function(parent, points, settings) {
+ var args = this._args(arguments, ['points']);
+ return this._poly(args.parent, 'polygon', args.points, args.settings);
+ },
+
+ /* Draw a polygonal line or shape. */
+ _poly: function(parent, name, points, settings) {
+ var ps = '';
+ for (var i = 0; i < points.length; i++) {
+ ps += points[i].join() + ' ';
+ }
+ return this._makeNode(parent, name, $.extend(
+ {points: $.trim(ps)}, settings || {}));
+ },
+
+ /* Draw text.
+ Specify both of x and y or neither of them.
+ @param parent (element) the parent node for the text (optional)
+ @param x (number or number[]) the x-coordinate(s) for the text (optional)
+ @param y (number or number[]) the y-coordinate(s) for the text (optional)
+ @param value (string) the text content or
+ (SVGText) text with spans and references
+ @param settings (object) additional settings for the text (optional)
+ @return (element) the new text node */
+ text: function(parent, x, y, value, settings) {
+ var args = this._args(arguments, ['x', 'y', 'value']);
+ if (typeof args.x == 'string' && arguments.length < 4) {
+ args.value = args.x;
+ args.settings = args.y;
+ args.x = args.y = null;
+ }
+ return this._text(args.parent, 'text', args.value, $.extend(
+ {x: (args.x && isArray(args.x) ? args.x.join(' ') : args.x),
+ y: (args.y && isArray(args.y) ? args.y.join(' ') : args.y)},
+ args.settings || {}));
+ },
+
+ /* Draw text along a path.
+ @param parent (element) the parent node for the text (optional)
+ @param path (string) the ID of the path
+ @param value (string) the text content or
+ (SVGText) text with spans and references
+ @param settings (object) additional settings for the text (optional)
+ @return (element) the new text node */
+ textpath: function(parent, path, value, settings) {
+ var args = this._args(arguments, ['path', 'value']);
+ var node = this._text(args.parent, 'textPath', args.value, args.settings || {});
+ node.setAttributeNS($.svg.xlinkNS, 'href', args.path);
+ return node;
+ },
+
+ /* Draw text. */
+ _text: function(parent, name, value, settings) {
+ var node = this._makeNode(parent, name, settings);
+ if (typeof value == 'string') {
+ node.appendChild(node.ownerDocument.createTextNode(value));
+ }
+ else {
+ for (var i = 0; i < value._parts.length; i++) {
+ var part = value._parts[i];
+ if (part[0] == 'tspan') {
+ var child = this._makeNode(node, part[0], part[2]);
+ child.appendChild(node.ownerDocument.createTextNode(part[1]));
+ node.appendChild(child);
+ }
+ else if (part[0] == 'tref') {
+ var child = this._makeNode(node, part[0], part[2]);
+ child.setAttributeNS($.svg.xlinkNS, 'href', part[1]);
+ node.appendChild(child);
+ }
+ else if (part[0] == 'textpath') {
+ var set = $.extend({}, part[2]);
+ set.href = null;
+ var child = this._makeNode(node, part[0], set);
+ child.setAttributeNS($.svg.xlinkNS, 'href', part[2].href);
+ child.appendChild(node.ownerDocument.createTextNode(part[1]));
+ node.appendChild(child);
+ }
+ else { // straight text
+ node.appendChild(node.ownerDocument.createTextNode(part[1]));
+ }
+ }
+ }
+ return node;
+ },
+
+ /* Add a custom SVG element.
+ @param parent (element) the parent node for the new element (optional)
+ @param name (string) the name of the element
+ @param settings (object) additional settings for the element (optional)
+ @return (element) the new title node */
+ other: function(parent, name, settings) {
+ var args = this._args(arguments, ['name']);
+ return this._makeNode(args.parent, args.name, args.settings || {});
+ },
+
+ /* Create a shape node with the given settings. */
+ _makeNode: function(parent, name, settings) {
+ parent = parent || this._svg;
+ var node = this._svg.ownerDocument.createElementNS($.svg.svgNS, name);
+ for (var name in settings) {
+ var value = settings[name];
+ if (value != null && value != null &&
+ (typeof value != 'string' || value != '')) {
+ node.setAttribute($.svg._attrNames[name] || name, value);
+ }
+ }
+ parent.appendChild(node);
+ return node;
+ },
+
+ /* Add an existing SVG node to the diagram.
+ @param parent (element) the parent node for the new node (optional)
+ @param node (element) the new node to add or
+ (string) the jQuery selector for the node or
+ (jQuery collection) set of nodes to add
+ @return (SVGWrapper) this wrapper */
+ add: function(parent, node) {
+ var args = this._args(arguments, ['node']);
+ var svg = this;
+ args.parent = args.parent || this._svg;
+ try {
+ if ($.svg._renesis) {
+ throw 'Force traversal';
+ }
+ args.parent.appendChild(args.node.cloneNode(true));
+ }
+ catch (e) {
+ args.node = (args.node.jquery ? args.node : $(args.node));
+ args.node.each(function() {
+ var child = svg._cloneAsSVG(this);
+ if (child) {
+ args.parent.appendChild(child);
+ }
+ });
+ }
+ return this;
+ },
+
+ /* SVG nodes must belong to the SVG namespace, so clone and ensure this is so. */
+ _cloneAsSVG: function(node) {
+ var newNode = null;
+ if (node.nodeType == 1) { // element
+ newNode = this._svg.ownerDocument.createElementNS(
+ $.svg.svgNS, this._checkName(node.nodeName));
+ for (var i = 0; i < node.attributes.length; i++) {
+ var attr = node.attributes.item(i);
+ if (attr.nodeName != 'xmlns' && attr.nodeValue) {
+ if (attr.prefix == 'xlink') {
+ newNode.setAttributeNS($.svg.xlinkNS, attr.localName, attr.nodeValue);
+ }
+ else {
+ newNode.setAttribute(this._checkName(attr.nodeName), attr.nodeValue);
+ }
+ }
+ }
+ for (var i = 0; i < node.childNodes.length; i++) {
+ var child = this._cloneAsSVG(node.childNodes[i]);
+ if (child) {
+ newNode.appendChild(child);
+ }
+ }
+ }
+ else if (node.nodeType == 3) { // text
+ if ($.trim(node.nodeValue)) {
+ newNode = this._svg.ownerDocument.createTextNode(node.nodeValue);
+ }
+ }
+ else if (node.nodeType == 4) { // CDATA
+ if ($.trim(node.nodeValue)) {
+ try {
+ newNode = this._svg.ownerDocument.createCDATASection(node.nodeValue);
+ }
+ catch (e) {
+ newNode = this._svg.ownerDocument.createTextNode(
+ node.nodeValue.replace(/&/g, '&amp;').
+ replace(/</g, '&lt;').replace(/>/g, '&gt;'));
+ }
+ }
+ }
+ return newNode;
+ },
+
+ /* Node names must be lower case and without SVG namespace prefix. */
+ _checkName: function(name) {
+ name = (name.substring(0, 1) >= 'A' && name.substring(0, 1) <= 'Z' ?
+ name.toLowerCase() : name);
+ return (name.substring(0, 4) == 'svg:' ? name.substring(4) : name);
+ },
+
+ /* Load an external SVG document.
+ @param url (string) the location of the SVG document or
+ the actual SVG content
+ @param settings (boolean) see addTo below or
+ (function) see onLoad below or
+ (object) additional settings for the load with attributes below:
+ addTo (boolean) true to add to what's already there,
+ or false to clear the canvas first
+ changeSize (boolean) true to allow the canvas size to change,
+ or false to retain the original
+ onLoad (function) callback after the document has loaded,
+ 'this' is the container, receives SVG object and
+ optional error message as a parameter
+ @return (SVGWrapper) this root */
+ load: function(url, settings) {
+ settings = (typeof settings == 'boolean'? {addTo: settings} :
+ (typeof settings == 'function'? {onLoad: settings} : settings || {}));
+ if (!settings.addTo) {
+ this.clear(false);
+ }
+ var size = [this._svg.getAttribute('width'), this._svg.getAttribute('height')];
+ var wrapper = this;
+ // Report a problem with the load
+ var reportError = function(message) {
+ message = $.svg.local.errorLoadingText + ': ' + message;
+ if (settings.onLoad) {
+ settings.onLoad.apply(wrapper._container, [wrapper, message]);
+ }
+ else {
+ wrapper.text(null, 10, 20, message);
+ }
+ };
+ // Create a DOM from SVG content
+ var loadXML4IE = function(data) {
+ var xml = new ActiveXObject('Microsoft.XMLDOM');
+ xml.validateOnParse = false;
+ xml.resolveExternals = false;
+ xml.async = false;
+ xml.loadXML(data);
+ if (xml.parseError.errorCode != 0) {
+ reportError(xml.parseError.reason);
+ return null;
+ }
+ return xml;
+ };
+ // Load the SVG DOM
+ var loadSVG = function(data) {
+ if (!data) {
+ return;
+ }
+ if (data.documentElement.nodeName != 'svg') {
+ var errors = data.getElementsByTagName('parsererror');
+ var messages = (errors.length ? errors[0].getElementsByTagName('div') : []); // Safari
+ reportError(!errors.length ? '???' :
+ (messages.length ? messages[0] : errors[0]).firstChild.nodeValue);
+ return;
+ }
+ var attrs = {};
+ for (var i = 0; i < data.documentElement.attributes.length; i++) {
+ var attr = data.documentElement.attributes.item(i);
+ if (!(attr.nodeName == 'version' || attr.nodeName.substring(0, 5) == 'xmlns')) {
+ attrs[attr.nodeName] = attr.nodeValue;
+ }
+ }
+ wrapper.configure(attrs, true);
+ var nodes = data.documentElement.childNodes;
+ for (var i = 0; i < nodes.length; i++) {
+ try {
+ if ($.svg._renesis) {
+ throw 'Force traversal';
+ }
+ wrapper._svg.appendChild(nodes[i].cloneNode(true));
+ }
+ catch (e) {
+ wrapper.add(null, nodes[i]);
+ }
+ }
+ if (!settings.changeSize) {
+ wrapper.configure({width: size[0], height: size[1]});
+ }
+ if (settings.onLoad) {
+ settings.onLoad.apply(wrapper._container, [wrapper]);
+ }
+ };
+ if (url.match('<svg')) { // Inline SVG
+ loadSVG($.browser.msie ? loadXML4IE(url) :
+ new DOMParser().parseFromString(url, 'text/xml'));
+ }
+ else { // Remote SVG
+ $.ajax({url: url, dataType: ($.browser.msie ? 'text' : 'xml'),
+ success: function(xml) {
+ loadSVG($.browser.msie ? loadXML4IE(xml) : xml);
+ }, error: function(http, message, exc) {
+ reportError(message + (exc ? ' ' + exc.message : ''));
+ }});
+ }
+ return this;
+ },
+
+ /* Delete a specified node.
+ @param node (element) the drawing node to remove
+ @return (SVGWrapper) this root */
+ remove: function(node) {
+ node.parentNode.removeChild(node);
+ return this;
+ },
+
+ /* Delete everything in the current document.
+ @param attrsToo (boolean) true to clear any root attributes as well,
+ false to leave them (optional)
+ @return (SVGWrapper) this root */
+ clear: function(attrsToo) {
+ if (attrsToo) {
+ this.configure({}, true);
+ }
+ while (this._svg.firstChild) {
+ this._svg.removeChild(this._svg.firstChild);
+ }
+ return this;
+ },
+
+ /* Serialise the current diagram into an SVG text document.
+ @param node (SVG element) the starting node (optional)
+ @return (string) the SVG as text */
+ toSVG: function(node) {
+ node = node || this._svg;
+ return (typeof XMLSerializer == 'undefined' ? this._toSVG(node) :
+ new XMLSerializer().serializeToString(node));
+ },
+
+ /* Serialise one node in the SVG hierarchy. */
+ _toSVG: function(node) {
+ var svgDoc = '';
+ if (!node) {
+ return svgDoc;
+ }
+ if (node.nodeType == 3) { // Text
+ svgDoc = node.nodeValue;
+ }
+ else if (node.nodeType == 4) { // CDATA
+ svgDoc = '<![CDATA[' + node.nodeValue + ']]>';
+ }
+ else { // Element
+ svgDoc = '<' + node.nodeName;
+ if (node.attributes) {
+ for (var i = 0; i < node.attributes.length; i++) {
+ var attr = node.attributes.item(i);
+ if (!($.trim(attr.nodeValue) == '' || attr.nodeValue.match(/^\[object/) ||
+ attr.nodeValue.match(/^function/))) {
+ svgDoc += ' ' + (attr.namespaceURI == $.svg.xlinkNS ? 'xlink:' : '') +
+ attr.nodeName + '="' + attr.nodeValue + '"';
+ }
+ }
+ }
+ if (node.firstChild) {
+ svgDoc += '>';
+ var child = node.firstChild;
+ while (child) {
+ svgDoc += this._toSVG(child);
+ child = child.nextSibling;
+ }
+ svgDoc += '</' + node.nodeName + '>';
+ }
+ else {
+ svgDoc += '/>';
+ }
+ }
+ return svgDoc;
+ },
+
+ /* Escape reserved characters in XML. */
+ _escapeXML: function(text) {
+ text = text.replace(/&/g, '&amp;');
+ text = text.replace(/</g, '&lt;');
+ text = text.replace(/>/g, '&gt;');
+ return text;
+ }
+});
+
+/* Helper to generate an SVG path.
+ Obtain an instance from the SVGWrapper object.
+ String calls together to generate the path and use its value:
+ var path = root.createPath();
+ root.path(null, path.move(100, 100).line(300, 100).line(200, 300).close(), {fill: 'red'});
+ or
+ root.path(null, path.move(100, 100).line([[300, 100], [200, 300]]).close(), {fill: 'red'}); */
+function SVGPath() {
+ this._path = '';
+}
+
+$.extend(SVGPath.prototype, {
+ /* Prepare to create a new path.
+ @return (SVGPath) this path */
+ reset: function() {
+ this._path = '';
+ return this;
+ },
+
+ /* Move the pointer to a position.
+ @param x (number) x-coordinate to move to or
+ (number[][]) x-/y-coordinates to move to
+ @param y (number) y-coordinate to move to (omitted if x is array)
+ @param relative (boolean) true for coordinates relative to the current point,
+ false for coordinates being absolute
+ @return (SVGPath) this path */
+ move: function(x, y, relative) {
+ relative = (isArray(x) ? y : relative);
+ return this._coords((relative ? 'm' : 'M'), x, y);
+ },
+
+ /* Draw a line to a position.
+ @param x (number) x-coordinate to move to or
+ (number[][]) x-/y-coordinates to move to
+ @param y (number) y-coordinate to move to (omitted if x is array)
+ @param relative (boolean) true for coordinates relative to the current point,
+ false for coordinates being absolute
+ @return (SVGPath) this path */
+ line: function(x, y, relative) {
+ relative = (isArray(x) ? y : relative);
+ return this._coords((relative ? 'l' : 'L'), x, y);
+ },
+
+ /* Draw a horizontal line to a position.
+ @param x (number) x-coordinate to draw to or
+ (number[]) x-coordinates to draw to
+ @param relative (boolean) true for coordinates relative to the current point,
+ false for coordinates being absolute
+ @return (SVGPath) this path */
+ horiz: function(x, relative) {
+ this._path += (relative ? 'h' : 'H') + (isArray(x) ? x.join(' ') : x);
+ return this;
+ },
+
+ /* Draw a vertical line to a position.
+ @param y (number) y-coordinate to draw to or
+ (number[]) y-coordinates to draw to
+ @param relative (boolean) true for coordinates relative to the current point,
+ false for coordinates being absolute
+ @return (SVGPath) this path */
+ vert: function(y, relative) {
+ this._path += (relative ? 'v' : 'V') + (isArray(y) ? y.join(' ') : y);
+ return this;
+ },
+
+ /* Draw a cubic Bzier curve.
+ @param x1 (number) x-coordinate of beginning control point or
+ (number[][]) x-/y-coordinates of control and end points to draw to
+ @param y1 (number) y-coordinate of beginning control point (omitted if x1 is array)
+ @param x2 (number) x-coordinate of ending control point (omitted if x1 is array)
+ @param y2 (number) y-coordinate of ending control point (omitted if x1 is array)
+ @param x (number) x-coordinate of curve end (omitted if x1 is array)
+ @param y (number) y-coordinate of curve end (omitted if x1 is array)
+ @param relative (boolean) true for coordinates relative to the current point,
+ false for coordinates being absolute
+ @return (SVGPath) this path */
+ curveC: function(x1, y1, x2, y2, x, y, relative) {
+ relative = (isArray(x1) ? y1 : relative);
+ return this._coords((relative ? 'c' : 'C'), x1, y1, x2, y2, x, y);
+ },
+
+ /* Continue a cubic Bzier curve.
+ Starting control point is the reflection of the previous end control point.
+ @param x2 (number) x-coordinate of ending control point or
+ (number[][]) x-/y-coordinates of control and end points to draw to
+ @param y2 (number) y-coordinate of ending control point (omitted if x2 is array)
+ @param x (number) x-coordinate of curve end (omitted if x2 is array)
+ @param y (number) y-coordinate of curve end (omitted if x2 is array)
+ @param relative (boolean) true for coordinates relative to the current point,
+ false for coordinates being absolute
+ @return (SVGPath) this path */
+ smoothC: function(x2, y2, x, y, relative) {
+ relative = (isArray(x2) ? y2 : relative);
+ return this._coords((relative ? 's' : 'S'), x2, y2, x, y);
+ },
+
+ /* Draw a quadratic Bzier curve.
+ @param x1 (number) x-coordinate of control point or
+ (number[][]) x-/y-coordinates of control and end points to draw to
+ @param y1 (number) y-coordinate of control point (omitted if x1 is array)
+ @param x (number) x-coordinate of curve end (omitted if x1 is array)
+ @param y (number) y-coordinate of curve end (omitted if x1 is array)
+ @param relative (boolean) true for coordinates relative to the current point,
+ false for coordinates being absolute
+ @return (SVGPath) this path */
+ curveQ: function(x1, y1, x, y, relative) {
+ relative = (isArray(x1) ? y1 : relative);
+ return this._coords((relative ? 'q' : 'Q'), x1, y1, x, y);
+ },
+
+ /* Continue a quadratic Bzier curve.
+ Control point is the reflection of the previous control point.
+ @param x (number) x-coordinate of curve end or
+ (number[][]) x-/y-coordinates of points to draw to
+ @param y (number) y-coordinate of curve end (omitted if x is array)
+ @param relative (boolean) true for coordinates relative to the current point,
+ false for coordinates being absolute
+ @return (SVGPath) this path */
+ smoothQ: function(x, y, relative) {
+ relative = (isArray(x) ? y : relative);
+ return this._coords((relative ? 't' : 'T'), x, y);
+ },
+
+ /* Generate a path command with (a list of) coordinates. */
+ _coords: function(cmd, x1, y1, x2, y2, x3, y3) {
+ if (isArray(x1)) {
+ for (var i = 0; i < x1.length; i++) {
+ var cs = x1[i];
+ this._path += (i == 0 ? cmd : ' ') + cs[0] + ',' + cs[1] +
+ (cs.length < 4 ? '' : ' ' + cs[2] + ',' + cs[3] +
+ (cs.length < 6 ? '': ' ' + cs[4] + ',' + cs[5]));
+ }
+ }
+ else {
+ this._path += cmd + x1 + ',' + y1 +
+ (x2 == null ? '' : ' ' + x2 + ',' + y2 +
+ (x3 == null ? '' : ' ' + x3 + ',' + y3));
+ }
+ return this;
+ },
+
+ /* Draw an arc to a position.
+ @param rx (number) x-radius of arc or
+ (number/boolean[][]) x-/y-coordinates and flags for points to draw to
+ @param ry (number) y-radius of arc (omitted if rx is array)
+ @param xRotate (number) x-axis rotation (degrees, clockwise) (omitted if rx is array)
+ @param large (boolean) true to draw the large part of the arc,
+ false to draw the small part (omitted if rx is array)
+ @param clockwise (boolean) true to draw the clockwise arc,
+ false to draw the anti-clockwise arc (omitted if rx is array)
+ @param x (number) x-coordinate of arc end (omitted if rx is array)
+ @param y (number) y-coordinate of arc end (omitted if rx is array)
+ @param relative (boolean) true for coordinates relative to the current point,
+ false for coordinates being absolute
+ @return (SVGPath) this path */
+ arc: function(rx, ry, xRotate, large, clockwise, x, y, relative) {
+ relative = (isArray(rx) ? ry : relative);
+ this._path += (relative ? 'a' : 'A');
+ if (isArray(rx)) {
+ for (var i = 0; i < rx.length; i++) {
+ var cs = rx[i];
+ this._path += (i == 0 ? '' : ' ') + cs[0] + ',' + cs[1] + ' ' +
+ cs[2] + ' ' + (cs[3] ? '1' : '0') + ',' +
+ (cs[4] ? '1' : '0') + ' ' + cs[5] + ',' + cs[6];
+ }
+ }
+ else {
+ this._path += rx + ',' + ry + ' ' + xRotate + ' ' +
+ (large ? '1' : '0') + ',' + (clockwise ? '1' : '0') + ' ' + x + ',' + y;
+ }
+ return this;
+ },
+
+ /* Close the current path.
+ @return (SVGPath) this path */
+ close: function() {
+ this._path += 'z';
+ return this;
+ },
+
+ /* Return the string rendering of the specified path.
+ @return (string) stringified path */
+ path: function() {
+ return this._path;
+ }
+});
+
+SVGPath.prototype.moveTo = SVGPath.prototype.move;
+SVGPath.prototype.lineTo = SVGPath.prototype.line;
+SVGPath.prototype.horizTo = SVGPath.prototype.horiz;
+SVGPath.prototype.vertTo = SVGPath.prototype.vert;
+SVGPath.prototype.curveCTo = SVGPath.prototype.curveC;
+SVGPath.prototype.smoothCTo = SVGPath.prototype.smoothC;
+SVGPath.prototype.curveQTo = SVGPath.prototype.curveQ;
+SVGPath.prototype.smoothQTo = SVGPath.prototype.smoothQ;
+SVGPath.prototype.arcTo = SVGPath.prototype.arc;
+
+/* Helper to generate an SVG text object.
+ Obtain an instance from the SVGWrapper object.
+ String calls together to generate the text and use its value:
+ var text = root.createText();
+ root.text(null, x, y, text.string('This is ').
+ span('red', {fill: 'red'}).string('!'), {fill: 'blue'}); */
+function SVGText() {
+ this._parts = []; // The components of the text object
+}
+
+$.extend(SVGText.prototype, {
+ /* Prepare to create a new text object.
+ @return (SVGText) this text */
+ reset: function() {
+ this._parts = [];
+ return this;
+ },
+
+ /* Add a straight string value.
+ @param value (string) the actual text
+ @return (SVGText) this text object */
+ string: function(value) {
+ this._parts[this._parts.length] = ['text', value];
+ return this;
+ },
+
+ /* Add a separate text span that has its own settings.
+ @param value (string) the actual text
+ @param settings (object) the settings for this text
+ @return (SVGText) this text object */
+ span: function(value, settings) {
+ this._parts[this._parts.length] = ['tspan', value, settings];
+ return this;
+ },
+
+ /* Add a reference to a previously defined text string.
+ @param id (string) the ID of the actual text
+ @param settings (object) the settings for this text
+ @return (SVGText) this text object */
+ ref: function(id, settings) {
+ this._parts[this._parts.length] = ['tref', id, settings];
+ return this;
+ },
+
+ /* Add text drawn along a path.
+ @param id (string) the ID of the path
+ @param value (string) the actual text
+ @param settings (object) the settings for this text
+ @return (SVGText) this text object */
+ path: function(id, value, settings) {
+ this._parts[this._parts.length] = ['textpath', value,
+ $.extend({href: id}, settings || {})];
+ return this;
+ }
+});
+
+/* Attach the SVG functionality to a jQuery selection.
+ @param command (string) the command to run (optional, default 'attach')
+ @param options (object) the new settings to use for these SVG instances
+ @return jQuery (object) for chaining further calls */
+$.fn.svg = function(options) {
+ var otherArgs = Array.prototype.slice.call(arguments, 1);
+ if (typeof options == 'string' && options == 'get') {
+ return $.svg['_' + options + 'SVG'].apply($.svg, [this[0]].concat(otherArgs));
+ }
+ return this.each(function() {
+ if (typeof options == 'string') {
+ $.svg['_' + options + 'SVG'].apply($.svg, [this].concat(otherArgs));
+ }
+ else {
+ $.svg._attachSVG(this, options || {});
+ }
+ });
+};
+
+/* Determine whether an object is an array. */
+function isArray(a) {
+ return (a && a.constructor == Array);
+}
+
+// Singleton primary SVG interface
+$.svg = new SVGManager();
+
+})(jQuery);
diff --git a/js/jquery.svg.pack.js b/js/jquery.svg.pack.js
new file mode 100755
index 0000000..4727218
--- /dev/null
+++ b/js/jquery.svg.pack.js
@@ -0,0 +1,7 @@
+/* http://keith-wood.name/svg.html
+ SVG for jQuery v1.4.2.
+ Written by Keith Wood (kbwood{at}iinet.com.au) August 2007.
+ Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+ MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+ Please attribute the author if you use it. */
+eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(9($){9 2f(){7.1U=[];7.1V=[];7.2g=[];7.2g[\'\']={2Q:\'4d 4e\',2R:\'4f 1s 4g 4h 4i 2h\'};7.2i=7.2g[\'\'];7.2S=1d 4j().4k();7.2j=2T(\'4l.4m\')}9 2T(a){1t{u!!(4n.2k&&1d 2k(a))}1u(e){u 1H}}8 p=\'4o\';$.G(2f.R,{1C:\'4p\',1W:\'2U://2V.2W.2X/4q/B\',1h:\'2U://2V.2W.2X/4r/2l\',2Y:2m,2Z:{4s:\'30\',4t:\'1X\',4u:\'4v-2n\',4w:\'2n-4x\',4y:\'31-19\',4z:\'31-32\',4A:\'1D-33\',4B:\'1D-33-4C\',4D:\'1D-2o\',4E:\'4F-2n\',4G:\'4H-4I\',4J:\'34-1Y\',4K:\'34-32\',4L:\'35-1D\',4M:\'35-1Y\',4N:\'1v-4O\',4P:\'1v-36\',4Q:\'1v-36-4R\',4S:\'1v-4T\',4U:\'1v-1I\',4V:\'1v-4W\',4X:\'1v-4Y\',4Z:\'37-38-50\',51:\'37-38-52\',53:\'1Z-39-x\',54:\'1Z-3a-x\',55:\'21-2o\',56:\'57-3b\',58:\'59-1D\',5a:\'1J-5b\',5c:\'1J-5d\',5e:\'1J-5f\',3c:\'2p-1D\',3d:\'2p-1Y\',5g:\'3e-3f\',5h:\'3e-3g\',5i:\'1w-5j\',5k:\'1w-5l\',5m:\'1w-5n\',5o:\'1w-5p\',5q:\'1w-5r\',5s:\'1w-1Y\',5t:\'1w-P\',5u:\'13-5v\',5w:\'13-5x\',5y:\'13-2o\',5z:\'3h-3f\',5A:\'3h-3g\',5B:\'22-39-y\',5C:\'22-3a-y\',5D:\'5E-3b\',5F:\'5G-5H\'},3i:9(a,b){w($(a).2q(7.1C)){u}w(16 b==\'1i\'){b={23:b}}Y w(16 b==\'9\'){b={1l:b}}$(a).5I(7.1C);1t{8 c=24.2r(7.1W,\'B\');c.1x(\'2s\',\'1.1\');c.1x(\'P\',a.3j);c.1x(\'U\',a.3k);a.11(c);7.2t(a,c,b)}1u(e){w($.1s.25){w(!a.D){a.D=\'B\'+(7.2S++)}7.1U[a.D]=b;a.3l=\'<5J 1y="21/B+2u" P="3m%" \'+\'U="3m%" 5K="\'+(b.5L||\'\')+\'5M.B"/>\'}Y{a.3l=\'<p 30="5N">\'+7.2i.2R+\'</p>\'}}},3n:9(){12(8 i=0;i<24.2v.N;i++){8 a=24.2v[i].3o;w(!$(a).2q($.B.1C)||$.2w(a,p)){5O}8 b=W;1t{b=24.2v[i].5P()}1u(e){5Q($.B.3n,5R);u}b=(b?b.1K:W);w(b){$.B.2t(a,b)}}},2t:9(a,b,c){8 c=c||7.1U[a.D];7.1U[a.D]=W;8 d=1d 7.2Y(b,a);$.2w(a,p,d);1t{w(c.23){d.3p(c.23,c)}w(c.E){d.1L(c.E)}w(c.1l&&!c.23){c.1l.1M(a,[d])}}1u(e){5S(e)}},5T:9(a){a=(16 a==\'1i\'?$(a)[0]:(a.3q?a[0]:a));u $.2w(a,p)},5U:9(a){8 b=$(a);w(!b.2q(7.1C)){u}b.5V(7.1C).5W();$.5X(a,p)},5Y:9(a,b){7.1V.5Z([a,b])}});9 2m(a,b){7.O=a;7.1N=b;12(8 i=0;i<$.B.1V.N;i++){8 c=$.B.1V[i];7[c[0]]=1d c[1](7)}}$.G(2m.R,{60:9(){u 7.1N.3j},61:9(){u 7.1N.3k},62:9(){u 7.O},1L:9(a,b){w(b){12(8 i=7.O.1e.N-1;i>=0;i--){8 c=7.O.1e.26(i);w(!(c.15==\'63\'||c.15==\'2s\'||c.15.1E(0,5)==\'2x\')){7.O.1e.64(c.15)}}}12(8 d 1X a){7.O.1x(d,a[d])}u 7},3r:9(a){u 7.O.17.3r(a)},65:9(a,b){w(a){12(8 c 1X b){w(b[c]==W){a.66(c)}Y{a.1x(c,b[c])}}}u 7},J:9(b,c,d){c.3s(0,0,\'F\');c.3s(c.N,0,\'E\');8 e={};8 f=0;w(b[0]!=W&&(16 b[0]!=\'2y\'||!b[0].15)){e[\'F\']=W;f=1}12(8 i=0;i<b.N;i++){e[c[i+f]]=b[i]}w(d){$.2z(d,9(i,a){w(16 e[a]==\'2y\'){e.E=e[a];e[a]=W}})}u e},3t:9(a,b,c){8 d=7.J(I,[\'13\']);8 e=7.K(d.F,\'3t\',d.E||{});e.11(7.O.17.1f(d.13));u e},67:9(a,b,c){8 d=7.J(I,[\'13\']);8 e=7.K(d.F,\'68\',d.E||{});e.11(7.O.17.1f(d.13));u e},3u:9(a,b,c){8 d=7.J(I,[\'D\'],[\'D\']);u 7.K(d.F,\'3u\',$.G((d.D?{D:d.D}:{}),d.E||{}))},3v:9(a,b,c,d,e,f,g){8 h=7.J(I,[\'D\',\'1g\',\'1m\',\'1n\',\'1o\']);u 7.K(h.F,\'3v\',$.G({D:h.D,2A:h.1g+\' \'+h.1m+\' \'+h.1n+\' \'+h.1o},h.E||{}))},1J:9(a,b,c,d,e,f,g,h){8 i=7.J(I,[\'D\',\'2B\',\'2C\',\'3w\',\'3x\',\'27\'],[\'27\']);u 7.K(i.F,\'1J\',$.G({D:i.D,2B:i.2B,2C:i.2C,69:i.3w,6a:i.3x,27:i.27||\'6b\'},i.E||{}))},1I:9(a,b,c){8 d=7.J(I,[\'2D\']);8 e=7.K(d.F,\'1I\',$.G({1y:\'13/3y\'},d.E||{}));e.11(7.O.17.1f(d.2D));w($.1s.6c){$(\'6d\').6e(\'<1I 1y="13/3y">\'+d.2D+\'</1I>\')}u e},1O:9(a,b,c,d){8 e=7.J(I,[\'1O\',\'1y\'],[\'1y\']);8 f=7.K(e.F,\'1O\',$.G({1y:e.1y||\'13/6f\'},e.E||{}));f.11(7.O.17.1f(7.3z(e.1O)));w(!$.1s.6g){$.6h(e.1O)}u f},3A:9(a,b,c,d,e,f,g,h){8 i=7.J(I,[\'D\',\'28\',\'1g\',\'1m\',\'1n\',\'1o\'],[\'1g\']);8 j=$.G({D:i.D},(i.1g!=W?{1g:i.1g,1m:i.1m,1n:i.1n,1o:i.1o}:{}));u 7.2E(i.F,\'3A\',$.G(j,i.E||{}),i.28)},3B:9(a,b,c,d,e,r,f,g,h){8 i=7.J(I,[\'D\',\'28\',\'1b\',\'1j\',\'r\',\'2F\',\'2G\'],[\'1b\']);8 j=$.G({D:i.D},(i.1b!=W?{1b:i.1b,1j:i.1j,r:i.r,2F:i.2F,2G:i.2G}:{}));u 7.2E(i.F,\'3B\',$.G(j,i.E||{}),i.28)},2E:9(a,b,c,d){8 e=7.K(a,b,c);12(8 i=0;i<d.N;i++){8 f=d[i];7.K(e,\'2p\',$.G({6i:f[0],3c:f[1]},(f[2]!=W?{3d:f[2]}:{})))}u e},3C:9(a,b,x,y,c,d,e,f,g,h,i){8 j=7.J(I,[\'D\',\'x\',\'y\',\'P\',\'U\',\'1p\',\'29\',\'2a\',\'2b\'],[\'1p\']);8 k=$.G({D:j.D,x:j.x,y:j.y,P:j.P,U:j.U},(j.1p!=W?{2A:j.1p+\' \'+j.29+\' \'+j.2a+\' \'+j.2b}:{}));u 7.K(j.F,\'3C\',$.G(k,j.E||{}))},3D:9(a,b,x,y,c,d,e){8 f=7.J(I,[\'D\',\'x\',\'y\',\'P\',\'U\']);u 7.K(f.F,\'3D\',$.G({D:f.D,x:f.x,y:f.y,P:f.P,U:f.U},f.E||{}))},6j:9(){u 1d X()},6k:9(){u 1d 2H()},B:9(a,x,y,b,c,d,e,f,g,h){8 i=7.J(I,[\'x\',\'y\',\'P\',\'U\',\'1p\',\'29\',\'2a\',\'2b\'],[\'1p\']);8 j=$.G({x:i.x,y:i.y,P:i.P,U:i.U},(i.1p!=W?{2A:i.1p+\' \'+i.29+\' \'+i.2a+\' \'+i.2b}:{}));u 7.K(i.F,\'B\',$.G(j,i.E||{}))},6l:9(a,b,c){8 d=7.J(I,[\'D\'],[\'D\']);u 7.K(d.F,\'g\',$.G({D:d.D},d.E||{}))},3E:9(a,x,y,b,c,d,e){8 f=7.J(I,[\'x\',\'y\',\'P\',\'U\',\'1q\']);w(16 f.x==\'1i\'){f.1q=f.x;f.E=f.y;f.x=f.y=f.P=f.U=W}8 g=7.K(f.F,\'3E\',$.G({x:f.x,y:f.y,P:f.P,U:f.U},f.E||{}));g.1z($.B.1h,\'1k\',f.1q);u g},6m:9(a,b,c){8 d=7.J(I,[\'1q\']);8 e=7.K(d.F,\'a\',d.E);e.1z($.B.1h,\'1k\',d.1q);u e},21:9(a,x,y,b,c,d,e){8 f=7.J(I,[\'x\',\'y\',\'P\',\'U\',\'1q\']);8 g=7.K(f.F,\'21\',$.G({x:f.x,y:f.y,P:f.P,U:f.U},f.E||{}));g.1z($.B.1h,\'1k\',f.1q);u g},19:9(a,b,c){8 d=7.J(I,[\'19\']);u 7.K(d.F,\'19\',$.G({d:(d.19.19?d.19.19():d.19)},d.E||{}))},3F:9(a,x,y,b,c,d,e,f){8 g=7.J(I,[\'x\',\'y\',\'P\',\'U\',\'1r\',\'1F\'],[\'1r\']);u 7.K(g.F,\'3F\',$.G({x:g.x,y:g.y,P:g.P,U:g.U},(g.1r?{1r:g.1r,1F:g.1F}:{}),g.E||{}))},3G:9(a,b,c,r,d){8 e=7.J(I,[\'1b\',\'1j\',\'r\']);u 7.K(e.F,\'3G\',$.G({1b:e.1b,1j:e.1j,r:e.r},e.E||{}))},3H:9(a,b,c,d,e,f){8 g=7.J(I,[\'1b\',\'1j\',\'1r\',\'1F\']);u 7.K(g.F,\'3H\',$.G({1b:g.1b,1j:g.1j,1r:g.1r,1F:g.1F},g.E||{}))},2c:9(a,b,c,d,e,f){8 g=7.J(I,[\'1g\',\'1m\',\'1n\',\'1o\']);u 7.K(g.F,\'2c\',$.G({1g:g.1g,1m:g.1m,1n:g.1n,1o:g.1o},g.E||{}))},3I:9(a,b,c){8 d=7.J(I,[\'1P\']);u 7.2I(d.F,\'3I\',d.1P,d.E)},3J:9(a,b,c){8 d=7.J(I,[\'1P\']);u 7.2I(d.F,\'3J\',d.1P,d.E)},2I:9(a,b,c,d){8 e=\'\';12(8 i=0;i<c.N;i++){e+=c[i].1Q()+\' \'}u 7.K(a,b,$.G({1P:$.2d(e)},d||{}))},13:9(a,x,y,b,c){8 d=7.J(I,[\'x\',\'y\',\'1R\']);w(16 d.x==\'1i\'&&I.N<4){d.1R=d.x;d.E=d.y;d.x=d.y=W}u 7.2J(d.F,\'13\',d.1R,$.G({x:(d.x&&18(d.x)?d.x.1Q(\' \'):d.x),y:(d.y&&18(d.y)?d.y.1Q(\' \'):d.y)},d.E||{}))},2K:9(a,b,c,d){8 e=7.J(I,[\'19\',\'1R\']);8 f=7.2J(e.F,\'6n\',e.1R,e.E||{});f.1z($.B.1h,\'1k\',e.19);u f},2J:9(a,b,c,d){8 e=7.K(a,b,d);w(16 c==\'1i\'){e.11(e.17.1f(c))}Y{12(8 i=0;i<c.1a.N;i++){8 f=c.1a[i];w(f[0]==\'3K\'){8 g=7.K(e,f[0],f[2]);g.11(e.17.1f(f[1]));e.11(g)}Y w(f[0]==\'3L\'){8 g=7.K(e,f[0],f[2]);g.1z($.B.1h,\'1k\',f[1]);e.11(g)}Y w(f[0]==\'2K\'){8 h=$.G({},f[2]);h.1k=W;8 g=7.K(e,f[0],h);g.1z($.B.1h,\'1k\',f[2].1k);g.11(e.17.1f(f[1]));e.11(g)}Y{e.11(e.17.1f(f[1]))}}}u e},6o:9(a,b,c){8 d=7.J(I,[\'3M\']);u 7.K(d.F,d.3M,d.E||{})},K:9(a,b,c){a=a||7.O;8 d=7.O.17.2r($.B.1W,b);12(8 b 1X c){8 e=c[b];w(e!=W&&e!=W&&(16 e!=\'1i\'||e!=\'\')){d.1x($.B.2Z[b]||b,e)}}a.11(d);u d},3N:9(b,c){8 d=7.J(I,[\'1A\']);8 f=7;d.F=d.F||7.O;1t{w($.B.2j){3O\'3P 3Q\';}d.F.11(d.1A.3R(2e))}1u(e){d.1A=(d.1A.3q?d.1A:$(d.1A));d.1A.2z(9(){8 a=f.2L(7);w(a){d.F.11(a)}})}u 7},2L:9(a){8 b=W;w(a.1S==1){b=7.O.17.2r($.B.1W,7.2M(a.15));12(8 i=0;i<a.1e.N;i++){8 c=a.1e.26(i);w(c.15!=\'2x\'&&c.14){w(c.6p==\'2l\'){b.1z($.B.1h,c.6q,c.14)}Y{b.1x(7.2M(c.15),c.14)}}}12(8 i=0;i<a.2N.N;i++){8 d=7.2L(a.2N[i]);w(d){b.11(d)}}}Y w(a.1S==3){w($.2d(a.14)){b=7.O.17.1f(a.14)}}Y w(a.1S==4){w($.2d(a.14)){1t{b=7.O.17.6r(a.14)}1u(e){b=7.O.17.1f(a.14.1G(/&/g,\'&3S;\').1G(/</g,\'&3T;\').1G(/>/g,\'&3U;\'))}}}u b},2M:9(a){a=(a.1E(0,1)>=\'A\'&&a.1E(0,1)<=\'Z\'?a.6s():a);u(a.1E(0,4)==\'B:\'?a.1E(4):a)},3p:9(h,j){j=(16 j==\'6t\'?{3V:j}:(16 j==\'9\'?{1l:j}:j||{}));w(!j.3V){7.3W(1H)}8 k=[7.O.3X(\'P\'),7.O.3X(\'U\')];8 l=7;8 m=9(a){a=$.B.2i.2Q+\': \'+a;w(j.1l){j.1l.1M(l.1N,[l,a])}Y{l.13(W,10,20,a)}};8 n=9(a){8 b=1d 2k(\'6u.6v\');b.6w=1H;b.6x=1H;b.6y=1H;b.6z(a);w(b.3Y.6A!=0){m(b.3Y.6B);u W}u b};8 o=9(a){w(!a){u}w(a.1K.15!=\'B\'){8 b=a.3Z(\'6C\');8 c=(b.N?b[0].3Z(\'6D\'):[]);m(!b.N?\'???\':(c.N?c[0]:b[0]).1T.14);u}8 d={};12(8 i=0;i<a.1K.1e.N;i++){8 f=a.1K.1e.26(i);w(!(f.15==\'2s\'||f.15.1E(0,5)==\'2x\')){d[f.15]=f.14}}l.1L(d,2e);8 g=a.1K.2N;12(8 i=0;i<g.N;i++){1t{w($.B.2j){3O\'3P 3Q\';}l.O.11(g[i].3R(2e))}1u(e){l.3N(W,g[i])}}w(!j.6E){l.1L({P:k[0],U:k[1]})}w(j.1l){j.1l.1M(l.1N,[l])}};w(h.2O(\'<B\')){o($.1s.25?n(h):1d 6F().6G(h,\'13/2u\'))}Y{$.6H({6I:h,6J:($.1s.25?\'13\':\'2u\'),6K:9(a){o($.1s.25?n(a):a)},6L:9(a,b,c){m(b+(c?\' \'+c.6M:\'\'))}})}u 7},6N:9(a){a.3o.40(a);u 7},3W:9(a){w(a){7.1L({},2e)}41(7.O.1T){7.O.40(7.O.1T)}u 7},6O:9(a){a=a||7.O;u(16 42==\'6P\'?7.2P(a):1d 42().6Q(a))},2P:9(a){8 b=\'\';w(!a){u b}w(a.1S==3){b=a.14}Y w(a.1S==4){b=\'<![6R[\'+a.14+\']]>\'}Y{b=\'<\'+a.15;w(a.1e){12(8 i=0;i<a.1e.N;i++){8 c=a.1e.26(i);w(!($.2d(c.14)==\'\'||c.14.2O(/^\\[2y/)||c.14.2O(/^9/))){b+=\' \'+(c.6S==$.B.1h?\'2l:\':\'\')+c.15+\'="\'+c.14+\'"\'}}}w(a.1T){b+=\'>\';8 d=a.1T;41(d){b+=7.2P(d);d=d.6T}b+=\'</\'+a.15+\'>\'}Y{b+=\'/>\'}}u b},3z:9(a){a=a.1G(/&/g,\'&3S;\');a=a.1G(/</g,\'&3T;\');a=a.1G(/>/g,\'&3U;\');u a}});9 X(){7.1c=\'\'}$.G(X.R,{43:9(){7.1c=\'\';u 7},44:9(x,y,a){a=(18(x)?y:a);u 7.1B((a?\'m\':\'M\'),x,y)},2c:9(x,y,a){a=(18(x)?y:a);u 7.1B((a?\'l\':\'L\'),x,y)},1Z:9(x,a){7.1c+=(a?\'h\':\'H\')+(18(x)?x.1Q(\' \'):x);u 7},22:9(y,a){7.1c+=(a?\'v\':\'V\')+(18(y)?y.1Q(\' \'):y);u 7},45:9(a,b,c,d,x,y,e){e=(18(a)?b:e);u 7.1B((e?\'c\':\'C\'),a,b,c,d,x,y)},46:9(a,b,x,y,c){c=(18(a)?b:c);u 7.1B((c?\'s\':\'S\'),a,b,x,y)},47:9(a,b,x,y,c){c=(18(a)?b:c);u 7.1B((c?\'q\':\'Q\'),a,b,x,y)},48:9(x,y,a){a=(18(x)?y:a);u 7.1B((a?\'t\':\'T\'),x,y)},1B:9(a,b,c,d,e,f,g){w(18(b)){12(8 i=0;i<b.N;i++){8 h=b[i];7.1c+=(i==0?a:\' \')+h[0]+\',\'+h[1]+(h.N<4?\'\':\' \'+h[2]+\',\'+h[3]+(h.N<6?\'\':\' \'+h[4]+\',\'+h[5]))}}Y{7.1c+=a+b+\',\'+c+(d==W?\'\':\' \'+d+\',\'+e+(f==W?\'\':\' \'+f+\',\'+g))}u 7},49:9(a,b,c,d,e,x,y,f){f=(18(a)?b:f);7.1c+=(f?\'a\':\'A\');w(18(a)){12(8 i=0;i<a.N;i++){8 g=a[i];7.1c+=(i==0?\'\':\' \')+g[0]+\',\'+g[1]+\' \'+g[2]+\' \'+(g[3]?\'1\':\'0\')+\',\'+(g[4]?\'1\':\'0\')+\' \'+g[5]+\',\'+g[6]}}Y{7.1c+=a+\',\'+b+\' \'+c+\' \'+(d?\'1\':\'0\')+\',\'+(e?\'1\':\'0\')+\' \'+x+\',\'+y}u 7},6U:9(){7.1c+=\'z\';u 7},19:9(){u 7.1c}});X.R.6V=X.R.44;X.R.6W=X.R.2c;X.R.6X=X.R.1Z;X.R.6Y=X.R.22;X.R.6Z=X.R.45;X.R.70=X.R.46;X.R.71=X.R.47;X.R.72=X.R.48;X.R.73=X.R.49;9 2H(){7.1a=[]}$.G(2H.R,{43:9(){7.1a=[];u 7},1i:9(a){7.1a[7.1a.N]=[\'13\',a];u 7},74:9(a,b){7.1a[7.1a.N]=[\'3K\',a,b];u 7},1q:9(a,b){7.1a[7.1a.N]=[\'3L\',a,b];u 7},19:9(a,b,c){7.1a[7.1a.N]=[\'2K\',b,$.G({1k:a},c||{})];u 7}});$.75.B=9(a){8 b=4a.R.76.77(I,1);w(16 a==\'1i\'&&a==\'78\'){u $.B[\'4b\'+a+\'2h\'].1M($.B,[7[0]].4c(b))}u 7.2z(9(){w(16 a==\'1i\'){$.B[\'4b\'+a+\'2h\'].1M($.B,[7].4c(b))}Y{$.B.3i(7,a||{})}})};9 18(a){u(a&&a.79==4a)}$.B=1d 2f()})(7a);',62,445,'|||||||this|var|function|||||||||||||||||||||return||if|||||svg||id|settings|parent|extend||arguments|_args|_makeNode|||length|_svg|width||prototype|||height||null|SVGPath|else|||appendChild|for|text|nodeValue|nodeName|typeof|ownerDocument|isArray|path|_parts|cx|_path|new|attributes|createTextNode|x1|xlinkNS|string|cy|href|onLoad|y1|x2|y2|vx|ref|rx|browser|try|catch|font|stroke|setAttribute|type|setAttributeNS|node|_coords|markerClassName|color|substring|ry|replace|false|style|marker|documentElement|configure|apply|_container|script|points|join|value|nodeType|firstChild|_settings|_extensions|svgNS|in|opacity|horiz||image|vert|loadURL|document|msie|item|orient|stops|vy|vwidth|vheight|line|trim|true|SVGManager|regional|SVG|local|_renesis|ActiveXObject|xlink|SVGWrapper|baseline|rendering|stop|hasClass|createElementNS|version|_afterLoad|xml|embeds|data|xmlns|object|each|viewBox|refX|refY|styles|_gradient|fx|fy|SVGText|_poly|_text|textpath|_cloneAsSVG|_checkName|childNodes|match|_toSVG|errorLoadingText|notSupportedText|_uuid|detectActiveX|http|www|w3|org|_wrapperClass|_attrNames|class|clip|rule|interpolation|fill|flood|size|glyph|orientation|adv|origin|spacing|stopColor|stopOpacity|strikethrough|position|thickness|underline|_attachSVG|clientWidth|clientHeight|innerHTML|100|_registerSVG|parentNode|load|jquery|getElementById|splice|title|defs|symbol|mWidth|mHeight|css|_escapeXML|linearGradient|radialGradient|pattern|mask|use|rect|circle|ellipse|polyline|polygon|tspan|tref|name|add|throw|Force|traversal|cloneNode|amp|lt|gt|addTo|clear|getAttribute|parseError|getElementsByTagName|removeChild|while|XMLSerializer|reset|move|curveC|smoothC|curveQ|smoothQ|arc|Array|_|concat|Error|loading|This|does|not|support|Date|getTime|RenesisX|RenesisCtrl|window|svgwrapper|hasSVG|2000|1999|class_|in_|alignmentBaseline|alignment|baselineShift|shift|clipPath|clipRule|colorInterpolation|colorInterpolationFilters|filters|colorRendering|dominantBaseline|dominant|enableBackground|enable|background|fillOpacity|fillRule|floodColor|floodOpacity|fontFamily|family|fontSize|fontSizeAdjust|adjust|fontStretch|stretch|fontStyle|fontVariant|variant|fontWeight|weight|glyphOrientationHorizontal|horizontal|glyphOrientationVertical|vertical|horizAdvX|horizOriginX|imageRendering|letterSpacing|letter|lightingColor|lighting|markerEnd|end|markerMid|mid|markerStart|start|strikethroughPosition|strikethroughThickness|strokeDashArray|dasharray|strokeDashOffset|dashoffset|strokeLineCap|linecap|strokeLineJoin|linejoin|strokeMiterLimit|miterlimit|strokeOpacity|strokeWidth|textAnchor|anchor|textDecoration|decoration|textRendering|underlinePosition|underlineThickness|vertAdvY|vertOriginY|wordSpacing|word|writingMode|writing|mode|addClass|embed|src|initPath|blank|svg_error|continue|getSVGDocument|setTimeout|250|alert|_getSVG|_destroySVG|removeClass|empty|removeData|addExtension|push|_width|_height|root|onload|removeNamedItem|change|removeAttribute|describe|desc|markerWidth|markerHeight|auto|opera|head|append|javascript|mozilla|globalEval|offset|createPath|createText|group|link|textPath|other|prefix|localName|createCDATASection|toLowerCase|boolean|Microsoft|XMLDOM|validateOnParse|resolveExternals|async|loadXML|errorCode|reason|parsererror|div|changeSize|DOMParser|parseFromString|ajax|url|dataType|success|error|message|remove|toSVG|undefined|serializeToString|CDATA|namespaceURI|nextSibling|close|moveTo|lineTo|horizTo|vertTo|curveCTo|smoothCTo|curveQTo|smoothQTo|arcTo|span|fn|slice|call|get|constructor|jQuery'.split('|'),0,{})) \ No newline at end of file
diff --git a/js/jquery.svgdom.js b/js/jquery.svgdom.js
new file mode 100644
index 0000000..e350298
--- /dev/null
+++ b/js/jquery.svgdom.js
@@ -0,0 +1,356 @@
+/* http://keith-wood.name/svg.html
+ SVG/jQuery DOM compatibility for jQuery v1.4.2.
+ Written by Keith Wood (kbwood{at}iinet.com.au) April 2009.
+ Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+ MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+ Please attribute the author if you use it. */
+
+(function($) { // Hide scope, no $ conflict
+
+/* Support adding class names to SVG nodes. */
+var origAddClass = $.fn.addClass;
+
+$.fn.addClass = function(classNames) {
+ classNames = classNames || '';
+ return this.each(function() {
+ if (isSVGElem(this)) {
+ var node = this;
+ $.each(classNames.split(/\s+/), function(i, className) {
+ var classes = (node.className ? node.className.baseVal : node.getAttribute('class'));
+ if ($.inArray(className, classes.split(/\s+/)) == -1) {
+ classes += (classes ? ' ' : '') + className;
+ (node.className ? node.className.baseVal = classes :
+ node.setAttribute('class', classes));
+ }
+ });
+ }
+ else {
+ origAddClass.apply($(this), [classNames]);
+ }
+ });
+};
+
+/* Support removing class names from SVG nodes. */
+var origRemoveClass = $.fn.removeClass;
+
+$.fn.removeClass = function(classNames) {
+ classNames = classNames || '';
+ return this.each(function() {
+ if (isSVGElem(this)) {
+ var node = this;
+ $.each(classNames.split(/\s+/), function(i, className) {
+ var classes = (node.className ? node.className.baseVal : node.getAttribute('class'));
+ classes = $.grep(classes.split(/\s+/), function(n, i) { return n != className; }).
+ join(' ');
+ (node.className ? node.className.baseVal = classes :
+ node.setAttribute('class', classes));
+ });
+ }
+ else {
+ origRemoveClass.apply($(this), [classNames]);
+ }
+ });
+};
+
+/* Support toggling class names on SVG nodes. */
+var origToggleClass = $.fn.toggleClass;
+
+$.fn.toggleClass = function(className, state) {
+ return this.each(function() {
+ if (isSVGElem(this)) {
+ if (typeof state !== 'boolean') {
+ state = !$(this).hasClass(className);
+ }
+ $(this)[(state ? 'add' : 'remove') + 'Class'](className);
+ }
+ else {
+ origToggleClass.apply($(this), [className, state]);
+ }
+ });
+};
+
+/* Support checking class names on SVG nodes. */
+var origHasClass = $.fn.hasClass;
+
+$.fn.hasClass = function(className) {
+ className = className || '';
+ var found = false;
+ this.each(function() {
+ if (isSVGElem(this)) {
+ var classes = (this.className ? this.className.baseVal :
+ this.getAttribute('class')).split(/\s+/);
+ found = ($.inArray(className, classes) > -1);
+ }
+ else {
+ found = (origHasClass.apply($(this), [className]));
+ }
+ return !found;
+ });
+ return found;
+};
+
+/* Support attributes on SVG nodes. */
+var origAttr = $.fn.attr;
+
+//BWB: is this what i need to do for css?
+$.fn.attr = function(name, value, type) {
+ if (typeof name === 'string' && value === undefined) {
+ var val = origAttr.apply(this, [name, value, type]);
+ return (val && val.baseVal ? val.baseVal.valueAsString : val);
+ }
+ var options = name;
+ if (typeof name === 'string') {
+ options = {};
+ options[name] = value;
+ }
+ return this.each(function() {
+ if (isSVGElem(this)) {
+ for (var n in options) {
+ this.setAttribute(n,
+ (typeof options[n] == 'function' ? options[n]() : options[n]));
+ }
+ }
+ else {
+ origAttr.apply($(this), [name, value, type]);
+ }
+ });
+};
+
+// BWB attempting to patch css manipulation of SVG
+//support manipulation of css styles
+var origCss = $.fn.css;
+
+$.fn.css = function(name, value, type) {
+ var revAttrName = function(name){
+ for (var jsName in $.svg._attrNames){
+ if ($.svg._attrNames[jsName] === name){
+ return jsName;
+ }
+ }
+ return name;
+ };
+
+ if (typeof name === 'string' && value === undefined) {
+ var val = origCss.apply(this, [name, value, type]);
+ return (val && val.baseVal ? val.baseVal.valueAsString : val);
+ }
+ var options = name;
+ if (typeof name === 'string') {
+ options = {};
+ options[name] = value;
+ }
+ return this.each(function() {
+ if (isSVGElem(this)) {
+ for (var n in options) {
+ //if Firefox
+ if (this.style.MozBinding === "") {
+ var jsName = revAttrName(n);
+ console.log(jsName);
+ this.style[jsName] = options[n];
+ (typeof options[n] === 'function' ? options[n]() : options[n]);
+ } else {
+ this.style.setProperty(n,
+ typeof options[n] == 'function' ? options[n]() : options[n]);
+ }
+ }
+ }
+ else {
+ origCss.apply($(this), [name, value, type]);
+ }
+ });
+};
+
+
+/* Support removing attributes on SVG nodes. */
+var origRemoveAttr = $.fn.removeAttr;
+
+$.fn.removeAttr = function(name) {
+ return this.each(function() {
+ if (isSVGElem(this)) {
+ (this[name] && this[name].baseVal ? this[name].baseVal.value = '' :
+ this.setAttribute(name, ''));
+ }
+ else {
+ origRemoveAttr.apply($(this), [name]);
+ }
+ });
+};
+
+/* Update Sizzle selectors. */
+var origRelativeNext = $.expr.relative['+'];
+var origRelativeChild = $.expr.relative['>'];
+var origRelativeDescendant = $.expr.relative[''];
+var origRelativeSiblings = $.expr.relative['~'];
+var origFindId = $.expr.find.ID;
+var origFindTag = $.expr.find.TAG;
+var origPreFilterClass = $.expr.preFilter.CLASS;
+var origFilterClass = $.expr.filter.CLASS;
+var origFilterAttr = $.expr.filter.ATTR;
+
+/* Determine if any nodes are SVG nodes. */
+function anySVG(checkSet) {
+ for (var i = 0; i < checkSet.length; i++) {
+ if (checkSet[i].nodeType == 1 && checkSet[i].namespaceURI == $.svg.svgNS) {
+ return true;
+ }
+ }
+ return false;
+}
+
+$.expr.relative['+'] = function(checkSet, part, isXML) {
+ origRelativeNext(checkSet, part, isXML || anySVG(checkSet));
+};
+
+$.expr.relative['>'] = function(checkSet, part, isXML) {
+ origRelativeChild(checkSet, part, isXML || anySVG(checkSet));
+};
+
+$.expr.relative[''] = function(checkSet, part, isXML) {
+ origRelativeDescendant(checkSet, part, isXML || anySVG(checkSet));
+};
+
+$.expr.relative['~'] = function(checkSet, part, isXML) {
+ origRelativeSiblings(checkSet, part, isXML || anySVG(checkSet));
+};
+
+$.expr.find.ID = function(match, context, isXML) {
+ return (isSVGElem(context) ?
+ [context.ownerDocument.getElementById(match[1])] :
+ origFindId(match, context, isXML));
+};
+
+var div = document.createElement('div');
+div.appendChild(document.createComment(''));
+if (div.getElementsByTagName('*').length > 0) { // Make sure no comments are found
+ $.expr.find.TAG = function(match, context) {
+ var results = context.getElementsByTagName(match[1]);
+ if (match[1] === '*') { // Filter out possible comments
+ var tmp = [];
+ for (var i = 0; results[i] || results.item(i); i++) {
+ if ((results[i] || results.item(i)).nodeType === 1) {
+ tmp.push(results[i] || results.item(i));
+ }
+ }
+ results = tmp;
+ }
+ return results;
+ };
+}
+
+$.expr.preFilter.CLASS = function(match, curLoop, inplace, result, not, isXML) {
+ match = ' ' + match[1].replace(/\\/g, '') + ' ';
+ if (isXML) {
+ return match;
+ }
+ for (var i = 0, elem = {}; elem != null; i++) {
+ elem = curLoop[i];
+ if (!elem) {
+ try {
+ elem = curLoop.item(i);
+ }
+ catch (e) {
+ // Ignore
+ }
+ }
+ if (elem) {
+ var className = (!isSVGElem(elem) ? elem.className :
+ (elem.className ? elem.className.baseVal : '') || elem.getAttribute('class'));
+ if (not ^ (className && (' ' + className + ' ').indexOf(match) > -1)) {
+ if (!inplace)
+ result.push(elem);
+ }
+ else if (inplace) {
+ curLoop[i] = false;
+ }
+ }
+ }
+ return false;
+};
+
+$.expr.filter.CLASS = function(elem, match) {
+ var className = (!isSVGElem(elem) ? elem.className :
+ (elem.className ? elem.className.baseVal : elem.getAttribute('class')));
+ return (' ' + className + ' ').indexOf(match) > -1;
+};
+
+$.expr.filter.ATTR = function(elem, match) {
+ var handler = null;
+ if (isSVGElem(elem)) {
+ handler = match[1];
+ $.expr.attrHandle[handler] = function(elem){
+ var attr = elem.getAttribute(handler);
+ return attr && attr.baseVal || attr;
+ };
+ }
+ var filter = origFilterAttr(elem, match);
+ if (handler) {
+ $.expr.attrHandle[handler] = null;
+ }
+ return filter;
+};
+
+/*
+ Change Sizzle initialisation (line 1425) in jQuery v1.3.2 base code...
+
+ if ( toString.call(checkSet) === "[object Array]" ) {
+ if ( !prune ) {
+ results.push.apply( results, checkSet );
+ } else if ( context.nodeType === 1 ) {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
+ results.push( set[i] || set.item(i) ); // Here
+ }
+ }
+ } else {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+ results.push( set[i] || set.item(i) ); // Here
+ }
+ }
+ }
+ }
+
+ Change fallback makeArray (line 2076) implementation in jQuery Sizzle...
+
+ if ( typeof array.length === "number" ) {
+ for ( var i = 0, l = array.length; i < l; i++ ) {
+ ret.push( array[i] || array.item(i) ); // Here
+ }
+ }
+*/
+
+/*
+ Events management requires changes to jQuery v1.3.2 base code...
+
+ In $.event.add (line 2437)...
+
+ if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem, data, namespaces) === false ) {
+ // Bind the global event handler to the element
+ try { // Here
+ elem.addEventListener(type, handle, false);
+ }
+ catch(e) {
+ if (elem.attachEvent)
+ elem.attachEvent("on" + type, handle);
+ }
+ }
+
+ In $.event.remove (line 2521)...
+
+ if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem, namespaces) === false ) {
+ try { // Here
+ elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
+ }
+ catch (e) {
+ if (elem.detachEvent)
+ elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
+ }
+ }
+*/
+
+/* Does this node belong to SVG? */
+function isSVGElem(node) {
+ return (node.nodeType == 1 && node.namespaceURI == $.svg.svgNS);
+}
+
+})(jQuery);
diff --git a/js/jquery.svgdom.pack.js b/js/jquery.svgdom.pack.js
new file mode 100755
index 0000000..be88a52
--- /dev/null
+++ b/js/jquery.svgdom.pack.js
@@ -0,0 +1,7 @@
+/* http://keith-wood.name/svg.html
+ SVG/jQuery DOM compatibility for jQuery v1.4.2.
+ Written by Keith Wood (kbwood{at}iinet.com.au) April 2009.
+ Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+ MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+ Please attribute the author if you use it. */
+eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(4($){2 j=$.9.W;$.9.W=4(d){d=d||\'\';7 3.D(4(){5(C(3)){2 c=3;$.D(d.J(/\\s+/),4(i,a){2 b=(c.8?c.8.A:c.I(\'F\'));5($.X(a,b.J(/\\s+/))==-1){b+=(b?\' \':\'\')+a;(c.8?c.8.A=b:c.L(\'F\',b))}})}G{j.H($(3),[d])}})};2 k=$.9.Y;$.9.Y=4(d){d=d||\'\';7 3.D(4(){5(C(3)){2 c=3;$.D(d.J(/\\s+/),4(i,a){2 b=(c.8?c.8.A:c.I(\'F\'));b=$.1g(b.J(/\\s+/),4(n,i){7 n!=a}).1h(\' \');(c.8?c.8.A=b:c.L(\'F\',b))})}G{k.H($(3),[d])}})};2 l=$.9.Z;$.9.Z=4(a,b){7 3.D(4(){5(C(3)){5(M b!==\'1i\'){b=!$(3).T(a)}$(3)[(b?\'1j\':\'1k\')+\'1l\'](a)}G{l.H($(3),[a,b])}})};2 m=$.9.T;$.9.T=4(b){b=b||\'\';2 c=N;3.D(4(){5(C(3)){2 a=(3.8?3.8.A:3.I(\'F\')).J(/\\s+/);c=($.X(b,a)>-1)}G{c=(m.H($(3),[b]))}7!c});7 c};2 o=$.9.10;$.9.10=4(a,b,c){5(M a===\'11\'&&b===1m){2 d=o.H(3,[a,b,c]);7(d&&d.A?d.A.1n:d)}2 e=a;5(M a===\'11\'){e={};e[a]=b}7 3.D(4(){5(C(3)){O(2 n 1o e){3.L(n,(M e[n]==\'4\'?e[n]():e[n]))}}G{o.H($(3),[a,b,c])}})};2 p=$.9.12;$.9.12=4(a){7 3.D(4(){5(C(3)){(3[a]&&3[a].A?3[a].A.1p=\'\':3.L(a,\'\'))}G{p.H($(3),[a])}})};2 q=$.6.E[\'+\'];2 r=$.6.E[\'>\'];2 s=$.6.E[\'\'];2 t=$.6.E[\'~\'];2 u=$.6.P.13;2 v=$.6.P.14;2 w=$.6.15.Q;2 x=$.6.R.Q;2 y=$.6.R.16;4 K(a){O(2 i=0;i<a.17;i++){5(a[i].U==1&&a[i].18==$.19.1a){7 1q}}7 N}$.6.E[\'+\']=4(a,b,c){q(a,b,c||K(a))};$.6.E[\'>\']=4(a,b,c){r(a,b,c||K(a))};$.6.E[\'\']=4(a,b,c){s(a,b,c||K(a))};$.6.E[\'~\']=4(a,b,c){t(a,b,c||K(a))};$.6.P.13=4(a,b,c){7(C(b)?[b.1r.1s(a[1])]:u(a,b,c))};2 z=1b.1t(\'1u\');z.1v(1b.1w(\'\'));5(z.1c(\'*\').17>0){$.6.P.14=4(a,b){2 c=b.1c(a[1]);5(a[1]===\'*\'){2 d=[];O(2 i=0;c[i]||c.S(i);i++){5((c[i]||c.S(i)).U===1){d.1d(c[i]||c.S(i))}}c=d}7 c}}$.6.15.Q=4(a,b,c,d,f,g){a=\' \'+a[1].1x(/\\\\/g,\'\')+\' \';5(g){7 a}O(2 i=0,B={};B!=V;i++){B=b[i];5(!B){1y{B=b.S(i)}1z(e){}}5(B){2 h=(!C(B)?B.8:(B.8?B.8.A:\'\')||B.I(\'F\'));5(f^(h&&(\' \'+h+\' \').1e(a)>-1)){5(!c)d.1d(B)}G 5(c){b[i]=N}}}7 N};$.6.R.Q=4(a,b){2 c=(!C(a)?a.8:(a.8?a.8.A:a.I(\'F\')));7(\' \'+c+\' \').1e(b)>-1};$.6.R.16=4(c,d){2 e=V;5(C(c)){e=d[1];$.6.1f[e]=4(a){2 b=a.I(e);7 b&&b.A||b}}2 f=y(c,d);5(e){$.6.1f[e]=V}7 f};4 C(a){7(a.U==1&&a.18==$.19.1a)}})(1A);',62,99,'||var|this|function|if|expr|return|className|fn|||||||||||||||||||||||||||baseVal|elem|isSVGElem|each|relative|class|else|apply|getAttribute|split|anySVG|setAttribute|typeof|false|for|find|CLASS|filter|item|hasClass|nodeType|null|addClass|inArray|removeClass|toggleClass|attr|string|removeAttr|ID|TAG|preFilter|ATTR|length|namespaceURI|svg|svgNS|document|getElementsByTagName|push|indexOf|attrHandle|grep|join|boolean|add|remove|Class|undefined|valueAsString|in|value|true|ownerDocument|getElementById|createElement|div|appendChild|createComment|replace|try|catch|jQuery'.split('|'),0,{})) \ No newline at end of file
diff --git a/js/karma.js b/js/karma.js
new file mode 100755
index 0000000..97530d7
--- /dev/null
+++ b/js/karma.js
@@ -0,0 +1,1650 @@
+/* Documentation Note:
+ * Public methods and properties are commented with /** some text *\/
+ * and private methods and properties are commented with //
+ *
+ * Please leave it that way to keep this documentation sane
+ */
+
+
+/*
+* Karma Framework
+* http://karmaeducation.org
+*
+* Copyright (c) 2009
+* Bryan W Berry bryan@olenepal.org
+* Felipe López Toledo zer.subzero@gmail.com
+*
+* Under MIT License:
+* 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.
+*/
+
+/**
+* @fileOverview Contains karma library
+* @author Bryan Berry <bryan@olenepal.org>
+* @author Felipe Lopez Toledo <zer.subzero@gmail.com>
+*/
+
+
+//common.js modules use exports object
+if(!this.exports) {
+ exports = {};
+}
+
+
+
+/** Karma is the namespace for the Karma library and Karma() is the constructor
+ * function for the Karma library object Karma.karma.
+ * Karma() checks if the current document type is set to HTML 5, throws
+ * an error if not. Otherwise, initializes the karma object and returns
+ * a reference to that object.
+ * @namespace Global namespace for Karma library
+ * @param {Object} [options={}] options for intializing Karma library
+ * @param {String} [options.locale=''] sets current locale Not Yet Implemented
+ * @param {Array} [options.image=[]] array of images to be converted into a collection
+ * @param {Array} [options.audio=[]] array of audio to be converted into a collection
+ * @param {Array} [options.video=[]] NYI array of videos to be converted into a collection
+ * @param {Array} [options.svg=[]] array of SVG elements to be
+ * converted into a collection. Each SVG element must already exist in the html document
+ * @param {Array} [options.canvas=[]] array of canvas elements
+ * to be converted into a collection. Each canvas element must already exist in the
+ * html document and width and height of each element must be set as attributes
+ * @throws {Error} if the document type declaration is not set to HTML 5, e.g.
+ * <!DOCTYPE html>
+ * @throws {Error} If any of the initialization parameters are invalid values
+ * @returns {Object} Karma.karma -- reference to the initialized Karma library
+ * @example
+ *
+ * var k = Karma({
+ * image: [
+ * {name: "ninja", file: "ninja.png"},
+ * {name: "cowboy", file: "cowboy.png"}
+ * ],
+ * audio: [
+ * {name: "woosh", file: "woosh.ogg"},
+ * {name: "yeehaw", file: "yeehaw.ogg"}
+ * ],
+ * video: [ //Not Yet Implemented
+ * {name: "attack", file: "attack.ogv"},
+ * {name: "ride", file: "ride.ogv"}
+ * ]
+ * canvas: [
+ * {name: "ninja", domId: "ninjaCanvas"},
+ * {name: "cowboy", domId: "cowboyCanvas"}
+ * ],
+ * svg: [
+ * {name: "ninja", domId: "ninjaSvg"},
+ * {name: "cowboy", domId: "cowboySvg"}
+ * ],
+ * });
+ * Next, call the ready function with a callback to your program code
+ *
+ * k.ready(function () { ... your application code . . . }
+ *
+ * after that you can access each asset like so
+ * k.image.ninja;
+ * k.svg.cowboy;
+ * k.audio.yeehaw.play();
+ * k.canvas.ninja.drawImage(k.image.ninja, 0, 0);
+ *
+ */
+var Karma = exports.Karma = function (options) {
+ Karma._isHtml5(document.doctype.nodeName);
+
+ if ( Karma.karma._initialized === true ) {
+ return Karma.karma;
+ } else {
+ return Karma.karma._init(options);
+ }
+};
+
+
+//helper functions
+
+/**This emulates the Object.create method in ecmascript 5 spec
+ * This isn't a full implementation as it doesn't support an all of Object.create's features
+ * This has the same functionality as Crockford's beget method
+ * and this primary building block for prototypal inheritance in
+ * this library
+ * @param {Object} parent that the new object's prototype should point to
+ * @returns {Object} a new object whose prototype is parent
+ * @example
+ *
+ * var ninja = { weapon : "sword" };
+ * var ninja1 = Karma.create(ninja);
+ * ninja1.weapon === "sword"
+ */
+Karma.create = function (parent){
+ function F () {};
+ F.prototype = parent;
+ return new F();
+};
+
+/** Returns a shallow copy of the passed in object
+ * @param {Object} target to be copied
+ * @returns {Object} a shallow copy of target
+ */
+Karma.clone = function (target){
+ var copy = {};
+ for ( var i in target ) {
+ if(target.hasOwnProperty(i)){
+ copy[i] = target[i];
+ }
+ }
+ return copy;
+};
+
+/** Extends properties of the target object with those of
+ * the source object
+ * @param {Object} target object to be extended
+ * @param {Object} source whose properties will extend target
+ * @returns {Object} target extended by source
+ */
+Karma.objectPlus = function (target, source){
+ for ( var i in source){
+ if (source.hasOwnProperty(i)){
+ target[i] = source[i];
+ }
+ }
+ return target;
+};
+
+/** Creates a new object that is a prototype of the first argument
+ * then extends it with the properties of the second argument
+ * @param {Object} parent1 will be prototype of returned object
+ * @param {Object} parent2 will extend properties of returned object
+ * @returns {Object} object that whose prototype is parent1 and has
+ * been extended with properties of parent2
+ */
+Karma.copyObjectPlus = function (parent1, parent2){
+ function F () {};
+ F.prototype = parent1;
+ var G = new F();
+ return Karma.objectPlus(G, parent2);
+};
+
+
+//Throws big ugly error if doctype isn't html5
+Karma._isHtml5 = function (doctype){
+ var regex = new RegExp('^html$', 'i');
+ if(!regex.test(doctype)){
+ var errorMsg = "ERROR: The doctype must be set to <!DOCTYPE html> " +
+ "in order to use Karma. Karma require you use html5";
+ var errorElem = document.createElement('div');
+ errorElem.setAttribute('id', 'errorDoctype');
+ errorElem.innerText = errorMsg;
+ document.body.appendChild(errorElem);
+ throw new Error(errorMsg);
+ }
+};
+
+
+/** Stores global settings for the Karma library
+ * @class This object stores the global settings for the Karma library
+ */
+Karma.karma = {
+ /** This is the global locale as passed to Karma(),
+ * such as "en", "es_SP"
+ * @property {string} locale This is the global locale as passed to Karma()
+ * @default undefined
+ */
+ locale : undefined,
+ /** Collection of images with special helper
+ * methods added to each reference
+ * @type object
+ * @default empty object
+ */
+ image : {},
+ /** Collection of audio files with special helper
+ * methods added to each reference
+ * @type object
+ * @default empty object
+ */
+ audio : {},
+ /** Collection of html 5 canvases with special helper
+ * methods added to each reference
+ * @type object
+ * @default empty object
+ */
+ canvas : {},
+ /** Collection of svgs with special helper
+ * methods added to each reference
+ * @type object
+ * @default empty object
+ */
+ svg : {},
+ /** Collection of videos with special helper
+ * methods added to each reference
+ * @type object
+ * @default empty object
+ */
+ video : {},
+ _localized : false,
+ _assetPath : "assets/",
+ _localePath : "",
+ _initialized : false,
+ _statusDiv: undefined,
+ _loaderDiv : undefined,
+ _counters : { total : 0, errors : 0, loaded : 0},
+
+ //This constructs the Karma.karma object per values provided by the user
+ _init: function(options) {
+ this._initialized = true;
+
+ //set up message that show count of assets loaded
+ //and has an ordered list to append error messages to
+ var _statusDiv = this._statusDiv = document.createElement('div');
+ this._loaderDiv = this._loaderDiv = document.createElement('div');
+ var errorList = document.createElement('ol');
+
+ _statusDiv.setAttribute('id', 'karma-status');
+ _statusDiv.setAttribute('style', 'position:absolute;');
+ _statusDiv.innerHTML = 'Karma is loading ...';
+ this._loaderDiv.setAttribute('id', 'karma-loader');
+ this._loaderDiv.setAttribute('class', 'status');
+ errorList.setAttribute('id', 'errorList');
+
+ _statusDiv.appendChild(this._loaderDiv);
+ this._statusDiv.appendChild(errorList);
+ document.body.appendChild(_statusDiv);
+
+ //regular expression that matches the name of aprivate property
+ // the karma object
+ var regexPrivate = new RegExp('^_.*');
+
+ for ( var option in options ) {
+ if (options.hasOwnProperty(option)){
+ if (option === "image" || option === "audio" || option ===
+ "svg" || option === "video" || option === "canvas"){
+
+ if(!(options[option] instanceof Array)){
+ throw new Error("" + option + " must be an array");
+ } else if (options[option].length === 0){
+ continue;
+ }
+ } else if (regexPrivate.test(option)){
+ //don't overwrite a private property of karma object
+ continue;
+ }
+
+ switch (option){
+ case "locale":
+
+ if (this._isValidLocale(options[option])){
+ this.locale = this._normalizeLocale(options[option]);
+ this._localized = true;
+ this._localePath = Karma._computeLocalePath(this.locale);
+ } else {
+ throw new Error("locale provided to karma._init() is invalid");
+ }
+
+ break;
+ case "image":
+ options[option]._type = 'image';
+ Karma._makeCollection(options[option], 'image');
+ break;
+ case "audio":
+ options[option]._type = 'audio';
+ Karma._makeCollection(options[option], 'audio');
+ break;
+ case "video":
+ options[option]._type = 'video';
+ Karma._makeCollection(options[option], 'video');
+ break;
+ case "svg":
+ options[option]._type = 'svg';
+ Karma._makeCollection(options[option], 'svg');
+ break;
+ case "canvas":
+ options[option]._type = 'canvas';
+ Karma._makeCollection(options[option], 'canvas');
+ break;
+ }
+ }
+ }
+
+
+
+ return this;
+ },
+
+ /** Waits until all assets loaded(ready), then calls callback cb
+ * @param {Function} [cb] callback function
+ * @returns this
+ * @throws {Error} if Karma.karma is not initialized with the
+ * Karma({ options }) function
+ * @example
+ *
+ * var k = Karma({ . . . your assets here . . . });
+ * k.ready(function(){ .. your code here . . .});
+ *
+ * your code will not be called until all assets have been loaded
+ * into collections
+ *
+ */
+ ready : function( cb ) {
+ var that = this;
+ if (Karma.karma._initialized !== true){
+ throw new Error("Karma.karma not initialized");
+ }
+
+ if (this._counters.loaded !== this._counters.total){
+ setTimeout(function(){ that.ready(cb);}, 5);
+ } else if (cb) {
+ //hide the "Karma is loading..." message
+ this._statusDiv.setAttribute('style', 'display:none;');
+
+ cb();
+ } else if (!cb) {
+ //hide the "Karma is loading..." message
+ this._statusDiv.setAttribute('style', 'display:none;');
+
+ //if no options passed, show it works message
+ this._showStarterMessage();
+ }
+
+
+
+
+ return this;
+ },
+
+ //Display Apache-like "It works" message if no options
+ _showStarterMessage : function (){
+ var starterMsg = document.createElement('div');
+ starterMsg.setAttribute('id', 'starterMsg');
+ starterMsg.innerHTML = "<h1>It Works</h1>";
+ document.body.appendChild(starterMsg);
+ },
+
+ //Updates visible counter of how many assets are loaded
+ _updateStatus : function (errorMsg) {
+ var loaded = this._counters.loaded;
+ var total = this._counters.total;
+ var errors = this._counters.errors;
+ this._loaderDiv.innerHTML = "Loaded " + loaded + " / " + total +
+ "" + (errors > 0 ? " Errors [ " + errors +" ]" : '');
+ if (errorMsg) {
+ var liError = document.createElement('li');
+ liError.innerHTML = errorMsg;
+ var errorList = document.getElementById('errorList');
+ errorList.appendChild(liError);
+ }
+ },
+
+ //matches 2 letter country code then optionally
+ //a dash or underscore followed by a country or language identifier
+ //i currently only allow a language identifier 2-3 chars long
+ _isValidLocale : function (locale) {
+ var localeRegex = new RegExp('^[a-zA-Z][a-zA-Z]([-_][a-zA-z]{2,3})?$');
+ return localeRegex.test(locale);
+ },
+
+ _normalizeLocale : function(locale) {
+ var lang = "";
+ var country = "";
+ var divider = "";
+
+ lang = locale.slice(0, 2).toLowerCase();
+ divider = "_";
+ country = locale.slice(3, 6).toUpperCase();
+
+ return locale.length > 2 ? "" + lang + divider + country : lang;
+ },
+
+ // Below are geometry and math helper methods
+
+ /**
+ * Converts a value from degrees to radians.
+ * @param {Number} angle The angle in degrees
+ * @returns {Number} The angle in radians
+ */
+ radians : function( angle ){
+ return ( angle / 180 ) * Math.PI;
+ },
+ /**
+ * Gets the square of the Euclidian (ordinary) distance between 2 points.
+ * @param {Object} Point No. 0
+ * @param {Number} Point0.x
+ * @param {Number} Point0.y
+ * @param {Object} Point No. 1
+ * @param {Number} Point1.x
+ * @param {Number} Point1.y
+ * @returns {Number} The square of the Euclidian distance
+ * @example
+ *
+ * p0 = {x:0, y:1};
+ * p1 = {x:50, y:70};
+ * var d = distance2(p0, p1);
+ *
+ */
+ distance2 : function ( p0, p1 ) {
+ return (p1.x - p0.x) * (p1.x - p0.x) + (p1.y - p1.y) * (p1.y - p1.y);
+ },
+ /**
+ * Gets the Euclidian (ordinary) distance between 2 points.<br>
+ * <b>Warning:</b> It's slower than distance2 function
+ * @param {Object} Point No. 0
+ * @param {Number} Point0.x
+ * @param {Number} Point0.y
+ * @param {Object} Point No. 1
+ * @param {Number} Point1.x
+ * @param {Number} Point1.y
+ * @returns {Number} The Euclidian distance
+ * @example
+ *
+ * p0 = {x:0, y:1};
+ * p1 = {x:50, y:70};
+ * var d = distance2(p0, p1);
+ *
+ */
+ distance : function ( p0, p1 ) {
+ return Math.sqrt( this.distance2( p0, p1 ) );
+ },
+ /** Returns a random number within the range provided
+ * @param {Number} lower limit of the range, lowest number that can be returned
+ * @param {Number} upper limit of the range, highest number that can be returned
+ * @returns {Number} number that is >= lower and <= upper
+ * @example
+ *
+ * var num = rand(0, 10);
+ *
+ * //num could be 0, 1, 2, 3 ... or 10
+ *
+ */
+ rand : function ( lower, upper ){
+ return Math.round( Math.random() * (upper - lower) + lower );
+ }
+
+};
+
+//Helper functions for creating assets
+
+Karma._isLocalized = function (boolLocalized) {
+ if (typeof boolLocalized === "boolean" ) {
+ if(boolLocalized === true &&
+ Karma.karma.locale === undefined){
+ throw new Error("You cannot localize a media asset" +
+ " if the global locale for Karma isn't set");
+ } else {
+ return boolLocalized;
+ }
+ } else if (typeof boolLocalized === undefined){
+ return false;
+ } else{
+ throw new Error("This is not a valid value for the localized option");
+ }
+};
+
+Karma._computeLocalePath = function(locale) {
+ return Karma.karma._assetPath + locale + "/";
+};
+
+
+
+
+Karma._makeCollection = function (configs, type){
+ var makeAsset = function (config){
+ var asset = undefined;
+ var target = undefined;
+ switch(type){
+ case "image":
+ target = Karma.kImage;
+ break;
+ case "audio":
+ target = Karma.kAudio;
+ break;
+ case "video":
+ target = Karma.kVideo;
+ break;
+ case "svg":
+ target = Karma.kSvg;
+ break;
+ case "canvas":
+ target = Karma.kCanvas;
+ break;
+ }
+
+ asset = Karma.create(target)._init(config);
+ Karma.karma[type][config.name] = asset;
+ };
+
+ configs.forEach(function(config){ makeAsset(config);});
+};
+
+
+
+
+
+//Prototype objects for assets
+
+
+/** Prototype object for images
+ * @class This object is the prototype for images submitted to Karma in the
+ * Karma() method
+ * @ throws {Error} if the image asset is set to be localized but
+ * the global locale is not set on the Karma.karma object
+ * @ throws {Error} if the name and file properties are not supplied
+ * @example
+ * kImage is the prototype object for images. This 'media' asset is loaded
+ * in a distinctly different way from the canvas or svg assets.
+ *
+ */
+Karma.kImage =
+ {
+ /** file location of image
+ * @type String
+ * @default ""
+ */
+ file : "",
+ /** media object
+ * @type Image
+ * @default undefined
+ */
+ media : undefined,
+ //actual path to the file
+ _path : "",
+ //if using localized version of this image
+ _localized : false,
+ _type : "image",
+ //initializes kImage instance with values provided by user
+ _init : function (image) {
+ image._localized = image._localized || false;
+ Karma.karma._counters.total++;
+
+ if (image.name === undefined || image.file === undefined){
+ throw new Error("properties name and file have to be defined");
+ } else {
+ this.name = image.name;
+ this.file = image.file;
+ }
+
+ this.media = new Image();
+
+ if(Karma._isLocalized(image._localized)){
+ this._localized = image._localized;
+ this._path = Karma.karma._localePath + "image/";
+ } else {
+ this._path = Karma.karma._assetPath + "image/";
+ }
+
+ //IMPORTANT: This one magic line loads the file
+ this.media.src = this.src = this._path + this.file;
+
+ //add event handlers
+ this._addEventHandlers();
+
+
+ return this;
+ },
+ //Adds event handlers to update the counters when
+ //the image is successfully or unsuccessfully loaded
+ _addEventHandlers : function () {
+ var that = this;
+
+ that.media.addEventListener(
+ "load",
+ function (e) {
+ Karma.karma._counters.loaded++;
+ Karma.karma._updateStatus();
+ that.status = "loaded";}, false);
+
+ that.media.addEventListener(
+ "error",
+ function (e) {
+ Karma.karma._counters.errors++;
+ that.status = "error";
+ var errorMsg = "Error: " + that._type.toUpperCase() +
+ " " + that.name + " cannot be loaded.";
+ Karma.karma._updateStatus(errorMsg);
+ },
+ false);
+ that.media.addEventListener(
+ "abort",
+ function (e) {
+ Karma.karma._counters.total++;
+ that.status = "aborted";
+ var errorMsg = "ABORT: " + that._type.toUpperCase() +
+ " " + that.name + " loading was aborted.";
+ Karma.karma._updateStatus(errorMsg);
+
+ }, false);
+ }
+
+};
+
+/** Prototype object for audio files
+ * @class This object is the prototype for audio files submitted to Karma in the
+ * Karma() method
+ * @ throws {Error} if the individual audio asset is set to be localized but
+ * the globale locale is not set on the Karma.karma object
+ * @ throws {Error} if the name and file properties are not supplied
+ * @example
+ * kAudio is the prototype object for audio
+ * The audio assets are loaded in a distinctly different way
+ * from the canvas or svg assets. They also have distinctly different
+ * helper methods
+ *
+ * You initialize the kAudio assets by passing an array of objects
+ */
+Karma.kAudio = {
+ /** file location of asset
+ * @type String
+ * @default ""
+ */
+ file : "",
+ /** Media object. You can access the src, autobuffer, autoplay, loop, and
+ * controls attributes
+ * via the media property of kAudio. Read more about the properties of the <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#media-element-attributes">HTML 5 media element</a>
+ * @type Audio
+ * @default undefined
+ */
+ media : undefined,
+ //actual path to the file
+ _path : "",
+ //if using localized version of this asset
+ _localized : false,
+ _type : "audio",
+ //initializes kAudio instance with values provided by user
+ _init : function (audio) {
+ audio._localized = audio._localized || false;
+ Karma.karma._counters.total++;
+
+ if (audio.name === undefined || audio.file === undefined){
+ throw new Error("properties name and file have to be defined");
+ } else {
+ this.name = audio.name;
+ this.file = audio.file;
+ }
+
+ this.media = new Audio();
+
+ if(Karma._isLocalized(audio._localized)){
+ this._localized = audio._localized;
+ this._path = Karma.karma._localePath + "audio/";
+ } else {
+ this._path = Karma.karma._assetPath + "audio/";
+ }
+
+
+ //IMPORTANT: This one magic line loads the file
+ this.media.src = this.src = this._path + this.file;
+
+ //add event handlers
+ this._addEventHandlers();
+
+ if (this._type === "audio"){
+ this.media.autobuffer = true;
+ this.media.load();
+ }
+
+
+ return this;
+ },
+ //Adds event handlers to update the counters when
+ //the asset is successfully or unsuccessfully loaded
+ _addEventHandlers : function () {
+ var that = this;
+ //'canplaythrough' event is a Browser Hack recommended by chromium devs
+ //http://code.google.com/p/chromium/issues/detail?id=20251&q=loading%20audio&colspec=ID%20Stars%20Pri%20Area%20Type%20Status%20Summary%20Modified%20Owner%20Mstone%20OS#c4
+
+ that.media.addEventListener(
+ "canplaythrough",
+ function (e) {
+ Karma.karma._counters.loaded++;
+ Karma.karma._updateStatus();
+ that.status = "loaded";}, false);
+
+ that.media.addEventListener(
+ "error",
+ function (e) {
+ Karma.karma._counters.errors++;
+ that.status = "error";
+ var errorMsg = "Error: " + that._type.toUpperCase() +
+ " " + that.name + " cannot be loaded.";
+ Karma.karma._updateStatus(errorMsg);
+ },
+ false);
+ that.media.addEventListener(
+ "abort",
+ function (e) {
+ Karma.karma._counters.total++;
+ that.status = "aborted";
+ var errorMsg = "ABORT: " + that._type.toUpperCase() +
+ " " + that.name + " loading was aborted.";
+ Karma.karma._updateStatus(errorMsg);
+
+ }, false);
+
+ },
+ /** Plays the audio file */
+ play : function () {
+ this.media.play();
+ }
+
+};
+
+/** NYI:Prototype object for Video files
+ * @class Not Yet Implemented:This object is the prototype for video files submitted
+ * to Karma in the Karma() method
+ * @ throws {Error} if the individual video asset is set to be localized but
+ * the globale locale is not set on the Karma.karma object
+ * @ throws {Error} if the name and file properties are not supplied
+ */
+Karma.kVideo = {
+ /** file location of asset
+ * @type String
+ * @default ""
+ */
+ file : "",
+ /** media object
+ * @type Video
+ * @default undefined
+ */
+ media : undefined,
+ //actual path to the file
+ _path : "",
+ //if using localized version of this asset
+ _localized : false,
+ _type : "video",
+ //initializes kVideo instance with values provided by user
+ _init : function (video) {
+ //Not Yet Implemented
+ Karma.karma._counters.errors++;
+ throw new Error("Video is not Yet Implemented");
+
+ video._localized = video._localized || false;
+ Karma.karma._counters.total++;
+
+ if (video.name === undefined || video.file === undefined){
+ throw new Error("properties name and file have to be defined");
+ } else {
+ this.name = video.name;
+ this.file = video.file;
+ }
+
+ this.media = new Video();
+
+ if(Karma._isLocalized(video._localized)){
+ this._localized = video._localized;
+ this._path = Karma.karma._localePath + "video/";
+ } else {
+ this._path = Karma.karma._assetPath + "video/";
+ }
+
+
+ //IMPORTANT: This one magic line loads the file
+ this.media.src = this.src = this._path + this.file;
+
+ //add event handlers
+ this._addEventHandlers();
+
+ return this;
+ },
+ //Adds event handlers to update the counters when
+ //the asset is successfully or unsuccessfully loaded
+ _addEventHandlers : function () {
+ var that = this;
+ //'canplaythrough' event is a Browser Hack recommended by chromium devs
+ //http://code.google.com/p/chromium/issues/detail?id=20251&q=loading%20audio&colspec=ID%20Stars%20Pri%20Area%20Type%20Status%20Summary%20Modified%20Owner%20Mstone%20OS#c4
+
+ that.media.addEventListener(
+ "canplaythrough",
+ function (e) {
+ Karma.karma._counters.loaded++;
+ Karma.karma._updateStatus();
+ that.status = "loaded";}, false);
+
+ that.media.addEventListener(
+ "error",
+ function (e) {
+ Karma.karma._counters.errors++;
+ that.status = "error";
+ var errorMsg = "Error: " + that._type.toUpperCase() +
+ " " + that.name + " cannot be loaded.";
+ Karma.karma._updateStatus(errorMsg);
+ },
+ false);
+ that.media.addEventListener(
+ "abort",
+ function (e) {
+ Karma.karma._counters.total++;
+ that.status = "aborted";
+ var errorMsg = "ABORT: " + that._type.toUpperCase() +
+ " " + that.name + " loading was aborted.";
+ Karma.karma._updateStatus(errorMsg);
+
+ }, false);
+
+ }
+
+};
+
+
+
+/** Prototype object for each canvas element submitted to Karma in the
+ * Karma() method
+ * @throws {Error} if the name and domId for the canvas element are not specified
+ * @thows {Error} if the supplied domId does not match an element in the DOM
+ * @class This object is the prototype for each canvas element submitted to Karma in the
+ * Karma() method
+ */
+Karma.kCanvas = {
+ /** Name of the canvas, used internally by karma.js
+ * @type String
+ * @default ''
+ */
+ name : '',
+ /** Width of canvas element
+ * @type Number
+ * @default 0
+ */
+ width: 0,
+ /** Height of canvas element
+ * @type Number
+ * @default 0
+ */
+ height: 0,
+ /** Whether canvas is visible
+ * @type boolean
+ * @default true
+ */
+ visible: true,
+ /** Element ID for canvas element in html document. This value is read-only
+ * @type String
+ * @default undefined
+ */
+ domId: undefined,
+ /** Reference to the DOM element
+ * @type DOMElement
+ * @default undefined
+ * @example
+ * //You can access all properties and methods of the underlying DOM element
+ * //using the 'node' property
+ * Karma.karma.canvas.someCanvas.node.dispatchEvent( ... some event ...);
+ * var stuff = Karma.karma.canvas.someCanvas.node.innerHTML;
+ *
+ */
+ node: undefined,
+ /** The 2 Dimensional Rendering context property for this canvas
+ * @type 2DRenderingContext
+ * @default undefined
+ * @example
+ * //Almost all of the context attributes and methods are wrapped in helper functions
+ * //but you can also access them directly using the ctx property
+ * Karma.karma.canvas.someCanvas.ctx.drawImage(someImage, x, y);
+ * Karma.karma.canvas.someCanvas.ctx.fillStyle = "#ffffff";
+ */
+ ctx: undefined,
+
+ //initializes object with values provides by user
+ _init: function (config) {
+ for (var option in config){
+ if (config.hasOwnProperty(option)){
+ switch (option){
+ case "name":
+ this.name = config[option];
+ break;
+ case "domId":
+ this.domId = config[option];
+ break;
+ case "width":
+ if(!this.height){
+ throw new Error("If you specify a width you must also" +
+ "specify a height");
+ }
+ this.width = config[option];
+ break;
+ case "height":
+ if(!this.width){
+ throw new Error("If you specify a height you must also" +
+ "specify a width");
+ }
+ this.height = parseInt(config.option, 10);
+ break;
+ case "fps":
+ this.fps = parseInt(config.option, 10);
+ break;
+ }
+ }
+ }
+
+ if(this.domId && document.getElementById(this.domId)){
+ this.node = document.getElementById(this.domId);
+ this.ctx = this.node.getContext('2d');
+ } else {
+ throw new Error('you must specify a valid domId that' +
+ 'is in your html page');
+ }
+
+ if(!config.height && !config.width){
+ this.width = parseInt(this.node.getAttribute('width'), 10);
+ this.height = parseInt(this.node.getAttribute('height'), 10);
+ }
+
+ return this;
+ },
+ /** Clear area of canvas element specified by parameters, if no
+ * parameters supplied, clears entire canvas
+ * @param {Number} [x=0] x coordinate, defaults to zero if left blank
+ * @param {Number} [y=0] y coordinate, defaults to zero if left blank
+ * @param {Number} [width=0] width of area to be cleared, defaults
+ * entire width of canvas
+ * @param {Number} [height=0] height of area to be cleared, defaults
+ * entire height of canvas
+ * @returns this
+ * @example
+ *
+ * k.canvas.ninja.clear();
+ * // clears the entire ninja canvas
+ *
+ * k.canvas.ninja.clear(0, 10, 20, 30);
+ * //clears a specific portion of the ninja canvas
+ *
+ */
+ clear : function ( x, y, width, height ) {
+ var that = this;
+ that.ctx.clearRect(
+ x || 0,
+ y || 0,
+ width || that.width,
+ height || that.height
+ );
+ return that;
+ },
+
+ /** The globalAlpha attribute gives an alpha value that is applied to shapes
+ * and images before they are composited onto the canvas
+ * @param {Number} number in the range from 0.0 to 1.0
+ * @returns this
+ */
+ globalAlpha : function (attribute){
+ var name = 'globalAlpha';
+ this.ctx[name] = attribute;
+ return this;
+ },
+
+ /** Sets the globalCompositeOperation attribute, which sets how shapes and images
+ * are drawn onto the existing bitmap, once they have had globalAlpha and the
+ * current transformation matrix applied.
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param {String} globalCompositeOperation source-atop,
+ * source-in, source-out,
+ * source-over, destination-atop, destination-in, destination-out, destination-over,
+ * lighter
+ * @returns this
+ */
+ globalCompositeOperation: function (attribute){
+ var name = ' globalCompositeOperation';
+ this.ctx[name] = attribute;
+ return this;
+ },
+
+ /** Sets the lineWidth attribute which gives the width of lines, in coordinate space
+ * units.
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param {Number} lineWidth
+ * @returns this
+ */
+ lineWidth: function (attribute){
+ var name = 'lineWidth';
+ this.ctx[name] = attribute;
+ return this;
+ },
+ /** The lineCap attribute defines the type of endings that UAs will place on
+ * the end of lines.
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param {String} type butt, round, square
+ * @returns this
+ */
+ lineCap: function (attribute){
+ var name = 'lineCap';
+ this.ctx[name] = attribute;
+ return this;
+ },
+ /** The lineJoin attribute defines the type of corners that UAs will place
+ * where two lines meet. The three valid values are bevel, round, and miter.
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param {String} type
+ * @returns this
+ */
+ lineJoin: function (attribute){
+ var name = 'lineJoin';
+ this.ctx[name] = attribute;
+ return this;
+ },
+
+ /** Sets the miter limit
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param {Number} number
+ * @returns this
+ */
+ miterLimit: function (attribute){
+ var name = 'miterLimit';
+ this.ctx[name] = attribute;
+ return this;
+ },
+ /** Sets the font property and takes the same syntax as setting the font property
+ * in CSS
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param {String}
+ * @returns this
+ */
+ font: function (attribute){
+ var name = 'font';
+ this.ctx[name] = attribute;
+ return this;
+ },
+
+ /** Changes the text alignment. The possible values are start, end, left, right,
+ * and center. The default is start. Other values are ignored.
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param {string} alignment
+ * @returns this
+ */
+ textAlign: function (attribute){
+ var name = 'textAlign';
+ this.ctx[name] = attribute;
+ return this;
+ },
+
+ /** Changes the baseline alignment. If the value is one of top, hanging, middle,
+ * alphabetic, ideographic, or bottom, then the value must be changed to the new value.
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param {String} alignment
+ * @returns this
+ */
+ textBaseline: function (attribute){
+ var name = 'textBaseline';
+ this.ctx[name] = attribute;
+ return this;
+ },
+
+ /** Save the current state of the context
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ save : function ( ){
+ var name = 'save';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Restore the saved context
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ restore : function ( ){
+ var name = 'restore';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Perform a scale transformation
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ scale : function ( ){
+ var name = 'scale';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Perform a rotation transformation
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ rotate : function ( ){
+ var name = 'rotate';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Performa a translation transformation
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ translate : function ( ){
+ var name = 'translate';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+
+ /** Transform the identity matrix
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ transform : function ( ){
+ var name = 'transform';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Set the transform
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ setTransform : function ( ){
+ var name = 'setTransform';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Clear a rectangular area
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ clearRect : function ( ){
+ var name = 'clearRect';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Fill a rectangular area
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ fillRect : function ( ){
+ var name = 'fillRect';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+
+ /** Draw the outline of the rectangle
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ strokeRect : function ( ){
+ var name = 'strokeRect';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Begin a path
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ beginPath : function ( ){
+ var name = 'beginPath';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** End a path
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ closePath : function ( ){
+ var name = 'closePath';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Move to specified coordinates
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ moveTo : function ( ){
+ var name = 'moveTo';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+
+
+ /** Draw a line to the given coordinates
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ lineTo : function ( ){
+ var name = 'lineTo';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+
+ /** Draw a quadratic curve to given coordinates
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ quadraticCurveTo : function ( ){
+ var name = 'quadraticCurveTo';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Draw a bezier curve to given coordinates
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ bezierCurveTo : function ( ){
+ var name = 'bezierCurveTo';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Draw an arc to the given points
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ arcTo : function ( ){
+ var name = 'arcTo';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Create an arc
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ arc : function ( ){
+ var name = 'arc';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+
+ /** Create a rectangle
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ rect : function ( ){
+ var name = 'rect';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** fill in the current subpaths with the current fillstyle
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ fill : function ( ){
+ var name = 'fill';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Stroke the subpaths
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ stroke : function ( ){
+ var name = 'stroke';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ clip : function ( ){
+ var name = 'clip';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ fillText : function ( ){
+ var name = 'fillText';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ strokeText : function ( ){
+ var name = 'strokeText';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ measureText : function ( ){
+ var name = 'measureText';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ isPointInPath : function ( ){
+ var name = 'isPointInPath';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+
+ /** Sets the stroke style
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ strokeStyle: function (attribute){
+ var name = 'strokeStyle';
+ this.ctx[name] = attribute;
+ return this;
+ },
+
+ /** Sets the fill style
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ fillStyle: function (attribute){
+ var name = 'fillStyle';
+ this.ctx[name] = attribute;
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ createLinearGradient : function ( ){
+ var name = 'createLinearGradient';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ createRadialGradient : function ( ){
+ var name = 'createRadialGradient';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ createPattern : function ( ){
+ var name = 'createPattern';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ shadowOffsetX: function (attribute){
+ var name = 'shadowOffsetX';
+ this.ctx[name] = attribute;
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ shadowOffsetY: function (attribute){
+ var name = 'shadowOffsetY';
+ this.ctx[name] = attribute;
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ shadowBlur: function (attribute){
+ var name = 'shadowBlur';
+ this.ctx[name] = attribute;
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ shadowColor: function (attribute){
+ var name = 'shadowColor';
+ this.ctx[name] = attribute;
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ drawImage : function ( ){
+ var name = 'drawImage';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ getImageData : function ( ){
+ var name = 'getImageData';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ putImageData : function ( ){
+ var name = 'putImageData';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ createImageData : function ( ){
+ var name = 'createImageData';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ drawWindow : function ( ){
+ var name = 'drawWindow';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+
+
+
+
+};
+
+
+/** Prototype object for each svg element submitted to Karma in the
+ * Karma() method
+ * @throws {Error} if the name and domId for the svg element are not specified
+ * @thows {Error} if the supplied domId does not match an element in the DOM
+ * @class This object is the prototype for each svg element submitted to Karma in the
+ * Karma() method
+ */
+Karma.kSvg = {
+ /** name of instance, used internally
+ * @typeof string
+ * @default ""
+ */
+ name : "",
+ /** width of element
+ * @type number
+ * @default 0
+ */
+ width: 0,
+ /** height of element
+ * @type number
+ * @default 0
+ */
+ height: 0,
+ /** Status of element, either "loaded" or "error"
+ * @type string
+ * @default ""
+ */
+ status: "",
+ /** Whether canvas is visible. This value is read-only
+ * @type boolean
+ * @default true
+ */
+ visible: true,
+ /** Element ID for canvas element in html document.
+ * @type String
+ * @default undefined
+ */
+ domId: undefined,
+ /** Reference to the DOM element.
+ * @type DOMElement
+ * @default undefined
+ * @example
+ * //You can access all properties and methods of the underlying DOM element
+ * //using the 'node' property
+ * Karma.karma.svg.someSvg.node.dispatchEvent;
+ * Karma.karma.svg.someSvg.node.addEvenListener(...);
+ */
+ node: undefined,
+ /** Reference to the SVGDocument. You can use the this.doc to manipulate
+ * the SVG document
+ * @type SVGDocument
+ * @default undefined
+ * @example
+ * var myElem = Karma.karma.svg.someSvg.doc.getElementById('foobar');
+ * Karma.karma.svg.someSvg.doc.createElement(...);
+ * Karma.karma.svg.someSvg.doc.removeChild(someNode);
+ *
+ */
+ doc: undefined,
+ /** Reference to the root element of the SVG Document
+ * @type DocumentElement
+ * @default undefined
+ * @example
+ * // The root element is equivalent to "document" in a regular html document
+ * // The root attribute is used frequently with the jQuery SVG plugin for CSS selectors
+ * $('#someId', Karma.karma.svg.someSvg.root).css(.. manipulate css attributes ...);
+ */
+ root: undefined,
+ _localized : undefined,
+ _init: function (config) {
+ Karma.karma._counters.total++;
+
+ for (var option in config){
+ if (config.hasOwnProperty(option)){
+ switch (option){
+ case "name":
+ this.name = config[option];
+ break;
+ case "domId":
+ this.domId = config[option];
+ break;
+ case "width":
+ if(!this.height){
+ throw new Error("If you specify a width you must also" +
+ "specify a height");
+ }
+ this.width = parseInt(config[option], 10);
+ break;
+ case "height":
+ if(!this.width){
+ throw new Error("If you specify a height you must also" +
+ "specify a width");
+ }
+ this.height = config[option];
+ break;
+ }
+ }
+ }
+
+ if(this.domId && document.getElementById(this.domId)){
+ this.node = document.getElementById(this.domId);
+ } else {
+ throw new Error('you must specify a valid domId that' +
+ 'is in your html page');
+ }
+
+ if(!config.height && !config.width){
+ this.width = parseInt(this.node.getAttribute('width'), 10);
+ this.height = parseInt(this.node.getAttribute('height'), 10);
+ }
+
+ var that = this;
+ that._addEventHandlers();
+
+ return this;
+
+
+ },
+ _addEventHandlers : function () {
+ var that = this;
+ that.doc = that.node.getSVGDocument();
+ that.node.addEventListener(
+ "load",
+ function (e) {
+ that.doc = that.node.getSVGDocument();
+ that.root = that.doc.documentElement;
+ Karma.karma._counters.loaded++;
+ Karma.karma._updateStatus();
+ that.status = "loaded";
+ }, false);
+
+ that.node.addEventListener(
+ "error",
+ function (e) {
+ Karma.karma._counters.loaded--;
+ Karma.karma._counters.errors++;
+ that.status = "error";
+ var errorMsg = "Error: " + that._type.toUpperCase() +
+ " " + that.name + " cannot be loaded.";
+ Karma.karma._updateStatus(errorMsg);
+ },
+ false);
+ that.node.addEventListener(
+ "abort",
+ function (e) {
+ that.status = "aborted";
+ var errorMsg = "ABORT: " + that._type.toUpperCase() +
+ " " + that.name + " loading was aborted.";
+ Karma.karma._updateStatus(errorMsg);
+
+ }, false);
+
+ }
+};
diff --git a/js/lesson.js b/js/lesson.js
new file mode 100755
index 0000000..b591973
--- /dev/null
+++ b/js/lesson.js
@@ -0,0 +1,363 @@
+/* jslint browser: true
+*/
+$(document).ready(function(){
+
+
+ var k = Karma({
+ image: [
+ {name: "ball", file: "ball37px.png"},
+ {name: "balloon", file: "balloon37px.png"},
+ {name: "banana", file: "banana37px.png"},
+ {name: "chilli", file: "chilli.png"},
+ {name: "fish" , file: "fish64px.png"},
+ {name: "flower", file: "flower37px.png"},
+ {name: "normalChimp", file: "normalChimp_120x125.png"},
+ {name: "happyChimp", file: "happyChimp_120x125.png"},
+ {name: "sadChimp", file: "sadChimp_120x125.png"}],
+ audio: [
+ {name: "correct", file: "correct.ogg"},
+ {name: "incorrect", file: "incorrect.ogg"},
+ {name: "trigger", file: "trigger.ogg"}
+ ]
+
+ });
+
+
+k.ready(function() {
+
+ var imageNames = ["ball", "banana", "balloon","chilli", "fish", "flower"];
+ //game logic
+ var cards;
+ var totalCorrect = 0, n0 = 0, n1 = 0, correctCard = 0,
+ level = 0, score = 0, numCorrectAnswers = 0;
+ var DRAW_MAX_X = 170, DRAW_MAX_Y = 170;
+ var choices=[0, 0, 0];
+ var timerSpeed = 12000;
+ var START_TIMER_Y = 25, END_TIMER_Y = 125;
+ var timerPaper, chimpPaper;
+ var timerRect;
+ var normalChimpImage, sadChimpImage, happyChimpImage;
+ var overlayCard, topLeftCard, topRightCard, bottomLeftCard,
+ bottomMiddleCard, bottomRightCard;
+
+ var buttons=[];
+ var isTimerRunning = false;
+ var isGameRunning = false;
+
+
+ var createCard = function (paperName, width, height) {
+ var set;
+ var paper;
+
+ if(!width || !height){
+ paper = Raphael(paperName+"Paper", 200, 200);
+ }
+ else {
+ paper = Raphael(paperName+"Paper", width, height);
+ }
+ set = paper.set();
+ return { "paper": paper, "prefix": paperName, "set": set};
+ };
+
+
+ overlayCard = createCard("overlay", 800, 600);
+ topLeftCard = createCard("topLeft");
+ topRightCard = createCard("topRight");
+ bottomLeftCard = createCard("bottomLeft");
+ bottomMiddleCard = createCard("bottomMiddle");
+ bottomRightCard = createCard("bottomRight");
+
+
+ cards = [ topLeftCard, topRightCard, bottomLeftCard,
+ bottomMiddleCard, bottomRightCard];
+
+ sets = [topLeftCard.set, topRightCard.set, bottomLeftCard.set,
+ bottomMiddleCard.set, bottomRightCard.set];
+
+
+ function drawCards () {
+ var imageId = imageNames[ level ];
+ //reinitialize choices to zero
+ choices = [0, 0, 0];
+
+ cards.forEach(function (box) {
+ box.set.remove();
+ });
+
+ totalCorrect = k.rand( 2, 5 + level ); //the totalCorrect
+ n0 = totalCorrect - k.rand(1, totalCorrect - 1 ); //first number
+ n1 = totalCorrect - n0; //second number
+
+ //chose one option (the correct option)
+ //and then put the correct value into it
+ correctCard = k.rand( 0, 2 );
+ choices[ correctCard ] = totalCorrect;
+
+ var computeUniqueChoice = function(choice){
+ var newChoice = 0;
+ if (choice === totalCorrect) {
+ return choice;
+ } else {
+ newChoice = k.rand( 1, 10 );
+ if (newChoice === totalCorrect){
+ return computeUniqueChoice(choice);
+ } else {
+ return newChoice;
+ }
+ }
+ };
+
+ choices = choices.map(computeUniqueChoice);
+
+ var drawCard = function (card, n) {
+ var positions = [];
+ var x = 0, y = 0;
+ var isOverlapping = false;
+ var imageVarNames = {};
+ var varPrefix = card.prefix;
+ imageVarNames[varPrefix] = [];
+ card.set = card.paper.set();
+
+ for (var i=0; i<n; i++) {
+ do {
+ isOverlapping = false;
+ x = k.rand( 0, DRAW_MAX_X);
+ y = k.rand( 0, DRAW_MAX_Y );
+ for ( var j=0; j<positions.length; j++) {
+ if ( k.distance2( positions[j],
+ {"x": x, "y": y} ) < 137 ) {
+ isOverlapping = true;
+ break;
+ }
+ }
+
+ }while ( isOverlapping === true );
+ positions.push( { "x":x, "y": y } );
+ imageVarNames[varPrefix][i] = card.paper.
+ image(k.image[imageId].src, x , y, 35, 35);
+ card.set.push(imageVarNames[varPrefix][i]);
+ }
+
+ };
+
+ //put the cards
+ drawCard(topLeftCard, n0);
+ drawCard(topRightCard, n1);
+ drawCard(bottomLeftCard, choices[ 0 ]);
+ drawCard(bottomMiddleCard, choices[ 1 ]);
+ drawCard(bottomRightCard, choices[ 2 ]);
+
+ }
+
+ //put the buttons on the cards
+ buttons[ 0 ] = { node: $('#bottomLeftPaper')[0], num: 0};
+ buttons[ 1 ] = { node: $('#bottomMiddlePaper')[0], num: 1};
+ buttons[ 2 ] = { node: $('#bottomRightPaper')[0], num: 2};
+
+ buttons.forEach(
+ function(button) {
+ var numButton = button.num;
+ button.node
+ .addEventListener('click', function (){
+ if(isGameRunning === true){
+ var myButton = numButton;
+ chooseCard(myButton);
+ }
+ }, false);
+ });
+
+
+
+
+
+ var chooseCard = function(numButton) {
+ if ( choices[numButton] === totalCorrect){
+ //If the player has completed all the levels
+ if (numCorrectAnswers === 4 && level === 5) {
+ congrats();
+ } else {
+ computeScore(true, false);
+ resetTimer();
+ animateTimer();
+ drawCards();
+ }
+ }else {
+ computeScore(false, false);
+ resetTimer();
+ animateTimer();
+ drawCards();
+ }
+ };
+
+
+
+ var writeScore = function (newScore){
+ $('#scoreBoxText')[0].innerHTML = newScore;
+ };
+
+
+ var computeScore = function (correct, tooSlow) {
+
+ if ( correct === false) {
+ //answer was incorrect or took too long
+ score = score - 1;
+ numCorrectAnswers = numCorrectAnswers - 1;
+ writeScore(score);
+ if (tooSlow === true) {
+ k.audio.trigger.play();
+ } else {
+ k.audio.incorrect.play();
+ }
+ //animate sad monkey
+ animateChimp(false);
+
+ } else {
+ score = score + 1;
+ numCorrectAnswers = numCorrectAnswers + 1;
+ writeScore(score);
+ k.audio.correct.play();
+ animateChimp(true);
+ if (numCorrectAnswers == 5){
+ level = level + 1;
+ timerSpeed = timerSpeed - 1000;
+ numCorrectAnswers = 0;
+ }
+
+ }
+
+
+ };
+
+
+ var startGame = function () {
+ score = 0;
+ writeScore(score);
+ isTimerRunning = true;
+ isGameRunning = true;
+
+ //move timer back to start in case it is
+ //already running
+ resetTimer();
+
+ //start timer
+ animateTimer();
+
+ drawCards();
+ };
+
+ var stopGame = function () {
+ writeScore(' ');
+ isGameRunning = false;
+ //stop timer
+ isTimerRunning = false;
+ resetTimer();
+
+ //clear the cards
+ cards.forEach(function (card) {
+ card.set.remove();
+ card.set = card.paper.set();
+ });
+
+ };
+
+ var resetGame = function () {
+ score = 0;
+ writeScore(score);
+ isTimerRunning = true;
+ resetTimer();
+ animateTimer();
+ drawCards();
+
+ };
+
+ var resetTimer = function () {
+ timerRect.animate({y: START_TIMER_Y}, 0);
+ };
+
+ var animateTimer = function () {
+ timerRect.animate({y : END_TIMER_Y}, timerSpeed, function(){
+ timerRect.attr("y", START_TIMER_Y);
+ if (isTimerRunning === true){
+ computeScore(false, true);
+ animateTimer();
+ drawCards();
+ }
+ });
+ };
+
+
+ var animateChimp = function (answer) {
+ var timerChimp;
+ normalChimpImage.hide();
+ if( answer === true){
+ happyChimpImage.show();
+ } else {
+ sadChimpImage.show();
+ }
+
+
+ timerChip = setTimeout(function() {
+ happyChimpImage.hide();
+ sadChimpImage.hide();
+ normalChimpImage.show();}, 800);
+
+ };
+
+ var congrats = function () {
+ var congratsText;
+ stopGame();
+
+ $('#overlay').css({"position": "absolute", "background": "white", "opacity": "0.7",
+ "width": 800, "height": 600, "z-index": 10});
+ $('#overlayPaper').css({"position": "absolute", "z-index": "100", "opacity": 1});
+ congratsChimp = overlayCard.paper.image(
+ k.image.happyChimp.src, 200, 100, 300, 400);
+ congratsChimp.attr({"fill-opacity": "1", "opacity": "1"});
+ congratsText = overlayCard.paper.text(400, 550, "Great Job!");
+ congratsText.attr({"font-size": 80});
+ overlayCard.set.push(congratsChimp, congratsText);
+
+ congratsChimp.node.addEventListener('click', function(){
+ $('#overlay').css({"opacity": 0});
+ overlayCard.set.remove();
+ }, false);
+
+ };
+
+ document.getElementById('start').
+ addEventListener('click', startGame, false);
+
+
+ document.getElementById('stop').
+ addEventListener('click', stopGame, true);
+
+ document.getElementById('reset').
+ addEventListener('click', resetGame, false);
+
+
+ //set up the timer
+ timerPaper = Raphael('timerPaper', 100, 150);
+ timerRect = timerPaper.rect(7, START_TIMER_Y, 85, 20, 3);
+ timerRect.attr('fill', "#fff");
+
+ //Set up the monkeys
+ chimpPaper = Raphael('chimpPaper', 120, 125);
+ normalChimpImage = chimpPaper.image(k.image.normalChimp.src,
+ 0, 20, 100, 100);
+ sadChimpImage = chimpPaper.image(k.image.sadChimp.src,
+ 0, 20, 100, 100);
+ happyChimpImage = chimpPaper.image(k.image.happyChimp.src,
+ 0, 20, 100, 100);
+ happyChimpImage.hide();
+ sadChimpImage.hide();
+
+
+
+
+});
+
+
+
+
+//end of ready
+}); \ No newline at end of file
diff --git a/po/en.po b/po/en.po
new file mode 100755
index 0000000..4d1444f
--- /dev/null
+++ b/po/en.po
@@ -0,0 +1,28 @@
+# English translations for PACKAGE package.
+msgid ""
+msgstr ""
+"Project-Id-Version: adding up to 10 v1\n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: 2009-07-07 04:46-0600\n"
+"Last-Translator: Felipe López Toledo <zer.subzero@gmail.com>\n"
+"Language-Team: karma <zer.subzero@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: English\n"
+"X-Poedit-Country: United States\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+
+msgid "choose an option"
+msgstr "choose an optionxxxxxxx"
+
+msgid "Time"
+msgstr "Time1"
+
+msgid "Level"
+msgstr "Level1"
+
+msgid "Restart"
+msgstr "Restart1"
+
diff --git a/po/es-MX.po b/po/es-MX.po
new file mode 100755
index 0000000..ca1e61c
--- /dev/null
+++ b/po/es-MX.po
@@ -0,0 +1,29 @@
+# Spanish translations for PACKAGE package.
+msgid ""
+msgstr ""
+"Project-Id-Version: adding up to 10 v1\n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: 2009-07-07 04:46-0600\n"
+"Last-Translator: Felipe López Toledo <zer.subzero@gmail.com>\n"
+"Language-Team: karma <zer.subzero@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Spanish\n"
+"X-Poedit-Country: MEXICO\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+
+msgid "choose an option"
+msgstr "escoge una opción"
+
+msgid "Time"
+msgstr "Tiempo"
+
+msgid "Level"
+msgstr "Nivel"
+
+msgid "Restart"
+msgstr "Reinicia"
+
+
diff --git a/po/es.po b/po/es.po
new file mode 100755
index 0000000..b665366
--- /dev/null
+++ b/po/es.po
@@ -0,0 +1,29 @@
+# Spanish translations for PACKAGE package.
+msgid ""
+msgstr ""
+"Project-Id-Version: adding up to 10 v1\n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: 2009-07-07 04:46-0600\n"
+"Last-Translator: Felipe López Toledo <zer.subzero@gmail.com>\n"
+"Language-Team: karma <zer.subzero@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Spanish\n"
+"X-Poedit-Country: MEXICO\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+
+msgid "choose an option"
+msgstr "escoge una opciónXXX"
+
+msgid "Time"
+msgstr "Tiempo"
+
+msgid "Level"
+msgstr "Nivel"
+
+msgid "Restart"
+msgstr "Reinicia"
+
+
diff --git a/po/he-IL.po b/po/he-IL.po
new file mode 100755
index 0000000..f681aca
--- /dev/null
+++ b/po/he-IL.po
@@ -0,0 +1,28 @@
+# Hebrew translations for PACKAGE package.
+msgid ""
+msgstr ""
+"Project-Id-Version: adding up to 10 v1\n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: 2009-07-07 04:46-0600\n"
+"Last-Translator: Felipe López Toledo <zer.subzero@gmail.com>\n"
+"Language-Team: karma <zer.subzero@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Hebrew\n"
+"X-Poedit-Country: Israel\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+
+msgid "choose an option"
+msgstr "בחר באפשרות"
+
+msgid "Time"
+msgstr "שעה"
+
+msgid "Level"
+msgstr "רמת"
+
+msgid "Restart"
+msgstr "הפעל מחדש"
+
diff --git a/resources.html b/resources.html
new file mode 100755
index 0000000..0e93455
--- /dev/null
+++ b/resources.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Karma - Adding Up to 10</title>
+ <meta name="keywords" content="karma,javascript,html5,sugar,sugarlabs,gsoc,ole,nepal" />
+ <link type="text/css" rel="stylesheet" href="css/lesson.css" />
+ <meta http-equiv="content-type" content="text/html; charset=utf-8">
+ <link type="image/ico" rel="icon" href="../../assets/default/images/favicon.ico" />
+ <script type="text/javascript" src="../../js/jquery-1.3.2.min.js"></script>
+ <script type="text/javascript" src="../../js/karma.Gettext.js"></script>
+ <script type="text/javascript" src="../../js/jquery.karma.js"></script>
+ <link rel="stylesheet" href="css/knavbar.css" type="text/css"/>
+
+</head>
+
+<body>
+
+<div id="lesson">
+<nav>
+<li><a href="../../chakra/grade1mathematics.html"><img src="../../assets/default/images/back.png" alt="Back" title="Back"></a></li>
+<li><a href="../../index.html"><img src="../../assets/default/images/chakra_logo.png" alt="Chakra" title="Chakra"></a></li>
+<li><a id="welcome" href="index_knavbar.html">Adding up to 10</a></li>
+<li><img src="../../assets/default/images/tutorial_bw.png" alt="Tutorial" title="Tutorial"></li>
+<li><a href="exercise.html"><img src="../../assets/default/images/exercise.png" alt="Exercise" title="Exercise"></a></li>
+<li><a href="resources.html" class="selected"><img src="../../assets/default/images/resources.png" alt="Resources" title="Resources"></a></li>
+<li><a href="#tab_help"><img src="../../assets/default/images/help.png" alt="Help" title="Help"></a></li>
+<li><a href="http://olenepal.org/" target="_blank"><img src="../../assets/default/images/olenepal_logo.gif" alt="OLE Nepal logo" title="OLE Nepal Web site"></a></li>
+</nav>
+
+<li><a href="assets/en/docs/teachernotes.swf" target="_blank">Teacher's notes</a></li>
+<li><a href="assets/en/docs/lessonplan.swf" target="_blank">Lesson plan</a></li>
+<li><a href="quadrilaterals.zip">Download</a></li>
+</div>
+
+</body>
+
+</html>