ai4r 1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (196) hide show
  1. data/README.rdoc +48 -0
  2. data/examples/decision_trees/data_set.csv +121 -0
  3. data/examples/decision_trees/id3_example.rb +31 -0
  4. data/examples/decision_trees/results.txt +29 -0
  5. data/examples/genetic_algorithm/genetic_algorithm_example.rb +39 -0
  6. data/examples/genetic_algorithm/travel_cost.csv +16 -0
  7. data/examples/neural_network/backpropagation_example.rb +65 -0
  8. data/examples/neural_network/patterns_with_base_noise.rb +68 -0
  9. data/examples/neural_network/patterns_with_noise.rb +66 -0
  10. data/examples/neural_network/training_patterns.rb +68 -0
  11. data/lib/decision_tree/id3.rb +354 -0
  12. data/lib/genetic_algorithm/genetic_algorithm.rb +268 -0
  13. data/lib/neural_network/backpropagation.rb +259 -0
  14. data/site/build/site/en/broken-links.xml +2 -0
  15. data/site/build/site/en/downloads.html +187 -0
  16. data/site/build/site/en/downloads.pdf +151 -0
  17. data/site/build/site/en/geneticAlgorithms.html +564 -0
  18. data/site/build/site/en/geneticAlgorithms.pdf +911 -0
  19. data/site/build/site/en/images/ai4r-logo.png +0 -0
  20. data/site/build/site/en/images/built-with-forrest-button.png +0 -0
  21. data/site/build/site/en/images/c.png +0 -0
  22. data/site/build/site/en/images/c_wbn.png +0 -0
  23. data/site/build/site/en/images/c_wn.png +0 -0
  24. data/site/build/site/en/images/ero.gif +0 -0
  25. data/site/build/site/en/images/europe2.png +0 -0
  26. data/site/build/site/en/images/europe3.png +0 -0
  27. data/site/build/site/en/images/fitness.png +0 -0
  28. data/site/build/site/en/images/instruction_arrow.png +0 -0
  29. data/site/build/site/en/images/my_email.png +0 -0
  30. data/site/build/site/en/images/rubyforge.png +0 -0
  31. data/site/build/site/en/images/s.png +0 -0
  32. data/site/build/site/en/images/s_wbn.png +0 -0
  33. data/site/build/site/en/images/s_wn.png +0 -0
  34. data/site/build/site/en/images/sigmoid.png +0 -0
  35. data/site/build/site/en/images/t.png +0 -0
  36. data/site/build/site/en/images/t_wbn.png +0 -0
  37. data/site/build/site/en/images/t_wn.png +0 -0
  38. data/site/build/site/en/index.html +258 -0
  39. data/site/build/site/en/index.pdf +306 -0
  40. data/site/build/site/en/linkmap.html +231 -0
  41. data/site/build/site/en/linkmap.pdf +94 -0
  42. data/site/build/site/en/locationmap.xml +72 -0
  43. data/site/build/site/en/machineLearning.html +325 -0
  44. data/site/build/site/en/machineLearning.pdf +337 -0
  45. data/site/build/site/en/neuralNetworks.html +446 -0
  46. data/site/build/site/en/neuralNetworks.pdf +604 -0
  47. data/site/build/site/en/skin/CommonMessages_de.xml +23 -0
  48. data/site/build/site/en/skin/CommonMessages_en_US.xml +23 -0
  49. data/site/build/site/en/skin/CommonMessages_es.xml +23 -0
  50. data/site/build/site/en/skin/CommonMessages_fr.xml +23 -0
  51. data/site/build/site/en/skin/basic.css +166 -0
  52. data/site/build/site/en/skin/breadcrumbs-optimized.js +90 -0
  53. data/site/build/site/en/skin/breadcrumbs.js +237 -0
  54. data/site/build/site/en/skin/fontsize.js +166 -0
  55. data/site/build/site/en/skin/getBlank.js +40 -0
  56. data/site/build/site/en/skin/getMenu.js +45 -0
  57. data/site/build/site/en/skin/images/README.txt +1 -0
  58. data/site/build/site/en/skin/images/add.jpg +0 -0
  59. data/site/build/site/en/skin/images/built-with-forrest-button.png +0 -0
  60. data/site/build/site/en/skin/images/chapter.gif +0 -0
  61. data/site/build/site/en/skin/images/chapter_open.gif +0 -0
  62. data/site/build/site/en/skin/images/current.gif +0 -0
  63. data/site/build/site/en/skin/images/error.png +0 -0
  64. data/site/build/site/en/skin/images/external-link.gif +0 -0
  65. data/site/build/site/en/skin/images/fix.jpg +0 -0
  66. data/site/build/site/en/skin/images/forrest-credit-logo.png +0 -0
  67. data/site/build/site/en/skin/images/hack.jpg +0 -0
  68. data/site/build/site/en/skin/images/header_white_line.gif +0 -0
  69. data/site/build/site/en/skin/images/info.png +0 -0
  70. data/site/build/site/en/skin/images/instruction_arrow.png +0 -0
  71. data/site/build/site/en/skin/images/label.gif +0 -0
  72. data/site/build/site/en/skin/images/page.gif +0 -0
  73. data/site/build/site/en/skin/images/pdfdoc.gif +0 -0
  74. data/site/build/site/en/skin/images/poddoc.png +0 -0
  75. data/site/build/site/en/skin/images/printer.gif +0 -0
  76. data/site/build/site/en/skin/images/rc-b-l-15-1body-2menu-3menu.png +0 -0
  77. data/site/build/site/en/skin/images/rc-b-r-15-1body-2menu-3menu.png +0 -0
  78. data/site/build/site/en/skin/images/rc-b-r-5-1header-2tab-selected-3tab-selected.png +0 -0
  79. data/site/build/site/en/skin/images/rc-t-l-5-1header-2searchbox-3searchbox.png +0 -0
  80. data/site/build/site/en/skin/images/rc-t-l-5-1header-2tab-selected-3tab-selected.png +0 -0
  81. data/site/build/site/en/skin/images/rc-t-l-5-1header-2tab-unselected-3tab-unselected.png +0 -0
  82. data/site/build/site/en/skin/images/rc-t-r-15-1body-2menu-3menu.png +0 -0
  83. data/site/build/site/en/skin/images/rc-t-r-5-1header-2searchbox-3searchbox.png +0 -0
  84. data/site/build/site/en/skin/images/rc-t-r-5-1header-2tab-selected-3tab-selected.png +0 -0
  85. data/site/build/site/en/skin/images/rc-t-r-5-1header-2tab-unselected-3tab-unselected.png +0 -0
  86. data/site/build/site/en/skin/images/remove.jpg +0 -0
  87. data/site/build/site/en/skin/images/rss.png +0 -0
  88. data/site/build/site/en/skin/images/spacer.gif +0 -0
  89. data/site/build/site/en/skin/images/success.png +0 -0
  90. data/site/build/site/en/skin/images/txtdoc.png +0 -0
  91. data/site/build/site/en/skin/images/update.jpg +0 -0
  92. data/site/build/site/en/skin/images/valid-html401.png +0 -0
  93. data/site/build/site/en/skin/images/vcss.png +0 -0
  94. data/site/build/site/en/skin/images/warning.png +0 -0
  95. data/site/build/site/en/skin/images/xmldoc.gif +0 -0
  96. data/site/build/site/en/skin/menu.js +48 -0
  97. data/site/build/site/en/skin/note.txt +50 -0
  98. data/site/build/site/en/skin/print.css +54 -0
  99. data/site/build/site/en/skin/profile.css +163 -0
  100. data/site/build/site/en/skin/prototype.js +1257 -0
  101. data/site/build/site/en/skin/screen.css +587 -0
  102. data/site/build/site/en/svn.html +223 -0
  103. data/site/build/site/en/svn.pdf +239 -0
  104. data/site/build/site/en/wholesite.pdf +1686 -0
  105. data/site/build/tmp/brokenlinks.xml +2 -0
  106. data/site/build/tmp/build-info.xml +5 -0
  107. data/site/build/tmp/cocoon-work/cache-dir/cocoon-ehcache-1.data +0 -0
  108. data/site/build/tmp/cocoon-work/cache-dir/cocoon-ehcache-1.index +0 -0
  109. data/site/build/tmp/input.xmap +32 -0
  110. data/site/build/tmp/internal.xmap +32 -0
  111. data/site/build/tmp/locationmap.xml +29 -0
  112. data/site/build/tmp/output.xmap +38 -0
  113. data/site/build/tmp/pluginlist2fetchbuild.xml +144 -0
  114. data/site/build/tmp/plugins-1.xml +212 -0
  115. data/site/build/tmp/plugins-2.xml +347 -0
  116. data/site/build/tmp/projfilters.properties +41 -0
  117. data/site/build/tmp/resources.xmap +32 -0
  118. data/site/build/webapp/WEB-INF/logs/access.log +0 -0
  119. data/site/build/webapp/WEB-INF/logs/core.log +788 -0
  120. data/site/build/webapp/WEB-INF/logs/debug.log +0 -0
  121. data/site/build/webapp/WEB-INF/logs/error.log +248 -0
  122. data/site/build/webapp/WEB-INF/logs/flow.log +0 -0
  123. data/site/build/webapp/WEB-INF/logs/idgen.log +0 -0
  124. data/site/build/webapp/WEB-INF/logs/linkrewriter.log +0 -0
  125. data/site/build/webapp/WEB-INF/logs/locationmap.log +0 -0
  126. data/site/build/webapp/WEB-INF/logs/sitemap.log +0 -0
  127. data/site/build/webapp/WEB-INF/logs/xmlform.log +0 -0
  128. data/site/forrest.properties +152 -0
  129. data/site/forrest.properties.dispatcher.properties +25 -0
  130. data/site/forrest.properties.xml +29 -0
  131. data/site/src/documentation/README.txt +7 -0
  132. data/site/src/documentation/classes/CatalogManager.properties +62 -0
  133. data/site/src/documentation/content/locationmap.xml +72 -0
  134. data/site/src/documentation/content/xdocs/downloads.html +9 -0
  135. data/site/src/documentation/content/xdocs/geneticAlgorithms.xml +280 -0
  136. data/site/src/documentation/content/xdocs/index.xml +73 -0
  137. data/site/src/documentation/content/xdocs/machineLearning.xml +129 -0
  138. data/site/src/documentation/content/xdocs/neuralNetworks.xml +218 -0
  139. data/site/src/documentation/content/xdocs/site.xml +51 -0
  140. data/site/src/documentation/content/xdocs/svn.xml +31 -0
  141. data/site/src/documentation/content/xdocs/tabs.xml +35 -0
  142. data/site/src/documentation/resources/images/ai4r-logo.png +0 -0
  143. data/site/src/documentation/resources/images/c.png +0 -0
  144. data/site/src/documentation/resources/images/c_wbn.png +0 -0
  145. data/site/src/documentation/resources/images/c_wn.png +0 -0
  146. data/site/src/documentation/resources/images/ellipse-2.svg +30 -0
  147. data/site/src/documentation/resources/images/ero.gif +0 -0
  148. data/site/src/documentation/resources/images/europe2.png +0 -0
  149. data/site/src/documentation/resources/images/europe3.png +0 -0
  150. data/site/src/documentation/resources/images/fitness.png +0 -0
  151. data/site/src/documentation/resources/images/icon-a.png +0 -0
  152. data/site/src/documentation/resources/images/icon-b.png +0 -0
  153. data/site/src/documentation/resources/images/icon.png +0 -0
  154. data/site/src/documentation/resources/images/my_email.png +0 -0
  155. data/site/src/documentation/resources/images/project-logo.png +0 -0
  156. data/site/src/documentation/resources/images/rubyforge.png +0 -0
  157. data/site/src/documentation/resources/images/s.png +0 -0
  158. data/site/src/documentation/resources/images/s_wbn.png +0 -0
  159. data/site/src/documentation/resources/images/s_wn.png +0 -0
  160. data/site/src/documentation/resources/images/sigmoid.png +0 -0
  161. data/site/src/documentation/resources/images/sub-dir/icon-c.png +0 -0
  162. data/site/src/documentation/resources/images/t.png +0 -0
  163. data/site/src/documentation/resources/images/t_wbn.png +0 -0
  164. data/site/src/documentation/resources/images/t_wn.png +0 -0
  165. data/site/src/documentation/resources/schema/catalog.xcat +29 -0
  166. data/site/src/documentation/resources/schema/hello-v10.dtd +51 -0
  167. data/site/src/documentation/resources/schema/symbols-project-v10.ent +26 -0
  168. data/site/src/documentation/resources/stylesheets/hello2document.xsl +33 -0
  169. data/site/src/documentation/sitemap.xmap +66 -0
  170. data/site/src/documentation/skinconf.xml +418 -0
  171. data/site/src/documentation/translations/langcode.xml +29 -0
  172. data/site/src/documentation/translations/languages_de.xml +24 -0
  173. data/site/src/documentation/translations/languages_en.xml +24 -0
  174. data/site/src/documentation/translations/languages_es.xml +22 -0
  175. data/site/src/documentation/translations/languages_fr.xml +24 -0
  176. data/site/src/documentation/translations/languages_nl.xml +24 -0
  177. data/site/src/documentation/translations/menu.xml +33 -0
  178. data/site/src/documentation/translations/menu_af.xml +33 -0
  179. data/site/src/documentation/translations/menu_de.xml +33 -0
  180. data/site/src/documentation/translations/menu_es.xml +33 -0
  181. data/site/src/documentation/translations/menu_fr.xml +33 -0
  182. data/site/src/documentation/translations/menu_it.xml +33 -0
  183. data/site/src/documentation/translations/menu_nl.xml +33 -0
  184. data/site/src/documentation/translations/menu_no.xml +33 -0
  185. data/site/src/documentation/translations/menu_ru.xml +33 -0
  186. data/site/src/documentation/translations/menu_sk.xml +33 -0
  187. data/site/src/documentation/translations/tabs.xml +22 -0
  188. data/site/src/documentation/translations/tabs_de.xml +22 -0
  189. data/site/src/documentation/translations/tabs_es.xml +22 -0
  190. data/site/src/documentation/translations/tabs_fr.xml +22 -0
  191. data/site/src/documentation/translations/tabs_nl.xml +22 -0
  192. data/test/decision_tree/id3_test.rb +209 -0
  193. data/test/genetic_algorithm/chromosome_test.rb +55 -0
  194. data/test/genetic_algorithm/genetic_algorithm_test.rb +78 -0
  195. data/test/neural_network/backpropagation_test.rb +44 -0
  196. metadata +274 -0
@@ -0,0 +1,54 @@
1
+ /*
2
+ * Licensed to the Apache Software Foundation (ASF) under one or more
3
+ * contributor license agreements. See the NOTICE file distributed with
4
+ * this work for additional information regarding copyright ownership.
5
+ * The ASF licenses this file to You under the Apache License, Version 2.0
6
+ * (the "License"); you may not use this file except in compliance with
7
+ * the License. You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ body {
18
+ font-family: Georgia, Palatino, serif;
19
+ font-size: 12pt;
20
+ background: white;
21
+ }
22
+
23
+ #tabs,
24
+ #menu,
25
+ #content .toc {
26
+ display: none;
27
+ }
28
+
29
+ #content {
30
+ width: auto;
31
+ padding: 0;
32
+ float: none !important;
33
+ color: black;
34
+ background: inherit;
35
+ }
36
+
37
+ a:link, a:visited {
38
+ color: #336699;
39
+ background: inherit;
40
+ text-decoration: underline;
41
+ }
42
+
43
+ #top .logo {
44
+ padding: 0;
45
+ margin: 0 0 2em 0;
46
+ }
47
+
48
+ #footer {
49
+ margin-top: 4em;
50
+ }
51
+
52
+ acronym {
53
+ border: 0;
54
+ }
@@ -0,0 +1,163 @@
1
+
2
+
3
+ /* ==================== aural ============================ */
4
+
5
+ @media aural {
6
+ h1, h2, h3, h4, h5, h6 { voice-family: paul, male; stress: 20; richness: 90 }
7
+ h1 { pitch: x-low; pitch-range: 90 }
8
+ h2 { pitch: x-low; pitch-range: 80 }
9
+ h3 { pitch: low; pitch-range: 70 }
10
+ h4 { pitch: medium; pitch-range: 60 }
11
+ h5 { pitch: medium; pitch-range: 50 }
12
+ h6 { pitch: medium; pitch-range: 40 }
13
+ li, dt, dd { pitch: medium; richness: 60 }
14
+ dt { stress: 80 }
15
+ pre, code, tt { pitch: medium; pitch-range: 0; stress: 0; richness: 80 }
16
+ em { pitch: medium; pitch-range: 60; stress: 60; richness: 50 }
17
+ strong { pitch: medium; pitch-range: 60; stress: 90; richness: 90 }
18
+ dfn { pitch: high; pitch-range: 60; stress: 60 }
19
+ s, strike { richness: 0 }
20
+ i { pitch: medium; pitch-range: 60; stress: 60; richness: 50 }
21
+ b { pitch: medium; pitch-range: 60; stress: 90; richness: 90 }
22
+ u { richness: 0 }
23
+
24
+ :link { voice-family: harry, male }
25
+ :visited { voice-family: betty, female }
26
+ :active { voice-family: betty, female; pitch-range: 80; pitch: x-high }
27
+ }
28
+
29
+ a.external {
30
+ padding: 0 20px 0px 0px;
31
+ display:inline;
32
+ background-repeat: no-repeat;
33
+ background-position: center right;
34
+ background-image: url(images/external-link.gif);
35
+ }
36
+
37
+ #top { background-color: #003366;}
38
+
39
+ #top .header .current { background-color: #dddddd;}
40
+ #top .header .current a:link { color: #555555; }
41
+ #top .header .current a:visited { color: #555555; }
42
+ #top .header .current a:hover { color: #555555; }
43
+
44
+ #tabs li { background-color: #999999 ;}
45
+ #tabs li a:link { color: #ffffff; }
46
+ #tabs li a:visited { color: #ffffff; }
47
+ #tabs li a:hover { color: #ffffff; }
48
+
49
+ #level2tabs a.selected { background-color: #cccccc ;}
50
+ #level2tabs a:link { color: #000000; }
51
+ #level2tabs a:visited { color: #000000; }
52
+ #level2tabs a:hover { color: #000000; }
53
+
54
+ #level2tabs { background-color: #cccccc;}
55
+ #level2tabs a.unselected:link { color: #555555; }
56
+ #level2tabs a.unselected:visited { color: #555555; }
57
+ #level2tabs a.unselected:hover { color: #555555; }
58
+
59
+ .heading { background-color: #003366;}
60
+
61
+ .boxed { background-color: #888888;}
62
+ .underlined_5 {border-bottom: solid 5px #888888;}
63
+ .underlined_10 {border-bottom: solid 10px #888888;}
64
+ table caption {
65
+ background-color: #888888;
66
+ color: #000000;
67
+ }
68
+
69
+ #publishedStrip {
70
+ color: #555555;
71
+ background: #dddddd;
72
+ }
73
+
74
+ #menu .menupagetitle { background-color: #dddddd;
75
+ color: #555555;}
76
+
77
+ #menu { border-color: #999999;}
78
+ #menu .menupagetitle { border-color: #999999;}
79
+ #menu .menupageitemgroup { border-color: #999999;}
80
+
81
+ #menu { background-color: #ffffff;}
82
+ #menu { color: #000000;}
83
+ #menu a:link { color: #0000ff;}
84
+ #menu a:visited { color: #009999;}
85
+ #menu a:hover {
86
+ background-color: #ffffff;
87
+ color: #6587ff;}
88
+
89
+ #menu .menupageitemgroup {
90
+ background-color: #eeeeee;
91
+ }
92
+ #menu .menupageitem {
93
+ color: #000000;
94
+ }
95
+ #menu .menupageitem a:link { color: #0000ff;}
96
+ #menu .menupageitem a:visited { color: #009999;}
97
+ #menu .menupageitem a:hover {
98
+ background-color: #eeeeee;
99
+ color: #6587ff;
100
+ }
101
+
102
+ body{
103
+ background-color: #ffffff;
104
+ color: #000000;
105
+ }
106
+ a:link { color:#0000ff}
107
+ a:visited { color:#009999}
108
+ a:hover { color:#6587ff}
109
+
110
+
111
+ .ForrestTable { background-color: #ccc;}
112
+
113
+ .ForrestTable td { background-color: #ffffff;}
114
+
115
+ .highlight { background-color: #ffff00;}
116
+
117
+ .fixme { border-color: #cc6600;}
118
+
119
+ .note { border-color: #006699;}
120
+
121
+ .warning { border-color: #990000;}
122
+
123
+ .code { border-color: #003366;}
124
+
125
+ #footer { background-color: #ffffff;}
126
+
127
+ #feedback {
128
+ color: #FFFFFF;
129
+ background: #4C6C8F;
130
+ text-align: center;
131
+ }
132
+ #feedback #feedbackto {
133
+ color: #FFFFFF;
134
+ }
135
+
136
+ #publishedStrip {
137
+ color: #FFFFFF;
138
+ background: #4C6C8F;
139
+ }
140
+
141
+ #menu h1 {
142
+ color: #000000;
143
+ background-color: #cfdced;
144
+ }
145
+
146
+ #top .searchbox {
147
+ height: 34px;
148
+ background-color: #DDDDDD;
149
+ color: #000000;
150
+ }
151
+ /* extra-css */
152
+
153
+ p.quote {
154
+ margin-left: 2em;
155
+ padding: .5em;
156
+ background-color: #f0f0f0;
157
+ font-family: monospace;
158
+ }
159
+
160
+ #footer a { color: #0F3660; }
161
+ #footer a:visited { color: #009999; }
162
+ #top :searchbox { height: 34px; background-color: #DDDDDD; }
163
+
@@ -0,0 +1,1257 @@
1
+ /* Prototype JavaScript framework, version 1.4.0_pre4
2
+ * (c) 2005 Sam Stephenson <sam@conio.net>
3
+ *
4
+ * THIS FILE IS AUTOMATICALLY GENERATED. When sending patches, please diff
5
+ * against the source tree, available from the Prototype darcs repository.
6
+ *
7
+ * Prototype is freely distributable under the terms of an MIT-style license.
8
+ *
9
+ * For details, see the Prototype web site: http://prototype.conio.net/
10
+ *
11
+ /*--------------------------------------------------------------------------*/
12
+
13
+ var Prototype = {
14
+ Version: '1.4.0_pre4',
15
+
16
+ emptyFunction: function() {},
17
+ K: function(x) {return x}
18
+ }
19
+
20
+ var Class = {
21
+ create: function() {
22
+ return function() {
23
+ this.initialize.apply(this, arguments);
24
+ }
25
+ }
26
+ }
27
+
28
+ var Abstract = new Object();
29
+
30
+ Object.extend = function(destination, source) {
31
+ for (property in source) {
32
+ destination[property] = source[property];
33
+ }
34
+ return destination;
35
+ }
36
+
37
+ Function.prototype.bind = function(object) {
38
+ var __method = this;
39
+ return function() {
40
+ return __method.apply(object, arguments);
41
+ }
42
+ }
43
+
44
+ Function.prototype.bindAsEventListener = function(object) {
45
+ var __method = this;
46
+ return function(event) {
47
+ return __method.call(object, event || window.event);
48
+ }
49
+ }
50
+
51
+ Number.prototype.toColorPart = function() {
52
+ var digits = this.toString(16);
53
+ if (this < 16) return '0' + digits;
54
+ return digits;
55
+ }
56
+
57
+ var Try = {
58
+ these: function() {
59
+ var returnValue;
60
+
61
+ for (var i = 0; i < arguments.length; i++) {
62
+ var lambda = arguments[i];
63
+ try {
64
+ returnValue = lambda();
65
+ break;
66
+ } catch (e) {}
67
+ }
68
+
69
+ return returnValue;
70
+ }
71
+ }
72
+
73
+ /*--------------------------------------------------------------------------*/
74
+
75
+ var PeriodicalExecuter = Class.create();
76
+ PeriodicalExecuter.prototype = {
77
+ initialize: function(callback, frequency) {
78
+ this.callback = callback;
79
+ this.frequency = frequency;
80
+ this.currentlyExecuting = false;
81
+
82
+ this.registerCallback();
83
+ },
84
+
85
+ registerCallback: function() {
86
+ setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
87
+ },
88
+
89
+ onTimerEvent: function() {
90
+ if (!this.currentlyExecuting) {
91
+ try {
92
+ this.currentlyExecuting = true;
93
+ this.callback();
94
+ } finally {
95
+ this.currentlyExecuting = false;
96
+ }
97
+ }
98
+ }
99
+ }
100
+
101
+ /*--------------------------------------------------------------------------*/
102
+
103
+ function $() {
104
+ var elements = new Array();
105
+
106
+ for (var i = 0; i < arguments.length; i++) {
107
+ var element = arguments[i];
108
+ if (typeof element == 'string')
109
+ element = document.getElementById(element);
110
+
111
+ if (arguments.length == 1)
112
+ return element;
113
+
114
+ elements.push(element);
115
+ }
116
+
117
+ return elements;
118
+ }
119
+
120
+ if (!Array.prototype.push) {
121
+ Array.prototype.push = function() {
122
+ var startLength = this.length;
123
+ for (var i = 0; i < arguments.length; i++)
124
+ this[startLength + i] = arguments[i];
125
+ return this.length;
126
+ }
127
+ }
128
+
129
+ if (!Function.prototype.apply) {
130
+ // Based on code from http://www.youngpup.net/
131
+ Function.prototype.apply = function(object, parameters) {
132
+ var parameterStrings = new Array();
133
+ if (!object) object = window;
134
+ if (!parameters) parameters = new Array();
135
+
136
+ for (var i = 0; i < parameters.length; i++)
137
+ parameterStrings[i] = 'parameters[' + i + ']';
138
+
139
+ object.__apply__ = this;
140
+ var result = eval('object.__apply__(' +
141
+ parameterStrings.join(', ') + ')');
142
+ object.__apply__ = null;
143
+
144
+ return result;
145
+ }
146
+ }
147
+
148
+ Object.extend(String.prototype, {
149
+ stripTags: function() {
150
+ return this.replace(/<\/?[^>]+>/gi, '');
151
+ },
152
+
153
+ escapeHTML: function() {
154
+ var div = document.createElement('div');
155
+ var text = document.createTextNode(this);
156
+ div.appendChild(text);
157
+ return div.innerHTML;
158
+ },
159
+
160
+ unescapeHTML: function() {
161
+ var div = document.createElement('div');
162
+ div.innerHTML = this.stripTags();
163
+ return div.childNodes[0].nodeValue;
164
+ },
165
+
166
+ parseQuery: function() {
167
+ var str = this;
168
+ if (str.substring(0,1) == '?') {
169
+ str = this.substring(1);
170
+ }
171
+ var result = {};
172
+ var pairs = str.split('&');
173
+ for (var i = 0; i < pairs.length; i++) {
174
+ var pair = pairs[i].split('=');
175
+ result[pair[0]] = pair[1];
176
+ }
177
+ return result;
178
+ }
179
+ });
180
+
181
+
182
+ var _break = new Object();
183
+ var _continue = new Object();
184
+
185
+ var Enumerable = {
186
+ each: function(iterator) {
187
+ var index = 0;
188
+ try {
189
+ this._each(function(value) {
190
+ try {
191
+ iterator(value, index++);
192
+ } catch (e) {
193
+ if (e != _continue) throw e;
194
+ }
195
+ });
196
+ } catch (e) {
197
+ if (e != _break) throw e;
198
+ }
199
+ },
200
+
201
+ all: function(iterator) {
202
+ var result = true;
203
+ this.each(function(value, index) {
204
+ if (!(result &= (iterator || Prototype.K)(value, index)))
205
+ throw _break;
206
+ });
207
+ return result;
208
+ },
209
+
210
+ any: function(iterator) {
211
+ var result = true;
212
+ this.each(function(value, index) {
213
+ if (result &= (iterator || Prototype.K)(value, index))
214
+ throw _break;
215
+ });
216
+ return result;
217
+ },
218
+
219
+ collect: function(iterator) {
220
+ var results = [];
221
+ this.each(function(value, index) {
222
+ results.push(iterator(value, index));
223
+ });
224
+ return results;
225
+ },
226
+
227
+ detect: function (iterator) {
228
+ var result;
229
+ this.each(function(value, index) {
230
+ if (iterator(value, index)) {
231
+ result = value;
232
+ throw _break;
233
+ }
234
+ });
235
+ return result;
236
+ },
237
+
238
+ findAll: function(iterator) {
239
+ var results = [];
240
+ this.each(function(value, index) {
241
+ if (iterator(value, index))
242
+ results.push(value);
243
+ });
244
+ return results;
245
+ },
246
+
247
+ grep: function(pattern, iterator) {
248
+ var results = [];
249
+ this.each(function(value, index) {
250
+ var stringValue = value.toString();
251
+ if (stringValue.match(pattern))
252
+ results.push((iterator || Prototype.K)(value, index));
253
+ })
254
+ return results;
255
+ },
256
+
257
+ include: function(object) {
258
+ var found = false;
259
+ this.each(function(value) {
260
+ if (value == object) {
261
+ found = true;
262
+ throw _break;
263
+ }
264
+ });
265
+ return found;
266
+ },
267
+
268
+ inject: function(memo, iterator) {
269
+ this.each(function(value, index) {
270
+ memo = iterator(memo, value, index);
271
+ });
272
+ return memo;
273
+ },
274
+
275
+ invoke: function(method) {
276
+ var args = $A(arguments).slice(1);
277
+ return this.collect(function(value) {
278
+ return value[method].apply(value, args);
279
+ });
280
+ },
281
+
282
+ max: function(iterator) {
283
+ var result;
284
+ this.each(function(value, index) {
285
+ value = (iterator || Prototype.K)(value, index);
286
+ if (value >= (result || value))
287
+ result = value;
288
+ });
289
+ return result;
290
+ },
291
+
292
+ min: function(iterator) {
293
+ var result;
294
+ this.each(function(value, index) {
295
+ value = (iterator || Prototype.K)(value, index);
296
+ if (value <= (result || value))
297
+ result = value;
298
+ });
299
+ return result;
300
+ },
301
+
302
+ partition: function(iterator) {
303
+ var trues = [], falses = [];
304
+ this.each(function(value, index) {
305
+ ((iterator || Prototype.K)(value, index) ?
306
+ trues : falses).push(value);
307
+ });
308
+ return [trues, falses];
309
+ },
310
+
311
+ pluck: function(property) {
312
+ var results = [];
313
+ this.each(function(value, index) {
314
+ results.push(value[property]);
315
+ });
316
+ return results;
317
+ },
318
+
319
+ reject: function(iterator) {
320
+ var results = [];
321
+ this.each(function(value, index) {
322
+ if (!iterator(value, index))
323
+ results.push(value);
324
+ });
325
+ return results;
326
+ },
327
+
328
+ sortBy: function(iterator) {
329
+ return this.collect(function(value, index) {
330
+ return {value: value, criteria: iterator(value, index)};
331
+ }).sort(function(left, right) {
332
+ var a = left.criteria, b = right.criteria;
333
+ return a < b ? -1 : a > b ? 1 : 0;
334
+ }).pluck('value');
335
+ },
336
+
337
+ toArray: function() {
338
+ return this.collect(Prototype.K);
339
+ },
340
+
341
+ zip: function() {
342
+ var iterator = Prototype.K, args = $A(arguments);
343
+ if (typeof args.last() == 'function')
344
+ iterator = args.pop();
345
+
346
+ var collections = [this].concat(args).map($A);
347
+ return this.map(function(value, index) {
348
+ iterator(value = collections.pluck(index));
349
+ return value;
350
+ });
351
+ }
352
+ }
353
+
354
+ Object.extend(Enumerable, {
355
+ map: Enumerable.collect,
356
+ find: Enumerable.detect,
357
+ select: Enumerable.findAll,
358
+ member: Enumerable.include,
359
+ entries: Enumerable.toArray
360
+ });
361
+
362
+ $A = Array.from = function(iterable) {
363
+ var results = [];
364
+ for (var i = 0; i < iterable.length; i++)
365
+ results.push(iterable[i]);
366
+ return results;
367
+ }
368
+
369
+ Object.extend(Array.prototype, {
370
+ _each: function(iterator) {
371
+ for (var i = 0; i < this.length; i++)
372
+ iterator(this[i]);
373
+ },
374
+
375
+ first: function() {
376
+ return this[0];
377
+ },
378
+
379
+ last: function() {
380
+ return this[this.length - 1];
381
+ }
382
+ });
383
+
384
+ Object.extend(Array.prototype, Enumerable);
385
+
386
+
387
+ var Ajax = {
388
+ getTransport: function() {
389
+ return Try.these(
390
+ function() {return new ActiveXObject('Msxml2.XMLHTTP')},
391
+ function() {return new ActiveXObject('Microsoft.XMLHTTP')},
392
+ function() {return new XMLHttpRequest()}
393
+ ) || false;
394
+ }
395
+ }
396
+
397
+ Ajax.Base = function() {};
398
+ Ajax.Base.prototype = {
399
+ setOptions: function(options) {
400
+ this.options = {
401
+ method: 'post',
402
+ asynchronous: true,
403
+ parameters: ''
404
+ }
405
+ Object.extend(this.options, options || {});
406
+ },
407
+
408
+ responseIsSuccess: function() {
409
+ return this.transport.status == undefined
410
+ || this.transport.status == 0
411
+ || (this.transport.status >= 200 && this.transport.status < 300);
412
+ },
413
+
414
+ responseIsFailure: function() {
415
+ return !this.responseIsSuccess();
416
+ }
417
+ }
418
+
419
+ Ajax.Request = Class.create();
420
+ Ajax.Request.Events =
421
+ ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
422
+
423
+ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
424
+ initialize: function(url, options) {
425
+ this.transport = Ajax.getTransport();
426
+ this.setOptions(options);
427
+ this.request(url);
428
+ },
429
+
430
+ request: function(url) {
431
+ var parameters = this.options.parameters || '';
432
+ if (parameters.length > 0) parameters += '&_=';
433
+
434
+ try {
435
+ if (this.options.method == 'get')
436
+ url += '?' + parameters;
437
+
438
+ this.transport.open(this.options.method, url,
439
+ this.options.asynchronous);
440
+
441
+ if (this.options.asynchronous) {
442
+ this.transport.onreadystatechange = this.onStateChange.bind(this);
443
+ setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);
444
+ }
445
+
446
+ this.setRequestHeaders();
447
+
448
+ var body = this.options.postBody ? this.options.postBody : parameters;
449
+ this.transport.send(this.options.method == 'post' ? body : null);
450
+
451
+ } catch (e) {
452
+ }
453
+ },
454
+
455
+ setRequestHeaders: function() {
456
+ var requestHeaders =
457
+ ['X-Requested-With', 'XMLHttpRequest',
458
+ 'X-Prototype-Version', Prototype.Version];
459
+
460
+ if (this.options.method == 'post') {
461
+ requestHeaders.push('Content-type',
462
+ 'application/x-www-form-urlencoded');
463
+
464
+ /* Force "Connection: close" for Mozilla browsers to work around
465
+ * a bug where XMLHttpReqeuest sends an incorrect Content-length
466
+ * header. See Mozilla Bugzilla #246651.
467
+ */
468
+ if (this.transport.overrideMimeType)
469
+ requestHeaders.push('Connection', 'close');
470
+ }
471
+
472
+ if (this.options.requestHeaders)
473
+ requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);
474
+
475
+ for (var i = 0; i < requestHeaders.length; i += 2)
476
+ this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
477
+ },
478
+
479
+ onStateChange: function() {
480
+ var readyState = this.transport.readyState;
481
+ if (readyState != 1)
482
+ this.respondToReadyState(this.transport.readyState);
483
+ },
484
+
485
+ respondToReadyState: function(readyState) {
486
+ var event = Ajax.Request.Events[readyState];
487
+
488
+ if (event == 'Complete')
489
+ (this.options['on' + this.transport.status]
490
+ || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
491
+ || Prototype.emptyFunction)(this.transport);
492
+
493
+ (this.options['on' + event] || Prototype.emptyFunction)(this.transport);
494
+
495
+ /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
496
+ if (event == 'Complete')
497
+ this.transport.onreadystatechange = Prototype.emptyFunction;
498
+ }
499
+ });
500
+
501
+ Ajax.Updater = Class.create();
502
+ Ajax.Updater.ScriptFragment = '(?:<script.*?>)((\n|.)*?)(?:<\/script>)';
503
+
504
+ Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
505
+ initialize: function(container, url, options) {
506
+ this.containers = {
507
+ success: container.success ? $(container.success) : $(container),
508
+ failure: container.failure ? $(container.failure) :
509
+ (container.success ? null : $(container))
510
+ }
511
+
512
+ this.transport = Ajax.getTransport();
513
+ this.setOptions(options);
514
+
515
+ var onComplete = this.options.onComplete || Prototype.emptyFunction;
516
+ this.options.onComplete = (function() {
517
+ this.updateContent();
518
+ onComplete(this.transport);
519
+ }).bind(this);
520
+
521
+ this.request(url);
522
+ },
523
+
524
+ updateContent: function() {
525
+ var receiver = this.responseIsSuccess() ?
526
+ this.containers.success : this.containers.failure;
527
+
528
+ var match = new RegExp(Ajax.Updater.ScriptFragment, 'img');
529
+ var response = this.transport.responseText.replace(match, '');
530
+ var scripts = this.transport.responseText.match(match);
531
+
532
+ if (receiver) {
533
+ if (this.options.insertion) {
534
+ new this.options.insertion(receiver, response);
535
+ } else {
536
+ receiver.innerHTML = response;
537
+ }
538
+ }
539
+
540
+ if (this.responseIsSuccess()) {
541
+ if (this.onComplete)
542
+ setTimeout((function() {this.onComplete(
543
+ this.transport)}).bind(this), 10);
544
+ }
545
+
546
+ if (this.options.evalScripts && scripts) {
547
+ match = new RegExp(Ajax.Updater.ScriptFragment, 'im');
548
+ setTimeout((function() {
549
+ for (var i = 0; i < scripts.length; i++)
550
+ eval(scripts[i].match(match)[1]);
551
+ }).bind(this), 10);
552
+ }
553
+ }
554
+ });
555
+
556
+ Ajax.PeriodicalUpdater = Class.create();
557
+ Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
558
+ initialize: function(container, url, options) {
559
+ this.setOptions(options);
560
+ this.onComplete = this.options.onComplete;
561
+
562
+ this.frequency = (this.options.frequency || 2);
563
+ this.decay = 1;
564
+
565
+ this.updater = {};
566
+ this.container = container;
567
+ this.url = url;
568
+
569
+ this.start();
570
+ },
571
+
572
+ start: function() {
573
+ this.options.onComplete = this.updateComplete.bind(this);
574
+ this.onTimerEvent();
575
+ },
576
+
577
+ stop: function() {
578
+ this.updater.onComplete = undefined;
579
+ clearTimeout(this.timer);
580
+ (this.onComplete || Ajax.emptyFunction).apply(this, arguments);
581
+ },
582
+
583
+ updateComplete: function(request) {
584
+ if (this.options.decay) {
585
+ this.decay = (request.responseText == this.lastText ?
586
+ this.decay * this.options.decay : 1);
587
+
588
+ this.lastText = request.responseText;
589
+ }
590
+ this.timer = setTimeout(this.onTimerEvent.bind(this),
591
+ this.decay * this.frequency * 1000);
592
+ },
593
+
594
+ onTimerEvent: function() {
595
+ this.updater = new Ajax.Updater(this.container, this.url, this.options);
596
+ }
597
+ });
598
+
599
+ document.getElementsByClassName = function(className) {
600
+ var children = document.getElementsByTagName('*') || document.all;
601
+ var elements = new Array();
602
+
603
+ for (var i = 0; i < children.length; i++) {
604
+ var child = children[i];
605
+ var classNames = child.className.split(' ');
606
+ for (var j = 0; j < classNames.length; j++) {
607
+ if (classNames[j] == className) {
608
+ elements.push(child);
609
+ break;
610
+ }
611
+ }
612
+ }
613
+
614
+ return elements;
615
+ }
616
+
617
+ /*--------------------------------------------------------------------------*/
618
+
619
+ if (!window.Element) {
620
+ var Element = new Object();
621
+ }
622
+
623
+ Object.extend(Element, {
624
+ toggle: function() {
625
+ for (var i = 0; i < arguments.length; i++) {
626
+ var element = $(arguments[i]);
627
+ element.style.display =
628
+ (element.style.display == 'none' ? '' : 'none');
629
+ }
630
+ },
631
+
632
+ hide: function() {
633
+ for (var i = 0; i < arguments.length; i++) {
634
+ var element = $(arguments[i]);
635
+ element.style.display = 'none';
636
+ }
637
+ },
638
+
639
+ show: function() {
640
+ for (var i = 0; i < arguments.length; i++) {
641
+ var element = $(arguments[i]);
642
+ element.style.display = '';
643
+ }
644
+ },
645
+
646
+ remove: function(element) {
647
+ element = $(element);
648
+ element.parentNode.removeChild(element);
649
+ },
650
+
651
+ getHeight: function(element) {
652
+ element = $(element);
653
+ return element.offsetHeight;
654
+ },
655
+
656
+ hasClassName: function(element, className) {
657
+ element = $(element);
658
+ if (!element)
659
+ return;
660
+ var a = element.className.split(' ');
661
+ for (var i = 0; i < a.length; i++) {
662
+ if (a[i] == className)
663
+ return true;
664
+ }
665
+ return false;
666
+ },
667
+
668
+ addClassName: function(element, className) {
669
+ element = $(element);
670
+ Element.removeClassName(element, className);
671
+ element.className += ' ' + className;
672
+ },
673
+
674
+ removeClassName: function(element, className) {
675
+ element = $(element);
676
+ if (!element)
677
+ return;
678
+ var newClassName = '';
679
+ var a = element.className.split(' ');
680
+ for (var i = 0; i < a.length; i++) {
681
+ if (a[i] != className) {
682
+ if (i > 0)
683
+ newClassName += ' ';
684
+ newClassName += a[i];
685
+ }
686
+ }
687
+ element.className = newClassName;
688
+ },
689
+
690
+ // removes whitespace-only text node children
691
+ cleanWhitespace: function(element) {
692
+ var element = $(element);
693
+ for (var i = 0; i < element.childNodes.length; i++) {
694
+ var node = element.childNodes[i];
695
+ if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
696
+ Element.remove(node);
697
+ }
698
+ }
699
+ });
700
+
701
+ var Toggle = new Object();
702
+ Toggle.display = Element.toggle;
703
+
704
+ /*--------------------------------------------------------------------------*/
705
+
706
+ Abstract.Insertion = function(adjacency) {
707
+ this.adjacency = adjacency;
708
+ }
709
+
710
+ Abstract.Insertion.prototype = {
711
+ initialize: function(element, content) {
712
+ this.element = $(element);
713
+ this.content = content;
714
+
715
+ if (this.adjacency && this.element.insertAdjacentHTML) {
716
+ this.element.insertAdjacentHTML(this.adjacency, this.content);
717
+ } else {
718
+ this.range = this.element.ownerDocument.createRange();
719
+ if (this.initializeRange) this.initializeRange();
720
+ this.fragment = this.range.createContextualFragment(this.content);
721
+ this.insertContent();
722
+ }
723
+ }
724
+ }
725
+
726
+ var Insertion = new Object();
727
+
728
+ Insertion.Before = Class.create();
729
+ Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
730
+ initializeRange: function() {
731
+ this.range.setStartBefore(this.element);
732
+ },
733
+
734
+ insertContent: function() {
735
+ this.element.parentNode.insertBefore(this.fragment, this.element);
736
+ }
737
+ });
738
+
739
+ Insertion.Top = Class.create();
740
+ Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
741
+ initializeRange: function() {
742
+ this.range.selectNodeContents(this.element);
743
+ this.range.collapse(true);
744
+ },
745
+
746
+ insertContent: function() {
747
+ this.element.insertBefore(this.fragment, this.element.firstChild);
748
+ }
749
+ });
750
+
751
+ Insertion.Bottom = Class.create();
752
+ Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
753
+ initializeRange: function() {
754
+ this.range.selectNodeContents(this.element);
755
+ this.range.collapse(this.element);
756
+ },
757
+
758
+ insertContent: function() {
759
+ this.element.appendChild(this.fragment);
760
+ }
761
+ });
762
+
763
+ Insertion.After = Class.create();
764
+ Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
765
+ initializeRange: function() {
766
+ this.range.setStartAfter(this.element);
767
+ },
768
+
769
+ insertContent: function() {
770
+ this.element.parentNode.insertBefore(this.fragment,
771
+ this.element.nextSibling);
772
+ }
773
+ });
774
+
775
+ var Field = {
776
+ clear: function() {
777
+ for (var i = 0; i < arguments.length; i++)
778
+ $(arguments[i]).value = '';
779
+ },
780
+
781
+ focus: function(element) {
782
+ $(element).focus();
783
+ },
784
+
785
+ present: function() {
786
+ for (var i = 0; i < arguments.length; i++)
787
+ if ($(arguments[i]).value == '') return false;
788
+ return true;
789
+ },
790
+
791
+ select: function(element) {
792
+ $(element).select();
793
+ },
794
+
795
+ activate: function(element) {
796
+ $(element).focus();
797
+ $(element).select();
798
+ }
799
+ }
800
+
801
+ /*--------------------------------------------------------------------------*/
802
+
803
+ var Form = {
804
+ serialize: function(form) {
805
+ var elements = Form.getElements($(form));
806
+ var queryComponents = new Array();
807
+
808
+ for (var i = 0; i < elements.length; i++) {
809
+ var queryComponent = Form.Element.serialize(elements[i]);
810
+ if (queryComponent)
811
+ queryComponents.push(queryComponent);
812
+ }
813
+
814
+ return queryComponents.join('&');
815
+ },
816
+
817
+ getElements: function(form) {
818
+ var form = $(form);
819
+ var elements = new Array();
820
+
821
+ for (tagName in Form.Element.Serializers) {
822
+ var tagElements = form.getElementsByTagName(tagName);
823
+ for (var j = 0; j < tagElements.length; j++)
824
+ elements.push(tagElements[j]);
825
+ }
826
+ return elements;
827
+ },
828
+
829
+ getInputs: function(form, typeName, name) {
830
+ var form = $(form);
831
+ var inputs = form.getElementsByTagName('input');
832
+
833
+ if (!typeName && !name)
834
+ return inputs;
835
+
836
+ var matchingInputs = new Array();
837
+ for (var i = 0; i < inputs.length; i++) {
838
+ var input = inputs[i];
839
+ if ((typeName && input.type != typeName) ||
840
+ (name && input.name != name))
841
+ continue;
842
+ matchingInputs.push(input);
843
+ }
844
+
845
+ return matchingInputs;
846
+ },
847
+
848
+ disable: function(form) {
849
+ var elements = Form.getElements(form);
850
+ for (var i = 0; i < elements.length; i++) {
851
+ var element = elements[i];
852
+ element.blur();
853
+ element.disabled = 'true';
854
+ }
855
+ },
856
+
857
+ enable: function(form) {
858
+ var elements = Form.getElements(form);
859
+ for (var i = 0; i < elements.length; i++) {
860
+ var element = elements[i];
861
+ element.disabled = '';
862
+ }
863
+ },
864
+
865
+ focusFirstElement: function(form) {
866
+ var form = $(form);
867
+ var elements = Form.getElements(form);
868
+ for (var i = 0; i < elements.length; i++) {
869
+ var element = elements[i];
870
+ if (element.type != 'hidden' && !element.disabled) {
871
+ Field.activate(element);
872
+ break;
873
+ }
874
+ }
875
+ },
876
+
877
+ reset: function(form) {
878
+ $(form).reset();
879
+ }
880
+ }
881
+
882
+ Form.Element = {
883
+ serialize: function(element) {
884
+ var element = $(element);
885
+ var method = element.tagName.toLowerCase();
886
+ var parameter = Form.Element.Serializers[method](element);
887
+
888
+ if (parameter)
889
+ return encodeURIComponent(parameter[0]) + '=' +
890
+ encodeURIComponent(parameter[1]);
891
+ },
892
+
893
+ getValue: function(element) {
894
+ var element = $(element);
895
+ var method = element.tagName.toLowerCase();
896
+ var parameter = Form.Element.Serializers[method](element);
897
+
898
+ if (parameter)
899
+ return parameter[1];
900
+ }
901
+ }
902
+
903
+ Form.Element.Serializers = {
904
+ input: function(element) {
905
+ switch (element.type.toLowerCase()) {
906
+ case 'submit':
907
+ case 'hidden':
908
+ case 'password':
909
+ case 'text':
910
+ return Form.Element.Serializers.textarea(element);
911
+ case 'checkbox':
912
+ case 'radio':
913
+ return Form.Element.Serializers.inputSelector(element);
914
+ }
915
+ return false;
916
+ },
917
+
918
+ inputSelector: function(element) {
919
+ if (element.checked)
920
+ return [element.name, element.value];
921
+ },
922
+
923
+ textarea: function(element) {
924
+ return [element.name, element.value];
925
+ },
926
+
927
+ select: function(element) {
928
+ var value = '';
929
+ if (element.type == 'select-one') {
930
+ var index = element.selectedIndex;
931
+ if (index >= 0)
932
+ value = element.options[index].value || element.options[index].text;
933
+ } else {
934
+ value = new Array();
935
+ for (var i = 0; i < element.length; i++) {
936
+ var opt = element.options[i];
937
+ if (opt.selected)
938
+ value.push(opt.value || opt.text);
939
+ }
940
+ }
941
+ return [element.name, value];
942
+ }
943
+ }
944
+
945
+ /*--------------------------------------------------------------------------*/
946
+
947
+ var $F = Form.Element.getValue;
948
+
949
+ /*--------------------------------------------------------------------------*/
950
+
951
+ Abstract.TimedObserver = function() {}
952
+ Abstract.TimedObserver.prototype = {
953
+ initialize: function(element, frequency, callback) {
954
+ this.frequency = frequency;
955
+ this.element = $(element);
956
+ this.callback = callback;
957
+
958
+ this.lastValue = this.getValue();
959
+ this.registerCallback();
960
+ },
961
+
962
+ registerCallback: function() {
963
+ setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
964
+ },
965
+
966
+ onTimerEvent: function() {
967
+ var value = this.getValue();
968
+ if (this.lastValue != value) {
969
+ this.callback(this.element, value);
970
+ this.lastValue = value;
971
+ }
972
+ }
973
+ }
974
+
975
+ Form.Element.Observer = Class.create();
976
+ Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
977
+ getValue: function() {
978
+ return Form.Element.getValue(this.element);
979
+ }
980
+ });
981
+
982
+ Form.Observer = Class.create();
983
+ Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
984
+ getValue: function() {
985
+ return Form.serialize(this.element);
986
+ }
987
+ });
988
+
989
+ /*--------------------------------------------------------------------------*/
990
+
991
+ Abstract.EventObserver = function() {}
992
+ Abstract.EventObserver.prototype = {
993
+ initialize: function(element, callback) {
994
+ this.element = $(element);
995
+ this.callback = callback;
996
+
997
+ this.lastValue = this.getValue();
998
+ if (this.element.tagName.toLowerCase() == 'form')
999
+ this.registerFormCallbacks();
1000
+ else
1001
+ this.registerCallback(this.element);
1002
+ },
1003
+
1004
+ onElementEvent: function() {
1005
+ var value = this.getValue();
1006
+ if (this.lastValue != value) {
1007
+ this.callback(this.element, value);
1008
+ this.lastValue = value;
1009
+ }
1010
+ },
1011
+
1012
+ registerFormCallbacks: function() {
1013
+ var elements = Form.getElements(this.element);
1014
+ for (var i = 0; i < elements.length; i++)
1015
+ this.registerCallback(elements[i]);
1016
+ },
1017
+
1018
+ registerCallback: function(element) {
1019
+ if (element.type) {
1020
+ switch (element.type.toLowerCase()) {
1021
+ case 'checkbox':
1022
+ case 'radio':
1023
+ element.target = this;
1024
+ element.prev_onclick = element.onclick || Prototype.emptyFunction;
1025
+ element.onclick = function() {
1026
+ this.prev_onclick();
1027
+ this.target.onElementEvent();
1028
+ }
1029
+ break;
1030
+ case 'password':
1031
+ case 'text':
1032
+ case 'textarea':
1033
+ case 'select-one':
1034
+ case 'select-multiple':
1035
+ element.target = this;
1036
+ element.prev_onchange = element.onchange || Prototype.emptyFunction;
1037
+ element.onchange = function() {
1038
+ this.prev_onchange();
1039
+ this.target.onElementEvent();
1040
+ }
1041
+ break;
1042
+ }
1043
+ }
1044
+ }
1045
+ }
1046
+
1047
+ Form.Element.EventObserver = Class.create();
1048
+ Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
1049
+ getValue: function() {
1050
+ return Form.Element.getValue(this.element);
1051
+ }
1052
+ });
1053
+
1054
+ Form.EventObserver = Class.create();
1055
+ Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
1056
+ getValue: function() {
1057
+ return Form.serialize(this.element);
1058
+ }
1059
+ });
1060
+
1061
+
1062
+ if (!window.Event) {
1063
+ var Event = new Object();
1064
+ }
1065
+
1066
+ Object.extend(Event, {
1067
+ KEY_BACKSPACE: 8,
1068
+ KEY_TAB: 9,
1069
+ KEY_RETURN: 13,
1070
+ KEY_ESC: 27,
1071
+ KEY_LEFT: 37,
1072
+ KEY_UP: 38,
1073
+ KEY_RIGHT: 39,
1074
+ KEY_DOWN: 40,
1075
+ KEY_DELETE: 46,
1076
+
1077
+ element: function(event) {
1078
+ return event.target || event.srcElement;
1079
+ },
1080
+
1081
+ isLeftClick: function(event) {
1082
+ return (((event.which) && (event.which == 1)) ||
1083
+ ((event.button) && (event.button == 1)));
1084
+ },
1085
+
1086
+ pointerX: function(event) {
1087
+ return event.pageX || (event.clientX +
1088
+ (document.documentElement.scrollLeft || document.body.scrollLeft));
1089
+ },
1090
+
1091
+ pointerY: function(event) {
1092
+ return event.pageY || (event.clientY +
1093
+ (document.documentElement.scrollTop || document.body.scrollTop));
1094
+ },
1095
+
1096
+ stop: function(event) {
1097
+ if (event.preventDefault) {
1098
+ event.preventDefault();
1099
+ event.stopPropagation();
1100
+ } else {
1101
+ event.returnValue = false;
1102
+ }
1103
+ },
1104
+
1105
+ // find the first node with the given tagName, starting from the
1106
+ // node the event was triggered on; traverses the DOM upwards
1107
+ findElement: function(event, tagName) {
1108
+ var element = Event.element(event);
1109
+ while (element.parentNode && (!element.tagName ||
1110
+ (element.tagName.toUpperCase() != tagName.toUpperCase())))
1111
+ element = element.parentNode;
1112
+ return element;
1113
+ },
1114
+
1115
+ observers: false,
1116
+
1117
+ _observeAndCache: function(element, name, observer, useCapture) {
1118
+ if (!this.observers) this.observers = [];
1119
+ if (element.addEventListener) {
1120
+ this.observers.push([element, name, observer, useCapture]);
1121
+ element.addEventListener(name, observer, useCapture);
1122
+ } else if (element.attachEvent) {
1123
+ this.observers.push([element, name, observer, useCapture]);
1124
+ element.attachEvent('on' + name, observer);
1125
+ }
1126
+ },
1127
+
1128
+ unloadCache: function() {
1129
+ if (!Event.observers) return;
1130
+ for (var i = 0; i < Event.observers.length; i++) {
1131
+ Event.stopObserving.apply(this, Event.observers[i]);
1132
+ Event.observers[i][0] = null;
1133
+ }
1134
+ Event.observers = false;
1135
+ },
1136
+
1137
+ observe: function(element, name, observer, useCapture) {
1138
+ var element = $(element);
1139
+ useCapture = useCapture || false;
1140
+
1141
+ if (name == 'keypress' &&
1142
+ ((/Konqueror|Safari|KHTML/.test(navigator.userAgent))
1143
+ || element.attachEvent))
1144
+ name = 'keydown';
1145
+
1146
+ this._observeAndCache(element, name, observer, useCapture);
1147
+ },
1148
+
1149
+ stopObserving: function(element, name, observer, useCapture) {
1150
+ var element = $(element);
1151
+ useCapture = useCapture || false;
1152
+
1153
+ if (name == 'keypress' &&
1154
+ ((/Konqueror|Safari|KHTML/.test(navigator.userAgent))
1155
+ || element.detachEvent))
1156
+ name = 'keydown';
1157
+
1158
+ if (element.removeEventListener) {
1159
+ element.removeEventListener(name, observer, useCapture);
1160
+ } else if (element.detachEvent) {
1161
+ element.detachEvent('on' + name, observer);
1162
+ }
1163
+ }
1164
+ });
1165
+
1166
+ /* prevent memory leaks in IE */
1167
+ Event.observe(window, 'unload', Event.unloadCache, false);
1168
+
1169
+ var Position = {
1170
+
1171
+ // set to true if needed, warning: firefox performance problems
1172
+ // NOT neeeded for page scrolling, only if draggable contained in
1173
+ // scrollable elements
1174
+ includeScrollOffsets: false,
1175
+
1176
+ // must be called before calling withinIncludingScrolloffset, every time the
1177
+ // page is scrolled
1178
+ prepare: function() {
1179
+ this.deltaX = window.pageXOffset
1180
+ || document.documentElement.scrollLeft
1181
+ || document.body.scrollLeft
1182
+ || 0;
1183
+ this.deltaY = window.pageYOffset
1184
+ || document.documentElement.scrollTop
1185
+ || document.body.scrollTop
1186
+ || 0;
1187
+ },
1188
+
1189
+ realOffset: function(element) {
1190
+ var valueT = 0, valueL = 0;
1191
+ do {
1192
+ valueT += element.scrollTop || 0;
1193
+ valueL += element.scrollLeft || 0;
1194
+ element = element.parentNode;
1195
+ } while (element);
1196
+ return [valueL, valueT];
1197
+ },
1198
+
1199
+ cumulativeOffset: function(element) {
1200
+ var valueT = 0, valueL = 0;
1201
+ do {
1202
+ valueT += element.offsetTop || 0;
1203
+ valueL += element.offsetLeft || 0;
1204
+ element = element.offsetParent;
1205
+ } while (element);
1206
+ return [valueL, valueT];
1207
+ },
1208
+
1209
+ // caches x/y coordinate pair to use with overlap
1210
+ within: function(element, x, y) {
1211
+ if (this.includeScrollOffsets)
1212
+ return this.withinIncludingScrolloffsets(element, x, y);
1213
+ this.xcomp = x;
1214
+ this.ycomp = y;
1215
+ this.offset = this.cumulativeOffset(element);
1216
+
1217
+ return (y >= this.offset[1] &&
1218
+ y < this.offset[1] + element.offsetHeight &&
1219
+ x >= this.offset[0] &&
1220
+ x < this.offset[0] + element.offsetWidth);
1221
+ },
1222
+
1223
+ withinIncludingScrolloffsets: function(element, x, y) {
1224
+ var offsetcache = this.realOffset(element);
1225
+
1226
+ this.xcomp = x + offsetcache[0] - this.deltaX;
1227
+ this.ycomp = y + offsetcache[1] - this.deltaY;
1228
+ this.offset = this.cumulativeOffset(element);
1229
+
1230
+ return (this.ycomp >= this.offset[1] &&
1231
+ this.ycomp < this.offset[1] + element.offsetHeight &&
1232
+ this.xcomp >= this.offset[0] &&
1233
+ this.xcomp < this.offset[0] + element.offsetWidth);
1234
+ },
1235
+
1236
+ // within must be called directly before
1237
+ overlap: function(mode, element) {
1238
+ if (!mode) return 0;
1239
+ if (mode == 'vertical')
1240
+ return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
1241
+ element.offsetHeight;
1242
+ if (mode == 'horizontal')
1243
+ return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
1244
+ element.offsetWidth;
1245
+ },
1246
+
1247
+ clone: function(source, target) {
1248
+ source = $(source);
1249
+ target = $(target);
1250
+ target.style.position = 'absolute';
1251
+ var offsets = this.cumulativeOffset(source);
1252
+ target.style.top = offsets[1] + 'px';
1253
+ target.style.left = offsets[0] + 'px';
1254
+ target.style.width = source.offsetWidth + 'px';
1255
+ target.style.height = source.offsetHeight + 'px';
1256
+ }
1257
+ }