[PerformanceTests] Each Dromaeo test needs its landing html.
authormorrita@google.com <morrita@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 6 Feb 2012 23:44:33 +0000 (23:44 +0000)
committermorrita@google.com <morrita@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 6 Feb 2012 23:44:33 +0000 (23:44 +0000)
https://bugs.webkit.org/show_bug.cgi?id=77504

Reviewed by Ryosuke Niwa.

PerformanceTests:

- Added landing pages for each test which are listed in MANIFEST.json
- Removed some tests which depends on the library whose license is incompatible to WebKit.
- Added local copy of corresponding library. And replace the references to the remote sources
  to the local copies.
- Removed old library files under Dromaeo/resources/dromaeo/web/lib/.
- Skipped Sunsupier and v8 test. Such JS centric test should have its own test instead of
  running as a part of Dromaeo.

* Dromaeo/cssquery-dojo.html: Added.
* Dromaeo/cssquery-jquery.html: Added.
* Dromaeo/cssquery-prototype.html: Added.
* Dromaeo/dom-attr.html: Added.
* Dromaeo/dom-modify.html: Added.
* Dromaeo/dom-traverse.html: Added.
* Dromaeo/dromaeo-3d-cube.html: Added.
* Dromaeo/dromaeo-core-eval.html: Added.
* Dromaeo/dromaeo-object-array.html: Added.
* Dromaeo/dromaeo-object-regexp.html: Added.
* Dromaeo/dromaeo-object-string.html: Added.
* Dromaeo/dromaeo-string-base64.html: Added.
* Dromaeo/jslib-attr-jquery.html: Added.
* Dromaeo/jslib-attr-prototype.html: Added.
* Dromaeo/jslib-event-jquery.html: Added.
* Dromaeo/jslib-event-prototype.html: Added.
* Dromaeo/jslib-modify-jquery.html: Added.
* Dromaeo/jslib-modify-prototype.html: Added.
* Dromaeo/jslib-style-jquery.html: Added.
* Dromaeo/jslib-style-prototype.html: Added.
* Dromaeo/jslib-traverse-jquery.html: Added.
* Dromaeo/jslib-traverse-prototype.html: Added.
* Dromaeo/resources/dromaeo/web/lib/dojo.js: Removed.
* Dromaeo/resources/dromaeo/web/lib/dojo-1.6.1.js: Added.
* Dromaeo/resources/dromaeo/web/lib/jquery.js: Removed.
* Dromaeo/resources/dromaeo/web/lib/jquery-1.6.4.js: Added.
* Dromaeo/resources/dromaeo/web/lib/mootools.js: Removed.
* Dromaeo/resources/dromaeo/web/lib/prototype.js: Removed.
* Dromaeo/resources/dromaeo/web/lib/prototype-1.7.js: Added.
* Dromaeo/resources/dromaeo/web/tests/cssquery-dojo.html:
* Dromaeo/resources/dromaeo/web/tests/cssquery-jquery.html:
* Dromaeo/resources/dromaeo/web/tests/cssquery-mootools.html: Removed.
* Dromaeo/resources/dromaeo/web/tests/cssquery-prototype.html:
* Dromaeo/resources/dromaeo/web/tests/jslib-attr-jquery.html:
* Dromaeo/resources/dromaeo/web/tests/jslib-attr-prototype.html:
* Dromaeo/resources/dromaeo/web/tests/jslib-event-jquery.html:
* Dromaeo/resources/dromaeo/web/tests/jslib-event-prototype.html:
* Dromaeo/resources/dromaeo/web/tests/jslib-modify-jquery.html:
* Dromaeo/resources/dromaeo/web/tests/jslib-modify-prototype.html:
* Dromaeo/resources/dromaeo/web/tests/jslib-style-jquery.html:
* Dromaeo/resources/dromaeo/web/tests/jslib-style-prototype.html:
* Dromaeo/resources/dromaeo/web/tests/jslib-traverse-jquery.html:
* Dromaeo/resources/dromaeo/web/tests/jslib-traverse-prototype.html:
* Dromaeo/sunspider-3d-morph.html: Added.
* Dromaeo/sunspider-3d-raytrace.html: Added.
* Dromaeo/sunspider-access-binary-trees.html: Added.
* Dromaeo/sunspider-access-fannkuch.html: Added.
* Dromaeo/sunspider-access-nbody.html: Added.
* Dromaeo/sunspider-access-nsieve.html: Added.
* Dromaeo/sunspider-bitops-3bit-bits-in-byte.html: Added.
* Dromaeo/sunspider-bitops-bits-in-byte.html: Added.
* Dromaeo/sunspider-bitops-bitwise-and.html: Added.
* Dromaeo/sunspider-bitops-nsieve-bits.html: Added.
* Dromaeo/sunspider-controlflow-recursive.html: Added.
* Dromaeo/sunspider-crypto-aes.html: Added.
* Dromaeo/sunspider-crypto-md5.html: Added.
* Dromaeo/sunspider-crypto-sha1.html: Added.
* Dromaeo/sunspider-date-format-tofte.html: Added.
* Dromaeo/sunspider-date-format-xparb.html: Added.
* Dromaeo/sunspider-math-cordic.html: Added.
* Dromaeo/sunspider-math-partial-sums.html: Added.
* Dromaeo/sunspider-math-spectral-norm.html: Added.
* Dromaeo/sunspider-regexp-dna.html: Added.
* Dromaeo/sunspider-string-fasta.html: Added.
* Dromaeo/sunspider-string-tagcloud.html: Added.
* Dromaeo/sunspider-string-unpack-code.html: Added.
* Dromaeo/sunspider-string-validate-input.html: Added.
* Dromaeo/v8-crypto.html: Added.
* Dromaeo/v8-deltablue.html: Added.
* Dromaeo/v8-earley-boyer.html: Added.
* Dromaeo/v8-raytrace.html: Added.
* Dromaeo/v8-richards.html: Added.
* Skipped:

Tools:

Added an ignorable pattern which happens in some Dromaeo tests.

* Scripts/webkitpy/performance_tests/perftestsrunner.py:
(PerfTestsRunner):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@106865 268f45cc-cd09-0410-ab3c-d52691b4dbfc

77 files changed:
PerformanceTests/ChangeLog
PerformanceTests/Dromaeo/cssquery-dojo.html [new file with mode: 0644]
PerformanceTests/Dromaeo/cssquery-jquery.html [new file with mode: 0644]
PerformanceTests/Dromaeo/cssquery-prototype.html [new file with mode: 0644]
PerformanceTests/Dromaeo/dom-attr.html [new file with mode: 0644]
PerformanceTests/Dromaeo/dom-modify.html [new file with mode: 0644]
PerformanceTests/Dromaeo/dom-traverse.html [new file with mode: 0644]
PerformanceTests/Dromaeo/dromaeo-3d-cube.html [new file with mode: 0644]
PerformanceTests/Dromaeo/dromaeo-core-eval.html [new file with mode: 0644]
PerformanceTests/Dromaeo/dromaeo-object-array.html [new file with mode: 0644]
PerformanceTests/Dromaeo/dromaeo-object-regexp.html [new file with mode: 0644]
PerformanceTests/Dromaeo/dromaeo-object-string.html [new file with mode: 0644]
PerformanceTests/Dromaeo/dromaeo-string-base64.html [new file with mode: 0644]
PerformanceTests/Dromaeo/jslib-attr-jquery.html [new file with mode: 0644]
PerformanceTests/Dromaeo/jslib-attr-prototype.html [new file with mode: 0644]
PerformanceTests/Dromaeo/jslib-event-jquery.html [new file with mode: 0644]
PerformanceTests/Dromaeo/jslib-event-prototype.html [new file with mode: 0644]
PerformanceTests/Dromaeo/jslib-modify-jquery.html [new file with mode: 0644]
PerformanceTests/Dromaeo/jslib-modify-prototype.html [new file with mode: 0644]
PerformanceTests/Dromaeo/jslib-style-jquery.html [new file with mode: 0644]
PerformanceTests/Dromaeo/jslib-style-prototype.html [new file with mode: 0644]
PerformanceTests/Dromaeo/jslib-traverse-jquery.html [new file with mode: 0644]
PerformanceTests/Dromaeo/jslib-traverse-prototype.html [new file with mode: 0644]
PerformanceTests/Dromaeo/resources/dromaeo/web/index.html
PerformanceTests/Dromaeo/resources/dromaeo/web/lib/dojo-1.6.1.js [new file with mode: 0644]
PerformanceTests/Dromaeo/resources/dromaeo/web/lib/dojo.js [deleted file]
PerformanceTests/Dromaeo/resources/dromaeo/web/lib/jquery-1.6.4.js [new file with mode: 0644]
PerformanceTests/Dromaeo/resources/dromaeo/web/lib/jquery.js [deleted file]
PerformanceTests/Dromaeo/resources/dromaeo/web/lib/mootools.js [deleted file]
PerformanceTests/Dromaeo/resources/dromaeo/web/lib/prototype-1.7.js [new file with mode: 0644]
PerformanceTests/Dromaeo/resources/dromaeo/web/lib/prototype.js [deleted file]
PerformanceTests/Dromaeo/resources/dromaeo/web/tests/cssquery-dojo.html
PerformanceTests/Dromaeo/resources/dromaeo/web/tests/cssquery-jquery.html
PerformanceTests/Dromaeo/resources/dromaeo/web/tests/cssquery-mootools.html [deleted file]
PerformanceTests/Dromaeo/resources/dromaeo/web/tests/cssquery-prototype.html
PerformanceTests/Dromaeo/resources/dromaeo/web/tests/jslib-attr-jquery.html
PerformanceTests/Dromaeo/resources/dromaeo/web/tests/jslib-attr-prototype.html
PerformanceTests/Dromaeo/resources/dromaeo/web/tests/jslib-event-jquery.html
PerformanceTests/Dromaeo/resources/dromaeo/web/tests/jslib-event-prototype.html
PerformanceTests/Dromaeo/resources/dromaeo/web/tests/jslib-modify-jquery.html
PerformanceTests/Dromaeo/resources/dromaeo/web/tests/jslib-modify-prototype.html
PerformanceTests/Dromaeo/resources/dromaeo/web/tests/jslib-style-jquery.html
PerformanceTests/Dromaeo/resources/dromaeo/web/tests/jslib-style-prototype.html
PerformanceTests/Dromaeo/resources/dromaeo/web/tests/jslib-traverse-jquery.html
PerformanceTests/Dromaeo/resources/dromaeo/web/tests/jslib-traverse-prototype.html
PerformanceTests/Dromaeo/sunspider-3d-morph.html [new file with mode: 0644]
PerformanceTests/Dromaeo/sunspider-3d-raytrace.html [new file with mode: 0644]
PerformanceTests/Dromaeo/sunspider-access-binary-trees.html [new file with mode: 0644]
PerformanceTests/Dromaeo/sunspider-access-fannkuch.html [new file with mode: 0644]
PerformanceTests/Dromaeo/sunspider-access-nbody.html [new file with mode: 0644]
PerformanceTests/Dromaeo/sunspider-access-nsieve.html [new file with mode: 0644]
PerformanceTests/Dromaeo/sunspider-bitops-3bit-bits-in-byte.html [new file with mode: 0644]
PerformanceTests/Dromaeo/sunspider-bitops-bits-in-byte.html [new file with mode: 0644]
PerformanceTests/Dromaeo/sunspider-bitops-bitwise-and.html [new file with mode: 0644]
PerformanceTests/Dromaeo/sunspider-bitops-nsieve-bits.html [new file with mode: 0644]
PerformanceTests/Dromaeo/sunspider-controlflow-recursive.html [new file with mode: 0644]
PerformanceTests/Dromaeo/sunspider-crypto-aes.html [new file with mode: 0644]
PerformanceTests/Dromaeo/sunspider-crypto-md5.html [new file with mode: 0644]
PerformanceTests/Dromaeo/sunspider-crypto-sha1.html [new file with mode: 0644]
PerformanceTests/Dromaeo/sunspider-date-format-tofte.html [new file with mode: 0644]
PerformanceTests/Dromaeo/sunspider-date-format-xparb.html [new file with mode: 0644]
PerformanceTests/Dromaeo/sunspider-math-cordic.html [new file with mode: 0644]
PerformanceTests/Dromaeo/sunspider-math-partial-sums.html [new file with mode: 0644]
PerformanceTests/Dromaeo/sunspider-math-spectral-norm.html [new file with mode: 0644]
PerformanceTests/Dromaeo/sunspider-regexp-dna.html [new file with mode: 0644]
PerformanceTests/Dromaeo/sunspider-string-fasta.html [new file with mode: 0644]
PerformanceTests/Dromaeo/sunspider-string-tagcloud.html [new file with mode: 0644]
PerformanceTests/Dromaeo/sunspider-string-unpack-code.html [new file with mode: 0644]
PerformanceTests/Dromaeo/sunspider-string-validate-input.html [new file with mode: 0644]
PerformanceTests/Dromaeo/v8-crypto.html [new file with mode: 0644]
PerformanceTests/Dromaeo/v8-deltablue.html [new file with mode: 0644]
PerformanceTests/Dromaeo/v8-earley-boyer.html [new file with mode: 0644]
PerformanceTests/Dromaeo/v8-raytrace.html [new file with mode: 0644]
PerformanceTests/Dromaeo/v8-richards.html [new file with mode: 0644]
PerformanceTests/Skipped
Tools/ChangeLog
Tools/Scripts/webkitpy/performance_tests/perftestsrunner.py

index 7ef7311..d28557c 100644 (file)
@@ -1,3 +1,92 @@
+2012-02-02  Hajime Morrita  <morrita@chromium.org>
+
+        [PerformanceTests] Each Dromaeo test needs its landing html.
+        https://bugs.webkit.org/show_bug.cgi?id=77504
+
+        Reviewed by Ryosuke Niwa.
+
+        - Added landing pages for each test which are listed in MANIFEST.json
+        - Removed some tests which depends on the library whose license is incompatible to WebKit.
+        - Added local copy of corresponding library. And replace the references to the remote sources
+          to the local copies.
+        - Removed old library files under Dromaeo/resources/dromaeo/web/lib/.
+        - Skipped Sunsupier and v8 test. Such JS centric test should have its own test instead of
+          running as a part of Dromaeo.
+
+        * Dromaeo/cssquery-dojo.html: Added.
+        * Dromaeo/cssquery-jquery.html: Added.
+        * Dromaeo/cssquery-prototype.html: Added.
+        * Dromaeo/dom-attr.html: Added.
+        * Dromaeo/dom-modify.html: Added.
+        * Dromaeo/dom-traverse.html: Added.
+        * Dromaeo/dromaeo-3d-cube.html: Added.
+        * Dromaeo/dromaeo-core-eval.html: Added.
+        * Dromaeo/dromaeo-object-array.html: Added.
+        * Dromaeo/dromaeo-object-regexp.html: Added.
+        * Dromaeo/dromaeo-object-string.html: Added.
+        * Dromaeo/dromaeo-string-base64.html: Added.
+        * Dromaeo/jslib-attr-jquery.html: Added.
+        * Dromaeo/jslib-attr-prototype.html: Added.
+        * Dromaeo/jslib-event-jquery.html: Added.
+        * Dromaeo/jslib-event-prototype.html: Added.
+        * Dromaeo/jslib-modify-jquery.html: Added.
+        * Dromaeo/jslib-modify-prototype.html: Added.
+        * Dromaeo/jslib-style-jquery.html: Added.
+        * Dromaeo/jslib-style-prototype.html: Added.
+        * Dromaeo/jslib-traverse-jquery.html: Added.
+        * Dromaeo/jslib-traverse-prototype.html: Added.
+        * Dromaeo/resources/dromaeo/web/lib/dojo.js: Removed.
+        * Dromaeo/resources/dromaeo/web/lib/dojo-1.6.1.js: Added.
+        * Dromaeo/resources/dromaeo/web/lib/jquery.js: Removed.
+        * Dromaeo/resources/dromaeo/web/lib/jquery-1.6.4.js: Added.
+        * Dromaeo/resources/dromaeo/web/lib/mootools.js: Removed.
+        * Dromaeo/resources/dromaeo/web/lib/prototype.js: Removed.
+        * Dromaeo/resources/dromaeo/web/lib/prototype-1.7.js: Added.
+        * Dromaeo/resources/dromaeo/web/tests/cssquery-dojo.html:
+        * Dromaeo/resources/dromaeo/web/tests/cssquery-jquery.html:
+        * Dromaeo/resources/dromaeo/web/tests/cssquery-mootools.html: Removed.
+        * Dromaeo/resources/dromaeo/web/tests/cssquery-prototype.html:
+        * Dromaeo/resources/dromaeo/web/tests/jslib-attr-jquery.html:
+        * Dromaeo/resources/dromaeo/web/tests/jslib-attr-prototype.html:
+        * Dromaeo/resources/dromaeo/web/tests/jslib-event-jquery.html:
+        * Dromaeo/resources/dromaeo/web/tests/jslib-event-prototype.html:
+        * Dromaeo/resources/dromaeo/web/tests/jslib-modify-jquery.html:
+        * Dromaeo/resources/dromaeo/web/tests/jslib-modify-prototype.html:
+        * Dromaeo/resources/dromaeo/web/tests/jslib-style-jquery.html:
+        * Dromaeo/resources/dromaeo/web/tests/jslib-style-prototype.html:
+        * Dromaeo/resources/dromaeo/web/tests/jslib-traverse-jquery.html:
+        * Dromaeo/resources/dromaeo/web/tests/jslib-traverse-prototype.html:
+        * Dromaeo/sunspider-3d-morph.html: Added.
+        * Dromaeo/sunspider-3d-raytrace.html: Added.
+        * Dromaeo/sunspider-access-binary-trees.html: Added.
+        * Dromaeo/sunspider-access-fannkuch.html: Added.
+        * Dromaeo/sunspider-access-nbody.html: Added.
+        * Dromaeo/sunspider-access-nsieve.html: Added.
+        * Dromaeo/sunspider-bitops-3bit-bits-in-byte.html: Added.
+        * Dromaeo/sunspider-bitops-bits-in-byte.html: Added.
+        * Dromaeo/sunspider-bitops-bitwise-and.html: Added.
+        * Dromaeo/sunspider-bitops-nsieve-bits.html: Added.
+        * Dromaeo/sunspider-controlflow-recursive.html: Added.
+        * Dromaeo/sunspider-crypto-aes.html: Added.
+        * Dromaeo/sunspider-crypto-md5.html: Added.
+        * Dromaeo/sunspider-crypto-sha1.html: Added.
+        * Dromaeo/sunspider-date-format-tofte.html: Added.
+        * Dromaeo/sunspider-date-format-xparb.html: Added.
+        * Dromaeo/sunspider-math-cordic.html: Added.
+        * Dromaeo/sunspider-math-partial-sums.html: Added.
+        * Dromaeo/sunspider-math-spectral-norm.html: Added.
+        * Dromaeo/sunspider-regexp-dna.html: Added.
+        * Dromaeo/sunspider-string-fasta.html: Added.
+        * Dromaeo/sunspider-string-tagcloud.html: Added.
+        * Dromaeo/sunspider-string-unpack-code.html: Added.
+        * Dromaeo/sunspider-string-validate-input.html: Added.
+        * Dromaeo/v8-crypto.html: Added.
+        * Dromaeo/v8-deltablue.html: Added.
+        * Dromaeo/v8-earley-boyer.html: Added.
+        * Dromaeo/v8-raytrace.html: Added.
+        * Dromaeo/v8-richards.html: Added.
+        * Skipped:
+
 2012-02-02  Sheriff Bot  <webkit.review.bot@gmail.com>
 
         Unreviewed, rolling out r106543.
diff --git a/PerformanceTests/Dromaeo/cssquery-dojo.html b/PerformanceTests/Dromaeo/cssquery-dojo.html
new file mode 100644 (file)
index 0000000..15f537c
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/runner.js"></script>
+<script src="resources/dromaeo/web/jquery.js"></script>
+<script src="resources/dromaeorunner.js"></script>
+<script>
+$(document).ready(function() {
+    DRT.setup("cssquery-dojo");
+});
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/PerformanceTests/Dromaeo/cssquery-jquery.html b/PerformanceTests/Dromaeo/cssquery-jquery.html
new file mode 100644 (file)
index 0000000..964f5e8
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/runner.js"></script>
+<script src="resources/dromaeo/web/jquery.js"></script>
+<script src="resources/dromaeorunner.js"></script>
+<script>
+$(document).ready(function() {
+    DRT.setup("cssquery-jquery");
+});
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/PerformanceTests/Dromaeo/cssquery-prototype.html b/PerformanceTests/Dromaeo/cssquery-prototype.html
new file mode 100644 (file)
index 0000000..67a5951
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/runner.js"></script>
+<script src="resources/dromaeo/web/jquery.js"></script>
+<script src="resources/dromaeorunner.js"></script>
+<script>
+$(document).ready(function() {
+    DRT.setup("cssquery-prototype");
+});
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/PerformanceTests/Dromaeo/dom-attr.html b/PerformanceTests/Dromaeo/dom-attr.html
new file mode 100644 (file)
index 0000000..1a45947
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/runner.js"></script>
+<script src="resources/dromaeo/web/jquery.js"></script>
+<script src="resources/dromaeorunner.js"></script>
+<script>
+$(document).ready(function() {
+    DRT.setup("dom-attr");
+});
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/PerformanceTests/Dromaeo/dom-modify.html b/PerformanceTests/Dromaeo/dom-modify.html
new file mode 100644 (file)
index 0000000..5bf08e1
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/runner.js"></script>
+<script src="resources/dromaeo/web/jquery.js"></script>
+<script src="resources/dromaeorunner.js"></script>
+<script>
+$(document).ready(function() {
+    DRT.setup("dom-modify");
+});
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/PerformanceTests/Dromaeo/dom-traverse.html b/PerformanceTests/Dromaeo/dom-traverse.html
new file mode 100644 (file)
index 0000000..dc6375c
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/runner.js"></script>
+<script src="resources/dromaeo/web/jquery.js"></script>
+<script src="resources/dromaeorunner.js"></script>
+<script>
+$(document).ready(function() {
+    DRT.setup("dom-traverse");
+});
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/PerformanceTests/Dromaeo/dromaeo-3d-cube.html b/PerformanceTests/Dromaeo/dromaeo-3d-cube.html
new file mode 100644 (file)
index 0000000..21d0c96
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/runner.js"></script>
+<script src="resources/dromaeo/web/jquery.js"></script>
+<script src="resources/dromaeorunner.js"></script>
+<script>
+$(document).ready(function() {
+    DRT.setup("dromaeo-3d-cube");
+});
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/PerformanceTests/Dromaeo/dromaeo-core-eval.html b/PerformanceTests/Dromaeo/dromaeo-core-eval.html
new file mode 100644 (file)
index 0000000..4873d14
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/runner.js"></script>
+<script src="resources/dromaeo/web/jquery.js"></script>
+<script src="resources/dromaeorunner.js"></script>
+<script>
+$(document).ready(function() {
+    DRT.setup("dromaeo-core-eval");
+});
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/PerformanceTests/Dromaeo/dromaeo-object-array.html b/PerformanceTests/Dromaeo/dromaeo-object-array.html
new file mode 100644 (file)
index 0000000..5e8c73c
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/runner.js"></script>
+<script src="resources/dromaeo/web/jquery.js"></script>
+<script src="resources/dromaeorunner.js"></script>
+<script>
+$(document).ready(function() {
+    DRT.setup("dromaeo-object-array");
+});
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/PerformanceTests/Dromaeo/dromaeo-object-regexp.html b/PerformanceTests/Dromaeo/dromaeo-object-regexp.html
new file mode 100644 (file)
index 0000000..fc76ebc
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/runner.js"></script>
+<script src="resources/dromaeo/web/jquery.js"></script>
+<script src="resources/dromaeorunner.js"></script>
+<script>
+$(document).ready(function() {
+    DRT.setup("dromaeo-object-regexp");
+});
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/PerformanceTests/Dromaeo/dromaeo-object-string.html b/PerformanceTests/Dromaeo/dromaeo-object-string.html
new file mode 100644 (file)
index 0000000..5ffb792
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/runner.js"></script>
+<script src="resources/dromaeo/web/jquery.js"></script>
+<script src="resources/dromaeorunner.js"></script>
+<script>
+$(document).ready(function() {
+    DRT.setup("dromaeo-object-string");
+});
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/PerformanceTests/Dromaeo/dromaeo-string-base64.html b/PerformanceTests/Dromaeo/dromaeo-string-base64.html
new file mode 100644 (file)
index 0000000..6147a56
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/runner.js"></script>
+<script src="resources/dromaeo/web/jquery.js"></script>
+<script src="resources/dromaeorunner.js"></script>
+<script>
+$(document).ready(function() {
+    DRT.setup("dromaeo-string-base64");
+});
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/PerformanceTests/Dromaeo/jslib-attr-jquery.html b/PerformanceTests/Dromaeo/jslib-attr-jquery.html
new file mode 100644 (file)
index 0000000..812fc45
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/runner.js"></script>
+<script src="resources/dromaeo/web/jquery.js"></script>
+<script src="resources/dromaeorunner.js"></script>
+<script>
+$(document).ready(function() {
+    DRT.setup("jslib-attr-jquery");
+});
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/PerformanceTests/Dromaeo/jslib-attr-prototype.html b/PerformanceTests/Dromaeo/jslib-attr-prototype.html
new file mode 100644 (file)
index 0000000..02c7fbc
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/runner.js"></script>
+<script src="resources/dromaeo/web/jquery.js"></script>
+<script src="resources/dromaeorunner.js"></script>
+<script>
+$(document).ready(function() {
+    DRT.setup("jslib-attr-prototype");
+});
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/PerformanceTests/Dromaeo/jslib-event-jquery.html b/PerformanceTests/Dromaeo/jslib-event-jquery.html
new file mode 100644 (file)
index 0000000..fdd1788
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/runner.js"></script>
+<script src="resources/dromaeo/web/jquery.js"></script>
+<script src="resources/dromaeorunner.js"></script>
+<script>
+$(document).ready(function() {
+    DRT.setup("jslib-event-jquery");
+});
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/PerformanceTests/Dromaeo/jslib-event-prototype.html b/PerformanceTests/Dromaeo/jslib-event-prototype.html
new file mode 100644 (file)
index 0000000..c5cf7d9
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/runner.js"></script>
+<script src="resources/dromaeo/web/jquery.js"></script>
+<script src="resources/dromaeorunner.js"></script>
+<script>
+$(document).ready(function() {
+    DRT.setup("jslib-event-prototype");
+});
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/PerformanceTests/Dromaeo/jslib-modify-jquery.html b/PerformanceTests/Dromaeo/jslib-modify-jquery.html
new file mode 100644 (file)
index 0000000..6e3c8d5
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/runner.js"></script>
+<script src="resources/dromaeo/web/jquery.js"></script>
+<script src="resources/dromaeorunner.js"></script>
+<script>
+$(document).ready(function() {
+    DRT.setup("jslib-modify-jquery");
+});
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/PerformanceTests/Dromaeo/jslib-modify-prototype.html b/PerformanceTests/Dromaeo/jslib-modify-prototype.html
new file mode 100644 (file)
index 0000000..16b2a7d
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/runner.js"></script>
+<script src="resources/dromaeo/web/jquery.js"></script>
+<script src="resources/dromaeorunner.js"></script>
+<script>
+$(document).ready(function() {
+    DRT.setup("jslib-modify-prototype");
+});
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/PerformanceTests/Dromaeo/jslib-style-jquery.html b/PerformanceTests/Dromaeo/jslib-style-jquery.html
new file mode 100644 (file)
index 0000000..f96e63e
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/runner.js"></script>
+<script src="resources/dromaeo/web/jquery.js"></script>
+<script src="resources/dromaeorunner.js"></script>
+<script>
+$(document).ready(function() {
+    DRT.setup("jslib-style-jquery");
+});
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/PerformanceTests/Dromaeo/jslib-style-prototype.html b/PerformanceTests/Dromaeo/jslib-style-prototype.html
new file mode 100644 (file)
index 0000000..baca04a
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/runner.js"></script>
+<script src="resources/dromaeo/web/jquery.js"></script>
+<script src="resources/dromaeorunner.js"></script>
+<script>
+$(document).ready(function() {
+    DRT.setup("jslib-style-prototype");
+});
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/PerformanceTests/Dromaeo/jslib-traverse-jquery.html b/PerformanceTests/Dromaeo/jslib-traverse-jquery.html
new file mode 100644 (file)
index 0000000..6107af1
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/runner.js"></script>
+<script src="resources/dromaeo/web/jquery.js"></script>
+<script src="resources/dromaeorunner.js"></script>
+<script>
+$(document).ready(function() {
+    DRT.setup("jslib-traverse-jquery");
+});
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/PerformanceTests/Dromaeo/jslib-traverse-prototype.html b/PerformanceTests/Dromaeo/jslib-traverse-prototype.html
new file mode 100644 (file)
index 0000000..6baa358
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../resources/runner.js"></script>
+<script src="resources/dromaeo/web/jquery.js"></script>
+<script src="resources/dromaeorunner.js"></script>
+<script>
+$(document).ready(function() {
+    DRT.setup("jslib-traverse-prototype");
+});
+</script>
+</head>
+<body>
+</body>
+</html>
index 1a995d0..418d700 100644 (file)
@@ -9,6 +9,9 @@
   <script defer type="text/javascript" src="pngfix.js"></script>
   <![endif]-->
   <link href="application.css" rel="stylesheet" type="text/css" />
+<!--
+  <script src="lib/jquery-1.6.4.js"></script>
+  -->
   <script src="jquery.js"></script>
   <script src="json.js"></script>
   <script src="webrunner.js"></script>
diff --git a/PerformanceTests/Dromaeo/resources/dromaeo/web/lib/dojo-1.6.1.js b/PerformanceTests/Dromaeo/resources/dromaeo/web/lib/dojo-1.6.1.js
new file mode 100644 (file)
index 0000000..674e0ad
--- /dev/null
@@ -0,0 +1,11363 @@
+/*
+        Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+        Available via Academic Free License >= 2.1 OR the modified BSD license.
+        see: http://dojotoolkit.org/license for details
+*/
+
+/*
+        This is an optimized version of Dojo, built for deployment and not for
+        development. To get sources and documentation, please visit:
+
+                http://dojotoolkit.org
+*/
+
+;(function(){
+
+        /*
+        dojo, dijit, and dojox must always be the first three, and in that order.
+        djConfig.scopeMap = [
+                ["dojo", "fojo"],
+                ["dijit", "fijit"],
+                ["dojox", "fojox"]
+        
+        ]
+        */
+
+        /**Build will replace this comment with a scoped djConfig **/
+
+        //The null below can be relaced by a build-time value used instead of djConfig.scopeMap.
+        var sMap = null;
+
+        //See if new scopes need to be defined.
+        if((sMap || (typeof djConfig != "undefined" && djConfig.scopeMap)) && (typeof window != "undefined")){
+                var scopeDef = "", scopePrefix = "", scopeSuffix = "", scopeMap = {}, scopeMapRev = {};
+                sMap = sMap || djConfig.scopeMap;
+                for(var i = 0; i < sMap.length; i++){
+                        //Make local variables, then global variables that use the locals.
+                        var newScope = sMap[i];
+                        scopeDef += "var " + newScope[0] + " = {}; " + newScope[1] + " = " + newScope[0] + ";" + newScope[1] + "._scopeName = '" + newScope[1] + "';";
+                        scopePrefix += (i == 0 ? "" : ",") + newScope[0];
+                        scopeSuffix += (i == 0 ? "" : ",") + newScope[1];
+                        scopeMap[newScope[0]] = newScope[1];
+                        scopeMapRev[newScope[1]] = newScope[0];
+                }
+
+                eval(scopeDef + "dojo._scopeArgs = [" + scopeSuffix + "];");
+
+                dojo._scopePrefixArgs = scopePrefix;
+                dojo._scopePrefix = "(function(" + scopePrefix + "){";
+                dojo._scopeSuffix = "})(" + scopeSuffix + ")";
+                dojo._scopeMap = scopeMap;
+                dojo._scopeMapRev = scopeMapRev;
+        }
+
+/*=====
+// note:
+//              'djConfig' does not exist under 'dojo.*' so that it can be set before the
+//              'dojo' variable exists.
+// note:
+//              Setting any of these variables *after* the library has loaded does
+//              nothing at all.
+
+djConfig = {
+        // summary:
+        //              Application code can set the global 'djConfig' prior to loading
+        //              the library to override certain global settings for how dojo works.
+        //
+        // isDebug: Boolean
+        //              Defaults to `false`. If set to `true`, ensures that Dojo provides
+        //              extended debugging feedback via Firebug. If Firebug is not available
+        //              on your platform, setting `isDebug` to `true` will force Dojo to
+        //              pull in (and display) the version of Firebug Lite which is
+        //              integrated into the Dojo distribution, thereby always providing a
+        //              debugging/logging console when `isDebug` is enabled. Note that
+        //              Firebug's `console.*` methods are ALWAYS defined by Dojo. If
+        //              `isDebug` is false and you are on a platform without Firebug, these
+        //              methods will be defined as no-ops.
+        isDebug: false,
+        // debugAtAllCosts: Boolean
+        //              Defaults to `false`. If set to `true`, this triggers an alternate
+        //              mode of the package system in which dependencies are detected and
+        //              only then are resources evaluated in dependency order via
+        //              `<script>` tag inclusion. This may double-request resources and
+        //              cause problems with scripts which expect `dojo.require()` to
+        //              preform synchronously. `debugAtAllCosts` can be an invaluable
+        //              debugging aid, but when using it, ensure that all code which
+        //              depends on Dojo modules is wrapped in `dojo.addOnLoad()` handlers.
+        //              Due to the somewhat unpredictable side-effects of using
+        //              `debugAtAllCosts`, it is strongly recommended that you enable this
+        //              flag as a last resort. `debugAtAllCosts` has no effect when loading
+        //              resources across domains. For usage information, see the
+        //              [Dojo Book](http://dojotoolkit.org/book/book-dojo/part-4-meta-dojo-making-your-dojo-code-run-faster-and-better/debugging-facilities/deb)
+        debugAtAllCosts: false,
+        // locale: String
+        //              The locale to assume for loading localized resources in this page,
+        //              specified according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt).
+        //              Must be specified entirely in lowercase, e.g. `en-us` and `zh-cn`.
+        //              See the documentation for `dojo.i18n` and `dojo.requireLocalization`
+        //              for details on loading localized resources. If no locale is specified,
+        //              Dojo assumes the locale of the user agent, according to `navigator.userLanguage`
+        //              or `navigator.language` properties.
+        locale: undefined,
+        // extraLocale: Array
+        //              No default value. Specifies additional locales whose
+        //              resources should also be loaded alongside the default locale when
+        //              calls to `dojo.requireLocalization()` are processed.
+        extraLocale: undefined,
+        // baseUrl: String
+        //              The directory in which `dojo.js` is located. Under normal
+        //              conditions, Dojo auto-detects the correct location from which it
+        //              was loaded. You may need to manually configure `baseUrl` in cases
+        //              where you have renamed `dojo.js` or in which `<base>` tags confuse
+        //              some browsers (e.g. IE 6). The variable `dojo.baseUrl` is assigned
+        //              either the value of `djConfig.baseUrl` if one is provided or the
+        //              auto-detected root if not. Other modules are located relative to
+        //              this path. The path should end in a slash.
+        baseUrl: undefined,
+        // modulePaths: Object
+        //              A map of module names to paths relative to `dojo.baseUrl`. The
+        //              key/value pairs correspond directly to the arguments which
+        //              `dojo.registerModulePath` accepts. Specifiying
+        //              `djConfig.modulePaths = { "foo": "../../bar" }` is the equivalent
+        //              of calling `dojo.registerModulePath("foo", "../../bar");`. Multiple
+        //              modules may be configured via `djConfig.modulePaths`.
+        modulePaths: {},
+        // afterOnLoad: Boolean
+        //              Indicates Dojo was added to the page after the page load. In this case
+        //              Dojo will not wait for the page DOMContentLoad/load events and fire
+        //              its dojo.addOnLoad callbacks after making sure all outstanding
+        //              dojo.required modules have loaded. Only works with a built dojo.js,
+        //              it does not work the dojo.js directly from source control.
+        afterOnLoad: false,
+        // addOnLoad: Function or Array
+        //              Adds a callback via dojo.addOnLoad. Useful when Dojo is added after
+        //              the page loads and djConfig.afterOnLoad is true. Supports the same
+        //              arguments as dojo.addOnLoad. When using a function reference, use
+        //              `djConfig.addOnLoad = function(){};`. For object with function name use
+        //              `djConfig.addOnLoad = [myObject, "functionName"];` and for object with
+        //              function reference use
+        //              `djConfig.addOnLoad = [myObject, function(){}];`
+        addOnLoad: null,
+        // require: Array
+        //              An array of module names to be loaded immediately after dojo.js has been included
+        //              in a page.
+        require: [],
+        // defaultDuration: Array
+        //              Default duration, in milliseconds, for wipe and fade animations within dijits.
+        //              Assigned to dijit.defaultDuration.
+        defaultDuration: 200,
+        // dojoBlankHtmlUrl: String
+        //              Used by some modules to configure an empty iframe. Used by dojo.io.iframe and
+        //              dojo.back, and dijit popup support in IE where an iframe is needed to make sure native
+        //              controls do not bleed through the popups. Normally this configuration variable
+        //              does not need to be set, except when using cross-domain/CDN Dojo builds.
+        //              Save dojo/resources/blank.html to your domain and set `djConfig.dojoBlankHtmlUrl`
+        //              to the path on your domain your copy of blank.html.
+        dojoBlankHtmlUrl: undefined,
+        //      ioPublish: Boolean?
+        //              Set this to true to enable publishing of topics for the different phases of
+        //              IO operations. Publishing is done via dojo.publish. See dojo.__IoPublish for a list
+        //              of topics that are published.
+        ioPublish: false,
+        //  useCustomLogger: Anything?
+        //              If set to a value that evaluates to true such as a string or array and
+        //              isDebug is true and Firebug is not available or running, then it bypasses
+        //              the creation of Firebug Lite allowing you to define your own console object.
+        useCustomLogger: undefined,
+        // transparentColor: Array
+        //              Array containing the r, g, b components used as transparent color in dojo.Color;
+        //              if undefined, [255,255,255] (white) will be used.
+        transparentColor: undefined,
+        // skipIeDomLoaded: Boolean
+        //              For IE only, skip the DOMContentLoaded hack used. Sometimes it can cause an Operation
+        //              Aborted error if the rest of the page triggers script defers before the DOM is ready.
+        //              If this is config value is set to true, then dojo.addOnLoad callbacks will not be
+        //              triggered until the page load event, which is after images and iframes load. If you
+        //              want to trigger the callbacks sooner, you can put a script block in the bottom of
+        //              your HTML that calls dojo._loadInit();. If you are using multiversion support, change
+        //              "dojo." to the appropriate scope name for dojo.
+        skipIeDomLoaded: false
+}
+=====*/
+
+(function(){
+        // firebug stubs
+
+        if(typeof this["loadFirebugConsole"] == "function"){
+                // for Firebug 1.2
+                this["loadFirebugConsole"]();
+        }else{
+                this.console = this.console || {};
+
+                //      Be careful to leave 'log' always at the end
+                var cn = [
+                        "assert", "count", "debug", "dir", "dirxml", "error", "group",
+                        "groupEnd", "info", "profile", "profileEnd", "time", "timeEnd",
+                        "trace", "warn", "log"
+                ];
+                var i = 0, tn;
+                while((tn=cn[i++])){
+                        if(!console[tn]){
+                                (function(){
+                                        var tcn = tn+"";
+                                        console[tcn] = ('log' in console) ? function(){
+                                                var a = Array.apply({}, arguments);
+                                                a.unshift(tcn+":");
+                                                console["log"](a.join(" "));
+                                        } : function(){}
+                                        console[tcn]._fake = true;
+                                })();
+                        }
+                }
+        }
+
+        //TODOC:  HOW TO DOC THIS?
+        // dojo is the root variable of (almost all) our public symbols -- make sure it is defined.
+        if(typeof dojo == "undefined"){
+                dojo = {
+                        _scopeName: "dojo",
+                        _scopePrefix: "",
+                        _scopePrefixArgs: "",
+                        _scopeSuffix: "",
+                        _scopeMap: {},
+                        _scopeMapRev: {}
+                };
+        }
+
+        var d = dojo;
+
+        //Need placeholders for dijit and dojox for scoping code.
+        if(typeof dijit == "undefined"){
+                dijit = {_scopeName: "dijit"};
+        }
+        if(typeof dojox == "undefined"){
+                dojox = {_scopeName: "dojox"};
+        }
+
+        if(!d._scopeArgs){
+                d._scopeArgs = [dojo, dijit, dojox];
+        }
+
+/*=====
+dojo.global = {
+        //      summary:
+        //              Alias for the global scope
+        //              (e.g. the window object in a browser).
+        //      description:
+        //              Refer to 'dojo.global' rather than referring to window to ensure your
+        //              code runs correctly in contexts other than web browsers (e.g. Rhino on a server).
+}
+=====*/
+        d.global = this;
+
+        d.config =/*===== djConfig = =====*/{
+                isDebug: false,
+                debugAtAllCosts: false
+        };
+
+        // FIXME: 2.0, drop djConfig support. Use dojoConfig exclusively for global config.
+        var cfg = typeof djConfig != "undefined" ? djConfig :
+                typeof dojoConfig != "undefined" ? dojoConfig : null;
+                
+        if(cfg){
+                for(var c in cfg){
+                        d.config[c] = cfg[c];
+                }
+        }
+
+/*=====
+        // Override locale setting, if specified
+        dojo.locale = {
+                // summary: the locale as defined by Dojo (read-only)
+        };
+=====*/
+        dojo.locale = d.config.locale;
+
+        var rev = "$Rev: 24595 $".match(/\d+/);
+
+/*=====
+        dojo.version = function(){
+                // summary:
+                //              Version number of the Dojo Toolkit
+                // major: Integer
+                //              Major version. If total version is "1.2.0beta1", will be 1
+                // minor: Integer
+                //              Minor version. If total version is "1.2.0beta1", will be 2
+                // patch: Integer
+                //              Patch version. If total version is "1.2.0beta1", will be 0
+                // flag: String
+                //              Descriptor flag. If total version is "1.2.0beta1", will be "beta1"
+                // revision: Number
+                //              The SVN rev from which dojo was pulled
+                this.major = 0;
+                this.minor = 0;
+                this.patch = 0;
+                this.flag = "";
+                this.revision = 0;
+        }
+=====*/
+        dojo.version = {
+                major: 1, minor: 6, patch: 1, flag: "",
+                revision: rev ? +rev[0] : NaN,
+                toString: function(){
+                        with(d.version){
+                                return major + "." + minor + "." + patch + flag + " (" + revision + ")";        // String
+                        }
+                }
+        }
+
+                // Register with the OpenAjax hub
+        if(typeof OpenAjax != "undefined"){
+                OpenAjax.hub.registerLibrary(dojo._scopeName, "http://dojotoolkit.org", d.version.toString());
+        }
+        
+        var extraNames, extraLen, empty = {};
+        for(var i in {toString: 1}){ extraNames = []; break; }
+        dojo._extraNames = extraNames = extraNames || ["hasOwnProperty", "valueOf", "isPrototypeOf",
+                "propertyIsEnumerable", "toLocaleString", "toString", "constructor"];
+        extraLen = extraNames.length;
+
+        dojo._mixin = function(/*Object*/ target, /*Object*/ source){
+                // summary:
+                //              Adds all properties and methods of source to target. This addition
+                //              is "prototype extension safe", so that instances of objects
+                //              will not pass along prototype defaults.
+                var name, s, i;
+                for(name in source){
+                        // the "tobj" condition avoid copying properties in "source"
+                        // inherited from Object.prototype.  For example, if target has a custom
+                        // toString() method, don't overwrite it with the toString() method
+                        // that source inherited from Object.prototype
+                        s = source[name];
+                        if(!(name in target) || (target[name] !== s && (!(name in empty) || empty[name] !== s))){
+                                target[name] = s;
+                        }
+                }
+                                // IE doesn't recognize some custom functions in for..in
+                if(extraLen && source){
+                        for(i = 0; i < extraLen; ++i){
+                                name = extraNames[i];
+                                s = source[name];
+                                if(!(name in target) || (target[name] !== s && (!(name in empty) || empty[name] !== s))){
+                                        target[name] = s;
+                                }
+                        }
+                }
+                                return target; // Object
+        }
+
+        dojo.mixin = function(/*Object*/obj, /*Object...*/props){
+                // summary:
+                //              Adds all properties and methods of props to obj and returns the
+                //              (now modified) obj.
+                //      description:
+                //              `dojo.mixin` can mix multiple source objects into a
+                //              destination object which is then returned. Unlike regular
+                //              `for...in` iteration, `dojo.mixin` is also smart about avoiding
+                //              extensions which other toolkits may unwisely add to the root
+                //              object prototype
+                //      obj:
+                //              The object to mix properties into. Also the return value.
+                //      props:
+                //              One or more objects whose values are successively copied into
+                //              obj. If more than one of these objects contain the same value,
+                //              the one specified last in the function call will "win".
+                //      example:
+                //              make a shallow copy of an object
+                //      |       var copy = dojo.mixin({}, source);
+                //      example:
+                //              many class constructors often take an object which specifies
+                //              values to be configured on the object. In this case, it is
+                //              often simplest to call `dojo.mixin` on the `this` object:
+                //      |       dojo.declare("acme.Base", null, {
+                //      |               constructor: function(properties){
+                //      |                       // property configuration:
+                //      |                       dojo.mixin(this, properties);
+                //      |
+                //      |                       console.log(this.quip);
+                //      |                       //  ...
+                //      |               },
+                //      |               quip: "I wasn't born yesterday, you know - I've seen movies.",
+                //      |               // ...
+                //      |       });
+                //      |
+                //      |       // create an instance of the class and configure it
+                //      |       var b = new acme.Base({quip: "That's what it does!" });
+                //      example:
+                //              copy in properties from multiple objects
+                //      |       var flattened = dojo.mixin(
+                //      |               {
+                //      |                       name: "Frylock",
+                //      |                       braces: true
+                //      |               },
+                //      |               {
+                //      |                       name: "Carl Brutanananadilewski"
+                //      |               }
+                //      |       );
+                //      |
+                //      |       // will print "Carl Brutanananadilewski"
+                //      |       console.log(flattened.name);
+                //      |       // will print "true"
+                //      |       console.log(flattened.braces);
+                if(!obj){ obj = {}; }
+                for(var i=1, l=arguments.length; i<l; i++){
+                        d._mixin(obj, arguments[i]);
+                }
+                return obj; // Object
+        }
+
+        dojo._getProp = function(/*Array*/parts, /*Boolean*/create, /*Object*/context){
+                var obj=context || d.global;
+                for(var i=0, p; obj && (p=parts[i]); i++){
+                        if(i == 0 && d._scopeMap[p]){
+                                p = d._scopeMap[p];
+                        }
+                        obj = (p in obj ? obj[p] : (create ? obj[p]={} : undefined));
+                }
+                return obj; // mixed
+        }
+
+        dojo.setObject = function(/*String*/name, /*Object*/value, /*Object?*/context){
+                // summary:
+                //              Set a property from a dot-separated string, such as "A.B.C"
+                //      description:
+                //              Useful for longer api chains where you have to test each object in
+                //              the chain, or when you have an object reference in string format.
+                //              Objects are created as needed along `path`. Returns the passed
+                //              value if setting is successful or `undefined` if not.
+                //      name:
+                //              Path to a property, in the form "A.B.C".
+                //      context:
+                //              Optional. Object to use as root of path. Defaults to
+                //              `dojo.global`.
+                //      example:
+                //              set the value of `foo.bar.baz`, regardless of whether
+                //              intermediate objects already exist:
+                //      |       dojo.setObject("foo.bar.baz", value);
+                //      example:
+                //              without `dojo.setObject`, we often see code like this:
+                //      |       // ensure that intermediate objects are available
+                //      |       if(!obj["parent"]){ obj.parent = {}; }
+                //      |       if(!obj.parent["child"]){ obj.parent.child= {}; }
+                //      |       // now we can safely set the property
+                //      |       obj.parent.child.prop = "some value";
+                //              wheras with `dojo.setObject`, we can shorten that to:
+                //      |       dojo.setObject("parent.child.prop", "some value", obj);
+                var parts=name.split("."), p=parts.pop(), obj=d._getProp(parts, true, context);
+                return obj && p ? (obj[p]=value) : undefined; // Object
+        }
+
+        dojo.getObject = function(/*String*/name, /*Boolean?*/create, /*Object?*/context){
+                // summary:
+                //              Get a property from a dot-separated string, such as "A.B.C"
+                //      description:
+                //              Useful for longer api chains where you have to test each object in
+                //              the chain, or when you have an object reference in string format.
+                //      name:
+                //              Path to an property, in the form "A.B.C".
+                //      create:
+                //              Optional. Defaults to `false`. If `true`, Objects will be
+                //              created at any point along the 'path' that is undefined.
+                //      context:
+                //              Optional. Object to use as root of path. Defaults to
+                //              'dojo.global'. Null may be passed.
+                return d._getProp(name.split("."), create, context); // Object
+        }
+
+        dojo.exists = function(/*String*/name, /*Object?*/obj){
+                //      summary:
+                //              determine if an object supports a given method
+                //      description:
+                //              useful for longer api chains where you have to test each object in
+                //              the chain. Useful for object and method detection.
+                //      name:
+                //              Path to an object, in the form "A.B.C".
+                //      obj:
+                //              Object to use as root of path. Defaults to
+                //              'dojo.global'. Null may be passed.
+                //      example:
+                //      |       // define an object
+                //      |       var foo = {
+                //      |               bar: { }
+                //      |       };
+                //      |
+                //      |       // search the global scope
+                //      |       dojo.exists("foo.bar"); // true
+                //      |       dojo.exists("foo.bar.baz"); // false
+                //      |
+                //      |       // search from a particular scope
+                //      |       dojo.exists("bar", foo); // true
+                //      |       dojo.exists("bar.baz", foo); // false
+                return d.getObject(name, false, obj) !== undefined; // Boolean
+        }
+
+        dojo["eval"] = function(/*String*/ scriptFragment){
+                //      summary:
+                //              A legacy method created for use exclusively by internal Dojo methods. Do not use
+                //              this method directly, the behavior of this eval will differ from the normal
+                //              browser eval.
+                //      description:
+                //              Placed in a separate function to minimize size of trapped
+                //              exceptions. Calling eval() directly from some other scope may
+                //              complicate tracebacks on some platforms.
+                //      returns:
+                //              The result of the evaluation. Often `undefined`
+                return d.global.eval ? d.global.eval(scriptFragment) : eval(scriptFragment);    // Object
+        }
+
+        /*=====
+                dojo.deprecated = function(behaviour, extra, removal){
+                        //      summary:
+                        //              Log a debug message to indicate that a behavior has been
+                        //              deprecated.
+                        //      behaviour: String
+                        //              The API or behavior being deprecated. Usually in the form
+                        //              of "myApp.someFunction()".
+                        //      extra: String?
+                        //              Text to append to the message. Often provides advice on a
+                        //              new function or facility to achieve the same goal during
+                        //              the deprecation period.
+                        //      removal: String?
+                        //              Text to indicate when in the future the behavior will be
+                        //              removed. Usually a version number.
+                        //      example:
+                        //      |       dojo.deprecated("myApp.getTemp()", "use myApp.getLocaleTemp() instead", "1.0");
+                }
+
+                dojo.experimental = function(moduleName, extra){
+                        //      summary: Marks code as experimental.
+                        //      description:
+                        //              This can be used to mark a function, file, or module as
+                        //              experimental.  Experimental code is not ready to be used, and the
+                        //              APIs are subject to change without notice.  Experimental code may be
+                        //              completed deleted without going through the normal deprecation
+                        //              process.
+                        //      moduleName: String
+                        //              The name of a module, or the name of a module file or a specific
+                        //              function
+                        //      extra: String?
+                        //              some additional message for the user
+                        //      example:
+                        //      |       dojo.experimental("dojo.data.Result");
+                        //      example:
+                        //      |       dojo.experimental("dojo.weather.toKelvin()", "PENDING approval from NOAA");
+                }
+        =====*/
+
+        //Real functions declared in dojo._firebug.firebug.
+        d.deprecated = d.experimental = function(){};
+
+})();
+// vim:ai:ts=4:noet
+
+/*
+ * loader.js - A bootstrap module.  Runs before the hostenv_*.js file. Contains
+ * all of the package loading methods.
+ */
+(function(){
+        var d = dojo, currentModule;
+
+        d.mixin(d, {
+                _loadedModules: {},
+                _inFlightCount: 0,
+                _hasResource: {},
+
+                _modulePrefixes: {
+                        dojo:   {       name: "dojo", value: "." },
+                        // dojox:       {       name: "dojox", value: "../dojox" },
+                        // dijit:       {       name: "dijit", value: "../dijit" },
+                        doh:    {       name: "doh", value: "../util/doh" },
+                        tests:  {       name: "tests", value: "tests" }
+                },
+
+                _moduleHasPrefix: function(/*String*/module){
+                        // summary: checks to see if module has been established
+                        var mp = d._modulePrefixes;
+                        return !!(mp[module] && mp[module].value); // Boolean
+                },
+
+                _getModulePrefix: function(/*String*/module){
+                        // summary: gets the prefix associated with module
+                        var mp = d._modulePrefixes;
+                        if(d._moduleHasPrefix(module)){
+                                return mp[module].value; // String
+                        }
+                        return module; // String
+                },
+
+                _loadedUrls: [],
+
+                //WARNING:
+                //              This variable is referenced by packages outside of bootstrap:
+                //              FloatingPane.js and undo/browser.js
+                _postLoad: false,
+
+                //Egad! Lots of test files push on this directly instead of using dojo.addOnLoad.
+                _loaders: [],
+                _unloaders: [],
+                _loadNotifying: false
+        });
+
+
+                dojo._loadPath = function(/*String*/relpath, /*String?*/module, /*Function?*/cb){
+                //      summary:
+                //              Load a Javascript module given a relative path
+                //
+                //      description:
+                //              Loads and interprets the script located at relpath, which is
+                //              relative to the script root directory.  If the script is found but
+                //              its interpretation causes a runtime exception, that exception is
+                //              not caught by us, so the caller will see it.  We return a true
+                //              value if and only if the script is found.
+                //
+                // relpath:
+                //              A relative path to a script (no leading '/', and typically ending
+                //              in '.js').
+                // module:
+                //              A module whose existance to check for after loading a path.  Can be
+                //              used to determine success or failure of the load.
+                // cb:
+                //              a callback function to pass the result of evaluating the script
+
+                var uri = ((relpath.charAt(0) == '/' || relpath.match(/^\w+:/)) ? "" : d.baseUrl) + relpath;
+                try{
+                        currentModule = module;
+                        return !module ? d._loadUri(uri, cb) : d._loadUriAndCheck(uri, module, cb); // Boolean
+                }catch(e){
+                        console.error(e);
+                        return false; // Boolean
+                }finally{
+                        currentModule = null;
+                }
+        }
+
+        dojo._loadUri = function(/*String*/uri, /*Function?*/cb){
+                //      summary:
+                //              Loads JavaScript from a URI
+                //      description:
+                //              Reads the contents of the URI, and evaluates the contents.  This is
+                //              used to load modules as well as resource bundles. Returns true if
+                //              it succeeded. Returns false if the URI reading failed.  Throws if
+                //              the evaluation throws.
+                //      uri: a uri which points at the script to be loaded
+                //      cb:
+                //              a callback function to process the result of evaluating the script
+                //              as an expression, typically used by the resource bundle loader to
+                //              load JSON-style resources
+
+                if(d._loadedUrls[uri]){
+                        return true; // Boolean
+                }
+                d._inFlightCount++; // block addOnLoad calls that arrive while we're busy downloading
+                var contents = d._getText(uri, true);
+                if(contents){ // not 404, et al
+                        d._loadedUrls[uri] = true;
+                        d._loadedUrls.push(uri);
+                        if(cb){
+                                //conditional to support script-inject i18n bundle format
+                                contents = /^define\(/.test(contents) ? contents : '('+contents+')';
+                        }else{
+                                //Only do the scoping if no callback. If a callback is specified,
+                                //it is most likely the i18n bundle stuff.
+                                contents = d._scopePrefix + contents + d._scopeSuffix;
+                        }
+                        if(!d.isIE){ contents += "\r\n//@ sourceURL=" + uri; } // debugging assist for Firebug
+                        var value = d["eval"](contents);
+                        if(cb){ cb(value); }
+                }
+                // Check to see if we need to call _callLoaded() due to an addOnLoad() that arrived while we were busy downloading
+                if(--d._inFlightCount == 0 && d._postLoad && d._loaders.length){
+                        // We shouldn't be allowed to get here but Firefox allows an event
+                        // (mouse, keybd, async xhrGet) to interrupt a synchronous xhrGet.
+                        // If the current script block contains multiple require() statements, then after each
+                        // require() returns, inFlightCount == 0, but we want to hold the _callLoaded() until
+                        // all require()s are done since the out-of-sequence addOnLoad() presumably needs them all.
+                        // setTimeout allows the next require() to start (if needed), and then we check this again.
+                        setTimeout(function(){
+                                // If inFlightCount > 0, then multiple require()s are running sequentially and
+                                // the next require() started after setTimeout() was executed but before we got here.
+                                if(d._inFlightCount == 0){
+                                        d._callLoaded();
+                                }
+                        }, 0);
+                }
+                return !!contents; // Boolean: contents? true : false
+        }
+        
+        // FIXME: probably need to add logging to this method
+        dojo._loadUriAndCheck = function(/*String*/uri, /*String*/moduleName, /*Function?*/cb){
+                // summary: calls loadUri then findModule and returns true if both succeed
+                var ok = false;
+                try{
+                        ok = d._loadUri(uri, cb);
+                }catch(e){
+                        console.error("failed loading " + uri + " with error: " + e);
+                }
+                return !!(ok && d._loadedModules[moduleName]); // Boolean
+        }
+
+        dojo.loaded = function(){
+                // summary:
+                //              signal fired when initial environment and package loading is
+                //              complete. You should use dojo.addOnLoad() instead of doing a
+                //              direct dojo.connect() to this method in order to handle
+                //              initialization tasks that require the environment to be
+                //              initialized. In a browser host, declarative widgets will
+                //              be constructed when this function finishes runing.
+                d._loadNotifying = true;
+                d._postLoad = true;
+                var mll = d._loaders;
+
+                //Clear listeners so new ones can be added
+                //For other xdomain package loads after the initial load.
+                d._loaders = [];
+
+                for(var x = 0; x < mll.length; x++){
+                        mll[x]();
+                }
+
+                d._loadNotifying = false;
+                
+                //Make sure nothing else got added to the onload queue
+                //after this first run. If something did, and we are not waiting for any
+                //more inflight resources, run again.
+                if(d._postLoad && d._inFlightCount == 0 && mll.length){
+                        d._callLoaded();
+                }
+        }
+
+        dojo.unloaded = function(){
+                // summary:
+                //              signal fired by impending environment destruction. You should use
+                //              dojo.addOnUnload() instead of doing a direct dojo.connect() to this
+                //              method to perform page/application cleanup methods. See
+                //              dojo.addOnUnload for more info.
+                var mll = d._unloaders;
+                while(mll.length){
+                        (mll.pop())();
+                }
+        }
+
+        d._onto = function(arr, obj, fn){
+                if(!fn){
+                        arr.push(obj);
+                }else if(fn){
+                        var func = (typeof fn == "string") ? obj[fn] : fn;
+                        arr.push(function(){ func.call(obj); });
+                }
+        }
+
+        dojo.ready = dojo.addOnLoad = function(/*Object*/obj, /*String|Function?*/functionName){
+                // summary:
+                //              Registers a function to be triggered after the DOM and dojo.require() calls
+                //              have finished loading.
+                //
+                // description:
+                //              Registers a function to be triggered after the DOM has finished
+                //              loading and `dojo.require` modules have loaded. Widgets declared in markup
+                //              have been instantiated if `djConfig.parseOnLoad` is true when this fires.
+                //
+                //              Images and CSS files may or may not have finished downloading when
+                //              the specified function is called.  (Note that widgets' CSS and HTML
+                //              code is guaranteed to be downloaded before said widgets are
+                //              instantiated, though including css resouces BEFORE any script elements
+                //              is highly recommended).
+                //
+                // example:
+                //      Register an anonymous function to run when everything is ready
+                //      |       dojo.addOnLoad(function(){ doStuff(); });
+                //
+                // example:
+                //      Register a function to run when everything is ready by pointer:
+                //      |       var init = function(){ doStuff(); }
+                //      |       dojo.addOnLoad(init);
+                //
+                // example:
+                //      Register a function to run scoped to `object`, either by name or anonymously:
+                //      |       dojo.addOnLoad(object, "functionName");
+                //      |       dojo.addOnLoad(object, function(){ doStuff(); });
+
+                d._onto(d._loaders, obj, functionName);
+
+                //Added for xdomain loading. dojo.addOnLoad is used to
+                //indicate callbacks after doing some dojo.require() statements.
+                //In the xdomain case, if all the requires are loaded (after initial
+                //page load), then immediately call any listeners.
+                if(d._postLoad && d._inFlightCount == 0 && !d._loadNotifying){
+                        d._callLoaded();
+                }
+        }
+
+        //Support calling dojo.addOnLoad via djConfig.addOnLoad. Support all the
+        //call permutations of dojo.addOnLoad. Mainly useful when dojo is added
+        //to the page after the page has loaded.
+        var dca = d.config.addOnLoad;
+        if(dca){
+                d.addOnLoad[(dca instanceof Array ? "apply" : "call")](d, dca);
+        }
+
+        dojo._modulesLoaded = function(){
+                if(d._postLoad){ return; }
+                if(d._inFlightCount > 0){
+                        console.warn("files still in flight!");
+                        return;
+                }
+                d._callLoaded();
+        }
+
+        dojo._callLoaded = function(){
+
+                // The "object" check is for IE, and the other opera check fixes an
+                // issue in Opera where it could not find the body element in some
+                // widget test cases.  For 0.9, maybe route all browsers through the
+                // setTimeout (need protection still for non-browser environments
+                // though). This might also help the issue with FF 2.0 and freezing
+                // issues where we try to do sync xhr while background css images are
+                // being loaded (trac #2572)? Consider for 0.9.
+                if(typeof setTimeout == "object" || (d.config.useXDomain && d.isOpera)){
+                        setTimeout(
+                                d.isAIR ? function(){ d.loaded(); } : d._scopeName + ".loaded();",
+                                0);
+                }else{
+                        d.loaded();
+                }
+        }
+
+        dojo._getModuleSymbols = function(/*String*/modulename){
+                // summary:
+                //              Converts a module name in dotted JS notation to an array
+                //              representing the path in the source tree
+                var syms = modulename.split(".");
+                for(var i = syms.length; i>0; i--){
+                        var parentModule = syms.slice(0, i).join(".");
+                        if(i == 1 && !d._moduleHasPrefix(parentModule)){
+                                // Support default module directory (sibling of dojo) for top-level modules
+                                syms[0] = "../" + syms[0];
+                        }else{
+                                var parentModulePath = d._getModulePrefix(parentModule);
+                                if(parentModulePath != parentModule){
+                                        syms.splice(0, i, parentModulePath);
+                                        break;
+                                }
+                        }
+                }
+                return syms; // Array
+        }
+
+        dojo._global_omit_module_check = false;
+
+        dojo.loadInit = function(/*Function*/init){
+                //      summary:
+                //              Executes a function that needs to be executed for the loader's dojo.requireIf
+                //              resolutions to work. This is needed mostly for the xdomain loader case where
+                //              a function needs to be executed to set up the possible values for a dojo.requireIf
+                //              call.
+                //      init:
+                //              a function reference. Executed immediately.
+                //      description: This function is mainly a marker for the xdomain loader to know parts of
+                //              code that needs be executed outside the function wrappper that is placed around modules.
+                //              The init function could be executed more than once, and it should make no assumptions
+                //              on what is loaded, or what modules are available. Only the functionality in Dojo Base
+                //              is allowed to be used. Avoid using this method. For a valid use case,
+                //              see the source for dojox.gfx.
+                init();
+        }
+
+        dojo._loadModule = dojo.require = function(/*String*/moduleName, /*Boolean?*/omitModuleCheck){
+                //      summary:
+                //              loads a Javascript module from the appropriate URI
+                //
+                //      moduleName: String
+                //              module name to load, using periods for separators,
+                //               e.g. "dojo.date.locale".  Module paths are de-referenced by dojo's
+                //              internal mapping of locations to names and are disambiguated by
+                //              longest prefix. See `dojo.registerModulePath()` for details on
+                //              registering new modules.
+                //
+                //      omitModuleCheck: Boolean?
+                //              if `true`, omitModuleCheck skips the step of ensuring that the
+                //              loaded file actually defines the symbol it is referenced by.
+                //              For example if it called as `dojo.require("a.b.c")` and the
+                //              file located at `a/b/c.js` does not define an object `a.b.c`,
+                //              and exception will be throws whereas no exception is raised
+                //              when called as `dojo.require("a.b.c", true)`
+                //
+                //      description:
+                //              Modules are loaded via dojo.require by using one of two loaders: the normal loader
+                //              and the xdomain loader. The xdomain loader is used when dojo was built with a
+                //              custom build that specified loader=xdomain and the module lives on a modulePath
+                //              that is a whole URL, with protocol and a domain. The versions of Dojo that are on
+                //              the Google and AOL CDNs use the xdomain loader.
+                //
+                //              If the module is loaded via the xdomain loader, it is an asynchronous load, since
+                //              the module is added via a dynamically created script tag. This
+                //              means that dojo.require() can return before the module has loaded. However, this
+                //              should only happen in the case where you do dojo.require calls in the top-level
+                //              HTML page, or if you purposely avoid the loader checking for dojo.require
+                //              dependencies in your module by using a syntax like dojo["require"] to load the module.
+                //
+                //              Sometimes it is useful to not have the loader detect the dojo.require calls in the
+                //              module so that you can dynamically load the modules as a result of an action on the
+                //              page, instead of right at module load time.
+                //
+                //              Also, for script blocks in an HTML page, the loader does not pre-process them, so
+                //              it does not know to download the modules before the dojo.require calls occur.
+                //
+                //              So, in those two cases, when you want on-the-fly module loading or for script blocks
+                //              in the HTML page, special care must be taken if the dojo.required code is loaded
+                //              asynchronously. To make sure you can execute code that depends on the dojo.required
+                //              modules, be sure to add the code that depends on the modules in a dojo.addOnLoad()
+                //              callback. dojo.addOnLoad waits for all outstanding modules to finish loading before
+                //              executing.
+                //
+                //              This type of syntax works with both xdomain and normal loaders, so it is good
+                //              practice to always use this idiom for on-the-fly code loading and in HTML script
+                //              blocks. If at some point you change loaders and where the code is loaded from,
+                //              it will all still work.
+                //
+                //              More on how dojo.require
+                //              `dojo.require("A.B")` first checks to see if symbol A.B is
+                //              defined. If it is, it is simply returned (nothing to do).
+                //
+                //              If it is not defined, it will look for `A/B.js` in the script root
+                //              directory.
+                //
+                //              `dojo.require` throws an exception if it cannot find a file
+                //              to load, or if the symbol `A.B` is not defined after loading.
+                //
+                //              It returns the object `A.B`, but note the caveats above about on-the-fly loading and
+                //              HTML script blocks when the xdomain loader is loading a module.
+                //
+                //              `dojo.require()` does nothing about importing symbols into
+                //              the current namespace.  It is presumed that the caller will
+                //              take care of that.
+                //
+                //      example:
+                //              To use dojo.require in conjunction with dojo.ready:
+                //
+                //              |       dojo.require("foo");
+                //              |       dojo.require("bar");
+                //              |       dojo.addOnLoad(function(){
+                //              |               //you can now safely do something with foo and bar
+                //              |       });
+                //
+                //      example:
+                //              For example, to import all symbols into a local block, you might write:
+                //
+                //              |       with (dojo.require("A.B")) {
+                //              |               ...
+                //              |       }
+                //
+                //              And to import just the leaf symbol to a local variable:
+                //
+                //              |       var B = dojo.require("A.B");
+                //              |       ...
+                //
+                //      returns:
+                //              the required namespace object
+                omitModuleCheck = d._global_omit_module_check || omitModuleCheck;
+
+                //Check if it is already loaded.
+                var module = d._loadedModules[moduleName];
+                if(module){
+                        return module;
+                }
+
+                // convert periods to slashes
+                var relpath = d._getModuleSymbols(moduleName).join("/") + '.js';
+                var modArg = !omitModuleCheck ? moduleName : null;
+                var ok = d._loadPath(relpath, modArg);
+                if(!ok && !omitModuleCheck){
+                        throw new Error("Could not load '" + moduleName + "'; last tried '" + relpath + "'");
+                }
+
+                // check that the symbol was defined
+                // Don't bother if we're doing xdomain (asynchronous) loading.
+                if(!omitModuleCheck && !d._isXDomain){
+                        // pass in false so we can give better error
+                        module = d._loadedModules[moduleName];
+                        if(!module){
+                                throw new Error("symbol '" + moduleName + "' is not defined after loading '" + relpath + "'");
+                        }
+                }
+
+                return module;
+        }
+
+        dojo.provide = function(/*String*/ resourceName){
+                //      summary:
+                //              Register a resource with the package system. Works in conjunction with `dojo.require`
+                //
+                //      description:
+                //              Each javascript source file is called a resource.  When a
+                //              resource is loaded by the browser, `dojo.provide()` registers
+                //              that it has been loaded.
+                //
+                //              Each javascript source file must have at least one
+                //              `dojo.provide()` call at the top of the file, corresponding to
+                //              the file name.  For example, `js/dojo/foo.js` must have
+                //              `dojo.provide("dojo.foo");` before any calls to
+                //              `dojo.require()` are made.
+                //
+                //              For backwards compatibility reasons, in addition to registering
+                //              the resource, `dojo.provide()` also ensures that the javascript
+                //              object for the module exists.  For example,
+                //              `dojo.provide("dojox.data.FlickrStore")`, in addition to
+                //              registering that `FlickrStore.js` is a resource for the
+                //              `dojox.data` module, will ensure that the `dojox.data`
+                //              javascript object exists, so that calls like
+                //              `dojo.data.foo = function(){ ... }` don't fail.
+                //
+                //              In the case of a build where multiple javascript source files
+                //              are combined into one bigger file (similar to a .lib or .jar
+                //              file), that file may contain multiple dojo.provide() calls, to
+                //              note that it includes multiple resources.
+                //
+                // resourceName: String
+                //              A dot-sperated string identifying a resource.
+                //
+                // example:
+                //      Safely create a `my` object, and make dojo.require("my.CustomModule") work
+                //      |       dojo.provide("my.CustomModule");
+
+                //Make sure we have a string.
+                resourceName = resourceName + "";
+                return (d._loadedModules[resourceName] = d.getObject(resourceName, true)); // Object
+        }
+
+        //Start of old bootstrap2:
+
+        dojo.platformRequire = function(/*Object*/modMap){
+                //      summary:
+                //              require one or more modules based on which host environment
+                //              Dojo is currently operating in
+                //      description:
+                //              This method takes a "map" of arrays which one can use to
+                //              optionally load dojo modules. The map is indexed by the
+                //              possible dojo.name_ values, with two additional values:
+                //              "default" and "common". The items in the "default" array will
+                //              be loaded if none of the other items have been choosen based on
+                //              dojo.name_, set by your host environment. The items in the
+                //              "common" array will *always* be loaded, regardless of which
+                //              list is chosen.
+                //      example:
+                //              |       dojo.platformRequire({
+                //              |               browser: [
+                //              |                       "foo.sample", // simple module
+                //              |                       "foo.test",
+                //              |                       ["foo.bar.baz", true] // skip object check in _loadModule (dojo.require)
+                //              |               ],
+                //              |               default: [ "foo.sample._base" ],
+                //              |               common: [ "important.module.common" ]
+                //              |       });
+
+                var common = modMap.common || [];
+                var result = common.concat(modMap[d._name] || modMap["default"] || []);
+
+                for(var x=0; x<result.length; x++){
+                        var curr = result[x];
+                        if(curr.constructor == Array){
+                                d._loadModule.apply(d, curr);
+                        }else{
+                                d._loadModule(curr);
+                        }
+                }
+        }
+
+        dojo.requireIf = function(/*Boolean*/ condition, /*String*/ resourceName){
+                // summary:
+                //              If the condition is true then call `dojo.require()` for the specified
+                //              resource
+                //
+                // example:
+                //      |       dojo.requireIf(dojo.isBrowser, "my.special.Module");
+                
+                if(condition === true){
+                        // FIXME: why do we support chained require()'s here? does the build system?
+                        var args = [];
+                        for(var i = 1; i < arguments.length; i++){
+                                args.push(arguments[i]);
+                        }
+                        d.require.apply(d, args);
+                }
+        }
+
+        dojo.requireAfterIf = d.requireIf;
+
+        dojo.registerModulePath = function(/*String*/module, /*String*/prefix){
+                //      summary:
+                //              Maps a module name to a path
+                //      description:
+                //              An unregistered module is given the default path of ../[module],
+                //              relative to Dojo root. For example, module acme is mapped to
+                //              ../acme.  If you want to use a different module name, use
+                //              dojo.registerModulePath.
+                //      example:
+                //              If your dojo.js is located at this location in the web root:
+                //      |       /myapp/js/dojo/dojo/dojo.js
+                //              and your modules are located at:
+                //      |       /myapp/js/foo/bar.js
+                //      |       /myapp/js/foo/baz.js
+                //      |       /myapp/js/foo/thud/xyzzy.js
+                //              Your application can tell Dojo to locate the "foo" namespace by calling:
+                //      |       dojo.registerModulePath("foo", "../../foo");
+                //              At which point you can then use dojo.require() to load the
+                //              modules (assuming they provide() the same things which are
+                //              required). The full code might be:
+                //      |       <script type="text/javascript"
+                //      |               src="/myapp/js/dojo/dojo/dojo.js"></script>
+                //      |       <script type="text/javascript">
+                //      |               dojo.registerModulePath("foo", "../../foo");
+                //      |               dojo.require("foo.bar");
+                //      |               dojo.require("foo.baz");
+                //      |               dojo.require("foo.thud.xyzzy");
+                //      |       </script>
+                d._modulePrefixes[module] = { name: module, value: prefix };
+        };
+        
+        dojo.requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale, /*String?*/availableFlatLocales){
+                // summary:
+                //              Declares translated resources and loads them if necessary, in the
+                //              same style as dojo.require.  Contents of the resource bundle are
+                //              typically strings, but may be any name/value pair, represented in
+                //              JSON format.  See also `dojo.i18n.getLocalization`.
+                //
+                // description:
+                //              Load translated resource bundles provided underneath the "nls"
+                //              directory within a package.  Translated resources may be located in
+                //              different packages throughout the source tree.
+                //
+                //              Each directory is named for a locale as specified by RFC 3066,
+                //              (http://www.ietf.org/rfc/rfc3066.txt), normalized in lowercase.
+                //              Note that the two bundles in the example do not define all the
+                //              same variants.  For a given locale, bundles will be loaded for
+                //              that locale and all more general locales above it, including a
+                //              fallback at the root directory.  For example, a declaration for
+                //              the "de-at" locale will first load `nls/de-at/bundleone.js`,
+                //              then `nls/de/bundleone.js` and finally `nls/bundleone.js`.  The
+                //              data will be flattened into a single Object so that lookups
+                //              will follow this cascading pattern.  An optional build step can
+                //              preload the bundles to avoid data redundancy and the multiple
+                //              network hits normally required to load these resources.
+                //
+                // moduleName:
+                //              name of the package containing the "nls" directory in which the
+                //              bundle is found
+                //
+                // bundleName:
+                //              bundle name, i.e. the filename without the '.js' suffix. Using "nls" as a
+                //              a bundle name is not supported, since "nls" is the name of the folder
+                //              that holds bundles. Using "nls" as the bundle name will cause problems
+                //              with the custom build.
+                //
+                // locale:
+                //              the locale to load (optional)  By default, the browser's user
+                //              locale as defined by dojo.locale
+                //
+                // availableFlatLocales:
+                //              A comma-separated list of the available, flattened locales for this
+                //              bundle. This argument should only be set by the build process.
+                //
+                //      example:
+                //              A particular widget may define one or more resource bundles,
+                //              structured in a program as follows, where moduleName is
+                //              mycode.mywidget and bundleNames available include bundleone and
+                //              bundletwo:
+                //      |               ...
+                //      |       mycode/
+                //      |               mywidget/
+                //      |                       nls/
+                //      |                               bundleone.js (the fallback translation, English in this example)
+                //      |                               bundletwo.js (also a fallback translation)
+                //      |                               de/
+                //      |                                       bundleone.js
+                //      |                                       bundletwo.js
+                //      |                               de-at/
+                //      |                                       bundleone.js
+                //      |                               en/
+                //      |                                       (empty; use the fallback translation)
+                //      |                               en-us/
+                //      |                                       bundleone.js
+                //      |                               en-gb/
+                //      |                                       bundleone.js
+                //      |                               es/
+                //      |                                       bundleone.js
+                //      |                                       bundletwo.js
+                //      |                                 ...etc
+                //      |                               ...
+                //
+
+                d.require("dojo.i18n");
+                d.i18n._requireLocalization.apply(d.hostenv, arguments);
+        };
+
+
+        var ore = new RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$"),
+                ire = new RegExp("^((([^\\[:]+):)?([^@]+)@)?(\\[([^\\]]+)\\]|([^\\[:]*))(:([0-9]+))?$");
+
+        dojo._Url = function(/*dojo._Url|String...*/){
+                // summary:
+                //              Constructor to create an object representing a URL.
+                //              It is marked as private, since we might consider removing
+                //              or simplifying it.
+                // description:
+                //              Each argument is evaluated in order relative to the next until
+                //              a canonical uri is produced. To get an absolute Uri relative to
+                //              the current document use:
+                //              new dojo._Url(document.baseURI, url)
+
+                var n = null,
+                        _a = arguments,
+                        uri = [_a[0]];
+                // resolve uri components relative to each other
+                for(var i = 1; i<_a.length; i++){
+                        if(!_a[i]){ continue; }
+
+                        // Safari doesn't support this.constructor so we have to be explicit
+                        // FIXME: Tracked (and fixed) in Webkit bug 3537.
+                        //              http://bugs.webkit.org/show_bug.cgi?id=3537
+                        var relobj = new d._Url(_a[i]+""),
+                                uriobj = new d._Url(uri[0]+"");
+
+                        if(
+                                relobj.path == "" &&
+                                !relobj.scheme &&
+                                !relobj.authority &&
+                                !relobj.query
+                        ){
+                                if(relobj.fragment != n){
+                                        uriobj.fragment = relobj.fragment;
+                                }
+                                relobj = uriobj;
+                        }else if(!relobj.scheme){
+                                relobj.scheme = uriobj.scheme;
+
+                                if(!relobj.authority){
+                                        relobj.authority = uriobj.authority;
+
+                                        if(relobj.path.charAt(0) != "/"){
+                                                var path = uriobj.path.substring(0,
+                                                        uriobj.path.lastIndexOf("/") + 1) + relobj.path;
+
+                                                var segs = path.split("/");
+                                                for(var j = 0; j < segs.length; j++){
+                                                        if(segs[j] == "."){
+                                                                // flatten "./" references
+                                                                if(j == segs.length - 1){
+                                                                        segs[j] = "";
+                                                                }else{
+                                                                        segs.splice(j, 1);
+                                                                        j--;
+                                                                }
+                                                        }else if(j > 0 && !(j == 1 && segs[0] == "") &&
+                                                                segs[j] == ".." && segs[j-1] != ".."){
+                                                                // flatten "../" references
+                                                                if(j == (segs.length - 1)){
+                                                                        segs.splice(j, 1);
+                                                                        segs[j - 1] = "";
+                                                                }else{
+                                                                        segs.splice(j - 1, 2);
+                                                                        j -= 2;
+                                                                }
+                                                        }
+                                                }
+                                                relobj.path = segs.join("/");
+                                        }
+                                }
+                        }
+
+                        uri = [];
+                        if(relobj.scheme){
+                                uri.push(relobj.scheme, ":");
+                        }
+                        if(relobj.authority){
+                                uri.push("//", relobj.authority);
+                        }
+                        uri.push(relobj.path);
+                        if(relobj.query){
+                                uri.push("?", relobj.query);
+                        }
+                        if(relobj.fragment){
+                                uri.push("#", relobj.fragment);
+                        }
+                }
+
+                this.uri = uri.join("");
+
+                // break the uri into its main components
+                var r = this.uri.match(ore);
+
+                this.scheme = r[2] || (r[1] ? "" : n);
+                this.authority = r[4] || (r[3] ? "" : n);
+                this.path = r[5]; // can never be undefined
+                this.query = r[7] || (r[6] ? "" : n);
+                this.fragment  = r[9] || (r[8] ? "" : n);
+
+                if(this.authority != n){
+                        // server based naming authority
+                        r = this.authority.match(ire);
+
+                        this.user = r[3] || n;
+                        this.password = r[4] || n;
+                        this.host = r[6] || r[7]; // ipv6 || ipv4
+                        this.port = r[9] || n;
+                }
+        }
+
+        dojo._Url.prototype.toString = function(){ return this.uri; };
+
+        dojo.moduleUrl = function(/*String*/module, /*dojo._Url||String*/url){
+                //      summary:
+                //              Returns a `dojo._Url` object relative to a module.
+                //      example:
+                //      |       var pngPath = dojo.moduleUrl("acme","images/small.png");
+                //      |       console.dir(pngPath); // list the object properties
+                //      |       // create an image and set it's source to pngPath's value:
+                //      |       var img = document.createElement("img");
+                //      |       // NOTE: we assign the string representation of the url object
+                //      |       img.src = pngPath.toString();
+                //      |       // add our image to the document
+                //      |       dojo.body().appendChild(img);
+                //      example:
+                //              you may de-reference as far as you like down the package
+                //              hierarchy.  This is sometimes handy to avoid lenghty relative
+                //              urls or for building portable sub-packages. In this example,
+                //              the `acme.widget` and `acme.util` directories may be located
+                //              under different roots (see `dojo.registerModulePath`) but the
+                //              the modules which reference them can be unaware of their
+                //              relative locations on the filesystem:
+                //      |       // somewhere in a configuration block
+                //      |       dojo.registerModulePath("acme.widget", "../../acme/widget");
+                //      |       dojo.registerModulePath("acme.util", "../../util");
+                //      |
+                //      |       // ...
+                //      |
+                //      |       // code in a module using acme resources
+                //      |       var tmpltPath = dojo.moduleUrl("acme.widget","templates/template.html");
+                //      |       var dataPath = dojo.moduleUrl("acme.util","resources/data.json");
+
+                var loc = d._getModuleSymbols(module).join('/');
+                if(!loc){ return null; }
+                if(loc.lastIndexOf("/") != loc.length-1){
+                        loc += "/";
+                }
+                
+                //If the path is an absolute path (starts with a / or is on another
+                //domain/xdomain) then don't add the baseUrl.
+                var colonIndex = loc.indexOf(":");
+                if(loc.charAt(0) != "/" && (colonIndex == -1 || colonIndex > loc.indexOf("/"))){
+                        loc = d.baseUrl + loc;
+                }
+
+                return new d._Url(loc, url); // dojo._Url
+        };
+
+
+
+})();
+
+/*=====
+dojo.isBrowser = {
+        //      example:
+        //      |       if(dojo.isBrowser){ ... }
+};
+
+dojo.isFF = {
+        //      example:
+        //      |       if(dojo.isFF > 1){ ... }
+};
+
+dojo.isIE = {
+        // example:
+        //      |       if(dojo.isIE > 6){
+        //      |               // we are IE7
+        //      |       }
+};
+
+dojo.isSafari = {
+        //      example:
+        //      |       if(dojo.isSafari){ ... }
+        //      example:
+        //              Detect iPhone:
+        //      |       if(dojo.isSafari && navigator.userAgent.indexOf("iPhone") != -1){
+        //      |               // we are iPhone. Note, iPod touch reports "iPod" above and fails this test.
+        //      |       }
+};
+
+dojo = {
+        // isBrowser: Boolean
+        //              True if the client is a web-browser
+        isBrowser: true,
+        //      isFF: Number | undefined
+        //              Version as a Number if client is FireFox. undefined otherwise. Corresponds to
+        //              major detected FireFox version (1.5, 2, 3, etc.)
+        isFF: 2,
+        //      isIE: Number | undefined
+        //              Version as a Number if client is MSIE(PC). undefined otherwise. Corresponds to
+        //              major detected IE version (6, 7, 8, etc.)
+        isIE: 6,
+        //      isKhtml: Number | undefined
+        //              Version as a Number if client is a KHTML browser. undefined otherwise. Corresponds to major
+        //              detected version.
+        isKhtml: 0,
+        //      isWebKit: Number | undefined
+        //              Version as a Number if client is a WebKit-derived browser (Konqueror,
+        //              Safari, Chrome, etc.). undefined otherwise.
+        isWebKit: 0,
+        //      isMozilla: Number | undefined
+        //              Version as a Number if client is a Mozilla-based browser (Firefox,
+        //              SeaMonkey). undefined otherwise. Corresponds to major detected version.
+        isMozilla: 0,
+        //      isOpera: Number | undefined
+        //              Version as a Number if client is Opera. undefined otherwise. Corresponds to
+        //              major detected version.
+        isOpera: 0,
+        //      isSafari: Number | undefined
+        //              Version as a Number if client is Safari or iPhone. undefined otherwise.
+        isSafari: 0,
+        //      isChrome: Number | undefined
+        //              Version as a Number if client is Chrome browser. undefined otherwise.
+        isChrome: 0
+        //      isMac: Boolean
+        //              True if the client runs on Mac
+}
+=====*/
+if(typeof window != 'undefined'){
+        dojo.isBrowser = true;
+        dojo._name = "browser";
+
+
+        // attempt to figure out the path to dojo if it isn't set in the config
+        (function(){
+                var d = dojo;
+
+                // this is a scope protection closure. We set browser versions and grab
+                // the URL we were loaded from here.
+
+                // grab the node we were loaded from
+                if(document && document.getElementsByTagName){
+                        var scripts = document.getElementsByTagName("script");
+                        var rePkg = /dojo(\.xd)?\.js(\W|$)/i;
+                        for(var i = 0; i < scripts.length; i++){
+                                var src = scripts[i].getAttribute("src");
+                                if(!src){ continue; }
+                                var m = src.match(rePkg);
+                                if(m){
+                                        // find out where we came from
+                                        if(!d.config.baseUrl){
+                                                d.config.baseUrl = src.substring(0, m.index);
+                                        }
+                                        // and find out if we need to modify our behavior
+                                        var cfg = (scripts[i].getAttribute("djConfig") || scripts[i].getAttribute("data-dojo-config"));
+                                        if(cfg){
+                                                var cfgo = eval("({ "+cfg+" })");
+                                                for(var x in cfgo){
+                                                        dojo.config[x] = cfgo[x];
+                                                }
+                                        }
+                                        break; // "first Dojo wins"
+                                }
+                        }
+                }
+                d.baseUrl = d.config.baseUrl;
+
+                // fill in the rendering support information in dojo.render.*
+                var n = navigator;
+                var dua = n.userAgent,
+                        dav = n.appVersion,
+                        tv = parseFloat(dav);
+
+                if(dua.indexOf("Opera") >= 0){ d.isOpera = tv; }
+                if(dua.indexOf("AdobeAIR") >= 0){ d.isAIR = 1; }
+                d.isKhtml = (dav.indexOf("Konqueror") >= 0) ? tv : 0;
+                d.isWebKit = parseFloat(dua.split("WebKit/")[1]) || undefined;
+                d.isChrome = parseFloat(dua.split("Chrome/")[1]) || undefined;
+                d.isMac = dav.indexOf("Macintosh") >= 0;
+
+                // safari detection derived from:
+                //              http://developer.apple.com/internet/safari/faq.html#anchor2
+                //              http://developer.apple.com/internet/safari/uamatrix.html
+                var index = Math.max(dav.indexOf("WebKit"), dav.indexOf("Safari"), 0);
+                if(index && !dojo.isChrome){
+                        // try to grab the explicit Safari version first. If we don't get
+                        // one, look for less than 419.3 as the indication that we're on something
+                        // "Safari 2-ish".
+                        d.isSafari = parseFloat(dav.split("Version/")[1]);
+                        if(!d.isSafari || parseFloat(dav.substr(index + 7)) <= 419.3){
+                                d.isSafari = 2;
+                        }
+                }
+
+                                if(dua.indexOf("Gecko") >= 0 && !d.isKhtml && !d.isWebKit){ d.isMozilla = d.isMoz = tv; }
+                if(d.isMoz){
+                        //We really need to get away from this. Consider a sane isGecko approach for the future.
+                        d.isFF = parseFloat(dua.split("Firefox/")[1] || dua.split("Minefield/")[1]) || undefined;
+                }
+                if(document.all && !d.isOpera){
+                        d.isIE = parseFloat(dav.split("MSIE ")[1]) || undefined;
+                        //In cases where the page has an HTTP header or META tag with
+                        //X-UA-Compatible, then it is in emulation mode.
+                        //Make sure isIE reflects the desired version.
+                        //document.documentMode of 5 means quirks mode.
+                        //Only switch the value if documentMode's major version
+                        //is different from isIE's major version.
+                        var mode = document.documentMode;
+                        if(mode && mode != 5 && Math.floor(d.isIE) != mode){
+                                d.isIE = mode;
+                        }
+                }
+
+                //Workaround to get local file loads of dojo to work on IE 7
+                //by forcing to not use native xhr.
+                if(dojo.isIE && window.location.protocol === "file:"){
+                        dojo.config.ieForceActiveXXhr=true;
+                }
+                
+                d.isQuirks = document.compatMode == "BackCompat";
+
+                // TODO: is the HTML LANG attribute relevant?
+                d.locale = dojo.config.locale || (d.isIE ? n.userLanguage : n.language).toLowerCase();
+
+                // These are in order of decreasing likelihood; this will change in time.
+                                d._XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'];
+                
+                d._xhrObj = function(){
+                        // summary:
+                        //              does the work of portably generating a new XMLHTTPRequest object.
+                        var http, last_e;
+                                                if(!dojo.isIE || !dojo.config.ieForceActiveXXhr){
+                                                        try{ http = new XMLHttpRequest(); }catch(e){}
+                                                }
+                        if(!http){
+                                for(var i=0; i<3; ++i){
+                                        var progid = d._XMLHTTP_PROGIDS[i];
+                                        try{
+                                                http = new ActiveXObject(progid);
+                                        }catch(e){
+                                                last_e = e;
+                                        }
+
+                                        if(http){
+                                                d._XMLHTTP_PROGIDS = [progid];  // so faster next time
+                                                break;
+                                        }
+                                }
+                        }
+                        
+                        if(!http){
+                                throw new Error("XMLHTTP not available: "+last_e);
+                        }
+
+                        return http; // XMLHTTPRequest instance
+                }
+
+                d._isDocumentOk = function(http){
+                        var stat = http.status || 0,
+                                lp = location.protocol;
+                        return (stat >= 200 && stat < 300) ||   // Boolean
+                                stat == 304 ||                  // allow any 2XX response code
+                                stat == 1223 ||                 // get it out of the cache
+                                                                // Internet Explorer mangled the status code
+                                // Internet Explorer mangled the status code OR we're Titanium/browser chrome/chrome extension requesting a local file
+                                (!stat && (lp == "file:" || lp == "chrome:" || lp == "chrome-extension:" || lp == "app:"));
+                }
+
+                //See if base tag is in use.
+                //This is to fix http://trac.dojotoolkit.org/ticket/3973,
+                //but really, we need to find out how to get rid of the dojo._Url reference
+                //below and still have DOH work with the dojo.i18n test following some other
+                //test that uses the test frame to load a document (trac #2757).
+                //Opera still has problems, but perhaps a larger issue of base tag support
+                //with XHR requests (hasBase is true, but the request is still made to document
+                //path, not base path).
+                var owloc = window.location+"";
+                var base = document.getElementsByTagName("base");
+                var hasBase = (base && base.length > 0);
+
+                d._getText = function(/*URI*/ uri, /*Boolean*/ fail_ok){
+                        // summary: Read the contents of the specified uri and return those contents.
+                        // uri:
+                        //              A relative or absolute uri. If absolute, it still must be in
+                        //              the same "domain" as we are.
+                        // fail_ok:
+                        //              Default false. If fail_ok and loading fails, return null
+                        //              instead of throwing.
+                        // returns: The response text. null is returned when there is a
+                        //              failure and failure is okay (an exception otherwise)
+
+                        // NOTE: must be declared before scope switches ie. this._xhrObj()
+                        var http = d._xhrObj();
+
+                        if(!hasBase && dojo._Url){
+                                uri = (new dojo._Url(owloc, uri)).toString();
+                        }
+
+                        if(d.config.cacheBust){
+                                //Make sure we have a string before string methods are used on uri
+                                uri += "";
+                                uri += (uri.indexOf("?") == -1 ? "?" : "&") + String(d.config.cacheBust).replace(/\W+/g,"");
+                        }
+
+                        http.open('GET', uri, false);
+                        try{
+                                http.send(null);
+                                if(!d._isDocumentOk(http)){
+                                        var err = Error("Unable to load "+uri+" status:"+ http.status);
+                                        err.status = http.status;
+                                        err.responseText = http.responseText;
+                                        throw err;
+                                }
+                        }catch(e){
+                                if(fail_ok){ return null; } // null
+                                // rethrow the exception
+                                throw e;
+                        }
+                        return http.responseText; // String
+                }
+                
+
+                var _w = window;
+                var _handleNodeEvent = function(/*String*/evtName, /*Function*/fp){
+                        // summary:
+                        //              non-destructively adds the specified function to the node's
+                        //              evtName handler.
+                        // evtName: should be in the form "onclick" for "onclick" handlers.
+                        // Make sure you pass in the "on" part.
+                        var _a = _w.attachEvent || _w.addEventListener;
+                        evtName = _w.attachEvent ? evtName : evtName.substring(2);
+                        _a(evtName, function(){
+                                fp.apply(_w, arguments);
+                        }, false);
+                };
+
+
+                d._windowUnloaders = [];
+                
+                d.windowUnloaded = function(){
+                        // summary:
+                        //              signal fired by impending window destruction. You may use
+                        //              dojo.addOnWindowUnload() to register a listener for this
+                        //              event. NOTE: if you wish to dojo.connect() to this method
+                        //              to perform page/application cleanup, be aware that this
+                        //              event WILL NOT fire if no handler has been registered with
+                        //              dojo.addOnWindowUnload. This behavior started in Dojo 1.3.
+                        //              Previous versions always triggered dojo.windowUnloaded. See
+                        //              dojo.addOnWindowUnload for more info.
+                        var mll = d._windowUnloaders;
+                        while(mll.length){
+                                (mll.pop())();
+                        }
+                        d = null;
+                };
+
+                var _onWindowUnloadAttached = 0;
+                d.addOnWindowUnload = function(/*Object?|Function?*/obj, /*String|Function?*/functionName){
+                        // summary:
+                        //              registers a function to be triggered when window.onunload
+                        //              fires.
+                        //      description:
+                        //              The first time that addOnWindowUnload is called Dojo
+                        //              will register a page listener to trigger your unload
+                        //              handler with. Note that registering these handlers may
+                        //              destory "fastback" page caching in browsers that support
+                        //              it. Be careful trying to modify the DOM or access
+                        //              JavaScript properties during this phase of page unloading:
+                        //              they may not always be available. Consider
+                        //              dojo.addOnUnload() if you need to modify the DOM or do
+                        //              heavy JavaScript work since it fires at the eqivalent of
+                        //              the page's "onbeforeunload" event.
+                        // example:
+                        //      |       dojo.addOnWindowUnload(functionPointer)
+                        //      |       dojo.addOnWindowUnload(object, "functionName");
+                        //      |       dojo.addOnWindowUnload(object, function(){ /* ... */});
+
+                        d._onto(d._windowUnloaders, obj, functionName);
+                        if(!_onWindowUnloadAttached){
+                                _onWindowUnloadAttached = 1;
+                                _handleNodeEvent("onunload", d.windowUnloaded);
+                        }
+                };
+
+                var _onUnloadAttached = 0;
+                d.addOnUnload = function(/*Object?|Function?*/obj, /*String|Function?*/functionName){
+                        // summary:
+                        //              registers a function to be triggered when the page unloads.
+                        //      description:
+                        //              The first time that addOnUnload is called Dojo will
+                        //              register a page listener to trigger your unload handler
+                        //              with.
+                        //
+                        //              In a browser enviroment, the functions will be triggered
+                        //              during the window.onbeforeunload event. Be careful of doing
+                        //              too much work in an unload handler. onbeforeunload can be
+                        //              triggered if a link to download a file is clicked, or if
+                        //              the link is a javascript: link. In these cases, the
+                        //              onbeforeunload event fires, but the document is not
+                        //              actually destroyed. So be careful about doing destructive
+                        //              operations in a dojo.addOnUnload callback.
+                        //
+                        //              Further note that calling dojo.addOnUnload will prevent
+                        //              browsers from using a "fast back" cache to make page
+                        //              loading via back button instantaneous.
+                        // example:
+                        //      |       dojo.addOnUnload(functionPointer)
+                        //      |       dojo.addOnUnload(object, "functionName")
+                        //      |       dojo.addOnUnload(object, function(){ /* ... */});
+
+                        d._onto(d._unloaders, obj, functionName);
+                        if(!_onUnloadAttached){
+                                _onUnloadAttached = 1;
+                                _handleNodeEvent("onbeforeunload", dojo.unloaded);
+                        }
+                };
+
+        })();
+
+        //START DOMContentLoaded
+        dojo._initFired = false;
+        dojo._loadInit = function(e){
+                if(dojo._scrollIntervalId){
+                        clearInterval(dojo._scrollIntervalId);
+                        dojo._scrollIntervalId = 0;
+                }
+
+                if(!dojo._initFired){
+                        dojo._initFired = true;
+
+                        //Help out IE to avoid memory leak.
+                        if(!dojo.config.afterOnLoad && window.detachEvent){
+                                window.detachEvent("onload", dojo._loadInit);
+                        }
+
+                        if(dojo._inFlightCount == 0){
+                                dojo._modulesLoaded();
+                        }
+                }
+        }
+
+        if(!dojo.config.afterOnLoad){
+                if(document.addEventListener){
+                        //Standards. Hooray! Assumption here that if standards based,
+                        //it knows about DOMContentLoaded. It is OK if it does not, the fall through
+                        //to window onload should be good enough.
+                        document.addEventListener("DOMContentLoaded", dojo._loadInit, false);
+                        window.addEventListener("load", dojo._loadInit, false);
+                }else if(window.attachEvent){
+                        window.attachEvent("onload", dojo._loadInit);
+
+                        //DOMContentLoaded approximation. Diego Perini found this MSDN article
+                        //that indicates doScroll is available after DOM ready, so do a setTimeout
+                        //to check when it is available.
+                        //http://msdn.microsoft.com/en-us/library/ms531426.aspx
+                        if(!dojo.config.skipIeDomLoaded && self === self.top){
+                                dojo._scrollIntervalId = setInterval(function (){
+                                        try{
+                                                //When dojo is loaded into an iframe in an IE HTML Application
+                                                //(HTA), such as in a selenium test, javascript in the iframe
+                                                //can't see anything outside of it, so self===self.top is true,
+                                                //but the iframe is not the top window and doScroll will be
+                                                //available before document.body is set. Test document.body
+                                                //before trying the doScroll trick
+                                                if(document.body){
+                                                        document.documentElement.doScroll("left");
+                                                        dojo._loadInit();
+                                                }
+                                        }catch (e){}
+                                }, 30);
+                        }
+                }
+        }
+
+                if(dojo.isIE){
+                try{
+                        (function(){
+                                document.namespaces.add("v", "urn:schemas-microsoft-com:vml");
+                                var vmlElems = ["*", "group", "roundrect", "oval", "shape", "rect", "imagedata", "path", "textpath", "text"],
+                                        i = 0, l = 1, s = document.createStyleSheet();
+                                if(dojo.isIE >= 8){
+                                        i = 1;
+                                        l = vmlElems.length;
+                                }
+                                for(; i < l; ++i){
+                                        s.addRule("v\\:" + vmlElems[i], "behavior:url(#default#VML); display:inline-block");
+                                }
+                        })();
+                }catch(e){}
+        }
+                //END DOMContentLoaded
+
+
+        /*
+        OpenAjax.subscribe("OpenAjax", "onload", function(){
+                if(dojo._inFlightCount == 0){
+                        dojo._modulesLoaded();
+                }
+        });
+
+        OpenAjax.subscribe("OpenAjax", "onunload", function(){
+                dojo.unloaded();
+        });
+        */
+} //if (typeof window != 'undefined')
+
+//Register any module paths set up in djConfig. Need to do this
+//in the hostenvs since hostenv_browser can read djConfig from a
+//script tag's attribute.
+(function(){
+        var mp = dojo.config["modulePaths"];
+        if(mp){
+                for(var param in mp){
+                        dojo.registerModulePath(param, mp[param]);
+                }
+        }
+})();
+
+//Load debug code if necessary.
+if(dojo.config.isDebug){
+        dojo.require("dojo._firebug.firebug");
+}
+
+if(dojo.config.debugAtAllCosts){
+        // this breaks the new AMD based module loader. The XDomain won't be necessary
+        // anyway if you switch to the asynchronous loader
+        //dojo.config.useXDomain = true;
+        //dojo.require("dojo._base._loader.loader_xd");
+        dojo.require("dojo._base._loader.loader_debug");
+        dojo.require("dojo.i18n");
+}
+
+
+if(!dojo._hasResource["dojo._base.lang"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base.lang"] = true;
+dojo.provide("dojo._base.lang");
+
+
+(function(){
+        var d = dojo, opts = Object.prototype.toString;
+
+        // Crockford (ish) functions
+
+        dojo.isString = function(/*anything*/ it){
+                //      summary:
+                //              Return true if it is a String
+                return (typeof it == "string" || it instanceof String); // Boolean
+        };
+
+        dojo.isArray = function(/*anything*/ it){
+                //      summary:
+                //              Return true if it is an Array.
+                //              Does not work on Arrays created in other windows.
+                return it && (it instanceof Array || typeof it == "array"); // Boolean
+        };
+
+        dojo.isFunction = function(/*anything*/ it){
+                // summary:
+                //              Return true if it is a Function
+                return opts.call(it) === "[object Function]";
+        };
+
+        dojo.isObject = function(/*anything*/ it){
+                // summary:
+                //              Returns true if it is a JavaScript object (or an Array, a Function
+                //              or null)
+                return it !== undefined &&
+                        (it === null || typeof it == "object" || d.isArray(it) || d.isFunction(it)); // Boolean
+        };
+
+        dojo.isArrayLike = function(/*anything*/ it){
+                //      summary:
+                //              similar to dojo.isArray() but more permissive
+                //      description:
+                //              Doesn't strongly test for "arrayness".  Instead, settles for "isn't
+                //              a string or number and has a length property". Arguments objects
+                //              and DOM collections will return true when passed to
+                //              dojo.isArrayLike(), but will return false when passed to
+                //              dojo.isArray().
+                //      returns:
+                //              If it walks like a duck and quacks like a duck, return `true`
+                return it && it !== undefined && // Boolean
+                        // keep out built-in constructors (Number, String, ...) which have length
+                        // properties
+                        !d.isString(it) && !d.isFunction(it) &&
+                        !(it.tagName && it.tagName.toLowerCase() == 'form') &&
+                        (d.isArray(it) || isFinite(it.length));
+        };
+
+        dojo.isAlien = function(/*anything*/ it){
+                // summary:
+                //              Returns true if it is a built-in function or some other kind of
+                //              oddball that *should* report as a function but doesn't
+                return it && !d.isFunction(it) && /\{\s*\[native code\]\s*\}/.test(String(it)); // Boolean
+        };
+
+        dojo.extend = function(/*Object*/ constructor, /*Object...*/ props){
+                // summary:
+                //              Adds all properties and methods of props to constructor's
+                //              prototype, making them available to all instances created with
+                //              constructor.
+                for(var i=1, l=arguments.length; i<l; i++){
+                        d._mixin(constructor.prototype, arguments[i]);
+                }
+                return constructor; // Object
+        };
+
+        dojo._hitchArgs = function(scope, method /*,...*/){
+                var pre = d._toArray(arguments, 2);
+                var named = d.isString(method);
+                return function(){
+                        // arrayify arguments
+                        var args = d._toArray(arguments);
+                        // locate our method
+                        var f = named ? (scope||d.global)[method] : method;
+                        // invoke with collected args
+                        return f && f.apply(scope || this, pre.concat(args)); // mixed
+                }; // Function
+        };
+
+        dojo.hitch = function(/*Object*/scope, /*Function|String*/method /*,...*/){
+                //      summary:
+                //              Returns a function that will only ever execute in the a given scope.
+                //              This allows for easy use of object member functions
+                //              in callbacks and other places in which the "this" keyword may
+                //              otherwise not reference the expected scope.
+                //              Any number of default positional arguments may be passed as parameters
+                //              beyond "method".
+                //              Each of these values will be used to "placehold" (similar to curry)
+                //              for the hitched function.
+                //      scope:
+                //              The scope to use when method executes. If method is a string,
+                //              scope is also the object containing method.
+                //      method:
+                //              A function to be hitched to scope, or the name of the method in
+                //              scope to be hitched.
+                //      example:
+                //      |       dojo.hitch(foo, "bar")();
+                //              runs foo.bar() in the scope of foo
+                //      example:
+                //      |       dojo.hitch(foo, myFunction);
+                //              returns a function that runs myFunction in the scope of foo
+                //      example:
+                //              Expansion on the default positional arguments passed along from
+                //              hitch. Passed args are mixed first, additional args after.
+                //      |       var foo = { bar: function(a, b, c){ console.log(a, b, c); } };
+                //      |       var fn = dojo.hitch(foo, "bar", 1, 2);
+                //      |       fn(3); // logs "1, 2, 3"
+                //      example:
+                //      |       var foo = { bar: 2 };
+                //      |       dojo.hitch(foo, function(){ this.bar = 10; })();
+                //              execute an anonymous function in scope of foo
+                
+                if(arguments.length > 2){
+                        return d._hitchArgs.apply(d, arguments); // Function
+                }
+                if(!method){
+                        method = scope;
+                        scope = null;
+                }
+                if(d.isString(method)){
+                        scope = scope || d.global;
+                        if(!scope[method]){ throw(['dojo.hitch: scope["', method, '"] is null (scope="', scope, '")'].join('')); }
+                        return function(){ return scope[method].apply(scope, arguments || []); }; // Function
+                }
+                return !scope ? method : function(){ return method.apply(scope, arguments || []); }; // Function
+        };
+
+        /*=====
+        dojo.delegate = function(obj, props){
+                //      summary:
+                //              Returns a new object which "looks" to obj for properties which it
+                //              does not have a value for. Optionally takes a bag of properties to
+                //              seed the returned object with initially.
+                //      description:
+                //              This is a small implementaton of the Boodman/Crockford delegation
+                //              pattern in JavaScript. An intermediate object constructor mediates
+                //              the prototype chain for the returned object, using it to delegate
+                //              down to obj for property lookup when object-local lookup fails.
+                //              This can be thought of similarly to ES4's "wrap", save that it does
+                //              not act on types but rather on pure objects.
+                //      obj:
+                //              The object to delegate to for properties not found directly on the
+                //              return object or in props.
+                //      props:
+                //              an object containing properties to assign to the returned object
+                //      returns:
+                //              an Object of anonymous type
+                //      example:
+                //      |       var foo = { bar: "baz" };
+                //      |       var thinger = dojo.delegate(foo, { thud: "xyzzy"});
+                //      |       thinger.bar == "baz"; // delegated to foo
+                //      |       foo.thud == undefined; // by definition
+                //      |       thinger.thud == "xyzzy"; // mixed in from props
+                //      |       foo.bar = "thonk";
+                //      |       thinger.bar == "thonk"; // still delegated to foo's bar
+        }
+        =====*/
+
+        dojo.delegate = dojo._delegate = (function(){
+                // boodman/crockford delegation w/ cornford optimization
+                function TMP(){}
+                return function(obj, props){
+                        TMP.prototype = obj;
+                        var tmp = new TMP();
+                        TMP.prototype = null;
+                        if(props){
+                                d._mixin(tmp, props);
+                        }
+                        return tmp; // Object
+                };
+        })();
+
+        /*=====
+        dojo._toArray = function(obj, offset, startWith){
+                //      summary:
+                //              Converts an array-like object (i.e. arguments, DOMCollection) to an
+                //              array. Returns a new Array with the elements of obj.
+                //      obj: Object
+                //              the object to "arrayify". We expect the object to have, at a
+                //              minimum, a length property which corresponds to integer-indexed
+                //              properties.
+                //      offset: Number?
+                //              the location in obj to start iterating from. Defaults to 0.
+                //              Optional.
+                //      startWith: Array?
+                //              An array to pack with the properties of obj. If provided,
+                //              properties in obj are appended at the end of startWith and
+                //              startWith is the returned array.
+        }
+        =====*/
+
+        var efficient = function(obj, offset, startWith){
+                return (startWith||[]).concat(Array.prototype.slice.call(obj, offset||0));
+        };
+
+                var slow = function(obj, offset, startWith){
+                var arr = startWith||[];
+                for(var x = offset || 0; x < obj.length; x++){
+                        arr.push(obj[x]);
+                }
+                return arr;
+        };
+        
+        dojo._toArray =
+                                d.isIE ?  function(obj){
+                        return ((obj.item) ? slow : efficient).apply(this, arguments);
+                } :
+                                efficient;
+
+        dojo.partial = function(/*Function|String*/method /*, ...*/){
+                //      summary:
+                //              similar to hitch() except that the scope object is left to be
+                //              whatever the execution context eventually becomes.
+                //      description:
+                //              Calling dojo.partial is the functional equivalent of calling:
+                //              |       dojo.hitch(null, funcName, ...);
+                var arr = [ null ];
+                return d.hitch.apply(d, arr.concat(d._toArray(arguments))); // Function
+        };
+
+        var extraNames = d._extraNames, extraLen = extraNames.length, empty = {};
+
+        dojo.clone = function(/*anything*/ o){
+                // summary:
+                //              Clones objects (including DOM nodes) and all children.
+                //              Warning: do not clone cyclic structures.
+                if(!o || typeof o != "object" || d.isFunction(o)){
+                        // null, undefined, any non-object, or function
+                        return o;       // anything
+                }
+                if(o.nodeType && "cloneNode" in o){
+                        // DOM Node
+                        return o.cloneNode(true); // Node
+                }
+                if(o instanceof Date){
+                        // Date
+                        return new Date(o.getTime());   // Date
+                }
+                if(o instanceof RegExp){
+                        // RegExp
+                        return new RegExp(o);   // RegExp
+                }
+                var r, i, l, s, name;
+                if(d.isArray(o)){
+                        // array
+                        r = [];
+                        for(i = 0, l = o.length; i < l; ++i){
+                                if(i in o){
+                                        r.push(d.clone(o[i]));
+                                }
+                        }
+// we don't clone functions for performance reasons
+//              }else if(d.isFunction(o)){
+//                      // function
+//                      r = function(){ return o.apply(this, arguments); };
+                }else{
+                        // generic objects
+                        r = o.constructor ? new o.constructor() : {};
+                }
+                for(name in o){
+                        // the "tobj" condition avoid copying properties in "source"
+                        // inherited from Object.prototype.  For example, if target has a custom
+                        // toString() method, don't overwrite it with the toString() method
+                        // that source inherited from Object.prototype
+                        s = o[name];
+                        if(!(name in r) || (r[name] !== s && (!(name in empty) || empty[name] !== s))){
+                                r[name] = d.clone(s);
+                        }
+                }
+                                // IE doesn't recognize some custom functions in for..in
+                if(extraLen){
+                        for(i = 0; i < extraLen; ++i){
+                                name = extraNames[i];
+                                s = o[name];
+                                if(!(name in r) || (r[name] !== s && (!(name in empty) || empty[name] !== s))){
+                                        r[name] = s; // functions only, we don't clone them
+                                }
+                        }
+                }
+                                return r; // Object
+        };
+
+        /*=====
+        dojo.trim = function(str){
+                //      summary:
+                //              Trims whitespace from both sides of the string
+                //      str: String
+                //              String to be trimmed
+                //      returns: String
+                //              Returns the trimmed string
+                //      description:
+                //              This version of trim() was selected for inclusion into the base due
+                //              to its compact size and relatively good performance
+                //              (see [Steven Levithan's blog](http://blog.stevenlevithan.com/archives/faster-trim-javascript)
+                //              Uses String.prototype.trim instead, if available.
+                //              The fastest but longest version of this function is located at
+                //              dojo.string.trim()
+                return "";      // String
+        }
+        =====*/
+
+        dojo.trim = String.prototype.trim ?
+                function(str){ return str.trim(); } :
+                function(str){ return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); };
+
+        /*=====
+        dojo.replace = function(tmpl, map, pattern){
+                //      summary:
+                //              Performs parameterized substitutions on a string. Throws an
+                //              exception if any parameter is unmatched.
+                //      tmpl: String
+                //              String to be used as a template.
+                //      map: Object|Function
+                //              If an object, it is used as a dictionary to look up substitutions.
+                //              If a function, it is called for every substitution with following
+                //              parameters: a whole match, a name, an offset, and the whole template
+                //              string (see https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/replace
+                //              for more details).
+                //      pattern: RegEx?
+                //              Optional regular expression objects that overrides the default pattern.
+                //              Must be global and match one item. The default is: /\{([^\}]+)\}/g,
+                //              which matches patterns like that: "{xxx}", where "xxx" is any sequence
+                //              of characters, which doesn't include "}".
+                //      returns: String
+                //              Returns the substituted string.
+                //      example:
+                //      |       // uses a dictionary for substitutions:
+                //      |       dojo.replace("Hello, {name.first} {name.last} AKA {nick}!",
+                //      |         {
+                //      |           nick: "Bob",
+                //      |           name: {
+                //      |             first:  "Robert",
+                //      |             middle: "X",
+                //      |             last:   "Cringely"
+                //      |           }
+                //      |         });
+                //      |       // returns: Hello, Robert Cringely AKA Bob!
+                //      example:
+                //      |       // uses an array for substitutions:
+                //      |       dojo.replace("Hello, {0} {2}!",
+                //      |         ["Robert", "X", "Cringely"]);
+                //      |       // returns: Hello, Robert Cringely!
+                //      example:
+                //      |       // uses a function for substitutions:
+                //      |       function sum(a){
+                //      |         var t = 0;
+                //      |         dojo.forEach(a, function(x){ t += x; });
+                //      |         return t;
+                //      |       }
+                //      |       dojo.replace(
+                //      |         "{count} payments averaging {avg} USD per payment.",
+                //      |         dojo.hitch(
+                //      |           { payments: [11, 16, 12] },
+                //      |           function(_, key){
+                //      |             switch(key){
+                //      |               case "count": return this.payments.length;
+                //      |               case "min":   return Math.min.apply(Math, this.payments);
+                //      |               case "max":   return Math.max.apply(Math, this.payments);
+                //      |               case "sum":   return sum(this.payments);
+                //      |               case "avg":   return sum(this.payments) / this.payments.length;
+                //      |             }
+                //      |           }
+                //      |         )
+                //      |       );
+                //      |       // prints: 3 payments averaging 13 USD per payment.
+                //      example:
+                //      |       // uses an alternative PHP-like pattern for substitutions:
+                //      |       dojo.replace("Hello, ${0} ${2}!",
+                //      |         ["Robert", "X", "Cringely"], /\$\{([^\}]+)\}/g);
+                //      |       // returns: Hello, Robert Cringely!
+                return "";      // String
+        }
+        =====*/
+
+        var _pattern = /\{([^\}]+)\}/g;
+        dojo.replace = function(tmpl, map, pattern){
+                return tmpl.replace(pattern || _pattern, d.isFunction(map) ?
+                        map : function(_, k){ return d.getObject(k, false, map); });
+        };
+})();
+
+}
+
+if(!dojo._hasResource["dojo._base.array"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base.array"] = true;
+dojo.provide("dojo._base.array");
+
+
+
+(function(){
+        var _getParts = function(arr, obj, cb){
+                return [
+                        (typeof arr == "string") ? arr.split("") : arr,
+                        obj || dojo.global,
+                        // FIXME: cache the anonymous functions we create here?
+                        (typeof cb == "string") ? new Function("item", "index", "array", cb) : cb
+                ];
+        };
+
+        var everyOrSome = function(/*Boolean*/every, /*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
+                var _p = _getParts(arr, thisObject, callback); arr = _p[0];
+                for(var i=0,l=arr.length; i<l; ++i){
+                        var result = !!_p[2].call(_p[1], arr[i], i, arr);
+                        if(every ^ result){
+                                return result; // Boolean
+                        }
+                }
+                return every; // Boolean
+        };
+
+        dojo.mixin(dojo, {
+                indexOf: function(      /*Array*/               array,
+                                                        /*Object*/              value,
+                                                        /*Integer?*/    fromIndex,
+                                                        /*Boolean?*/    findLast){
+                        // summary:
+                        //              locates the first index of the provided value in the
+                        //              passed array. If the value is not found, -1 is returned.
+                        // description:
+                        //              This method corresponds to the JavaScript 1.6 Array.indexOf method, with one difference: when
+                        //              run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript
+                        //              1.6's indexOf skips the holes in the sparse array.
+                        //              For details on this method, see:
+                        //                      https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/indexOf
+
+                        var step = 1, end = array.length || 0, i = 0;
+                        if(findLast){
+                                i = end - 1;
+                                step = end = -1;
+                        }
+                        if(fromIndex != undefined){ i = fromIndex; }
+                        if((findLast && i > end) || i < end){
+                                for(; i != end; i += step){
+                                        if(array[i] == value){ return i; }
+                                }
+                        }
+                        return -1;      // Number
+                },
+
+                lastIndexOf: function(/*Array*/array, /*Object*/value, /*Integer?*/fromIndex){
+                        // summary:
+                        //              locates the last index of the provided value in the passed
+                        //              array. If the value is not found, -1 is returned.
+                        // description:
+                        //              This method corresponds to the JavaScript 1.6 Array.lastIndexOf method, with one difference: when
+                        //              run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript
+                        //              1.6's lastIndexOf skips the holes in the sparse array.
+                        //              For details on this method, see:
+                        //                      https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/lastIndexOf
+                        return dojo.indexOf(array, value, fromIndex, true); // Number
+                },
+
+                forEach: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
+                        //      summary:
+                        //              for every item in arr, callback is invoked. Return values are ignored.
+                        //              If you want to break out of the loop, consider using dojo.every() or dojo.some().
+                        //              forEach does not allow breaking out of the loop over the items in arr.
+                        //      arr:
+                        //              the array to iterate over. If a string, operates on individual characters.
+                        //      callback:
+                        //              a function is invoked with three arguments: item, index, and array
+                        //      thisObject:
+                        //              may be used to scope the call to callback
+                        //      description:
+                        //              This function corresponds to the JavaScript 1.6 Array.forEach() method, with one difference: when
+                        //              run over sparse arrays, this implemenation passes the "holes" in the sparse array to
+                        //              the callback function with a value of undefined. JavaScript 1.6's forEach skips the holes in the sparse array.
+                        //              For more details, see:
+                        //                      https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/forEach
+                        //      example:
+                        //      |       // log out all members of the array:
+                        //      |       dojo.forEach(
+                        //      |               [ "thinger", "blah", "howdy", 10 ],
+                        //      |               function(item){
+                        //      |                       console.log(item);
+                        //      |               }
+                        //      |       );
+                        //      example:
+                        //      |       // log out the members and their indexes
+                        //      |       dojo.forEach(
+                        //      |               [ "thinger", "blah", "howdy", 10 ],
+                        //      |               function(item, idx, arr){
+                        //      |                       console.log(item, "at index:", idx);
+                        //      |               }
+                        //      |       );
+                        //      example:
+                        //      |       // use a scoped object member as the callback
+                        //      |
+                        //      |       var obj = {
+                        //      |               prefix: "logged via obj.callback:",
+                        //      |               callback: function(item){
+                        //      |                       console.log(this.prefix, item);
+                        //      |               }
+                        //      |       };
+                        //      |
+                        //      |       // specifying the scope function executes the callback in that scope
+                        //      |       dojo.forEach(
+                        //      |               [ "thinger", "blah", "howdy", 10 ],
+                        //      |               obj.callback,
+                        //      |               obj
+                        //      |       );
+                        //      |
+                        //      |       // alternately, we can accomplish the same thing with dojo.hitch()
+                        //      |       dojo.forEach(
+                        //      |               [ "thinger", "blah", "howdy", 10 ],
+                        //      |               dojo.hitch(obj, "callback")
+                        //      |       );
+
+                        // match the behavior of the built-in forEach WRT empty arrs
+                        if(!arr || !arr.length){ return; }
+
+                        // FIXME: there are several ways of handilng thisObject. Is
+                        // dojo.global always the default context?
+                        var _p = _getParts(arr, thisObject, callback); arr = _p[0];
+                        for(var i=0,l=arr.length; i<l; ++i){
+                                _p[2].call(_p[1], arr[i], i, arr);
+                        }
+                },
+
+                every: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
+                        // summary:
+                        //              Determines whether or not every item in arr satisfies the
+                        //              condition implemented by callback.
+                        // arr:
+                        //              the array to iterate on. If a string, operates on individual characters.
+                        // callback:
+                        //              a function is invoked with three arguments: item, index,
+                        //              and array and returns true if the condition is met.
+                        // thisObject:
+                        //              may be used to scope the call to callback
+                        // description:
+                        //              This function corresponds to the JavaScript 1.6 Array.every() method, with one difference: when
+                        //              run over sparse arrays, this implemenation passes the "holes" in the sparse array to
+                        //              the callback function with a value of undefined. JavaScript 1.6's every skips the holes in the sparse array.
+                        //              For more details, see:
+                        //                      https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/every
+                        // example:
+                        //      |       // returns false
+                        //      |       dojo.every([1, 2, 3, 4], function(item){ return item>1; });
+                        // example:
+                        //      |       // returns true
+                        //      |       dojo.every([1, 2, 3, 4], function(item){ return item>0; });
+                        return everyOrSome(true, arr, callback, thisObject); // Boolean
+                },
+
+                some: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
+                        // summary:
+                        //              Determines whether or not any item in arr satisfies the
+                        //              condition implemented by callback.
+                        // arr:
+                        //              the array to iterate over. If a string, operates on individual characters.
+                        // callback:
+                        //              a function is invoked with three arguments: item, index,
+                        //              and array and returns true if the condition is met.
+                        // thisObject:
+                        //              may be used to scope the call to callback
+                        // description:
+                        //              This function corresponds to the JavaScript 1.6 Array.some() method, with one difference: when
+                        //              run over sparse arrays, this implemenation passes the "holes" in the sparse array to
+                        //              the callback function with a value of undefined. JavaScript 1.6's some skips the holes in the sparse array.
+                        //              For more details, see:
+                        //                      https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/some
+                        // example:
+                        //      |       // is true
+                        //      |       dojo.some([1, 2, 3, 4], function(item){ return item>1; });
+                        // example:
+                        //      |       // is false
+                        //      |       dojo.some([1, 2, 3, 4], function(item){ return item<1; });
+                        return everyOrSome(false, arr, callback, thisObject); // Boolean
+                },
+
+                map: function(/*Array|String*/arr, /*Function|String*/callback, /*Function?*/thisObject){
+                        // summary:
+                        //              applies callback to each element of arr and returns
+                        //              an Array with the results
+                        // arr:
+                        //              the array to iterate on. If a string, operates on
+                        //              individual characters.
+                        // callback:
+                        //              a function is invoked with three arguments, (item, index,
+                        //              array),  and returns a value
+                        // thisObject:
+                        //              may be used to scope the call to callback
+                        // description:
+                        //              This function corresponds to the JavaScript 1.6 Array.map() method, with one difference: when
+                        //              run over sparse arrays, this implemenation passes the "holes" in the sparse array to
+                        //              the callback function with a value of undefined. JavaScript 1.6's map skips the holes in the sparse array.
+                        //              For more details, see:
+                        //                      https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
+                        // example:
+                        //      |       // returns [2, 3, 4, 5]
+                        //      |       dojo.map([1, 2, 3, 4], function(item){ return item+1 });
+
+                        var _p = _getParts(arr, thisObject, callback); arr = _p[0];
+                        var outArr = (arguments[3] ? (new arguments[3]()) : []);
+                        for(var i=0,l=arr.length; i<l; ++i){
+                                outArr.push(_p[2].call(_p[1], arr[i], i, arr));
+                        }
+                        return outArr; // Array
+                },
+
+                filter: function(/*Array*/arr, /*Function|String*/callback, /*Object?*/thisObject){
+                        // summary:
+                        //              Returns a new Array with those items from arr that match the
+                        //              condition implemented by callback.
+                        // arr:
+                        //              the array to iterate over.
+                        // callback:
+                        //              a function that is invoked with three arguments (item,
+                        //              index, array). The return of this function is expected to
+                        //              be a boolean which determines whether the passed-in item
+                        //              will be included in the returned array.
+                        // thisObject:
+                        //              may be used to scope the call to callback
+                        // description:
+                        //              This function corresponds to the JavaScript 1.6 Array.filter() method, with one difference: when
+                        //              run over sparse arrays, this implemenation passes the "holes" in the sparse array to
+                        //              the callback function with a value of undefined. JavaScript 1.6's filter skips the holes in the sparse array.
+                        //              For more details, see:
+                        //                      https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
+                        // example:
+                        //      |       // returns [2, 3, 4]
+                        //      |       dojo.filter([1, 2, 3, 4], function(item){ return item>1; });
+
+                        var _p = _getParts(arr, thisObject, callback); arr = _p[0];
+                        var outArr = [];
+                        for(var i=0,l=arr.length; i<l; ++i){
+                                if(_p[2].call(_p[1], arr[i], i, arr)){
+                                        outArr.push(arr[i]);
+                                }
+                        }
+                        return outArr; // Array
+                }
+        });
+})();
+/*
+*/
+
+}
+
+if(!dojo._hasResource["dojo._base.declare"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base.declare"] = true;
+dojo.provide("dojo._base.declare");
+
+
+
+
+(function(){
+        var d = dojo, mix = d._mixin, op = Object.prototype, opts = op.toString,
+                xtor = new Function, counter = 0, cname = "constructor";
+
+        function err(msg, cls){ throw new Error("declare" + (cls ? " " + cls : "") + ": " + msg); }
+
+        // C3 Method Resolution Order (see http://www.python.org/download/releases/2.3/mro/)
+        function c3mro(bases, className){
+                var result = [], roots = [{cls: 0, refs: []}], nameMap = {}, clsCount = 1,
+                        l = bases.length, i = 0, j, lin, base, top, proto, rec, name, refs;
+
+                // build a list of bases naming them if needed
+                for(; i < l; ++i){
+                        base = bases[i];
+                        if(!base){
+                                err("mixin #" + i + " is unknown. Did you use dojo.require to pull it in?", className);
+                        }else if(opts.call(base) != "[object Function]"){
+                                err("mixin #" + i + " is not a callable constructor.", className);
+                        }
+                        lin = base._meta ? base._meta.bases : [base];
+                        top = 0;
+                        // add bases to the name map
+                        for(j = lin.length - 1; j >= 0; --j){
+                                proto = lin[j].prototype;
+                                if(!proto.hasOwnProperty("declaredClass")){
+                                        proto.declaredClass = "uniqName_" + (counter++);
+                                }
+                                name = proto.declaredClass;
+                                if(!nameMap.hasOwnProperty(name)){
+                                        nameMap[name] = {count: 0, refs: [], cls: lin[j]};
+                                        ++clsCount;
+                                }
+                                rec = nameMap[name];
+                                if(top && top !== rec){
+                                        rec.refs.push(top);
+                                        ++top.count;
+                                }
+                                top = rec;
+                        }
+                        ++top.count;
+                        roots[0].refs.push(top);
+                }
+
+                // remove classes without external references recursively
+                while(roots.length){
+                        top = roots.pop();
+                        result.push(top.cls);
+                        --clsCount;
+                        // optimization: follow a single-linked chain
+                        while(refs = top.refs, refs.length == 1){
+                                top = refs[0];
+                                if(!top || --top.count){
+                                        // branch or end of chain => do not end to roots
+                                        top = 0;
+                                        break;
+                                }
+                                result.push(top.cls);
+                                --clsCount;
+                        }
+                        if(top){
+                                // branch
+                                for(i = 0, l = refs.length; i < l; ++i){
+                                        top = refs[i];
+                                        if(!--top.count){
+                                                roots.push(top);
+                                        }
+                                }
+                        }
+                }
+                if(clsCount){
+                        err("can't build consistent linearization", className);
+                }
+
+                // calculate the superclass offset
+                base = bases[0];
+                result[0] = base ?
+                        base._meta && base === result[result.length - base._meta.bases.length] ?
+                                base._meta.bases.length : 1 : 0;
+
+                return result;
+        }
+
+        function inherited(args, a, f){
+                var name, chains, bases, caller, meta, base, proto, opf, pos,
+                        cache = this._inherited = this._inherited || {};
+
+                // crack arguments
+                if(typeof args == "string"){
+                        name = args;
+                        args = a;
+                        a = f;
+                }
+                f = 0;
+
+                caller = args.callee;
+                name = name || caller.nom;
+                if(!name){
+                        err("can't deduce a name to call inherited()", this.declaredClass);
+                }
+
+                meta = this.constructor._meta;
+                bases = meta.bases;
+
+                pos = cache.p;
+                if(name != cname){
+                        // method
+                        if(cache.c !== caller){
+                                // cache bust
+                                pos = 0;
+                                base = bases[0];
+                                meta = base._meta;
+                                if(meta.hidden[name] !== caller){
+                                        // error detection
+                                        chains = meta.chains;
+                                        if(chains && typeof chains[name] == "string"){
+                                                err("calling chained method with inherited: " + name, this.declaredClass);
+                                        }
+                                        // find caller
+                                        do{
+                                                meta = base._meta;
+                                                proto = base.prototype;
+                                                if(meta && (proto[name] === caller && proto.hasOwnProperty(name) || meta.hidden[name] === caller)){
+                                                        break;
+                                                }
+                                        }while(base = bases[++pos]); // intentional assignment
+                                        pos = base ? pos : -1;
+                                }
+                        }
+                        // find next
+                        base = bases[++pos];
+                        if(base){
+                                proto = base.prototype;
+                                if(base._meta && proto.hasOwnProperty(name)){
+                                        f = proto[name];
+                                }else{
+                                        opf = op[name];
+                                        do{
+                                                proto = base.prototype;
+                                                f = proto[name];
+                                                if(f && (base._meta ? proto.hasOwnProperty(name) : f !== opf)){
+                                                        break;
+                                                }
+                                        }while(base = bases[++pos]); // intentional assignment
+                                }
+                        }
+                        f = base && f || op[name];
+                }else{
+                        // constructor
+                        if(cache.c !== caller){
+                                // cache bust
+                                pos = 0;
+                                meta = bases[0]._meta;
+                                if(meta && meta.ctor !== caller){
+                                        // error detection
+                                        chains = meta.chains;
+                                        if(!chains || chains.constructor !== "manual"){
+                                                err("calling chained constructor with inherited", this.declaredClass);
+                                        }
+                                        // find caller
+                                        while(base = bases[++pos]){ // intentional assignment
+                                                meta = base._meta;
+                                                if(meta && meta.ctor === caller){
+                                                        break;
+                                                }
+                                        }
+                                        pos = base ? pos : -1;
+                                }
+                        }
+                        // find next
+                        while(base = bases[++pos]){     // intentional assignment
+                                meta = base._meta;
+                                f = meta ? meta.ctor : base;
+                                if(f){
+                                        break;
+                                }
+                        }
+                        f = base && f;
+                }
+
+                // cache the found super method
+                cache.c = f;
+                cache.p = pos;
+
+                // now we have the result
+                if(f){
+                        return a === true ? f : f.apply(this, a || args);
+                }
+                // intentionally if a super method was not found
+        }
+
+        function getInherited(name, args){
+                if(typeof name == "string"){
+                        return this.inherited(name, args, true);
+                }
+                return this.inherited(name, true);
+        }
+
+        // emulation of "instanceof"
+        function isInstanceOf(cls){
+                var bases = this.constructor._meta.bases;
+                for(var i = 0, l = bases.length; i < l; ++i){
+                        if(bases[i] === cls){
+                                return true;
+                        }
+                }
+                return this instanceof cls;
+        }
+
+        function mixOwn(target, source){
+                var name, i = 0, l = d._extraNames.length;
+                // add props adding metadata for incoming functions skipping a constructor
+                for(name in source){
+                        if(name != cname && source.hasOwnProperty(name)){
+                                target[name] = source[name];
+                        }
+                }
+                // process unenumerable methods on IE
+                for(; i < l; ++i){
+                        name = d._extraNames[i];
+                        if(name != cname && source.hasOwnProperty(name)){
+                                target[name] = source[name];
+                        }
+                }
+        }
+
+        // implementation of safe mixin function
+        function safeMixin(target, source){
+                var name, t, i = 0, l = d._extraNames.length;
+                // add props adding metadata for incoming functions skipping a constructor
+                for(name in source){
+                        t = source[name];
+                        if((t !== op[name] || !(name in op)) && name != cname){
+                                if(opts.call(t) == "[object Function]"){
+                                        // non-trivial function method => attach its name
+                                        t.nom = name;
+                                }
+                                target[name] = t;
+                        }
+                }
+                // process unenumerable methods on IE
+                for(; i < l; ++i){
+                        name = d._extraNames[i];
+                        t = source[name];
+                        if((t !== op[name] || !(name in op)) && name != cname){
+                                if(opts.call(t) == "[object Function]"){
+                                        // non-trivial function method => attach its name
+                                        t.nom = name;
+                                }
+                                target[name] = t;
+                        }
+                }
+                return target;
+        }
+
+        function extend(source){
+                safeMixin(this.prototype, source);
+                return this;
+        }
+
+        // chained constructor compatible with the legacy dojo.declare()
+        function chainedConstructor(bases, ctorSpecial){
+                return function(){
+                        var a = arguments, args = a, a0 = a[0], f, i, m,
+                                l = bases.length, preArgs;
+
+                        if(!(this instanceof a.callee)){
+                                // not called via new, so force it
+                                return applyNew(a);
+                        }
+
+                        //this._inherited = {};
+                        // perform the shaman's rituals of the original dojo.declare()
+                        // 1) call two types of the preamble
+                        if(ctorSpecial && (a0 && a0.preamble || this.preamble)){
+                                // full blown ritual
+                                preArgs = new Array(bases.length);
+                                // prepare parameters
+                                preArgs[0] = a;
+                                for(i = 0;;){
+                                        // process the preamble of the 1st argument
+                                        a0 = a[0];
+                                        if(a0){
+                                                f = a0.preamble;
+                                                if(f){
+                                                        a = f.apply(this, a) || a;
+                                                }
+                                        }
+                                        // process the preamble of this class
+                                        f = bases[i].prototype;
+                                        f = f.hasOwnProperty("preamble") && f.preamble;
+                                        if(f){
+                                                a = f.apply(this, a) || a;
+                                        }
+                                        // one peculiarity of the preamble:
+                                        // it is called if it is not needed,
+                                        // e.g., there is no constructor to call
+                                        // let's watch for the last constructor
+                                        // (see ticket #9795)
+                                        if(++i == l){
+                                                break;
+                                        }
+                                        preArgs[i] = a;
+                                }
+                        }
+                        // 2) call all non-trivial constructors using prepared arguments
+                        for(i = l - 1; i >= 0; --i){
+                                f = bases[i];
+                                m = f._meta;
+                                f = m ? m.ctor : f;
+                                if(f){
+                                        f.apply(this, preArgs ? preArgs[i] : a);
+                                }
+                        }
+                        // 3) continue the original ritual: call the postscript
+                        f = this.postscript;
+                        if(f){
+                                f.apply(this, args);
+                        }
+                };
+        }
+
+
+        // chained constructor compatible with the legacy dojo.declare()
+        function singleConstructor(ctor, ctorSpecial){
+                return function(){
+                        var a = arguments, t = a, a0 = a[0], f;
+
+                        if(!(this instanceof a.callee)){
+                                // not called via new, so force it
+                                return applyNew(a);
+                        }
+
+                        //this._inherited = {};
+                        // perform the shaman's rituals of the original dojo.declare()
+                        // 1) call two types of the preamble
+                        if(ctorSpecial){
+                                // full blown ritual
+                                if(a0){
+                                        // process the preamble of the 1st argument
+                                        f = a0.preamble;
+                                        if(f){
+                                                t = f.apply(this, t) || t;
+                                        }
+                                }
+                                f = this.preamble;
+                                if(f){
+                                        // process the preamble of this class
+                                        f.apply(this, t);
+                                        // one peculiarity of the preamble:
+                                        // it is called even if it is not needed,
+                                        // e.g., there is no constructor to call
+                                        // let's watch for the last constructor
+                                        // (see ticket #9795)
+                                }
+                        }
+                        // 2) call a constructor
+                        if(ctor){
+                                ctor.apply(this, a);
+                        }
+                        // 3) continue the original ritual: call the postscript
+                        f = this.postscript;
+                        if(f){
+                                f.apply(this, a);
+                        }
+                };
+        }
+
+        // plain vanilla constructor (can use inherited() to call its base constructor)
+        function simpleConstructor(bases){
+                return function(){
+                        var a = arguments, i = 0, f, m;
+
+                        if(!(this instanceof a.callee)){
+                                // not called via new, so force it
+                                return applyNew(a);
+                        }
+
+                        //this._inherited = {};
+                        // perform the shaman's rituals of the original dojo.declare()
+                        // 1) do not call the preamble
+                        // 2) call the top constructor (it can use this.inherited())
+                        for(; f = bases[i]; ++i){ // intentional assignment
+                                m = f._meta;
+                                f = m ? m.ctor : f;
+                                if(f){
+                                        f.apply(this, a);
+                                        break;
+                                }
+                        }
+                        // 3) call the postscript
+                        f = this.postscript;
+                        if(f){
+                                f.apply(this, a);
+                        }
+                };
+        }
+
+        function chain(name, bases, reversed){
+                return function(){
+                        var b, m, f, i = 0, step = 1;
+                        if(reversed){
+                                i = bases.length - 1;
+                                step = -1;
+                        }
+                        for(; b = bases[i]; i += step){ // intentional assignment
+                                m = b._meta;
+                                f = (m ? m.hidden : b.prototype)[name];
+                                if(f){
+                                        f.apply(this, arguments);
+                                }
+                        }
+                };
+        }
+
+        // forceNew(ctor)
+        // return a new object that inherits from ctor.prototype but
+        // without actually running ctor on the object.
+        function forceNew(ctor){
+                // create object with correct prototype using a do-nothing
+                // constructor
+                xtor.prototype = ctor.prototype;
+                var t = new xtor;
+                xtor.prototype = null;  // clean up
+                return t;
+        }
+
+        // applyNew(args)
+        // just like 'new ctor()' except that the constructor and its arguments come
+        // from args, which must be an array or an arguments object
+        function applyNew(args){
+                // create an object with ctor's prototype but without
+                // calling ctor on it.
+                var ctor = args.callee, t = forceNew(ctor);
+                // execute the real constructor on the new object
+                ctor.apply(t, args);
+                return t;
+        }
+
+        d.declare = function(className, superclass, props){
+                // crack parameters
+                if(typeof className != "string"){
+                        props = superclass;
+                        superclass = className;
+                        className = "";
+                }
+                props = props || {};
+
+                var proto, i, t, ctor, name, bases, chains, mixins = 1, parents = superclass;
+
+                // build a prototype
+                if(opts.call(superclass) == "[object Array]"){
+                        // C3 MRO
+                        bases = c3mro(superclass, className);
+                        t = bases[0];
+                        mixins = bases.length - t;
+                        superclass = bases[mixins];
+                }else{
+                        bases = [0];
+                        if(superclass){
+                                if(opts.call(superclass) == "[object Function]"){
+                                        t = superclass._meta;
+                                        bases = bases.concat(t ? t.bases : superclass);
+                                }else{
+                                        err("base class is not a callable constructor.", className);
+                                }
+                        }else if(superclass !== null){
+                                err("unknown base class. Did you use dojo.require to pull it in?", className);
+                        }
+                }
+                if(superclass){
+                        for(i = mixins - 1;; --i){
+                                proto = forceNew(superclass);
+                                if(!i){
+                                        // stop if nothing to add (the last base)
+                                        break;
+                                }
+                                // mix in properties
+                                t = bases[i];
+                                (t._meta ? mixOwn : mix)(proto, t.prototype);
+                                // chain in new constructor
+                                ctor = new Function;
+                                ctor.superclass = superclass;
+                                ctor.prototype = proto;
+                                superclass = proto.constructor = ctor;
+                        }
+                }else{
+                        proto = {};
+                }
+                // add all properties
+                safeMixin(proto, props);
+                // add constructor
+                t = props.constructor;
+                if(t !== op.constructor){
+                        t.nom = cname;
+                        proto.constructor = t;
+                }
+
+                // collect chains and flags
+                for(i = mixins - 1; i; --i){ // intentional assignment
+                        t = bases[i]._meta;
+                        if(t && t.chains){
+                                chains = mix(chains || {}, t.chains);
+                        }
+                }
+                if(proto["-chains-"]){
+                        chains = mix(chains || {}, proto["-chains-"]);
+                }
+
+                // build ctor
+                t = !chains || !chains.hasOwnProperty(cname);
+                bases[0] = ctor = (chains && chains.constructor === "manual") ? simpleConstructor(bases) :
+                        (bases.length == 1 ? singleConstructor(props.constructor, t) : chainedConstructor(bases, t));
+
+                // add meta information to the constructor
+                ctor._meta  = {bases: bases, hidden: props, chains: chains,
+                        parents: parents, ctor: props.constructor};
+                ctor.superclass = superclass && superclass.prototype;
+                ctor.extend = extend;
+                ctor.prototype = proto;
+                proto.constructor = ctor;
+
+                // add "standard" methods to the prototype
+                proto.getInherited = getInherited;
+                proto.inherited = inherited;
+                proto.isInstanceOf = isInstanceOf;
+
+                // add name if specified
+                if(className){
+                        proto.declaredClass = className;
+                        d.setObject(className, ctor);
+                }
+
+                // build chains and add them to the prototype
+                if(chains){
+                        for(name in chains){
+                                if(proto[name] && typeof chains[name] == "string" && name != cname){
+                                        t = proto[name] = chain(name, bases, chains[name] === "after");
+                                        t.nom = name;
+                                }
+                        }
+                }
+                // chained methods do not return values
+                // no need to chain "invisible" functions
+
+                return ctor;    // Function
+        };
+
+        d.safeMixin = safeMixin;
+
+        /*=====
+        dojo.declare = function(className, superclass, props){
+                //      summary:
+                //              Create a feature-rich constructor from compact notation.
+                //      className: String?:
+                //              The optional name of the constructor (loosely, a "class")
+                //              stored in the "declaredClass" property in the created prototype.
+                //              It will be used as a global name for a created constructor.
+                //      superclass: Function|Function[]:
+                //              May be null, a Function, or an Array of Functions. This argument
+                //              specifies a list of bases (the left-most one is the most deepest
+                //              base).
+                //      props: Object:
+                //              An object whose properties are copied to the created prototype.
+                //              Add an instance-initialization function by making it a property
+                //              named "constructor".
+                //      returns:
+                //              New constructor function.
+                //      description:
+                //              Create a constructor using a compact notation for inheritance and
+                //              prototype extension.
+                //
+                //              Mixin ancestors provide a type of multiple inheritance.
+                //              Prototypes of mixin ancestors are copied to the new class:
+                //              changes to mixin prototypes will not affect classes to which
+                //              they have been mixed in.
+                //
+                //              Ancestors can be compound classes created by this version of
+                //              dojo.declare. In complex cases all base classes are going to be
+                //              linearized according to C3 MRO algorithm
+                //              (see http://www.python.org/download/releases/2.3/mro/ for more
+                //              details).
+                //
+                //              "className" is cached in "declaredClass" property of the new class,
+                //              if it was supplied. The immediate super class will be cached in
+                //              "superclass" property of the new class.
+                //
+                //              Methods in "props" will be copied and modified: "nom" property
+                //              (the declared name of the method) will be added to all copied
+                //              functions to help identify them for the internal machinery. Be
+                //              very careful, while reusing methods: if you use the same
+                //              function under different names, it can produce errors in some
+                //              cases.
+                //
+                //              It is possible to use constructors created "manually" (without
+                //              dojo.declare) as bases. They will be called as usual during the
+                //              creation of an instance, their methods will be chained, and even
+                //              called by "this.inherited()".
+                //
+                //              Special property "-chains-" governs how to chain methods. It is
+                //              a dictionary, which uses method names as keys, and hint strings
+                //              as values. If a hint string is "after", this method will be
+                //              called after methods of its base classes. If a hint string is
+                //              "before", this method will be called before methods of its base
+                //              classes.
+                //
+                //              If "constructor" is not mentioned in "-chains-" property, it will
+                //              be chained using the legacy mode: using "after" chaining,
+                //              calling preamble() method before each constructor, if available,
+                //              and calling postscript() after all constructors were executed.
+                //              If the hint is "after", it is chained as a regular method, but
+                //              postscript() will be called after the chain of constructors.
+                //              "constructor" cannot be chained "before", but it allows
+                //              a special hint string: "manual", which means that constructors
+                //              are not going to be chained in any way, and programmer will call
+                //              them manually using this.inherited(). In the latter case
+                //              postscript() will be called after the construction.
+                //
+                //              All chaining hints are "inherited" from base classes and
+                //              potentially can be overridden. Be very careful when overriding
+                //              hints! Make sure that all chained methods can work in a proposed
+                //              manner of chaining.
+                //
+                //              Once a method was chained, it is impossible to unchain it. The
+                //              only exception is "constructor". You don't need to define a
+                //              method in order to supply a chaining hint.
+                //
+                //              If a method is chained, it cannot use this.inherited() because
+                //              all other methods in the hierarchy will be called automatically.
+                //
+                //              Usually constructors and initializers of any kind are chained
+                //              using "after" and destructors of any kind are chained as
+                //              "before". Note that chaining assumes that chained methods do not
+                //              return any value: any returned value will be discarded.
+                //
+                //      example:
+                //      |       dojo.declare("my.classes.bar", my.classes.foo, {
+                //      |               // properties to be added to the class prototype
+                //      |               someValue: 2,
+                //      |               // initialization function
+                //      |               constructor: function(){
+                //      |                       this.myComplicatedObject = new ReallyComplicatedObject();
+                //      |               },
+                //      |               // other functions
+                //      |               someMethod: function(){
+                //      |                       doStuff();
+                //      |               }
+                //      |       });
+                //
+                //      example:
+                //      |       var MyBase = dojo.declare(null, {
+                //      |               // constructor, properties, and methods go here
+                //      |               // ...
+                //      |       });
+                //      |       var MyClass1 = dojo.declare(MyBase, {
+                //      |               // constructor, properties, and methods go here
+                //      |               // ...
+                //      |       });
+                //      |       var MyClass2 = dojo.declare(MyBase, {
+                //      |               // constructor, properties, and methods go here
+                //      |               // ...
+                //      |       });
+                //      |       var MyDiamond = dojo.declare([MyClass1, MyClass2], {
+                //      |               // constructor, properties, and methods go here
+                //      |               // ...
+                //      |       });
+                //
+                //      example:
+                //      |       var F = function(){ console.log("raw constructor"); };
+                //      |       F.prototype.method = function(){
+                //      |               console.log("raw method");
+                //      |       };
+                //      |       var A = dojo.declare(F, {
+                //      |               constructor: function(){
+                //      |                       console.log("A.constructor");
+                //      |               },
+                //      |               method: function(){
+                //      |                       console.log("before calling F.method...");
+                //      |                       this.inherited(arguments);
+                //      |                       console.log("...back in A");
+                //      |               }
+                //      |       });
+                //      |       new A().method();
+                //      |       // will print:
+                //      |       // raw constructor
+                //      |       // A.constructor
+                //      |       // before calling F.method...
+                //      |       // raw method
+                //      |       // ...back in A
+                //
+                //      example:
+                //      |       var A = dojo.declare(null, {
+                //      |               "-chains-": {
+                //      |                       destroy: "before"
+                //      |               }
+                //      |       });
+                //      |       var B = dojo.declare(A, {
+                //      |               constructor: function(){
+                //      |                       console.log("B.constructor");
+                //      |               },
+                //      |               destroy: function(){
+                //      |                       console.log("B.destroy");
+                //      |               }
+                //      |       });
+                //      |       var C = dojo.declare(B, {
+                //      |               constructor: function(){
+                //      |                       console.log("C.constructor");
+                //      |               },
+                //      |               destroy: function(){
+                //      |                       console.log("C.destroy");
+                //      |               }
+                //      |       });
+                //      |       new C().destroy();
+                //      |       // prints:
+                //      |       // B.constructor
+                //      |       // C.constructor
+                //      |       // C.destroy
+                //      |       // B.destroy
+                //
+                //      example:
+                //      |       var A = dojo.declare(null, {
+                //      |               "-chains-": {
+                //      |                       constructor: "manual"
+                //      |               }
+                //      |       });
+                //      |       var B = dojo.declare(A, {
+                //      |               constructor: function(){
+                //      |                       // ...
+                //      |                       // call the base constructor with new parameters
+                //      |                       this.inherited(arguments, [1, 2, 3]);
+                //      |                       // ...
+                //      |               }
+                //      |       });
+                //
+                //      example:
+                //      |       var A = dojo.declare(null, {
+                //      |               "-chains-": {
+                //      |                       m1: "before"
+                //      |               },
+                //      |               m1: function(){
+                //      |                       console.log("A.m1");
+                //      |               },
+                //      |               m2: function(){
+                //      |                       console.log("A.m2");
+                //      |               }
+                //      |       });
+                //      |       var B = dojo.declare(A, {
+                //      |               "-chains-": {
+                //      |                       m2: "after"
+                //      |               },
+                //      |               m1: function(){
+                //      |                       console.log("B.m1");
+                //      |               },
+                //      |               m2: function(){
+                //      |                       console.log("B.m2");
+                //      |               }
+                //      |       });
+                //      |       var x = new B();
+                //      |       x.m1();
+                //      |       // prints:
+                //      |       // B.m1
+                //      |       // A.m1
+                //      |       x.m2();
+                //      |       // prints:
+                //      |       // A.m2
+                //      |       // B.m2
+                return new Function(); // Function
+        };
+        =====*/
+
+        /*=====
+        dojo.safeMixin = function(target, source){
+                //      summary:
+                //              Mix in properties skipping a constructor and decorating functions
+                //              like it is done by dojo.declare.
+                //      target: Object
+                //              Target object to accept new properties.
+                //      source: Object
+                //              Source object for new properties.
+                //      description:
+                //              This function is used to mix in properties like dojo._mixin does,
+                //              but it skips a constructor property and decorates functions like
+                //              dojo.declare does.
+                //
+                //              It is meant to be used with classes and objects produced with
+                //              dojo.declare. Functions mixed in with dojo.safeMixin can use
+                //              this.inherited() like normal methods.
+                //
+                //              This function is used to implement extend() method of a constructor
+                //              produced with dojo.declare().
+                //
+                //      example:
+                //      |       var A = dojo.declare(null, {
+                //      |               m1: function(){
+                //      |                       console.log("A.m1");
+                //      |               },
+                //      |               m2: function(){
+                //      |                       console.log("A.m2");
+                //      |               }
+                //      |       });
+                //      |       var B = dojo.declare(A, {
+                //      |               m1: function(){
+                //      |                       this.inherited(arguments);
+                //      |                       console.log("B.m1");
+                //      |               }
+                //      |       });
+                //      |       B.extend({
+                //      |               m2: function(){
+                //      |                       this.inherited(arguments);
+                //      |                       console.log("B.m2");
+                //      |               }
+                //      |       });
+                //      |       var x = new B();
+                //      |       dojo.safeMixin(x, {
+                //      |               m1: function(){
+                //      |                       this.inherited(arguments);
+                //      |                       console.log("X.m1");
+                //      |               },
+                //      |               m2: function(){
+                //      |                       this.inherited(arguments);
+                //      |                       console.log("X.m2");
+                //      |               }
+                //      |       });
+                //      |       x.m2();
+                //      |       // prints:
+                //      |       // A.m1
+                //      |       // B.m1
+                //      |       // X.m1
+        };
+        =====*/
+
+        /*=====
+        Object.inherited = function(name, args, newArgs){
+                //      summary:
+                //              Calls a super method.
+                //      name: String?
+                //              The optional method name. Should be the same as the caller's
+                //              name. Usually "name" is specified in complex dynamic cases, when
+                //              the calling method was dynamically added, undecorated by
+                //              dojo.declare, and it cannot be determined.
+                //      args: Arguments
+                //              The caller supply this argument, which should be the original
+                //              "arguments".
+                //      newArgs: Object?
+                //              If "true", the found function will be returned without
+                //              executing it.
+                //              If Array, it will be used to call a super method. Otherwise
+                //              "args" will be used.
+                //      returns:
+                //              Whatever is returned by a super method, or a super method itself,
+                //              if "true" was specified as newArgs.
+                //      description:
+                //              This method is used inside method of classes produced with
+                //              dojo.declare to call a super method (next in the chain). It is
+                //              used for manually controlled chaining. Consider using the regular
+                //              chaining, because it is faster. Use "this.inherited()" only in
+                //              complex cases.
+                //
+                //              This method cannot me called from automatically chained
+                //              constructors including the case of a special (legacy)
+                //              constructor chaining. It cannot be called from chained methods.
+                //
+                //              If "this.inherited()" cannot find the next-in-chain method, it
+                //              does nothing and returns "undefined". The last method in chain
+                //              can be a default method implemented in Object, which will be
+                //              called last.
+                //
+                //              If "name" is specified, it is assumed that the method that
+                //              received "args" is the parent method for this call. It is looked
+                //              up in the chain list and if it is found the next-in-chain method
+                //              is called. If it is not found, the first-in-chain method is
+                //              called.
+                //
+                //              If "name" is not specified, it will be derived from the calling
+                //              method (using a methoid property "nom").
+                //
+                //      example:
+                //      |       var B = dojo.declare(A, {
+                //      |               method1: function(a, b, c){
+                //      |                       this.inherited(arguments);
+                //      |               },
+                //      |               method2: function(a, b){
+                //      |                       return this.inherited(arguments, [a + b]);
+                //      |               }
+                //      |       });
+                //      |       // next method is not in the chain list because it is added
+                //      |       // manually after the class was created.
+                //      |       B.prototype.method3 = function(){
+                //      |               console.log("This is a dynamically-added method.");
+                //      |               this.inherited("method3", arguments);
+                //      |       };
+                //      example:
+                //      |       var B = dojo.declare(A, {
+                //      |               method: function(a, b){
+                //      |                       var super = this.inherited(arguments, true);
+                //      |                       // ...
+                //      |                       if(!super){
+                //      |                               console.log("there is no super method");
+                //      |                               return 0;
+                //      |                       }
+                //      |                       return super.apply(this, arguments);
+                //      |               }
+                //      |       });
+                return  {};     // Object
+        }
+        =====*/
+
+        /*=====
+        Object.getInherited = function(name, args){
+                //      summary:
+                //              Returns a super method.
+                //      name: String?
+                //              The optional method name. Should be the same as the caller's
+                //              name. Usually "name" is specified in complex dynamic cases, when
+                //              the calling method was dynamically added, undecorated by
+                //              dojo.declare, and it cannot be determined.
+                //      args: Arguments
+                //              The caller supply this argument, which should be the original
+                //              "arguments".
+                //      returns:
+                //              Returns a super method (Function) or "undefined".
+                //      description:
+                //              This method is a convenience method for "this.inherited()".
+                //              It uses the same algorithm but instead of executing a super
+                //              method, it returns it, or "undefined" if not found.
+                //
+                //      example:
+                //      |       var B = dojo.declare(A, {
+                //      |               method: function(a, b){
+                //      |                       var super = this.getInherited(arguments);
+                //      |                       // ...
+                //      |                       if(!super){
+                //      |                               console.log("there is no super method");
+                //      |                               return 0;
+                //      |                       }
+                //      |                       return super.apply(this, arguments);
+                //      |               }
+                //      |       });
+                return  {};     // Object
+        }
+        =====*/
+
+        /*=====
+        Object.isInstanceOf = function(cls){
+                //      summary:
+                //              Checks the inheritance chain to see if it is inherited from this
+                //              class.
+                //      cls: Function
+                //              Class constructor.
+                //      returns:
+                //              "true", if this object is inherited from this class, "false"
+                //              otherwise.
+                //      description:
+                //              This method is used with instances of classes produced with
+                //              dojo.declare to determine of they support a certain interface or
+                //              not. It models "instanceof" operator.
+                //
+                //      example:
+                //      |       var A = dojo.declare(null, {
+                //      |               // constructor, properties, and methods go here
+                //      |               // ...
+                //      |       });
+                //      |       var B = dojo.declare(null, {
+                //      |               // constructor, properties, and methods go here
+                //      |               // ...
+                //      |       });
+                //      |       var C = dojo.declare([A, B], {
+                //      |               // constructor, properties, and methods go here
+                //      |               // ...
+                //      |       });
+                //      |       var D = dojo.declare(A, {
+                //      |               // constructor, properties, and methods go here
+                //      |               // ...
+                //      |       });
+                //      |
+                //      |       var a = new A(), b = new B(), c = new C(), d = new D();
+                //      |
+                //      |       console.log(a.isInstanceOf(A)); // true
+                //      |       console.log(b.isInstanceOf(A)); // false
+                //      |       console.log(c.isInstanceOf(A)); // true
+                //      |       console.log(d.isInstanceOf(A)); // true
+                //      |
+                //      |       console.log(a.isInstanceOf(B)); // false
+                //      |       console.log(b.isInstanceOf(B)); // true
+                //      |       console.log(c.isInstanceOf(B)); // true
+                //      |       console.log(d.isInstanceOf(B)); // false
+                //      |
+                //      |       console.log(a.isInstanceOf(C)); // false
+                //      |       console.log(b.isInstanceOf(C)); // false
+                //      |       console.log(c.isInstanceOf(C)); // true
+                //      |       console.log(d.isInstanceOf(C)); // false
+                //      |
+                //      |       console.log(a.isInstanceOf(D)); // false
+                //      |       console.log(b.isInstanceOf(D)); // false
+                //      |       console.log(c.isInstanceOf(D)); // false
+                //      |       console.log(d.isInstanceOf(D)); // true
+                return  {};     // Object
+        }
+        =====*/
+
+        /*=====
+        Object.extend = function(source){
+                //      summary:
+                //              Adds all properties and methods of source to constructor's
+                //              prototype, making them available to all instances created with
+                //              constructor. This method is specific to constructors created with
+                //              dojo.declare.
+                //      source: Object
+                //              Source object which properties are going to be copied to the
+                //              constructor's prototype.
+                //      description:
+                //              Adds source properties to the constructor's prototype. It can
+                //              override existing properties.
+                //
+                //              This method is similar to dojo.extend function, but it is specific
+                //              to constructors produced by dojo.declare. It is implemented
+                //              using dojo.safeMixin, and it skips a constructor property,
+                //              and properly decorates copied functions.
+                //
+                //      example:
+                //      |       var A = dojo.declare(null, {
+                //      |               m1: function(){},
+                //      |               s1: "Popokatepetl"
+                //      |       });
+                //      |       A.extend({
+                //      |               m1: function(){},
+                //      |               m2: function(){},
+                //      |               f1: true,
+                //      |               d1: 42
+                //      |       });
+        };
+        =====*/
+})();
+
+}
+
+if(!dojo._hasResource["dojo._base.connect"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base.connect"] = true;
+dojo.provide("dojo._base.connect");
+
+
+
+// this file courtesy of the TurboAjax Group, licensed under a Dojo CLA
+
+// low-level delegation machinery
+dojo._listener = {
+        // create a dispatcher function
+        getDispatcher: function(){
+                // following comments pulled out-of-line to prevent cloning them
+                // in the returned function.
+                // - indices (i) that are really in the array of listeners (ls) will
+                //   not be in Array.prototype. This is the 'sparse array' trick
+                //   that keeps us safe from libs that take liberties with built-in
+                //   objects
+                // - listener is invoked with current scope (this)
+                return function(){
+                        var ap = Array.prototype, c = arguments.callee, ls = c._listeners, t = c.target,
+                        // return value comes from original target function
+                                r = t && t.apply(this, arguments),
+                        // make local copy of listener array so it is immutable during processing
+                                i, lls = [].concat(ls)
+                        ;
+
+                        // invoke listeners after target function
+                        for(i in lls){
+                                if(!(i in ap)){
+                                        lls[i].apply(this, arguments);
+                                }
+                        }
+                        // return value comes from original target function
+                        return r;
+                };
+        },
+        // add a listener to an object
+        add: function(/*Object*/ source, /*String*/ method, /*Function*/ listener){
+                // Whenever 'method' is invoked, 'listener' will have the same scope.
+                // Trying to supporting a context object for the listener led to
+                // complexity.
+                // Non trivial to provide 'once' functionality here
+                // because listener could be the result of a dojo.hitch call,
+                // in which case two references to the same hitch target would not
+                // be equivalent.
+                source = source || dojo.global;
+                // The source method is either null, a dispatcher, or some other function
+                var f = source[method];
+                // Ensure a dispatcher
+                if(!f || !f._listeners){
+                        var d = dojo._listener.getDispatcher();
+                        // original target function is special
+                        d.target = f;
+                        // dispatcher holds a list of listeners
+                        d._listeners = [];
+                        // redirect source to dispatcher
+                        f = source[method] = d;
+                }
+                // The contract is that a handle is returned that can
+                // identify this listener for disconnect.
+                //
+                // The type of the handle is private. Here is it implemented as Integer.
+                // DOM event code has this same contract but handle is Function
+                // in non-IE browsers.
+                //
+                // We could have separate lists of before and after listeners.
+                return f._listeners.push(listener); /*Handle*/
+        },
+        // remove a listener from an object
+        remove: function(/*Object*/ source, /*String*/ method, /*Handle*/ handle){
+                var f = (source || dojo.global)[method];
+                // remember that handle is the index+1 (0 is not a valid handle)
+                if(f && f._listeners && handle--){
+                        delete f._listeners[handle];
+                }
+        }
+};
+
+// Multiple delegation for arbitrary methods.
+
+// This unit knows nothing about DOM, but we include DOM aware documentation
+// and dontFix argument here to help the autodocs. Actual DOM aware code is in
+// event.js.
+
+dojo.connect = function(/*Object|null*/ obj,
+                                                /*String*/ event,
+                                                /*Object|null*/ context,
+                                                /*String|Function*/ method,
+                                                /*Boolean?*/ dontFix){
+        // summary:
+        //              `dojo.connect` is the core event handling and delegation method in
+        //              Dojo. It allows one function to "listen in" on the execution of
+        //              any other, triggering the second whenever the first is called. Many
+        //              listeners may be attached to a function, and source functions may
+        //              be either regular function calls or DOM events.
+        //
+        // description:
+        //              Connects listeners to actions, so that after event fires, a
+        //              listener is called with the same arguments passed to the original
+        //              function.
+        //
+        //              Since `dojo.connect` allows the source of events to be either a
+        //              "regular" JavaScript function or a DOM event, it provides a uniform
+        //              interface for listening to all the types of events that an
+        //              application is likely to deal with though a single, unified
+        //              interface. DOM programmers may want to think of it as
+        //              "addEventListener for everything and anything".
+        //
+        //              When setting up a connection, the `event` parameter must be a
+        //              string that is the name of the method/event to be listened for. If
+        //              `obj` is null, `dojo.global` is assumed, meaning that connections
+        //              to global methods are supported but also that you may inadvertently
+        //              connect to a global by passing an incorrect object name or invalid
+        //              reference.
+        //
+        //              `dojo.connect` generally is forgiving. If you pass the name of a
+        //              function or method that does not yet exist on `obj`, connect will
+        //              not fail, but will instead set up a stub method. Similarly, null
+        //              arguments may simply be omitted such that fewer than 4 arguments
+        //              may be required to set up a connection See the examples for details.
+        //
+        //              The return value is a handle that is needed to
+        //              remove this connection with `dojo.disconnect`.
+        //
+        // obj:
+        //              The source object for the event function.
+        //              Defaults to `dojo.global` if null.
+        //              If obj is a DOM node, the connection is delegated
+        //              to the DOM event manager (unless dontFix is true).
+        //
+        // event:
+        //              String name of the event function in obj.
+        //              I.e. identifies a property `obj[event]`.
+        //
+        // context:
+        //              The object that method will receive as "this".
+        //
+        //              If context is null and method is a function, then method
+        //              inherits the context of event.
+        //
+        //              If method is a string then context must be the source
+        //              object object for method (context[method]). If context is null,
+        //              dojo.global is used.
+        //
+        // method:
+        //              A function reference, or name of a function in context.
+        //              The function identified by method fires after event does.
+        //              method receives the same arguments as the event.
+        //              See context argument comments for information on method's scope.
+        //
+        // dontFix:
+        //              If obj is a DOM node, set dontFix to true to prevent delegation
+        //              of this connection to the DOM event manager.
+        //
+        // example:
+        //              When obj.onchange(), do ui.update():
+        //      |       dojo.connect(obj, "onchange", ui, "update");
+        //      |       dojo.connect(obj, "onchange", ui, ui.update); // same
+        //
+        // example:
+        //              Using return value for disconnect:
+        //      |       var link = dojo.connect(obj, "onchange", ui, "update");
+        //      |       ...
+        //      |       dojo.disconnect(link);
+        //
+        // example:
+        //              When onglobalevent executes, watcher.handler is invoked:
+        //      |       dojo.connect(null, "onglobalevent", watcher, "handler");
+        //
+        // example:
+        //              When ob.onCustomEvent executes, customEventHandler is invoked:
+        //      |       dojo.connect(ob, "onCustomEvent", null, "customEventHandler");
+        //      |       dojo.connect(ob, "onCustomEvent", "customEventHandler"); // same
+        //
+        // example:
+        //              When ob.onCustomEvent executes, customEventHandler is invoked
+        //              with the same scope (this):
+        //      |       dojo.connect(ob, "onCustomEvent", null, customEventHandler);
+        //      |       dojo.connect(ob, "onCustomEvent", customEventHandler); // same
+        //
+        // example:
+        //              When globalEvent executes, globalHandler is invoked
+        //              with the same scope (this):
+        //      |       dojo.connect(null, "globalEvent", null, globalHandler);
+        //      |       dojo.connect("globalEvent", globalHandler); // same
+
+        // normalize arguments
+        var a=arguments, args=[], i=0;
+        // if a[0] is a String, obj was omitted
+        args.push(dojo.isString(a[0]) ? null : a[i++], a[i++]);
+        // if the arg-after-next is a String or Function, context was NOT omitted
+        var a1 = a[i+1];
+        args.push(dojo.isString(a1)||dojo.isFunction(a1) ? a[i++] : null, a[i++]);
+        // absorb any additional arguments
+        for(var l=a.length; i<l; i++){  args.push(a[i]); }
+        // do the actual work
+        return dojo._connect.apply(this, args); /*Handle*/
+}
+
+// used by non-browser hostenvs. always overriden by event.js
+dojo._connect = function(obj, event, context, method){
+        var l=dojo._listener, h=l.add(obj, event, dojo.hitch(context, method));
+        return [obj, event, h, l]; // Handle
+};
+
+dojo.disconnect = function(/*Handle*/ handle){
+        // summary:
+        //              Remove a link created by dojo.connect.
+        // description:
+        //              Removes the connection between event and the method referenced by handle.
+        // handle:
+        //              the return value of the dojo.connect call that created the connection.
+        if(handle && handle[0] !== undefined){
+                dojo._disconnect.apply(this, handle);
+                // let's not keep this reference
+                delete handle[0];
+        }
+};
+
+dojo._disconnect = function(obj, event, handle, listener){
+        listener.remove(obj, event, handle);
+};
+
+// topic publish/subscribe
+
+dojo._topics = {};
+
+dojo.subscribe = function(/*String*/ topic, /*Object|null*/ context, /*String|Function*/ method){
+        //      summary:
+        //              Attach a listener to a named topic. The listener function is invoked whenever the
+        //              named topic is published (see: dojo.publish).
+        //              Returns a handle which is needed to unsubscribe this listener.
+        //      context:
+        //              Scope in which method will be invoked, or null for default scope.
+        //      method:
+        //              The name of a function in context, or a function reference. This is the function that
+        //              is invoked when topic is published.
+        //      example:
+        //      |       dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); });
+        //      |       dojo.publish("alerts", [ "read this", "hello world" ]);
+
+        // support for 2 argument invocation (omitting context) depends on hitch
+        return [topic, dojo._listener.add(dojo._topics, topic, dojo.hitch(context, method))]; /*Handle*/
+};
+
+dojo.unsubscribe = function(/*Handle*/ handle){
+        //      summary:
+        //              Remove a topic listener.
+        //      handle:
+        //              The handle returned from a call to subscribe.
+        //      example:
+        //      |       var alerter = dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
+        //      |       ...
+        //      |       dojo.unsubscribe(alerter);
+        if(handle){
+                dojo._listener.remove(dojo._topics, handle[0], handle[1]);
+        }
+};
+
+dojo.publish = function(/*String*/ topic, /*Array*/ args){
+        //      summary:
+        //              Invoke all listener method subscribed to topic.
+        //      topic:
+        //              The name of the topic to publish.
+        //      args:
+        //              An array of arguments. The arguments will be applied
+        //              to each topic subscriber (as first class parameters, via apply).
+        //      example:
+        //      |       dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
+        //      |       dojo.publish("alerts", [ "read this", "hello world" ]);
+
+        // Note that args is an array, which is more efficient vs variable length
+        // argument list.  Ideally, var args would be implemented via Array
+        // throughout the APIs.
+        var f = dojo._topics[topic];
+        if(f){
+                f.apply(this, args||[]);
+        }
+};
+
+dojo.connectPublisher = function(       /*String*/ topic,
+                                                                        /*Object|null*/ obj,
+                                                                        /*String*/ event){
+        //      summary:
+        //              Ensure that every time obj.event() is called, a message is published
+        //              on the topic. Returns a handle which can be passed to
+        //              dojo.disconnect() to disable subsequent automatic publication on
+        //              the topic.
+        //      topic:
+        //              The name of the topic to publish.
+        //      obj:
+        //              The source object for the event function. Defaults to dojo.global
+        //              if null.
+        //      event:
+        //              The name of the event function in obj.
+        //              I.e. identifies a property obj[event].
+        //      example:
+        //      |       dojo.connectPublisher("/ajax/start", dojo, "xhrGet");
+        var pf = function(){ dojo.publish(topic, arguments); }
+        return event ? dojo.connect(obj, event, pf) : dojo.connect(obj, pf); //Handle
+};
+
+}
+
+if(!dojo._hasResource["dojo._base.Deferred"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base.Deferred"] = true;
+dojo.provide("dojo._base.Deferred");
+
+
+
+(function(){
+        var mutator = function(){};
+        var freeze = Object.freeze || function(){};
+        // A deferred provides an API for creating and resolving a promise.
+        dojo.Deferred = function(/*Function?*/canceller){
+        // summary:
+        //              Deferreds provide a generic means for encapsulating an asynchronous
+        //              operation and notifying users of the completion and result of the operation.
+        // description:
+        //              The dojo.Deferred API is based on the concept of promises that provide a
+        //              generic interface into the eventual completion of an asynchronous action.
+        //              The motivation for promises fundamentally is about creating a
+        //              separation of concerns that allows one to achieve the same type of
+        //              call patterns and logical data flow in asynchronous code as can be
+        //              achieved in synchronous code. Promises allows one
+        //              to be able to call a function purely with arguments needed for
+        //              execution, without conflating the call with concerns of whether it is
+        //              sync or async. One shouldn't need to alter a call's arguments if the
+        //              implementation switches from sync to async (or vice versa). By having
+        //              async functions return promises, the concerns of making the call are
+        //              separated from the concerns of asynchronous interaction (which are
+        //              handled by the promise).
+        //
+        //      The dojo.Deferred is a type of promise that provides methods for fulfilling the
+        //              promise with a successful result or an error. The most important method for
+        //              working with Dojo's promises is the then() method, which follows the
+        //              CommonJS proposed promise API. An example of using a Dojo promise:
+        //
+        //              |       var resultingPromise = someAsyncOperation.then(function(result){
+        //              |               ... handle result ...
+        //              |       },
+        //              |       function(error){
+        //              |               ... handle error ...
+        //              |       });
+        //
+        //              The .then() call returns a new promise that represents the result of the
+        //              execution of the callback. The callbacks will never affect the original promises value.
+        //
+        //              The dojo.Deferred instances also provide the following functions for backwards compatibility:
+        //
+        //                      * addCallback(handler)
+        //                      * addErrback(handler)
+        //                      * callback(result)
+        //                      * errback(result)
+        //
+        //              Callbacks are allowed to return promises themselves, so
+        //              you can build complicated sequences of events with ease.
+        //
+        //              The creator of the Deferred may specify a canceller.  The canceller
+        //              is a function that will be called if Deferred.cancel is called
+        //              before the Deferred fires. You can use this to implement clean
+        //              aborting of an XMLHttpRequest, etc. Note that cancel will fire the
+        //              deferred with a CancelledError (unless your canceller returns
+        //              another kind of error), so the errbacks should be prepared to
+        //              handle that error for cancellable Deferreds.
+        // example:
+        //      |       var deferred = new dojo.Deferred();
+        //      |       setTimeout(function(){ deferred.callback({success: true}); }, 1000);
+        //      |       return deferred;
+        // example:
+        //              Deferred objects are often used when making code asynchronous. It
+        //              may be easiest to write functions in a synchronous manner and then
+        //              split code using a deferred to trigger a response to a long-lived
+        //              operation. For example, instead of register a callback function to
+        //              denote when a rendering operation completes, the function can
+        //              simply return a deferred:
+        //
+        //              |       // callback style:
+        //              |       function renderLotsOfData(data, callback){
+        //              |               var success = false
+        //              |               try{
+        //              |                       for(var x in data){
+        //              |                               renderDataitem(data[x]);
+        //              |                       }
+        //              |                       success = true;
+        //              |               }catch(e){ }
+        //              |               if(callback){
+        //              |                       callback(success);
+        //              |               }
+        //              |       }
+        //
+        //              |       // using callback style
+        //              |       renderLotsOfData(someDataObj, function(success){
+        //              |               // handles success or failure
+        //              |               if(!success){
+        //              |                       promptUserToRecover();
+        //              |               }
+        //              |       });
+        //              |       // NOTE: no way to add another callback here!!
+        // example:
+        //              Using a Deferred doesn't simplify the sending code any, but it
+        //              provides a standard interface for callers and senders alike,
+        //              providing both with a simple way to service multiple callbacks for
+        //              an operation and freeing both sides from worrying about details
+        //              such as "did this get called already?". With Deferreds, new
+        //              callbacks can be added at any time.
+        //
+        //              |       // Deferred style:
+        //              |       function renderLotsOfData(data){
+        //              |               var d = new dojo.Deferred();
+        //              |               try{
+        //              |                       for(var x in data){
+        //              |                               renderDataitem(data[x]);
+        //              |                       }
+        //              |                       d.callback(true);
+        //              |               }catch(e){
+        //              |                       d.errback(new Error("rendering failed"));
+        //              |               }
+        //              |               return d;
+        //              |       }
+        //
+        //              |       // using Deferred style
+        //              |       renderLotsOfData(someDataObj).then(null, function(){
+        //              |               promptUserToRecover();
+        //              |       });
+        //              |       // NOTE: addErrback and addCallback both return the Deferred
+        //              |       // again, so we could chain adding callbacks or save the
+        //              |       // deferred for later should we need to be notified again.
+        // example:
+        //              In this example, renderLotsOfData is synchronous and so both
+        //              versions are pretty artificial. Putting the data display on a
+        //              timeout helps show why Deferreds rock:
+        //
+        //              |       // Deferred style and async func
+        //              |       function renderLotsOfData(data){
+        //              |               var d = new dojo.Deferred();
+        //              |               setTimeout(function(){
+        //              |                       try{
+        //              |                               for(var x in data){
+        //              |                                       renderDataitem(data[x]);
+        //              |                               }
+        //              |                               d.callback(true);
+        //              |                       }catch(e){
+        //              |                               d.errback(new Error("rendering failed"));
+        //              |                       }
+        //              |               }, 100);
+        //              |               return d;
+        //              |       }
+        //
+        //              |       // using Deferred style
+        //              |       renderLotsOfData(someDataObj).then(null, function(){
+        //              |               promptUserToRecover();
+        //              |       });
+        //
+        //              Note that the caller doesn't have to change his code at all to
+        //              handle the asynchronous case.
+                var result, finished, isError, head, nextListener;
+                var promise = (this.promise = {});
+                
+                function complete(value){
+                        if(finished){
+                                throw new Error("This deferred has already been resolved");
+                        }
+                        result = value;
+                        finished = true;
+                        notify();
+                }
+                function notify(){
+                        var mutated;
+                        while(!mutated && nextListener){
+                                var listener = nextListener;
+                                nextListener = nextListener.next;
+                                if((mutated = (listener.progress == mutator))){ // assignment and check
+                                        finished = false;
+                                }
+                                var func = (isError ? listener.error : listener.resolved);
+                                if (func) {
+                                        try {
+                                                var newResult = func(result);
+                                                if (newResult && typeof newResult.then === "function") {
+                                                        newResult.then(dojo.hitch(listener.deferred, "resolve"), dojo.hitch(listener.deferred, "reject"));
+                                                        continue;
+                                                }
+                                                var unchanged = mutated && newResult === undefined;
+                                                if(mutated && !unchanged){
+                                                        isError = newResult instanceof Error;
+                                                }
+                                                listener.deferred[unchanged && isError ? "reject" : "resolve"](unchanged ? result : newResult);
+                                        }
+                                        catch (e) {
+                                                listener.deferred.reject(e);
+                                        }
+                                }else {
+                                        if(isError){
+                                                listener.deferred.reject(result);
+                                        }else{
+                                                listener.deferred.resolve(result);
+                                        }
+                                }
+                        }
+                }
+                // calling resolve will resolve the promise
+                this.resolve = this.callback = function(value){
+                        // summary:
+                        //              Fulfills the Deferred instance successfully with the provide value
+                        this.fired = 0;
+                        this.results = [value, null];
+                        complete(value);
+                };
+                
+                
+                // calling error will indicate that the promise failed
+                this.reject = this.errback = function(error){
+                        // summary:
+                        //              Fulfills the Deferred instance as an error with the provided error
+                        isError = true;
+                        this.fired = 1;
+                        complete(error);
+                        this.results = [null, error];
+                        if(!error || error.log !== false){
+                                (dojo.config.deferredOnError || function(x){ console.error(x); })(error);
+                        }
+                };
+                // call progress to provide updates on the progress on the completion of the promise
+                this.progress = function(update){
+                        // summary
+                        //              Send progress events to all listeners
+                        var listener = nextListener;
+                        while(listener){
+                                var progress = listener.progress;
+                                progress && progress(update);
+                                listener = listener.next;
+                        }
+                };
+                this.addCallbacks = function(/*Function?*/callback, /*Function?*/errback){
+                        this.then(callback, errback, mutator);
+                        return this;
+                };
+                // provide the implementation of the promise
+                this.then = promise.then = function(/*Function?*/resolvedCallback, /*Function?*/errorCallback, /*Function?*/progressCallback){
+                        // summary:
+                        //              Adds a fulfilledHandler, errorHandler, and progressHandler to be called for
+                        //              completion of a promise. The fulfilledHandler is called when the promise
+                        //              is fulfilled. The errorHandler is called when a promise fails. The
+                        //              progressHandler is called for progress events. All arguments are optional
+                        //              and non-function values are ignored. The progressHandler is not only an
+                        //              optional argument, but progress events are purely optional. Promise
+                        //              providers are not required to ever create progress events.
+                        //
+                        //              This function will return a new promise that is fulfilled when the given
+                        //              fulfilledHandler or errorHandler callback is finished. This allows promise
+                        //              operations to be chained together. The value returned from the callback
+                        //              handler is the fulfillment value for the returned promise. If the callback
+                        //              throws an error, the returned promise will be moved to failed state.
+                        //
+                        // example:
+                        //              An example of using a CommonJS compliant promise:
+                        //              |       asyncComputeTheAnswerToEverything().
+                        //              |               then(addTwo).
+                        //              |               then(printResult, onError);
+                        //              |       >44
+                        //
+                        var returnDeferred = progressCallback == mutator ? this : new dojo.Deferred(promise.cancel);
+                        var listener = {
+                                resolved: resolvedCallback,
+                                error: errorCallback,
+                                progress: progressCallback,
+                                deferred: returnDeferred
+                        };
+                        if(nextListener){
+                                head = head.next = listener;
+                        }
+                        else{
+                                nextListener = head = listener;
+                        }
+                        if(finished){
+                                notify();
+                        }
+                        return returnDeferred.promise;
+                };
+                var deferred = this;
+                this.cancel = promise.cancel = function () {
+                        // summary:
+                        //              Cancels the asynchronous operation
+                        if(!finished){
+                                var error = canceller && canceller(deferred);
+                                if(!finished){
+                                        if (!(error instanceof Error)) {
+                                                error = new Error(error);
+                                        }
+                                        error.log = false;
+                                        deferred.reject(error);
+                                }
+                        }
+                };
+                freeze(promise);
+        };
+        dojo.extend(dojo.Deferred, {
+                addCallback: function (/*Function*/callback) {
+                        return this.addCallbacks(dojo.hitch.apply(dojo, arguments));
+                },
+        
+                addErrback: function (/*Function*/errback) {
+                        return this.addCallbacks(null, dojo.hitch.apply(dojo, arguments));
+                },
+        
+                addBoth: function (/*Function*/callback) {
+                        var enclosed = dojo.hitch.apply(dojo, arguments);
+                        return this.addCallbacks(enclosed, enclosed);
+                },
+                fired: -1
+        });
+})();
+dojo.when = function(promiseOrValue, /*Function?*/callback, /*Function?*/errback, /*Function?*/progressHandler){
+        // summary:
+        //              This provides normalization between normal synchronous values and
+        //              asynchronous promises, so you can interact with them in a common way
+        //      example:
+        //              |       function printFirstAndList(items){
+        //              |               dojo.when(findFirst(items), console.log);
+        //              |               dojo.when(findLast(items), console.log);
+        //              |       }
+        //              |       function findFirst(items){
+        //              |               return dojo.when(items, function(items){
+        //              |                       return items[0];
+        //              |               });
+        //              |       }
+        //              |       function findLast(items){
+        //              |               return dojo.when(items, function(items){
+        //              |                       return items[items.length];
+        //              |               });
+        //              |       }
+        //              And now all three of his functions can be used sync or async.
+        //              |       printFirstAndLast([1,2,3,4]) will work just as well as
+        //              |       printFirstAndLast(dojo.xhrGet(...));
+        
+        if(promiseOrValue && typeof promiseOrValue.then === "function"){
+                return promiseOrValue.then(callback, errback, progressHandler);
+        }
+        return callback(promiseOrValue);
+};
+
+}
+
+if(!dojo._hasResource["dojo._base.json"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base.json"] = true;
+dojo.provide("dojo._base.json");
+
+
+dojo.fromJson = function(/*String*/ json){
+        // summary:
+        //              Parses a [JSON](http://json.org) string to return a JavaScript object.
+        // description:
+        //              Throws for invalid JSON strings, but it does not use a strict JSON parser. It
+        //              delegates to eval().  The content passed to this method must therefore come
+        //              from a trusted source.
+        // json:
+        //              a string literal of a JSON item, for instance:
+        //                      `'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'`
+
+        return eval("(" + json + ")"); // Object
+};
+
+dojo._escapeString = function(/*String*/str){
+        //summary:
+        //              Adds escape sequences for non-visual characters, double quote and
+        //              backslash and surrounds with double quotes to form a valid string
+        //              literal.
+        return ('"' + str.replace(/(["\\])/g, '\\$1') + '"').
+                replace(/[\f]/g, "\\f").replace(/[\b]/g, "\\b").replace(/[\n]/g, "\\n").
+                replace(/[\t]/g, "\\t").replace(/[\r]/g, "\\r"); // string
+};
+
+dojo.toJsonIndentStr = "\t";
+dojo.toJson = function(/*Object*/ it, /*Boolean?*/ prettyPrint, /*String?*/ _indentStr){
+        //      summary:
+        //              Returns a [JSON](http://json.org) serialization of an object.
+        //      description:
+        //              Returns a [JSON](http://json.org) serialization of an object.
+        //              Note that this doesn't check for infinite recursion, so don't do that!
+        //      it:
+        //              an object to be serialized. Objects may define their own
+        //              serialization via a special "__json__" or "json" function
+        //              property. If a specialized serializer has been defined, it will
+        //              be used as a fallback.
+        //      prettyPrint:
+        //              if true, we indent objects and arrays to make the output prettier.
+        //              The variable `dojo.toJsonIndentStr` is used as the indent string --
+        //              to use something other than the default (tab), change that variable
+        // &n